diff --git a/check-gpg.sh b/check-gpg.sh index f87062b..3e9cc93 100755 --- a/check-gpg.sh +++ b/check-gpg.sh @@ -18,8 +18,13 @@ BASE_URL="https://raw.githubusercontent.com/orochi-network/dev-off/${BASE_REVISI # Log the revision we are trusting (forensics: pin this to a commit SHA in CI). echo "[dev-off] check-gpg using revision: ${BASE_REVISION}" >&2 +# --connect-timeout/--max-time/--retry: bound every network fetch so a stalled +# connection fails fast (and retries transient blips) instead of hanging the +# trust check indefinitely. +CURL_OPTS=(--connect-timeout 15 --max-time 120 --retry 3 --retry-delay 2) + check_sha256sum() { - curl -fsSL "$BASE_URL/checksum.sha256" | grep -F --color=never -- "$1" | sha256sum -c --strict - + curl -fsSL "${CURL_OPTS[@]}" "$BASE_URL/checksum.sha256" | grep -F --color=never -- "$1" | sha256sum -c --strict - } # Clean state (important for self-hosted runners) @@ -28,7 +33,7 @@ mkdir -p ~/.gnupg chmod 700 ~/.gnupg # Fetch and verify allowlist -curl -fsSL -O "$BASE_URL/gpg-list.asc" +curl -fsSL "${CURL_OPTS[@]}" -O "$BASE_URL/gpg-list.asc" check_sha256sum "gpg-list.asc" # Import keys and trust them so Git returns 'G' diff --git a/check-ssh.sh b/check-ssh.sh index cf023c4..83e0cf1 100755 --- a/check-ssh.sh +++ b/check-ssh.sh @@ -18,15 +18,20 @@ BASE_URL="https://raw.githubusercontent.com/orochi-network/dev-off/${BASE_REVISI # Log the revision we are trusting (forensics: pin this to a commit SHA in CI). echo "[dev-off] check-ssh using revision: ${BASE_REVISION}" >&2 +# --connect-timeout/--max-time/--retry: bound every network fetch so a stalled +# connection fails fast (and retries transient blips) instead of hanging the +# trust check indefinitely. +CURL_OPTS=(--connect-timeout 15 --max-time 120 --retry 3 --retry-delay 2) + check_sha256sum() { - curl -fsSL "$BASE_URL/checksum.sha256" | grep -F --color=never -- "$1" | sha256sum -c --strict - + curl -fsSL "${CURL_OPTS[@]}" "$BASE_URL/checksum.sha256" | grep -F --color=never -- "$1" | sha256sum -c --strict - } # Clean state (important for self-hosted runners) rm -f ./ssh-allowed-signers .allowed-ssh-fingerprints.txt # Fetch and verify allowlist -curl -fsSL -O "$BASE_URL/ssh-allowed-signers" +curl -fsSL "${CURL_OPTS[@]}" -O "$BASE_URL/ssh-allowed-signers" check_sha256sum "ssh-allowed-signers" # Extract allowed key fingerprints from allowed-signers file diff --git a/checksum.sha256 b/checksum.sha256 index ea6626e..21ebfc5 100644 --- a/checksum.sha256 +++ b/checksum.sha256 @@ -1,11 +1,11 @@ 1e0c7cc14593577dcbd2b343f39a87120bc42482f25df215c52a9373029dbd4a ./ssh-allowed-signers +2866d0bf67d0a5e284123f445e2978e4b1389e2498de9fe08c3bb43dbe0e63b5 ./dockerfile.sh 48f2d49fab1d7c52f6930bfb239874f1e61479210ceb260d0e2dd9a54c2877e6 ./gpg-list.asc +4939e1364e91cfbb589ddf645ae26530a1e4ecbb4e21c607aad8ee64c9414bca ./scripts/build-prod-node.sh +4aa825fa514655414968415bebfbec5b0252803fbba16e994b29ff1fd3004110 ./check-ssh.sh 5b7f96cd62b02c59adb90159877bd61230c3d95eca3e19a1c4e5dfb4140a986c ./scripts/build-prod-next.sh -8334d814926b6f9368315606199db972f320d98bc997833eaabd5864fdad3a90 ./check-ssh.sh -89d4d141e77c525d43564e72a477cc4dcacae10624b81b9521ed3050be2c0494 ./dockerfile.sh 9dbf9d726d881c43729954f9a29777c0e17d84755c9c32c2fc72a0df39f335cb ./Dockerfile.template aad9d75f80076441f3164f81fb9fca4f4d55ec3c021129cad29633d89b24170d ./scripts/build-prod-nginx.sh -d1ab36d76bf4b3b4fb1d39a3daa02d679358fba2f884c61f5d64e9c764236edb ./check-gpg.sh -ece9b5c612ffff561d0a3b0a5fc7a28ef477ccf13e79da3fdc5460c96eced306 ./scripts/build-prod-node.sh +beee0be70f1a3e4a219e142bf7400415a26dea1873ce279f95f401e682fe0fe6 ./check-gpg.sh f15c4e8e374105e07ab7de3cf94e3ec6aaccd02a76ca9907368782612bc7e50f ./configs/nginx.conf fcf790d01c0ccde52a74a4fa49df33ba9a0f6210868dfa7895048a58bd613710 ./generate-yarn-npm.sh diff --git a/dockerfile.sh b/dockerfile.sh index 7b15c9c..d1245c2 100755 --- a/dockerfile.sh +++ b/dockerfile.sh @@ -382,7 +382,11 @@ generate_build_command() { echo " Pin BASE_REVISION to a commit SHA, or commit scripts/build-prod.sh," >&2 echo " to avoid trusting a moving branch. See SECURITY.md." >&2 local build_script="${BASE_URL}/scripts/build-prod-${BUILD_SCRIPT_TEMPLATE}.sh" - inner="curl -fsSL ${build_script} | bash -eo pipefail" + # --connect-timeout/--max-time/--retry: a stalled connection here would + # otherwise hang `docker build` forever with no output (the network fetch has + # no timeout of its own). Bound it and retry transient blips so the build + # fails fast instead of hanging. See SECURITY.md / build-time notes. + inner="curl -fsSL --connect-timeout 15 --max-time 120 --retry 3 --retry-delay 2 ${build_script} | bash -eo pipefail" fi # Emit a single RUN that mounts the npm token as a BuildKit secret, writes the @@ -397,6 +401,9 @@ generate_build_command() { local h="/home/${BUILDER_USER}" printf '%s\n' "# Application version, injected from the build host (image context has no .git)" printf '%s\n' "ARG APP_VERSION" + # The single quotes are intentional: ${APP_VERSION} must reach the Dockerfile + # verbatim so Docker (not this shell) expands it from the ARG at build time. + # shellcheck disable=SC2016 printf '%s\n' 'ENV APP_VERSION=${APP_VERSION}' printf '%s\n' "# Build with npm auth mounted as a secret (token never persists in a layer)" printf '%s\n' "RUN --mount=type=secret,id=npm_access_token,mode=0444 set -eu && \\" @@ -450,7 +457,7 @@ TEMPLATE_FILE="${CWD}/Dockerfile.template" if [[ ! -f "$TEMPLATE_FILE" ]]; then # Try to download from remote echo "Downloading template from ${BASE_URL}/Dockerfile.template" - curl -fsSL "${BASE_URL}/Dockerfile.template" -o "$TMP_WORK/Dockerfile.template" + curl -fsSL --connect-timeout 15 --max-time 120 --retry 3 --retry-delay 2 "${BASE_URL}/Dockerfile.template" -o "$TMP_WORK/Dockerfile.template" TEMPLATE_FILE="$TMP_WORK/Dockerfile.template" fi diff --git a/generate-ssh-allowed-signers.sh b/generate-ssh-allowed-signers.sh index aad4cca..fb4c7c6 100755 --- a/generate-ssh-allowed-signers.sh +++ b/generate-ssh-allowed-signers.sh @@ -47,7 +47,7 @@ EOF # Fetch and append SSH keys for each user for USER in "${GITHUB_USERS[@]}"; do - KEYS=$(curl -fsSL "https://github.com/${USER}.keys" 2>/dev/null || true) + KEYS=$(curl -fsSL --connect-timeout 15 --max-time 120 --retry 3 --retry-delay 2 "https://github.com/${USER}.keys" 2>/dev/null || true) if [[ -z "$KEYS" ]]; then echo "WARNING: no SSH keys found for $USER — skipping"