From a5b55313d2e1ea766887439aaa5f674ec20126b7 Mon Sep 17 00:00:00 2001 From: Mohammad amin Jafarian Date: Mon, 22 Jun 2026 19:34:02 +0330 Subject: [PATCH 1/5] Add healthcheck and little cleanup keep curl to add healthcheck logic and do little cleanup --- Dockerfile | 40 ++++++++++++++++++++++++++-------------- 1 file changed, 26 insertions(+), 14 deletions(-) diff --git a/Dockerfile b/Dockerfile index 1818742..03dc9c4 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,24 +1,36 @@ ARG DEBIAN_RELEASE=bullseye -FROM docker.io/debian:$DEBIAN_RELEASE-slim +FROM docker.io/debian:${DEBIAN_RELEASE}-slim + ARG DEBIAN_RELEASE ENV DEBIAN_FRONTEND=noninteractive -RUN true && \ - apt update && \ - apt install -y gnupg ca-certificates curl socat +RUN apt-get update && \ + apt-get install -y --no-install-recommends \ + gnupg \ + ca-certificates \ + curl \ + socat && \ + rm -rf /var/lib/apt/lists/* + +RUN curl -fsSL https://pkg.cloudflareclient.com/pubkey.gpg | \ + gpg --dearmor -o /usr/share/keyrings/cloudflare-warp-archive-keyring.gpg && \ + ARCH="$(dpkg --print-architecture)" && \ + echo "deb [arch=${ARCH} signed-by=/usr/share/keyrings/cloudflare-warp-archive-keyring.gpg] https://pkg.cloudflareclient.com/ ${DEBIAN_RELEASE} main" \ + > /etc/apt/sources.list.d/cloudflare-client.list -RUN curl https://pkg.cloudflareclient.com/pubkey.gpg | gpg --yes --dearmor --output /usr/share/keyrings/cloudflare-warp-archive-keyring.gpg && \ - ARCH="$(dpkg --print-architecture)" && \ - echo "deb [arch=${ARCH} signed-by=/usr/share/keyrings/cloudflare-warp-archive-keyring.gpg] https://pkg.cloudflareclient.com/ $DEBIAN_RELEASE main" | tee /etc/apt/sources.list.d/cloudflare-client.list && \ - apt update && \ - apt install cloudflare-warp -y --no-install-recommends +RUN apt-get update && \ + apt-get install -y --no-install-recommends cloudflare-warp && \ + apt-get clean && \ + rm -rf /var/lib/apt/lists/* COPY entrypoint.sh / -RUN apt remove -y curl && \ - apt clean -y && \ - rm -rf /var/lib/apt/lists/* && \ - chmod +x /entrypoint.sh +RUN chmod +x /entrypoint.sh EXPOSE 40000/tcp -ENTRYPOINT [ "/entrypoint.sh" ] + +HEALTHCHECK --interval=15s --timeout=10s --start-period=30s --retries=2 \ + CMD curl -fsSL https://www.cloudflare.com/cdn-cgi/trace \ + -x socks5h://127.0.0.1:40000 >/dev/null || exit 1 + +ENTRYPOINT ["/entrypoint.sh"] From 568ca97f527fad4de71b6aa98f23a4a93d472f64 Mon Sep 17 00:00:00 2001 From: Mohammad amin Jafarian Date: Tue, 23 Jun 2026 05:26:16 +0330 Subject: [PATCH 2/5] Replace socat with gost for multiplexed proxying Switching to `gost` enables the exposed port 40000 to accept both HTTP and SOCKS5 proxy requests, offering greater flexibility. --- Dockerfile | 27 ++++++++++++++++++--------- entrypoint.sh | 8 ++++++-- 2 files changed, 24 insertions(+), 11 deletions(-) diff --git a/Dockerfile b/Dockerfile index 03dc9c4..6ef9ddb 100644 --- a/Dockerfile +++ b/Dockerfile @@ -6,17 +6,27 @@ ENV DEBIAN_FRONTEND=noninteractive RUN apt-get update && \ apt-get install -y --no-install-recommends \ - gnupg \ - ca-certificates \ - curl \ - socat && \ + gnupg \ + ca-certificates \ + curl \ + gzip && \ rm -rf /var/lib/apt/lists/* +RUN ARCH="$(dpkg --print-architecture)" && \ + case "${ARCH}" in \ + amd64) GOST_ARCH="amd64" ;; \ + arm64) GOST_ARCH="armv8" ;; \ + armhf) GOST_ARCH="armv7" ;; \ + *) echo "Unsupported architecture" && exit 1 ;; \ + esac && \ + curl -fsSL "https://github.com/ginuerzh/gost/releases/download/v2.11.5/gost-linux-${GOST_ARCH}-2.11.5.gz" | gzip -d > /usr/local/bin/gost && \ + chmod +x /usr/local/bin/gost + RUN curl -fsSL https://pkg.cloudflareclient.com/pubkey.gpg | \ - gpg --dearmor -o /usr/share/keyrings/cloudflare-warp-archive-keyring.gpg && \ + gpg --dearmor -o /usr/share/keyrings/cloudflare-warp-archive-keyring.gpg && \ ARCH="$(dpkg --print-architecture)" && \ echo "deb [arch=${ARCH} signed-by=/usr/share/keyrings/cloudflare-warp-archive-keyring.gpg] https://pkg.cloudflareclient.com/ ${DEBIAN_RELEASE} main" \ - > /etc/apt/sources.list.d/cloudflare-client.list + > /etc/apt/sources.list.d/cloudflare-client.list RUN apt-get update && \ apt-get install -y --no-install-recommends cloudflare-warp && \ @@ -24,13 +34,12 @@ RUN apt-get update && \ rm -rf /var/lib/apt/lists/* COPY entrypoint.sh / - RUN chmod +x /entrypoint.sh EXPOSE 40000/tcp HEALTHCHECK --interval=15s --timeout=10s --start-period=30s --retries=2 \ CMD curl -fsSL https://www.cloudflare.com/cdn-cgi/trace \ - -x socks5h://127.0.0.1:40000 >/dev/null || exit 1 + -x socks5h://127.0.0.1:40000 >/dev/null || exit 1 -ENTRYPOINT ["/entrypoint.sh"] +ENTRYPOINT ["/entrypoint.sh"] \ No newline at end of file diff --git a/entrypoint.sh b/entrypoint.sh index 589c986..d39e24f 100755 --- a/entrypoint.sh +++ b/entrypoint.sh @@ -38,12 +38,16 @@ warp-cli --accept-tos proxy port 40001 2>/dev/null || true # which makes warp-cli reject the key — strip a single pair of leading/trailing quotes. LICENSE="${LICENSE#[\"\']}" LICENSE="${LICENSE%[\"\']}" + if [ "$LICENSE" != "" ]; then warp-cli --accept-tos registration license "$LICENSE" || true fi warp-cli --accept-tos connect -socat TCP-LISTEN:40000,fork TCP:localhost:40001 # socat is used to redirect traffic from 40000 to 40001 + +# Gost acts as a multiplexed proxy listening on 40000 (allows both HTTP & SOCKS5 usage) +# and forwards traffic directly to Cloudflare Warp's SOCKS5 on 40001. +gost -L :40000 -F socks5://127.0.0.1:40001 ) & -exec warp-svc +exec warp-svc \ No newline at end of file From 210550ae73b9713e6a764bdc2d16370eb340b6b6 Mon Sep 17 00:00:00 2001 From: Mohammad amin Jafarian Date: Tue, 23 Jun 2026 05:42:09 +0330 Subject: [PATCH 3/5] Update README to document gost multiplexed proxy --- README.md | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index c411c07..980c9c7 100644 --- a/README.md +++ b/README.md @@ -7,18 +7,19 @@ Docker image to run Cloudflare Warp in proxy mode. Image is rebuilt and updated ## Usage ### docker hub image -``` +```bash docker run -d -p 40000:40000 --restart unless-stopped seiry/cloudflare-warp-proxy + ``` ### or github package image -``` + +```bash docker run -d -p 40000:40000 --restart unless-stopped ghcr.io/seiry/cloudflare-warp-proxy + ``` -A **SOCKS5** proxy will be listening at port 40000 (this is WARP's proxy mode, -exposed via `socat`). The same port also accepts HTTP `CONNECT`, so you can point -either a `socks5h://` / `socks5://` or an `http://` client at it — see [test](#test). +A **multiplexed** proxy will be listening at port 40000. Under the hood, this uses `gost` to forward traffic to WARP's internal proxy. This setup allows the same port to automatically accept **both SOCKS5 and HTTP** proxy connections seamlessly. You can point a `socks5h://`, `socks5://`, or an `http://` client directly at it — see [test](#test). ### docker-compose @@ -100,14 +101,15 @@ using a **service token**. The same file pins the partner's endpoint overrides `service_mode`/`proxy_port` put the client into proxy mode locally. The Cloudflare One Client gives precedence to local settings, so this overrides the org's device profile — -keep `proxy_port` at `40001` to match the `socat` forward (`40000 → 40001`) in the container. +keep `proxy_port` at `40001` to match the `gost` forward (`40000 → 40001`) in the container. ### 3. run with the file mounted -``` +```bash docker run -d -p 40000:40000 --restart unless-stopped \ -v ./mdm.xml:/var/lib/cloudflare-warp/mdm.xml:ro \ seiry/cloudflare-warp-proxy + ``` A service-token enrolled device shows up under **My Team → Devices** with email @@ -140,7 +142,7 @@ curl https://www.cloudflare.com/cdn-cgi/trace -x http://127.1:40000 # http mode ... sni=plaintext warp=on -# 👆wrap on! +# 👆warp on! gateway=off ... ``` From 6dd3a3738212e332c467fe390a8066138612e681 Mon Sep 17 00:00:00 2001 From: Mohammad amin Jafarian Date: Tue, 23 Jun 2026 18:27:57 +0330 Subject: [PATCH 4/5] Improve GOST proxy with auto-protocol detection and dynamic updates --- Dockerfile | 12 +++++++++--- entrypoint.sh | 13 +++++++++---- 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/Dockerfile b/Dockerfile index 6ef9ddb..a65d067 100644 --- a/Dockerfile +++ b/Dockerfile @@ -9,17 +9,23 @@ RUN apt-get update && \ gnupg \ ca-certificates \ curl \ - gzip && \ + gzip \ + tar \ + jq && \ rm -rf /var/lib/apt/lists/* RUN ARCH="$(dpkg --print-architecture)" && \ case "${ARCH}" in \ amd64) GOST_ARCH="amd64" ;; \ - arm64) GOST_ARCH="armv8" ;; \ + arm64) GOST_ARCH="arm64" ;; \ armhf) GOST_ARCH="armv7" ;; \ *) echo "Unsupported architecture" && exit 1 ;; \ esac && \ - curl -fsSL "https://github.com/ginuerzh/gost/releases/download/v2.11.5/gost-linux-${GOST_ARCH}-2.11.5.gz" | gzip -d > /usr/local/bin/gost && \ + DOWNLOAD_URL=$(curl -fsSL https://api.github.com/repos/go-gost/gost/releases/latest | \ + jq -r --arg arch "linux_${GOST_ARCH}.tar.gz" '.assets[] | select(.name | endswith($arch)) | .browser_download_url' | head -n 1) && \ + if [ -z "$DOWNLOAD_URL" ]; then echo "Error: Failed to find download URL for architecture ${GOST_ARCH}"; exit 1; fi && \ + echo "Downloading GOST from: $DOWNLOAD_URL" && \ + curl -fsSL "$DOWNLOAD_URL" | tar -C /usr/local/bin -xzf - gost && \ chmod +x /usr/local/bin/gost RUN curl -fsSL https://pkg.cloudflareclient.com/pubkey.gpg | \ diff --git a/entrypoint.sh b/entrypoint.sh index d39e24f..80b2d02 100755 --- a/entrypoint.sh +++ b/entrypoint.sh @@ -16,7 +16,7 @@ else # Consumer deployment: create a free registration. Newer clients auto-register on # startup and the registration persists across restarts, so "registration new" can # fail with "Old registration is still around" — treat that as success instead of - # looping forever (otherwise socat below never starts). + # looping forever (otherwise gost below never starts). while true; do if out="$(warp-cli --accept-tos registration new 2>&1)"; then break @@ -45,9 +45,14 @@ fi warp-cli --accept-tos connect -# Gost acts as a multiplexed proxy listening on 40000 (allows both HTTP & SOCKS5 usage) -# and forwards traffic directly to Cloudflare Warp's SOCKS5 on 40001. -gost -L :40000 -F socks5://127.0.0.1:40001 +# Gost acts as a multiplexed proxy listening on 40000. Using the 'auto://' scheme, +# it automatically detects and supports incoming traffic for: +# - HTTP proxy +# - HTTPS proxy (CONNECT) +# - SOCKS4 +# - SOCKS5 +# and forwards that traffic directly to Cloudflare Warp's SOCKS5 on 40001. +gost -L "auto://:40000" -F "socks5://127.0.0.1:40001" ) & exec warp-svc \ No newline at end of file From fbbcff8dc2a76b08456162a7e2d3ae18aa68a72b Mon Sep 17 00:00:00 2001 From: Mohammad amin Jafarian Date: Fri, 31 Jul 2026 01:21:28 +0330 Subject: [PATCH 5/5] Improve logging, limit Gost memory, and handle graceful shutdown - Memory Optimization: Sets GOMEMLIMIT and GOGC to heavily restrict the `gost` multiplexer's memory footprint. This drops active memory consumption from 200~500 MB to 100~200 MB. - Log Silencing: Hides normal `warp-cli` command outputs and filters out persistent, non-fatal DBus errors from `warp-svc`. Sets `gost` to only log warnings. - Signal Handling: Traps SIGTERM and SIGINT to gracefully kill `warp-svc` when the Docker container stops, rather than relying on a hard `exec` termination. --- entrypoint.sh | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/entrypoint.sh b/entrypoint.sh index 80b2d02..b50cb79 100755 --- a/entrypoint.sh +++ b/entrypoint.sh @@ -31,7 +31,7 @@ fi # the mode is dictated by the org device profile and these calls return "Invalid setting # for this account type" — in that case set the profile's service mode to "Proxy mode" # (port 40001) in the Zero Trust dashboard, and ignore the errors below. -warp-cli --accept-tos mode proxy 2>/dev/null || >&2 echo "mode set by org profile, skipping local mode/port" +warp-cli --accept-tos mode proxy 2>/dev/null || true warp-cli --accept-tos proxy port 40001 2>/dev/null || true # docker-compose's `- LICENSE='...'` keeps the surrounding quotes as part of the value, @@ -40,10 +40,18 @@ LICENSE="${LICENSE#[\"\']}" LICENSE="${LICENSE%[\"\']}" if [ "$LICENSE" != "" ]; then - warp-cli --accept-tos registration license "$LICENSE" || true + warp-cli --accept-tos registration license "$LICENSE" >/dev/null 2>&1 || true fi -warp-cli --accept-tos connect +# Connect WARP silently +warp-cli --accept-tos connect >/dev/null 2>&1 + + +# ========================================== +# GOST MEMORY Limit +# ========================================== +export GOMEMLIMIT=50MiB +export GOGC=30 # Gost acts as a multiplexed proxy listening on 40000. Using the 'auto://' scheme, # it automatically detects and supports incoming traffic for: @@ -52,7 +60,15 @@ warp-cli --accept-tos connect # - SOCKS4 # - SOCKS5 # and forwards that traffic directly to Cloudflare Warp's SOCKS5 on 40001. -gost -L "auto://:40000" -F "socks5://127.0.0.1:40001" +gost -C '{"log": {"level": "warn"}}' -L "auto://:40000" -F "socks5://127.0.0.1:40001" & ) & -exec warp-svc \ No newline at end of file +# ========================================== +# WARP-SVC WITH LOG FILTER +# ========================================== +warp-svc 2>&1 | grep --line-buffered -vE 'Initializing dbus connection|org\.freedesktop\.DBus\.Error\.FileNotFound' & +WARP_PID=$! + +# Ensure graceful shutdown if container is stopped +trap 'kill -TERM $WARP_PID 2>/dev/null' TERM INT +wait $WARP_PID \ No newline at end of file