aws-samples / aws-iot-securetunneling-localproxy

AWS Iot Secure Tunneling local proxy reference C++ implementation
https://docs.aws.amazon.com/iot/latest/developerguide/what-is-secure-tunneling.html
Apache License 2.0
73 stars 70 forks source link

[suggestion] add support for raspberry pi builds #99

Closed Job-Heersink closed 10 months ago

Job-Heersink commented 1 year ago

I've been trying to build this application for my raspberry pi 3B+ using several of your proposed methods, but the raspberry pi 3B+ simply does not have enough compute power to build the dependencies. This issue with hardware limitations should be familiar with you, since i have seen it appear a number of times in other issues.

As a solution you propose cross-compilation on other machines, but give insufficient instructions on how to do so. For example, in the instructions you state: "Consult each dependency's documentation for guidance on how to cross compile". A reference to this information or some additional instructions would be nice :)

Since devices with limited hardware requirements are presumably a big portion of the market of AWS iot, having proper documentation/support for those builds would be great to have!

As a solution, you could do one of the following:

I'm only posting this since I see the potential in this project and would love to be able to use it :)

RogerZhongAWS commented 1 year ago

Hello, thanks for your suggestion! We do indeed want to have a long-term solution for this, please stay tuned for more details.

aikrana commented 1 year ago

I've been trying to build this application for my raspberry pi 3B+ using several of your proposed methods, but the raspberry pi 3B+ simply does not have enough compute power to build the dependencies. This issue with hardware limitations should be familiar with you, since i have seen it appear a number of times in other issues.

As a solution you propose cross-compilation on other machines, but give insufficient instructions on how to do so. For example, in the instructions you state: "Consult each dependency's documentation for guidance on how to cross compile". A reference to this information or some additional instructions would be nice :)

Since devices with limited hardware requirements are presumably a big portion of the market of AWS iot, having proper documentation/support for those builds would be great to have!

As a solution, you could do one of the following:

  • expand your documentation to include reference/further instructions for cross compilation.
  • prebuild docker images for specific architectures (ARMv7, ARM64, etc ) and have them publicly accessible on repositories.
  • prebuild package and make available via apt-get

I'm only posting this since I see the potential in this project and would love to be able to use it :)

It took me a long day but I managed to build it for 3B+ increasing the swap to 1GB and applying #103

sruon commented 1 year ago
# syntax = docker/dockerfile:1.4.0

FROM alpine

RUN apk add musl git wget tar zlib cmake openssl-libs-static gcc g++ linux-headers autoconf automake libtool make libucontext-dev

RUN wget https://boostorg.jfrog.io/artifactory/main/release/1.76.0/source/boost_1_76_0.tar.gz -O /tmp/boost.tar.gz && \
    tar xzvf /tmp/boost.tar.gz && \
    cd boost_1_76_0 && \
    ./bootstrap.sh && \
    ./b2 install link=static || /bin/true

RUN wget https://github.com/protocolbuffers/protobuf/releases/download/v3.17.3/protobuf-all-3.17.3.tar.gz -O /tmp/protobuf-all-3.17.3.tar.gz && \
    tar xzvf /tmp/protobuf-all-3.17.3.tar.gz && \
    cd protobuf-3.17.3 && \
    ./autogen.sh && \
    ./configure --enable-static --disable-shared && \
    make && \
    make install

RUN wget https://www.openssl.org/source/openssl-1.1.1.tar.gz && \
    tar xvf openssl-1.1.1.tar.gz && \
    cd openssl-1.1.1 && \
    ./Configure no-shared -lucontext linux-aarch64 && \
    make && \
    make install

RUN git clone --depth 1 --branch v3.0.2 https://github.com/aws-samples/aws-iot-securetunneling-localproxy.git localproxy

RUN <<EOF cat > /localproxy/CMakeLists.txt
cmake_minimum_required(VERSION 3.2 FATAL_ERROR)
set(AWS_TUNNEL_LOCAL_PROXY_TARGET_NAME localproxy)
set(AWS_TUNNEL_LOCAL_PROXY_LIB_NAME lproxy)
project(\${AWS_TUNNEL_LOCAL_PROXY_TARGET_NAME} CXX)
if (\${PROJECT_SOURCE_DIR} STREQUAL \${PROJECT_BINARY_DIR})
    message(FATAL_ERROR "In-source builds not allowed. Please make a new directory (called a build directory) and run CMake from there. You may need to remove CMakeCache.txt and CMakeFiles folder.")
endif ()
set(CMAKE_CXX_STANDARD 14) # C++14
set(CMAKE_CXX_STANDARD_REQUIRED ON) #...is required...
set(CMAKE_CXX_EXTENSIONS OFF) #...without compiler extensions like gnu++11
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY \${CMAKE_BINARY_DIR}/bin)
# Configure Compiler flags
if (UNIX OR APPLE)
    set(CUSTOM_COMPILER_FLAGS "-O2 -D_FORTIFY_SOURCE=2 -fPIE -Wall -Werror")
    set(TEST_COMPILER_FLAGS "\${CUSTOM_COMPILER_FLAGS} -D_AWSIOT_TUNNELING_NO_SSL")
elseif (WIN32 OR MSVC)
    set(CUSTOM_COMPILER_FLAGS "/W4 /DYNAMICBASE /NXCOMPAT /analyze")
    set(TEST_COMPILER_FLAGS "\${CUSTOM_COMPILER_FLAGS} /D_AWSIOT_TUNNELING_NO_SSL")
    add_definitions(-D_WIN32_WINNT=\${WIN32_WINNT})
endif ()
find_package(Threads)
set_property(GLOBAL PROPERTY PROTOBUF_USE_STATIC_LIBS ON)  #this flag doesn't actually seem to work yet but it's documented
find_package(Protobuf 3.17.3 REQUIRED)
string(REPLACE \${CMAKE_SHARED_LIBRARY_SUFFIX} \${CMAKE_STATIC_LIBRARY_SUFFIX} Protobuf_LITE_STATIC_LIBRARY \${Protobuf_LITE_LIBRARY})
include_directories(\${Protobuf_INCLUDE_DIRS})
include_directories(\${CMAKE_CURRENT_BINARY_DIR}) #needed to include generated protobuf headers
protobuf_generate_cpp(PROTO_SRCS PROTO_HDRS \${PROJECT_SOURCE_DIR}/resources/Message.proto)
#########################################
# OpenSSL dependency                    #
#########################################
find_package(OpenSSL REQUIRED)
set_property(GLOBAL PROPERTY Boost_USE_STATIC_LIBS ON)
set_property(GLOBAL PROPERTY Boost_USE_DEBUG_RUNTIME OFF)
#set_property(GLOBAL PROPERTY Boost_USE_MULTITHREADED ON)
find_package(Boost 1.76.0 REQUIRED COMPONENTS system log log_setup thread program_options date_time filesystem)
include_directories(\${Boost_INCLUDE_DIRS})
foreach(BOOST_LIB \${Boost_LIBRARIES})
    string(REPLACE \${CMAKE_SHARED_LIBRARY_SUFFIX} \${CMAKE_STATIC_LIBRARY_SUFFIX} BOOST_STATIC_LIB \${BOOST_LIB})
    list(APPEND Boost_STATIC_LIBRARIES \${BOOST_STATIC_LIB})
endforeach()
file(GLOB ALL_SOURCES \${PROJECT_SOURCE_DIR}/src/*.cpp)
set(UTIL_SOURCE \${PROJECT_SOURCE_DIR}/src/config/ConfigFile.cpp \${PROJECT_SOURCE_DIR}/src/Url.cpp)
set(CORE_SOURCES \${PROJECT_SOURCE_DIR}/src/TcpAdapterProxy.cpp \${PROJECT_SOURCE_DIR}/src/ProxySettings.cpp \${PROJECT_SOURCE_DIR}/src/WebProxyAdapter.cpp \${PROTO_HDRS} \${PROTO_SRCS} \${PROJECT_SOURCE_DIR}/src/WebSocketStream.cpp)
set(MAIN_SOURCES \${PROJECT_SOURCE_DIR}/src/main.cpp \${CORE_SOURCES} \${UTIL_SOURCE})
link_libraries("-static")
add_executable(\${AWS_TUNNEL_LOCAL_PROXY_TARGET_NAME} \${MAIN_SOURCES})
#libatomic ensured for all platforms except OSX and WINDOWS
if(NOT APPLE AND NOT MSVC)
    target_link_libraries(\${AWS_TUNNEL_LOCAL_PROXY_TARGET_NAME} atomic)
endif()
target_link_libraries(\${AWS_TUNNEL_LOCAL_PROXY_TARGET_NAME} \${CMAKE_THREAD_LIBS_INIT})
target_link_libraries(\${AWS_TUNNEL_LOCAL_PROXY_TARGET_NAME} OpenSSL::SSL)
target_link_libraries(\${AWS_TUNNEL_LOCAL_PROXY_TARGET_NAME} OpenSSL::Crypto)
target_link_libraries(\${AWS_TUNNEL_LOCAL_PROXY_TARGET_NAME} \${Boost_STATIC_LIBRARIES})
target_link_libraries(\${AWS_TUNNEL_LOCAL_PROXY_TARGET_NAME} \${Protobuf_LITE_STATIC_LIBRARY})
set_property(TARGET \${AWS_TUNNEL_LOCAL_PROXY_TARGET_NAME} APPEND_STRING PROPERTY COMPILE_FLAGS \${CUSTOM_COMPILER_FLAGS})
EOF

WORKDIR /localproxy/build

RUN cmake -DCMAKE_CXX_STANDARD_LIBRARIES="-lucontext" ..
RUN make

Builds a statically linked binary that works on a Raspberry Pi.

The boost build command exits with 1 for some non-issue, hence the /bin/true

The CMakeLists is modified slightly to enable static linking and remove references to the test binary/Catch2 library.

The OpenSSL steps can be removed when the project will start supporting OpenSSL 3 and replaced by apk add openssl-libs-static

Command used to build on a M1 Mac

docker buildx build --platform linux/arm64 --tag localproxy-arm64-builder:latest --file localproxy.Dockerfile .

HarshGandhi-AWS commented 10 months ago

Hello, the main issue with building localproxy on Raspberry pi is the low memory available on the device to build dependency libraries like CMake and Boost. Since it is a memory requirement from dependency library, we cannot do much about it. I would suggest using crossbuild for building a binary for raspberry pi OS or to use docker for building binary for your raspberry pi device. This will also me much faster since the build time will be less.

Closing this issue now since we do not have any possible action item to work on. PLease reopen or create a new issue if you are facing any difficulty using local proxy. Thank you.