From 07016897c5598a24a1ff27b290ddcc5066842a27 Mon Sep 17 00:00:00 2001 From: Marketen Date: Mon, 26 Oct 2026 12:11:17 +0100 Subject: [PATCH 1/3] Restrict web3signer host allowlist to known DAppNode callers Replace --http-host-allowlist=* with the hostnames DAppNode packages and the DAppManager actually use to reach web3signer, so the unauthenticated keymanager API stays protected against DNS rebinding from browsers on the DAppNode VPN/Wi-Fi. Users can append hosts (or "*") through the new EXTRA_HOST_ALLOWLIST env var. The list is a superset of the one gnosis/lukso/hoodi already run with. Co-Authored-By: Claude Opus 5.5 --- docker-compose.yml | 1 + services/web3signer/entrypoint.sh | 29 ++++++++++++++++++++++++++++- 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/docker-compose.yml b/docker-compose.yml index d643cd0..22aa0ac 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -25,6 +25,7 @@ services: environment: JAVA_OPTS: "-Xmx6g" EXTRA_OPTS: "" + EXTRA_HOST_ALLOWLIST: "" WEB3SIGNER_VERTX_WORKER_POOL_SIZE: "20" volumes: - web3signer_data:/data diff --git a/services/web3signer/entrypoint.sh b/services/web3signer/entrypoint.sh index 23e7a84..adfae0e 100755 --- a/services/web3signer/entrypoint.sh +++ b/services/web3signer/entrypoint.sh @@ -22,6 +22,32 @@ generate_cors_settings() { echo "[INFO - entrypoint] Generated CORS_ORIGINS: ${CORS_ORIGINS}" } +# Hostnames (Host header) web3signer accepts on port 9000. Every name another package +# or the DAppManager uses to reach this service must be listed here, otherwise its +# requests get a 403. Users can append more (or "*") with EXTRA_HOST_ALLOWLIST. +generate_host_allowlist() { + # localhost/127.0.0.1: web3signer defaults, used by local tooling + # web3signer.: staker-scripts validator URL, rocketpool, keys registered by brain <= 0.1.19 + HOST_ALLOWLIST="localhost,127.0.0.1,${WEB3SIGNER_DOMAIN},web3signer.${WEB3SIGNER_DOMAIN},brain.${WEB3SIGNER_DOMAIN}" + + # Aliases added by the DAppManager stakers module on dncore, staker and private networks. + # signer..dncore.dappnode: brain >= 0.1.20 (and the remote keys it registers), lido-csm + # web3signer..dncore.dappnode: validator-tracker + for alias in signer web3signer; do + HOST_ALLOWLIST="${HOST_ALLOWLIST},${alias}.${NETWORK}.dncore.dappnode,${alias}.${NETWORK}.staker.dappnode,${alias}.${NETWORK}.dappnode.private" + done + + if [ -n "${consensus_domain}" ]; then + HOST_ALLOWLIST="${HOST_ALLOWLIST},validator.${consensus_domain}" + fi + + if [ -n "${EXTRA_HOST_ALLOWLIST}" ]; then + HOST_ALLOWLIST="${HOST_ALLOWLIST},${EXTRA_HOST_ALLOWLIST}" + fi + + echo "[INFO - entrypoint] Generated HOST_ALLOWLIST: ${HOST_ALLOWLIST}" +} + prepare_keyfiles_dir() { # IMPORTANT! The dir defined for --key-store-path must exist and have specific permissions. Should not be created with a docker volume mkdir -p "${KEYFILES_DIR}" @@ -35,7 +61,7 @@ run_web3signer() { FLAGS="--key-store-path=$KEYFILES_DIR \ --http-listen-port=9000 \ --http-listen-host=0.0.0.0 \ - --http-host-allowlist=* \ + --http-host-allowlist=$HOST_ALLOWLIST \ --http-cors-origins=$CORS_ORIGINS \ --metrics-enabled=true \ --metrics-host 0.0.0.0 \ @@ -58,5 +84,6 @@ run_web3signer() { } generate_cors_settings +generate_host_allowlist prepare_keyfiles_dir run_web3signer From c025e96094812f5d2ebdcf06e4e8df67eeb62616 Mon Sep 17 00:00:00 2001 From: Marketen Date: Mon, 26 Oct 2026 16:38:32 +0100 Subject: [PATCH 2/3] Allow every hostname Docker and the DAppManager assign to web3signer Checked against a live DAppNode (DAppManager 0.2.129): besides the stakers-module aliases the container also gets the bare service name, .private, web3signer..private and its container name. No known caller uses them, but they are internal names, so allowing them costs nothing and avoids 403s for tooling that does. Co-Authored-By: Claude Opus 5.5 --- services/web3signer/entrypoint.sh | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/services/web3signer/entrypoint.sh b/services/web3signer/entrypoint.sh index adfae0e..b53414d 100755 --- a/services/web3signer/entrypoint.sh +++ b/services/web3signer/entrypoint.sh @@ -37,6 +37,11 @@ generate_host_allowlist() { HOST_ALLOWLIST="${HOST_ALLOWLIST},${alias}.${NETWORK}.dncore.dappnode,${alias}.${NETWORK}.staker.dappnode,${alias}.${NETWORK}.dappnode.private" done + # Remaining names Docker and the DAppManager give this container: the compose service + # name, the private network domain and the container name + if [ "${NETWORK}" = "mainnet" ]; then dnp_name="web3signer.dnp.dappnode.eth"; else dnp_name="web3signer-${NETWORK}.dnp.dappnode.eth"; fi + HOST_ALLOWLIST="${HOST_ALLOWLIST},web3signer,${WEB3SIGNER_DOMAIN}.private,web3signer.${WEB3SIGNER_DOMAIN}.private,DAppNodePackage-web3signer.${dnp_name}" + if [ -n "${consensus_domain}" ]; then HOST_ALLOWLIST="${HOST_ALLOWLIST},validator.${consensus_domain}" fi From 16a356a0388e8ff24a562804032b51733177c3c5 Mon Sep 17 00:00:00 2001 From: Marketen Date: Mon, 26 Oct 2026 17:06:42 +0100 Subject: [PATCH 3/3] Strip whitespace from EXTRA_HOST_ALLOWLIST The web3signer flags are passed word-split, so "a.example, b.example" made web3signer fail to start ("Unmatched argument at index 4: 'b.example'"). A typo in the package config must not stop the signer. Co-Authored-By: Claude Opus 5.5 --- services/web3signer/entrypoint.sh | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/services/web3signer/entrypoint.sh b/services/web3signer/entrypoint.sh index b53414d..1e0321e 100755 --- a/services/web3signer/entrypoint.sh +++ b/services/web3signer/entrypoint.sh @@ -46,8 +46,10 @@ generate_host_allowlist() { HOST_ALLOWLIST="${HOST_ALLOWLIST},validator.${consensus_domain}" fi - if [ -n "${EXTRA_HOST_ALLOWLIST}" ]; then - HOST_ALLOWLIST="${HOST_ALLOWLIST},${EXTRA_HOST_ALLOWLIST}" + # Strip whitespace: FLAGS is word-split, so "a, b" would pass "b" as a stray argument and web3signer would not start + extra_hosts=$(printf '%s' "${EXTRA_HOST_ALLOWLIST}" | tr -d '[:space:]') + if [ -n "${extra_hosts}" ]; then + HOST_ALLOWLIST="${HOST_ALLOWLIST},${extra_hosts}" fi echo "[INFO - entrypoint] Generated HOST_ALLOWLIST: ${HOST_ALLOWLIST}"