From eaeb619fa707be3edeed5e34a387bc027acf91ff Mon Sep 17 00:00:00 2001 From: lwthiker Date: Thu, 10 Mar 2022 11:57:53 +0200 Subject: [PATCH 1/7] Add Alpine Linux build system Add Dockerfiles for building curl-impersonate on Alpine Linux. The Dockerfile template file was modified to support Alpine Linux, mainly by changing the dependency installation from 'apt' to 'apk'. The resulting alpine images are small (~11mb) and will be uploaded to Docker hub. --- Dockerfile.template | 62 +++++++++++++++-- chrome/Dockerfile | 10 ++- chrome/Dockerfile.alpine | 135 ++++++++++++++++++++++++++++++++++++++ firefox/Dockerfile | 10 ++- firefox/Dockerfile.alpine | 131 ++++++++++++++++++++++++++++++++++++ generate_dockerfiles.sh | 15 +++++ 6 files changed, 345 insertions(+), 18 deletions(-) create mode 100644 chrome/Dockerfile.alpine create mode 100644 firefox/Dockerfile.alpine diff --git a/Dockerfile.template b/Dockerfile.template index ee5d5b8..9516c30 100644 --- a/Dockerfile.template +++ b/Dockerfile.template @@ -5,36 +5,65 @@ # PLEASE DO NOT EDIT IT DIRECTLY. # +{{#debian}} # Python is needed for building libnss. # Use it as a common base. FROM python:3.10.1-slim-buster +{{/debian}} +{{#alpine}} +FROM alpine:3.15.0 as builder +{{/alpine}} WORKDIR /build # Common dependencies +{{#debian}} RUN apt-get update && \ apt-get install -y git ninja-build cmake curl zlib1g-dev +{{/debian}} +{{#alpine}} +RUN apk add git build-base make cmake ninja curl zlib-dev patch linux-headers python3 python3-dev +{{/alpine}} + +# The following are needed because we are going to change some autoconf scripts, +# both for libnghttp2 and curl. +{{#debian}} +RUN apt-get install -y autoconf automake autotools-dev pkg-config libtool +{{/debian}} +{{#alpine}} +RUN apk add autoconf automake pkgconfig libtool +{{/alpine}} {{#firefox}} # Dependencies for building libnss # See https://firefox-source-docs.mozilla.org/security/nss/build.html#mozilla-projects-nss-building + {{#debian}} RUN apt-get install -y mercurial python3-pip + {{/debian}} + {{#alpine}} +RUN apk add mercurial py3-pip clang-analyzer + {{/alpine}} # 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 + {{#debian}} RUN apt-get install -y libnss3 + {{/debian}} + {{#alpine}} +RUN apk add nss + {{/alpine}} {{/firefox}} - {{#chrome}} # Dependencies for downloading and building BoringSSL + {{#debian}} RUN apt-get install -y g++ golang-go unzip + {{/debian}} + {{#alpine}} +RUN apk add g++ go unzip + {{/alpine}} {{/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 && \ @@ -56,9 +85,12 @@ ARG NSS_URL=https://ftp.mozilla.org/pub/security/nss/releases/NSS_3_74_RTM/src/n RUN curl -o ${NSS_VERSION}.tar.gz ${NSS_URL} RUN tar xf ${NSS_VERSION}.tar.gz && \ cd ${NSS_VERSION}/nss && \ +{{#alpine}} + # Hack to make nss compile on alpine with python3 + ln -sf python3 /usr/bin/python && \ +{{/alpine}} ./build.sh -o --disable-tests --static {{/firefox}} - {{#chrome}} # BoringSSL doesn't have versions. Choose a commit that is used in a stable # Chromium version. @@ -168,4 +200,22 @@ COPY curl_ff* out/ {{#chrome}} COPY curl_chrome* curl_edge* curl_safari* out/ {{/chrome}} +{{#alpine}} +# Replace /bin/bash with /bin/ash +RUN sed -i 's@/bin/bash@/bin/ash@' out/curl_* +{{/alpine}} RUN chmod +x out/curl_* +{{#alpine}} + +# When using alpine, create a final, minimal image with the compiled binaries +# only. +FROM alpine:3.15.0 + +# Copy curl-impersonate from the builder image +COPY --from=builder /build/out/curl-impersonate /usr/local/bin/ +# Wrapper scripts +COPY --from=builder /build/out/curl_* /usr/local/bin/ + +# Copy libcurl-impersonate from the builder image +COPY --from=builder /build/out/libcurl-impersonate.so /usr/local/lib/ +{{/alpine}} diff --git a/chrome/Dockerfile b/chrome/Dockerfile index d8ab5f3..0511a60 100644 --- a/chrome/Dockerfile +++ b/chrome/Dockerfile @@ -15,14 +15,13 @@ WORKDIR /build RUN apt-get update && \ 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. RUN apt-get install -y autoconf automake autotools-dev pkg-config libtool +# Dependencies for downloading and building BoringSSL +RUN apt-get install -y g++ golang-go unzip + # 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 && \ @@ -32,7 +31,6 @@ 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 @@ -50,7 +48,7 @@ RUN cd boringssl && \ ninja # Fix the directory structure so that curl can compile against it. -# See https://everything.curl.dev/source/build/tls/boringssl +# 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 && \ diff --git a/chrome/Dockerfile.alpine b/chrome/Dockerfile.alpine new file mode 100644 index 0000000..963074c --- /dev/null +++ b/chrome/Dockerfile.alpine @@ -0,0 +1,135 @@ +# +# NOTE: THIS DOCKERFILE IS GENERATED FROM "Dockerfile.template" VIA +# "generate-dockerfiles.sh". +# +# PLEASE DO NOT EDIT IT DIRECTLY. +# + +FROM alpine:3.15.0 as builder + +WORKDIR /build + +# Common dependencies +RUN apk add git build-base make cmake ninja curl zlib-dev patch linux-headers python3 python3-dev + +# The following are needed because we are going to change some autoconf scripts, +# both for libnghttp2 and curl. +RUN apk add autoconf automake pkgconfig libtool + +# Dependencies for downloading and building BoringSSL +RUN apk add g++ go unzip + +# 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 + +# 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 + +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 \ + --with-openssl=/build/boringssl/build \ + LIBS="-pthread" \ + CFLAGS="-I/build/boringssl/build" \ + 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 \ + --with-openssl=/build/boringssl/build \ + LIBS="-pthread" \ + CFLAGS="-I/build/boringssl/build" \ + 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 +COPY curl_chrome* curl_edge* curl_safari* out/ +# Replace /bin/bash with /bin/ash +RUN sed -i 's@/bin/bash@/bin/ash@' out/curl_* +RUN chmod +x out/curl_* + +# When using alpine, create a final, minimal image with the compiled binaries +# only. +FROM alpine:3.15.0 + +# Copy curl-impersonate from the builder image +COPY --from=builder /build/out/curl-impersonate /usr/local/bin/ +# Wrapper scripts +COPY --from=builder /build/out/curl_* /usr/local/bin/ + +# Copy libcurl-impersonate from the builder image +COPY --from=builder /build/out/libcurl-impersonate.so /usr/local/lib/ diff --git a/firefox/Dockerfile b/firefox/Dockerfile index 549547a..e8c4521 100644 --- a/firefox/Dockerfile +++ b/firefox/Dockerfile @@ -15,6 +15,10 @@ WORKDIR /build RUN apt-get update && \ apt-get install -y git ninja-build cmake 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 + # 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 @@ -24,11 +28,6 @@ RUN apt-get install -y mercurial python3-pip # 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 && \ @@ -51,7 +50,6 @@ 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 diff --git a/firefox/Dockerfile.alpine b/firefox/Dockerfile.alpine new file mode 100644 index 0000000..95511bb --- /dev/null +++ b/firefox/Dockerfile.alpine @@ -0,0 +1,131 @@ +# +# NOTE: THIS DOCKERFILE IS GENERATED FROM "Dockerfile.template" VIA +# "generate-dockerfiles.sh". +# +# PLEASE DO NOT EDIT IT DIRECTLY. +# + +FROM alpine:3.15.0 as builder + +WORKDIR /build + +# Common dependencies +RUN apk add git build-base make cmake ninja curl zlib-dev patch linux-headers python3 python3-dev + +# The following are needed because we are going to change some autoconf scripts, +# both for libnghttp2 and curl. +RUN apk add autoconf automake pkgconfig libtool + +# Dependencies for building libnss +# See https://firefox-source-docs.mozilla.org/security/nss/build.html#mozilla-projects-nss-building +RUN apk add mercurial py3-pip clang-analyzer + +# 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 apk add nss + +# 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 + +# 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 && \ + # Hack to make nss compile on alpine with python3 + ln -sf python3 /usr/bin/python && \ + ./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 + +# 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 \ + --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 + +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 \ + --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 + +# 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 +COPY curl_ff* out/ +# Replace /bin/bash with /bin/ash +RUN sed -i 's@/bin/bash@/bin/ash@' out/curl_* +RUN chmod +x out/curl_* + +# When using alpine, create a final, minimal image with the compiled binaries +# only. +FROM alpine:3.15.0 + +# Copy curl-impersonate from the builder image +COPY --from=builder /build/out/curl-impersonate /usr/local/bin/ +# Wrapper scripts +COPY --from=builder /build/out/curl_* /usr/local/bin/ + +# Copy libcurl-impersonate from the builder image +COPY --from=builder /build/out/libcurl-impersonate.so /usr/local/lib/ diff --git a/generate_dockerfiles.sh b/generate_dockerfiles.sh index 9d39abd..5a7cfaf 100755 --- a/generate_dockerfiles.sh +++ b/generate_dockerfiles.sh @@ -3,11 +3,26 @@ cat < chrome/Dockerfile --- chrome: true +debian: true +--- +EOF +cat < chrome/Dockerfile.alpine +--- +chrome: true +alpine: true --- EOF cat < firefox/Dockerfile --- firefox: true +debian: true +--- +EOF + +cat < firefox/Dockerfile.alpine +--- +firefox: true +alpine: true --- EOF From 21af00356e93079af1086069327694e0a0a15005 Mon Sep 17 00:00:00 2001 From: lwthiker Date: Thu, 10 Mar 2022 12:22:27 +0200 Subject: [PATCH 2/7] Add action to push alpine images to Docker Hub Add a GitHub action to push alpine images with curl-impersonate to Docker Hub whenever a new release tag is created. --- .github/workflows/publish-docker-image.yml | 42 ++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 .github/workflows/publish-docker-image.yml diff --git a/.github/workflows/publish-docker-image.yml b/.github/workflows/publish-docker-image.yml new file mode 100644 index 0000000..1087cbc --- /dev/null +++ b/.github/workflows/publish-docker-image.yml @@ -0,0 +1,42 @@ +# Build an Alpine Linux image containing curl-impersonate and push to +# Docker hub. +name: Publish Docker image + +on: + push: + tags: + - 'v*' + +jobs: + push-docker-image: + name: Push Docker image to Docker Hub + runs-on: ubuntu-latest + steps: + - name: Check out the repo + uses: actions/checkout@v2 + + - name: Log in to Docker Hub + uses: docker/login-action@v1 + with: + username: ${{ secrets.DOCKER_USERNAME }} + password: ${{ secrets.DOCKER_PASSWORD }} + + - name: Extract metadata (tags, labels) for Docker + id: meta_chrome + uses: docker/metadata-action@v3 + with: + images: lwthiker/curl-impersonate + tags: | + type=semver,pattern={{version}} + type=semver,pattern={{major}}.{{minor}} + flavor: | + suffix=-chrome-alpine3.15 + + - name: Build and push the Chrome version of curl-impersonate + uses: docker/build-push-action@v2 + with: + push: true + context: chrome/ + file: chrome/Dockerfile.alpine + tags: ${{ steps.meta_chrome.outputs.tags }} + labels: ${{ steps.meta_chrome.outputs.labels }} From 2e738cd7d09c9d4045902b2f2b9df3fb10ff4306 Mon Sep 17 00:00:00 2001 From: lwthiker Date: Thu, 10 Mar 2022 12:50:17 +0200 Subject: [PATCH 3/7] Push the Alpine image for Firefox version as well --- .github/workflows/publish-docker-image.yml | 24 ++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/.github/workflows/publish-docker-image.yml b/.github/workflows/publish-docker-image.yml index 1087cbc..2d7e5e5 100644 --- a/.github/workflows/publish-docker-image.yml +++ b/.github/workflows/publish-docker-image.yml @@ -21,7 +21,7 @@ jobs: username: ${{ secrets.DOCKER_USERNAME }} password: ${{ secrets.DOCKER_PASSWORD }} - - name: Extract metadata (tags, labels) for Docker + - name: Extract metadata (tags, labels) for Docker (chrome) id: meta_chrome uses: docker/metadata-action@v3 with: @@ -30,7 +30,7 @@ jobs: type=semver,pattern={{version}} type=semver,pattern={{major}}.{{minor}} flavor: | - suffix=-chrome-alpine3.15 + suffix=-chrome-alpine - name: Build and push the Chrome version of curl-impersonate uses: docker/build-push-action@v2 @@ -40,3 +40,23 @@ jobs: file: chrome/Dockerfile.alpine tags: ${{ steps.meta_chrome.outputs.tags }} labels: ${{ steps.meta_chrome.outputs.labels }} + + - name: Extract metadata (tags, labels) for Docker (firefox) + id: meta_firefox + uses: docker/metadata-action@v3 + with: + images: lwthiker/curl-impersonate + tags: | + type=semver,pattern={{version}} + type=semver,pattern={{major}}.{{minor}} + flavor: | + suffix=-ff-alpine + + - name: Build and push the Firefox version of curl-impersonate + uses: docker/build-push-action@v2 + with: + push: true + context: firefox/ + file: firefox/Dockerfile.alpine + tags: ${{ steps.meta_firefox.outputs.tags }} + labels: ${{ steps.meta_firefox.outputs.labels }} From 4ea8f859eb24496702a5078301b16af781f5a7f1 Mon Sep 17 00:00:00 2001 From: lwthiker Date: Thu, 10 Mar 2022 13:14:56 +0200 Subject: [PATCH 4/7] Install nss in final alpine image Add 'apk add nss' for the final alpine image of the Firefox version of curl-impersonate. This is needed for curl to find the list of root certificates. --- Dockerfile.template | 11 +++++++---- firefox/Dockerfile.alpine | 8 ++++---- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/Dockerfile.template b/Dockerfile.template index 9516c30..11a6916 100644 --- a/Dockerfile.template +++ b/Dockerfile.template @@ -44,15 +44,12 @@ RUN apt-get install -y mercurial python3-pip RUN apk add mercurial py3-pip clang-analyzer {{/alpine}} + {{#debian}} # 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 - {{#debian}} RUN apt-get install -y libnss3 {{/debian}} - {{#alpine}} -RUN apk add nss - {{/alpine}} {{/firefox}} {{#chrome}} # Dependencies for downloading and building BoringSSL @@ -210,6 +207,12 @@ RUN chmod +x out/curl_* # When using alpine, create a final, minimal image with the compiled binaries # only. FROM alpine:3.15.0 +{{#firefox}} +# curl tries to load the CA certificates for libnss. +# It loads them from /usr/lib/libnssckbi.so, +# which is supplied by 'nss' on alpine. +RUN apk add --no-cache nss +{{/firefox}} # Copy curl-impersonate from the builder image COPY --from=builder /build/out/curl-impersonate /usr/local/bin/ diff --git a/firefox/Dockerfile.alpine b/firefox/Dockerfile.alpine index 95511bb..91edcaa 100644 --- a/firefox/Dockerfile.alpine +++ b/firefox/Dockerfile.alpine @@ -20,10 +20,6 @@ RUN apk add autoconf automake pkgconfig libtool # See https://firefox-source-docs.mozilla.org/security/nss/build.html#mozilla-projects-nss-building RUN apk add mercurial py3-pip clang-analyzer -# 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 apk add nss # Download and compile libbrotli ARG BROTLI_VERSION=1.0.9 @@ -121,6 +117,10 @@ RUN chmod +x out/curl_* # When using alpine, create a final, minimal image with the compiled binaries # only. FROM alpine:3.15.0 +# curl tries to load the CA certificates for libnss. +# It loads them from /usr/lib/libnssckbi.so, +# which is supplied by 'nss' on alpine. +RUN apk add --no-cache nss # Copy curl-impersonate from the builder image COPY --from=builder /build/out/curl-impersonate /usr/local/bin/ From ebc8032615277e5a2bbfd0bb76965ee3571b391f Mon Sep 17 00:00:00 2001 From: lwthiker Date: Thu, 10 Mar 2022 13:23:12 +0200 Subject: [PATCH 5/7] Add more tags to alpine-based Docker Hub images --- .github/workflows/publish-docker-image.yml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/publish-docker-image.yml b/.github/workflows/publish-docker-image.yml index 2d7e5e5..3a4b667 100644 --- a/.github/workflows/publish-docker-image.yml +++ b/.github/workflows/publish-docker-image.yml @@ -27,10 +27,10 @@ jobs: with: images: lwthiker/curl-impersonate tags: | - type=semver,pattern={{version}} - type=semver,pattern={{major}}.{{minor}} - flavor: | - suffix=-chrome-alpine + type=semver,pattern={{version}},suffix=-chrome-alpine + type=semver,pattern={{version}},suffix=-chrome + type=semver,pattern={{major}}.{{minor}},suffix=-chrome-alpine + type=semver,pattern={{major}}.{{minor}},suffix=-chrome - name: Build and push the Chrome version of curl-impersonate uses: docker/build-push-action@v2 @@ -47,10 +47,10 @@ jobs: with: images: lwthiker/curl-impersonate tags: | - type=semver,pattern={{version}} - type=semver,pattern={{major}}.{{minor}} - flavor: | - suffix=-ff-alpine + type=semver,pattern={{version}},suffix=-ff-alpine + type=semver,pattern={{version}},suffix=-ff + type=semver,pattern={{major}}.{{minor}},suffix=-ff-alpine + type=semver,pattern={{major}}.{{minor}},suffix=-ff - name: Build and push the Firefox version of curl-impersonate uses: docker/build-push-action@v2 From 2cf96e93378adfe602d8d472dd5ce9bce31862a1 Mon Sep 17 00:00:00 2001 From: lwthiker Date: Thu, 10 Mar 2022 13:34:56 +0200 Subject: [PATCH 6/7] Update README.md with Alpine-based Docker images --- README.md | 27 +++++++++++++++++++++------ tests/README.md | 2 +- 2 files changed, 22 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index f03f480..942edec 100644 --- a/README.md +++ b/README.md @@ -45,10 +45,29 @@ You can add command line flags and they will be passed on to curl. However, some See [Advanced usage](#Advanced-usage) for more options. ## Installation -This repository maintains two separate build systems for technical reasons. The **chrome** build is used to impersonate Chrome, Edge and Safari. The **firefox** build is used to impersonate Firefox. +There are two version of `curl-impersonate` for technical reasons. The **chrome** version is used to impersonate Chrome, Edge and Safari. The **firefox** version is used to impersonate Firefox. + +### Docker images +Docker images based on Alpine Linux with `curl-impersonate` compiled and ready to use are available on [Docker Hub](https://hub.docker.com/repository/docker/lwthiker/curl-impersonate). The images contain the binary and all the wrapper scripts. Use like the following: +```bash +# Firefox version +docker pull lwthiker/curl-impersonate:0.3-ff +docker run --rm lwthiker/curl-impersonate:0.3-ff curl_ff95 https://www.wikipedia.org + +# Chrome version +docker pull lwthiker/curl-impersonate:0.3-chrome +docker run --rm lwthiker/curl-impersonate:0.3-chrome curl_chrome99 https://www.wikipedia.org +``` + +### Distro packages + +AUR packages are available to Arch users: [curl-impersonate-chrome](https://aur.archlinux.org/packages/curl-impersonate-chrome), [curl-impersonate-firefox](https://aur.archlinux.org/packages/curl-impersonate-firefox). + +## Building from source +As mentioned there are two separate build systems. The **chrome** build is used to impersonate Chrome, Edge and Safari. The **firefox** build is used to impersonate Firefox. ### Chrome build -[`chrome/Dockerfile`](chrome/Dockerfile) is a Dockerfile that will build curl with all the necessary modifications and patches. Build it like the following: +[`chrome/Dockerfile`](chrome/Dockerfile) is a debian-based Dockerfile that will build curl with all the necessary modifications and patches. Build it like the following: ``` docker build -t curl-impersonate-chrome chrome/ ``` @@ -72,10 +91,6 @@ The resulting image contains: If you use it outside the container, install the following dependency: * `sudo apt install libnss3`. Even though nss is statically compiled into `curl-impersonate`, it is still necessary to install libnss3 because curl dynamically loads `libnssckbi.so`, a file containing Mozilla's list of trusted root certificates. Alternatively, use `curl -k` to disable certificate verification. -### Distro packages - -AUR packages are available to Arch users: [curl-impersonate-chrome](https://aur.archlinux.org/packages/curl-impersonate-chrome), [curl-impersonate-firefox](https://aur.archlinux.org/packages/curl-impersonate-firefox). - ## Advanced usage ### libcurl-impersonate `libcurl-impersonate.so` is libcurl compiled with the same changes as the command line `curl-impersonate`. diff --git a/tests/README.md b/tests/README.md index 2c19b93..f7f16e7 100644 --- a/tests/README.md +++ b/tests/README.md @@ -2,7 +2,7 @@ The tests verify that `curl-impersonate` has the same network signature as that ## Running the tests -The tests assume that you've built both `curl-impersonate-chrome` and `curl-impersonate-ff` docker images before (see [Installation](https://github.com/lwthiker/curl-impersonate#installation)). +The tests assume that you've built both `curl-impersonate-chrome` and `curl-impersonate-ff` docker images before (see [Building from source](https://github.com/lwthiker/curl-impersonate#building-from-source)). To run the tests, build with: ``` From aba67a4cbebc4e2a7828eb0e2f88f6d4c48ee1c6 Mon Sep 17 00:00:00 2001 From: lwthiker Date: Thu, 10 Mar 2022 13:38:37 +0200 Subject: [PATCH 7/7] Fix typo and link in README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 942edec..4850d02 100644 --- a/README.md +++ b/README.md @@ -45,10 +45,10 @@ You can add command line flags and they will be passed on to curl. However, some See [Advanced usage](#Advanced-usage) for more options. ## Installation -There are two version of `curl-impersonate` for technical reasons. The **chrome** version is used to impersonate Chrome, Edge and Safari. The **firefox** version is used to impersonate Firefox. +There are two versions of `curl-impersonate` for technical reasons. The **chrome** version is used to impersonate Chrome, Edge and Safari. The **firefox** version is used to impersonate Firefox. ### Docker images -Docker images based on Alpine Linux with `curl-impersonate` compiled and ready to use are available on [Docker Hub](https://hub.docker.com/repository/docker/lwthiker/curl-impersonate). The images contain the binary and all the wrapper scripts. Use like the following: +Docker images based on Alpine Linux with `curl-impersonate` compiled and ready to use are available on [Docker Hub](https://hub.docker.com/r/lwthiker/curl-impersonate). The images contain the binary and all the wrapper scripts. Use like the following: ```bash # Firefox version docker pull lwthiker/curl-impersonate:0.3-ff