fix(pipelock): allow agent->sidecar traffic via SSRF exception
The agent's HTTP_PROXY points at pipelock, so a request to http://cred-proxy:9099/... arrives at pipelock; pipelock resolves the host, sees an RFC1918 address (the bottle's internal Docker network sits in 172.x), and 403's "SSRF blocked: cred-proxy resolves to internal IP 172.20.0.4". Bypassing pipelock entirely would also remove its body scanner from the agent->cred-proxy leg — we want to keep that DLP coverage. Pipelock has `ssrf.ip_allowlist` for exactly this: CIDRs that override the built-in internal-IP block while api_allowlist + body scanning + tls_interception keep firing. Wiring: - `pipelock_build_config` accepts `ssrf_ip_allowlist`; when non-empty, emits an `ssrf: { ip_allowlist: [...] }` block. - `pipelock_render_yaml` renders that block. - `PipelockProxyPlan` gains `internal_network_cidr`. - New `network_inspect_cidr(name)` helper reads the Docker-assigned subnet via `docker network inspect`. - launch.py: after `network_create_internal`, inspect the CIDR, re-render the yaml with `ssrf_ip_allowlist=(cidr,)`, overwrite the file in place; `DockerPipelockProxy.start` then docker-cp's the updated content. Prepare's initial render stays unchanged (CIDR isn't known yet at prepare time). The exception scope is the bottle's own internal network only — agent ↔ pipelock / git-gate / cred-proxy. Body scanning still applies to the bytes flowing through pipelock; pipelock just no longer treats those internal IPs as exfil targets.
This commit is contained in:
@@ -81,6 +81,29 @@ def network_create_egress(slug: str) -> str:
|
||||
return _network_create_with_prefix(network_egress_name_for_slug(slug), internal=False)
|
||||
|
||||
|
||||
def network_inspect_cidr(name: str) -> str:
|
||||
"""Return the IPv4 CIDR Docker assigned to a user-defined network.
|
||||
|
||||
Used by pipelock's SSRF guard exception: the bottle's internal
|
||||
network sits in RFC1918 space, so pipelock's `internal:` list
|
||||
would block any agent request whose destination resolves there
|
||||
— including the cred-proxy sidecar's address. Adding the
|
||||
network's CIDR to pipelock's `ssrf.ip_allowlist` lets traffic
|
||||
targeted at the bottle's own sidecars through while pipelock
|
||||
still body-scans and api_allowlist-gates as usual."""
|
||||
result = subprocess.run(
|
||||
["docker", "network", "inspect",
|
||||
"--format", "{{range .IPAM.Config}}{{.Subnet}}{{end}}", name],
|
||||
capture_output=True, text=True, check=False,
|
||||
)
|
||||
if result.returncode != 0:
|
||||
die(f"docker network inspect {name} failed: {result.stderr.strip()}")
|
||||
cidr = result.stdout.strip()
|
||||
if not cidr:
|
||||
die(f"network {name!r} has no IPAM subnet configured")
|
||||
return cidr
|
||||
|
||||
|
||||
def network_attach(network: str, container: str) -> None:
|
||||
result = subprocess.run(
|
||||
["docker", "network", "connect", network, container],
|
||||
|
||||
Reference in New Issue
Block a user