From 549986569ca828ea6873c44bf1ce6cf9e6f78fc1 Mon Sep 17 00:00:00 2001 From: Cao Mingjun Date: Wed, 14 Aug 2024 13:00:48 +0800 Subject: [PATCH] add `BETA_FIX_HOST_CONNECTIVITY`, resolve #23 --- Dockerfile | 8 +++-- healthcheck/connected-to-warp.sh | 4 +++ healthcheck/fix-host-connectivity.sh | 45 ++++++++++++++++++++++++++++ healthcheck/index.sh | 14 +++++++++ 4 files changed, 68 insertions(+), 3 deletions(-) create mode 100644 healthcheck/connected-to-warp.sh create mode 100644 healthcheck/fix-host-connectivity.sh create mode 100644 healthcheck/index.sh diff --git a/Dockerfile b/Dockerfile index 135083f..de419a0 100644 --- a/Dockerfile +++ b/Dockerfile @@ -12,6 +12,7 @@ LABEL GOST_VERSION=${GOST_VERSION} LABEL COMMIT_SHA=${COMMIT_SHA} COPY entrypoint.sh /entrypoint.sh +COPY ./healthcheck /healthcheck # install dependencies RUN case ${TARGETPLATFORM} in \ @@ -22,7 +23,7 @@ RUN case ${TARGETPLATFORM} in \ echo "Building for ${ARCH} with GOST ${GOST_VERSION}" &&\ apt-get update && \ apt-get upgrade -y && \ - apt-get install -y curl gnupg lsb-release sudo && \ + apt-get install -y curl gnupg lsb-release sudo jq ipcalc && \ curl https://pkg.cloudflareclient.com/pubkey.gpg | gpg --yes --dearmor --output /usr/share/keyrings/cloudflare-warp-archive-keyring.gpg && \ echo "deb [signed-by=/usr/share/keyrings/cloudflare-warp-archive-keyring.gpg] https://pkg.cloudflareclient.com/ $(lsb_release -cs) main" | tee /etc/apt/sources.list.d/cloudflare-client.list && \ apt-get update && \ @@ -34,6 +35,7 @@ RUN case ${TARGETPLATFORM} in \ mv gost-linux-${ARCH}-${GOST_VERSION} /usr/bin/gost && \ chmod +x /usr/bin/gost && \ chmod +x /entrypoint.sh && \ + chmod +x /healthcheck/index.sh && \ useradd -m -s /bin/bash warp && \ echo "warp ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/warp @@ -46,7 +48,7 @@ RUN mkdir -p /home/warp/.local/share/warp && \ ENV GOST_ARGS="-L :1080" ENV WARP_SLEEP=2 -HEALTHCHECK --interval=15s --timeout=5s --start-period=30s --retries=3 \ - CMD curl -fsS "https://cloudflare.com/cdn-cgi/trace" | grep -qE "warp=(plus|on)" || exit 1 +HEALTHCHECK --interval=15s --timeout=5s --start-period=10s --retries=3 \ + CMD /healthcheck/index.sh ENTRYPOINT ["/entrypoint.sh"] \ No newline at end of file diff --git a/healthcheck/connected-to-warp.sh b/healthcheck/connected-to-warp.sh new file mode 100644 index 0000000..19f8532 --- /dev/null +++ b/healthcheck/connected-to-warp.sh @@ -0,0 +1,4 @@ +#!/bin/bash + +curl -fsS "https://cloudflare.com/cdn-cgi/trace" | grep -qE "warp=(plus|on)" || exit 1 +exit 0 diff --git a/healthcheck/fix-host-connectivity.sh b/healthcheck/fix-host-connectivity.sh new file mode 100644 index 0000000..e16356f --- /dev/null +++ b/healthcheck/fix-host-connectivity.sh @@ -0,0 +1,45 @@ +#!/bin/bash + +# exit when any command fails +set -e + +interfaces=$(ip --json address | jq -r ' + .[] | + select(.ifname != "lo") | + .ifname + ') + +# if CloudflareWARP not started, abort +if [[ ! "$interfaces" =~ "CloudflareWARP" ]]; then + echo "[fix-host-connectivity] CloudflareWARP not started, skip." + exit 0 +fi + +# get excluded networks +networks=$(ip --json address | jq -r ' + .[] | + select((.ifname != "lo") and (.ifname != "CloudflareWARP")) | + .addr_info[] | + select(.family == "inet") | + "\(.local)/\(.prefixlen)"' | + xargs -I {} sh -c ' + if echo {} | grep -q "/32$"; then + echo {}; + else + ipcalc -n {} | grep Network | awk "{print \$2}"; + fi + ') + +# if no networks found, abort +if [ -z "$networks" ]; then + echo "[fix-host-connectivity] WARNING: No networks found, abort." + exit 0 +fi + +# add excluded networks to nft table cloudflare-warp and routing table +for network in $networks; do + sudo nft add rule inet cloudflare-warp input ip saddr $network accept + sudo nft add rule inet cloudflare-warp output ip daddr $network accept + # stop packet from using routing table created by CloudflareWARP + sudo ip rule add to $network lookup main priority 10 +done diff --git a/healthcheck/index.sh b/healthcheck/index.sh new file mode 100644 index 0000000..a5a6b33 --- /dev/null +++ b/healthcheck/index.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +# exit when any command fails +set -e + +# get where the script is located +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" + +bash $DIR/connected-to-warp.sh + +# if BETA_FIX_HOST_CONNECTIVITY is set, run fix-host-connectivity.sh +if [ -n "$BETA_FIX_HOST_CONNECTIVITY" ]; then + bash $DIR/fix-host-connectivity.sh +fi