fix(security): caddy-event self-noise conjunction filter for host curl probes (DC-118) [glm-grade=A]
CI / Test & Lint (push) Canceled after 0s
CI / Security audit (push) Canceled after 0s

The host-side uptime watchdog and on-host cron jobs curl Caddy with a stock
curl/8.5.0 UA from loopback and the host tailscale IP — ~300 GET /api/health
401 warn-events/day burying real perimeter signal (census: 339+20 of 5000
access.log lines). Dropping on UA alone would blind the store to external
curl scanners, so generic tool UAs (curl/) are now dropped ONLY when the
source remote_ip is one of this host's own addresses (DASHCADDY_SELF_IPS,
default loopback; start.sh derives 127.0.0.1 + tailscale ip -4, empty-safe).
remote_ip (TCP peer) is used, never the spoofable client_ip. DashCaddy-*
probe UAs stay unconditionally dropped. 9 regression pins cover the full
conjunction matrix incl. external-IP+curl KEPT and spoofed-XFF KEPT.
2858/2858 green (128 suites).

Judge: glm-4.6@zai-coding-paas cold-read round 1 = A clean (0 blocking),
both polish notes folded. URN urn:ump:s2sgitfepze65crtp57dpdw4gk4w7upsoi4tqcvfwahcsicyepba
This commit is contained in:
Hermes
2026-08-23 15:53:58 -07:00
parent 2dce6dca5e
commit 1744d1c86e
3 changed files with 214 additions and 3 deletions
+8
View File
@@ -8,6 +8,13 @@ ASSETS_DIR="/var/www/dashcaddy-status/assets"
UPDATES_DIR="/opt/dashcaddy/updates"
BACKUPS_DIR="/opt/dashcaddy/backups"
HOST_IP="172.17.0.1"
# DC-118: this host's own routable IPs (comma-sep) — passed to the API so the
# caddy-event self-noise filter can drop the host's own curl probes (watchdog,
# cron) without blinding the store to external curl traffic. Loopback is
# always implicit in the worker; add the tailscale IP when discoverable.
SELF_IPS="127.0.0.1"
TS_IP="$(tailscale ip -4 2>/dev/null | head -1 || true)"
[ -n "$TS_IP" ] && SELF_IPS="${SELF_IPS},${TS_IP}"
# Local Technitium (binds 0.0.0.0:53) resolves *.sami + recurses for docker subnet
# external fallback. Without this the container only has 8.8.8.8 and every
# *.sami health-check probe fails with ENOTFOUND (uptime bars stay empty).
@@ -182,6 +189,7 @@ docker run -d --restart unless-stopped --name ${CONTAINER_NAME} \
-e CADDYFILE_PATH=/caddyfile \
-e CADDY_ADMIN_URL=http://${HOST_IP}:2019 \
-e CADDY_ACCESS_LOG=/var/log/caddy/access.log \
-e DASHCADDY_SELF_IPS="${SELF_IPS}" \
-e ASSETS_DIR=/app/assets \
-e DASHCADDY_API_SOURCE_DIR=/opt/dashcaddy/dashcaddy-api \
-e DASHCADDY_UPDATE_ENABLED=false \