From d1dbfc89c55b9334173034297ef5386162ee2e68 Mon Sep 17 00:00:00 2001 From: lwthiker Date: Wed, 9 Mar 2022 11:01:44 +0200 Subject: [PATCH] Use a template for generating Dockerfiles Since the firefox and chrome builds are similar except for the TLS library used, it makes sense to unify their Dockerfiles. This commit introduces a template Dockerfile from which both the build Dockerfiles are generated using the simple 'mustache' template system. --- Dockerfile.template | 171 ++++++++++++++++++++++++++++++++++++++++ chrome/Dockerfile | 27 +++++-- firefox/Dockerfile | 41 ++++++---- generate_dockerfiles.sh | 13 +++ 4 files changed, 231 insertions(+), 21 deletions(-) create mode 100644 Dockerfile.template create mode 100755 generate_dockerfiles.sh diff --git a/Dockerfile.template b/Dockerfile.template new file mode 100644 index 0000000..ee5d5b8 --- /dev/null +++ b/Dockerfile.template @@ -0,0 +1,171 @@ +# +# NOTE: THIS DOCKERFILE IS GENERATED FROM "Dockerfile.template" VIA +# "generate-dockerfiles.sh". +# +# PLEASE DO NOT EDIT IT DIRECTLY. +# + +# Python is needed for building libnss. +# Use it as a common base. +FROM python:3.10.1-slim-buster + +WORKDIR /build + +# Common dependencies +RUN apt-get update && \ + apt-get install -y git ninja-build cmake curl zlib1g-dev + +{{#firefox}} +# Dependencies for building libnss +# See https://firefox-source-docs.mozilla.org/security/nss/build.html#mozilla-projects-nss-building +RUN apt-get install -y mercurial python3-pip + +# curl tries to load the CA certificates for libnss. +# It loads them from /usr/lib/x86_64-linux-gnu/nss/libnssckbi.so, +# which is supplied by libnss3 on Debian/Ubuntu +RUN apt-get install -y libnss3 +{{/firefox}} + +{{#chrome}} +# Dependencies for downloading and building BoringSSL +RUN apt-get install -y g++ golang-go unzip +{{/chrome}} + +# The following are needed because we are going to change some autoconf scripts, +# both for libnghttp2 and curl. +RUN apt-get install -y autoconf automake autotools-dev pkg-config libtool + +# Download and compile libbrotli +ARG BROTLI_VERSION=1.0.9 +RUN curl -L https://github.com/google/brotli/archive/refs/tags/v${BROTLI_VERSION}.tar.gz -o brotli-${BROTLI_VERSION}.tar.gz && \ + tar xf brotli-${BROTLI_VERSION}.tar.gz +RUN cd brotli-${BROTLI_VERSION} && \ + mkdir build && cd build && \ + cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=./installed .. && \ + cmake --build . --config Release --target install + +{{#firefox}} +# Needed for building libnss +RUN pip install gyp-next + +ARG NSS_VERSION=nss-3.74 +# This tarball is already bundled with nspr, a dependency of libnss. +ARG NSS_URL=https://ftp.mozilla.org/pub/security/nss/releases/NSS_3_74_RTM/src/nss-3.74-with-nspr-4.32.tar.gz + +# Download and compile nss. +RUN curl -o ${NSS_VERSION}.tar.gz ${NSS_URL} +RUN tar xf ${NSS_VERSION}.tar.gz && \ + cd ${NSS_VERSION}/nss && \ + ./build.sh -o --disable-tests --static +{{/firefox}} + +{{#chrome}} +# BoringSSL doesn't have versions. Choose a commit that is used in a stable +# Chromium version. +ARG BORING_SSL_COMMIT=3a667d10e94186fd503966f5638e134fe9fb4080 +RUN curl -L https://github.com/google/boringssl/archive/${BORING_SSL_COMMIT}.zip -o boringssl.zip && \ + unzip boringssl && \ + mv boringssl-${BORING_SSL_COMMIT} boringssl + +# Compile BoringSSL. +# See https://boringssl.googlesource.com/boringssl/+/HEAD/BUILDING.md +COPY patches/boringssl-*.patch boringssl/ +RUN cd boringssl && \ + for p in $(ls boringssl-*.patch); do patch -p1 < $p; done && \ + mkdir build && cd build && \ + cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_POSITION_INDEPENDENT_CODE=on -GNinja .. && \ + ninja + +# Fix the directory structure so that curl can compile against it. +# See https://everything.curl.dev/source/build/tls/boringssl +RUN mkdir boringssl/build/lib && \ + ln -s ../crypto/libcrypto.a boringssl/build/lib/libcrypto.a && \ + ln -s ../ssl/libssl.a boringssl/build/lib/libssl.a && \ + cp -R boringssl/include boringssl/build +{{/chrome}} + +ARG NGHTTP2_VERSION=nghttp2-1.46.0 +ARG NGHTTP2_URL=https://github.com/nghttp2/nghttp2/releases/download/v1.46.0/nghttp2-1.46.0.tar.bz2 + +# Download nghttp2 for HTTP/2.0 support. +RUN curl -o ${NGHTTP2_VERSION}.tar.bz2 -L ${NGHTTP2_URL} +RUN tar xf ${NGHTTP2_VERSION}.tar.bz2 + +# Patch nghttp2 pkg config file to support static builds. +COPY patches/libnghttp2-*.patch ${NGHTTP2_VERSION}/ +RUN cd ${NGHTTP2_VERSION} && \ + for p in $(ls libnghttp2-*.patch); do patch -p1 < $p; done && \ + autoreconf -i && automake && autoconf + +# Compile nghttp2 +RUN cd ${NGHTTP2_VERSION} && \ + ./configure --with-pic && \ + make && make install + +# Download curl. +ARG CURL_VERSION=curl-7.81.0 +RUN curl -o ${CURL_VERSION}.tar.xz https://curl.se/download/${CURL_VERSION}.tar.xz +RUN tar xf ${CURL_VERSION}.tar.xz + +# Patch curl and re-generate the configure script +COPY patches/curl-*.patch ${CURL_VERSION}/ +RUN cd ${CURL_VERSION} && \ + for p in $(ls curl-*.patch); do patch -p1 < $p; done && \ + autoreconf -fi + +# Compile curl with nghttp2, libbrotli and nss (firefox) or boringssl (chrome). +# Enable keylogfile for debugging of TLS traffic. +RUN cd ${CURL_VERSION} && \ + ./configure --enable-static \ + --disable-shared \ + --with-nghttp2=/usr/local \ + --with-brotli=/build/brotli-${BROTLI_VERSION}/build/installed \ +{{#firefox}} + --with-nss=/build/${NSS_VERSION}/dist/Release \ + CFLAGS="-I/build/${NSS_VERSION}/dist/public/nss -I/build/${NSS_VERSION}/dist/Release/include/nspr" \ +{{/firefox}} +{{#chrome}} + --with-openssl=/build/boringssl/build \ + LIBS="-pthread" \ + CFLAGS="-I/build/boringssl/build" \ +{{/chrome}} + USE_CURL_SSLKEYLOGFILE=true && \ + make + +RUN mkdir out && \ + cp ${CURL_VERSION}/src/curl out/curl-impersonate && \ + strip out/curl-impersonate + +# Re-compile libcurl dynamically +RUN cd ${CURL_VERSION} && \ + ./configure --with-nghttp2=/usr/local \ + --with-brotli=/build/brotli-${BROTLI_VERSION}/build/installed \ +{{#firefox}} + --with-nss=/build/${NSS_VERSION}/dist/Release \ + CFLAGS="-I/build/${NSS_VERSION}/dist/public/nss -I/build/${NSS_VERSION}/dist/Release/include/nspr" \ +{{/firefox}} +{{#chrome}} + --with-openssl=/build/boringssl/build \ + LIBS="-pthread" \ + CFLAGS="-I/build/boringssl/build" \ +{{/chrome}} + USE_CURL_SSLKEYLOGFILE=true && \ + make clean && make + +# Rename to 'libcurl-impersonate' to avoid confusion, and recreate the +# symbolic links. +RUN ver=$(readlink -f curl-7.81.0/lib/.libs/libcurl.so | sed 's/.*so\.//') && \ + major=$(echo -n $ver | cut -d'.' -f1) && \ + cp "${CURL_VERSION}/lib/.libs/libcurl.so.$ver" "out/libcurl-impersonate.so.$ver" && \ + ln -s "libcurl-impersonate.so.$ver" "out/libcurl-impersonate.so.$major" && \ + ln -s "libcurl-impersonate.so.$ver" "out/libcurl-impersonate.so" && \ + strip "out/libcurl-impersonate.so.$ver" + +# Wrapper scripts +{{#firefox}} +COPY curl_ff* out/ +{{/firefox}} +{{#chrome}} +COPY curl_chrome* curl_edge* curl_safari* out/ +{{/chrome}} +RUN chmod +x out/curl_* diff --git a/chrome/Dockerfile b/chrome/Dockerfile index ed0530c..d8ab5f3 100644 --- a/chrome/Dockerfile +++ b/chrome/Dockerfile @@ -1,11 +1,23 @@ -# Use same base as the existing Dockerfile +# +# NOTE: THIS DOCKERFILE IS GENERATED FROM "Dockerfile.template" VIA +# "generate-dockerfiles.sh". +# +# PLEASE DO NOT EDIT IT DIRECTLY. +# + +# Python is needed for building libnss. +# Use it as a common base. FROM python:3.10.1-slim-buster WORKDIR /build -# Dependencies for downloading and building BoringSSL +# Common dependencies RUN apt-get update && \ - apt-get install -y git g++ cmake golang-go ninja-build curl unzip zlib1g-dev + apt-get install -y git ninja-build cmake curl zlib1g-dev + + +# Dependencies for downloading and building BoringSSL +RUN apt-get install -y g++ golang-go unzip # The following are needed because we are going to change some autoconf scripts, # both for libnghttp2 and curl. @@ -20,6 +32,7 @@ RUN cd brotli-${BROTLI_VERSION} && \ cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=./installed .. && \ cmake --build . --config Release --target install + # BoringSSL doesn't have versions. Choose a commit that is used in a stable # Chromium version. ARG BORING_SSL_COMMIT=3a667d10e94186fd503966f5638e134fe9fb4080 @@ -72,14 +85,14 @@ RUN cd ${CURL_VERSION} && \ for p in $(ls curl-*.patch); do patch -p1 < $p; done && \ autoreconf -fi -# Compile curl with BoringSSL & nghttp2. +# Compile curl with nghttp2, libbrotli and nss (firefox) or boringssl (chrome). # Enable keylogfile for debugging of TLS traffic. RUN cd ${CURL_VERSION} && \ ./configure --enable-static \ --disable-shared \ - --with-openssl=/build/boringssl/build \ --with-nghttp2=/usr/local \ --with-brotli=/build/brotli-${BROTLI_VERSION}/build/installed \ + --with-openssl=/build/boringssl/build \ LIBS="-pthread" \ CFLAGS="-I/build/boringssl/build" \ USE_CURL_SSLKEYLOGFILE=true && \ @@ -91,9 +104,9 @@ RUN mkdir out && \ # Re-compile libcurl dynamically RUN cd ${CURL_VERSION} && \ - ./configure --with-openssl=/build/boringssl/build \ - --with-nghttp2=/usr/local \ + ./configure --with-nghttp2=/usr/local \ --with-brotli=/build/brotli-${BROTLI_VERSION}/build/installed \ + --with-openssl=/build/boringssl/build \ LIBS="-pthread" \ CFLAGS="-I/build/boringssl/build" \ USE_CURL_SSLKEYLOGFILE=true && \ diff --git a/firefox/Dockerfile b/firefox/Dockerfile index a5d0558..549547a 100644 --- a/firefox/Dockerfile +++ b/firefox/Dockerfile @@ -1,22 +1,34 @@ -# Python is needed for building libnss +# +# NOTE: THIS DOCKERFILE IS GENERATED FROM "Dockerfile.template" VIA +# "generate-dockerfiles.sh". +# +# PLEASE DO NOT EDIT IT DIRECTLY. +# + +# Python is needed for building libnss. +# Use it as a common base. FROM python:3.10.1-slim-buster WORKDIR /build +# Common dependencies +RUN apt-get update && \ + apt-get install -y git ninja-build cmake curl zlib1g-dev + # Dependencies for building libnss # See https://firefox-source-docs.mozilla.org/security/nss/build.html#mozilla-projects-nss-building -RUN apt-get update && \ - apt-get install -y mercurial git ninja-build cmake python3-pip curl zlib1g-dev - -# The following are needed because we are going to change some autoconf scripts, -# both for libnghttp2 and curl. -RUN apt-get install -y autoconf automake autotools-dev pkg-config libtool +RUN apt-get install -y mercurial python3-pip # curl tries to load the CA certificates for libnss. # It loads them from /usr/lib/x86_64-linux-gnu/nss/libnssckbi.so, # which is supplied by libnss3 on Debian/Ubuntu RUN apt-get install -y libnss3 + +# The following are needed because we are going to change some autoconf scripts, +# both for libnghttp2 and curl. +RUN apt-get install -y autoconf automake autotools-dev pkg-config libtool + # Download and compile libbrotli ARG BROTLI_VERSION=1.0.9 RUN curl -L https://github.com/google/brotli/archive/refs/tags/v${BROTLI_VERSION}.tar.gz -o brotli-${BROTLI_VERSION}.tar.gz && \ @@ -33,12 +45,13 @@ ARG NSS_VERSION=nss-3.74 # This tarball is already bundled with nspr, a dependency of libnss. ARG NSS_URL=https://ftp.mozilla.org/pub/security/nss/releases/NSS_3_74_RTM/src/nss-3.74-with-nspr-4.32.tar.gz -# Download the nss library. +# Download and compile nss. RUN curl -o ${NSS_VERSION}.tar.gz ${NSS_URL} RUN tar xf ${NSS_VERSION}.tar.gz && \ cd ${NSS_VERSION}/nss && \ ./build.sh -o --disable-tests --static + ARG NGHTTP2_VERSION=nghttp2-1.46.0 ARG NGHTTP2_URL=https://github.com/nghttp2/nghttp2/releases/download/v1.46.0/nghttp2-1.46.0.tar.bz2 @@ -68,13 +81,14 @@ RUN cd ${CURL_VERSION} && \ for p in $(ls curl-*.patch); do patch -p1 < $p; done && \ autoreconf -fi -# Compile curl with nss +# Compile curl with nghttp2, libbrotli and nss (firefox) or boringssl (chrome). +# Enable keylogfile for debugging of TLS traffic. RUN cd ${CURL_VERSION} && \ ./configure --enable-static \ --disable-shared \ - --with-nss=/build/${NSS_VERSION}/dist/Release \ --with-nghttp2=/usr/local \ --with-brotli=/build/brotli-${BROTLI_VERSION}/build/installed \ + --with-nss=/build/${NSS_VERSION}/dist/Release \ CFLAGS="-I/build/${NSS_VERSION}/dist/public/nss -I/build/${NSS_VERSION}/dist/Release/include/nspr" \ USE_CURL_SSLKEYLOGFILE=true && \ make @@ -85,9 +99,9 @@ RUN mkdir out && \ # Re-compile libcurl dynamically RUN cd ${CURL_VERSION} && \ - ./configure --with-nss=/build/${NSS_VERSION}/dist/Release \ - --with-nghttp2=/usr/local \ + ./configure --with-nghttp2=/usr/local \ --with-brotli=/build/brotli-${BROTLI_VERSION}/build/installed \ + --with-nss=/build/${NSS_VERSION}/dist/Release \ CFLAGS="-I/build/${NSS_VERSION}/dist/public/nss -I/build/${NSS_VERSION}/dist/Release/include/nspr" \ USE_CURL_SSLKEYLOGFILE=true && \ make clean && make @@ -101,7 +115,6 @@ RUN ver=$(readlink -f curl-7.81.0/lib/.libs/libcurl.so | sed 's/.*so\.//') && \ ln -s "libcurl-impersonate.so.$ver" "out/libcurl-impersonate.so" && \ strip "out/libcurl-impersonate.so.$ver" - -# Wrapper script +# Wrapper scripts COPY curl_ff* out/ RUN chmod +x out/curl_* diff --git a/generate_dockerfiles.sh b/generate_dockerfiles.sh new file mode 100755 index 0000000..9d39abd --- /dev/null +++ b/generate_dockerfiles.sh @@ -0,0 +1,13 @@ +#!/bin/sh + +cat < chrome/Dockerfile +--- +chrome: true +--- +EOF + +cat < firefox/Dockerfile +--- +firefox: true +--- +EOF