mirror of
https://github.com/rennf93/roboco.git
synced 2026-08-03 07:23:24 +02:00
fix(guard): operator-scoped XFF hop peers + tailnet allowlist (live-incident fix) (#650)
Two coupled hardenings from the chain-peers adversarial rounds plus the
root-cause fix for the live post-deploy incident where the CEO was
blocked from the panel ('IP not allowed: 100.x.x.x').
Hop peel-set: the whole docker bridge pool leaves the XFF hop set — hops
are now loopback plus operator-named single addresses only
(ROBOCO_GUARD_TRUSTED_CHAIN_PEERS, plain IPs; CIDR entries rejected with
a warning because a range readmits sibling containers). Default-empty
closes the CGNAT-forge residual outright; a gateway-fronted Tailscale
Serve deploy sets its real gateway IP, and a rate-limited detection log
names exactly that IP when an unconfigured host-proxied tailnet chain is
seen, so the silent-regression shape is observable. The connecting-peer
gate (may nginx present XFF at all) deliberately keeps the broad bridge
pool — different check, unchanged.
Incident root cause: guard-core's whitelist is an EXCLUSIVE allowlist
(any non-member is refused), so honestly resolving the tailnet client IP
made ip_security reject the CEO. The tailnet CGNAT range joins
_guard_whitelist() deliberately: Tailscale authenticates device
membership before a packet arrives, real-IP stamping still buys correct
attribution, and any future non-tailnet exposure keeps full scrutiny.
Both compose files now pass ROBOCO_GUARD_EMERGENCY_WHITELIST through to
the orchestrator (the operator escape hatch previously did nothing in a
compose deploy).
NAS is running ROBOCO_GUARD_PASSIVE_MODE=true as interim mitigation —
flip back to false when this deploys. 66 tests.
Co-authored-by: Renn F <rennf93@users.noreply.github.com>
This commit is contained in:
@@ -249,6 +249,11 @@ ROBOCO_DB_NETWORK_ISOLATED=true
|
||||
# ROBOCO_GUARD_PASSIVE_MODE=true
|
||||
# Fail CLOSED on an internal guard error (true) vs fail open (false).
|
||||
# ROBOCO_GUARD_FAIL_SECURE=true
|
||||
# Exact IP address(es), never a range, trusted as an XFF proxy hop beyond loopback
|
||||
# (a CIDR entry is rejected — it would readmit every sibling container). Empty =
|
||||
# loopback-only hop-peel. If Tailscale Serve sits behind this host's docker gateway,
|
||||
# set it to that gateway's exact address to keep the chain resolving (e.g. 172.18.0.1).
|
||||
# ROBOCO_GUARD_TRUSTED_CHAIN_PEERS=172.18.0.1
|
||||
|
||||
# =============================================================================
|
||||
# Architectural conventions standard + agent-runtime toolchain matching
|
||||
|
||||
Reference in New Issue
Block a user