chore(egress): release-gate harness — G1 capture + G2 double-gate smoke#157
Merged
Conversation
Tooling for the v0.4.0 egress-jail release gates (maintainer-run, bare Linux,
NOT in CI). No production files touched.
- scripts/egress-capture.sh (G1): enable/collect/finalize/disable subcommands.
enable appends a temporary `.*` allow-all to the global allowlist (backed up
first) so the per-session sidecar — which already runs LogLevel Connect — logs
every CONNECT; collect harvests unique requested hosts from `docker logs`;
finalize prints anchored-ERE baseline candidates not already shipped; disable
restores the backup. Pure parser helpers are unit-tested.
- scripts/egress-smoke.sh (G2): brings up a standalone sidecar on the real
drydock_internal/drydock_egress networks (mirroring prod hardening: cap_drop
ALL, no-new-privileges, read_only + tmpfs) and probes via the proxy — an
allowlisted host tunnels (CONNECT 200); non-allowlisted and IP-literal are
refused (CONNECT 403). Block-detection reads curl %{http_connect} (the proxy
CONNECT code), not %{http_code} (the tunneled GET, which is 000 on refusal).
- test/egress_gate.bats: 17 unit tests for the pure capture helpers
(_extract_connect_hosts, _to_ere_baseline_pattern), incl. malformed-line and
dedup edge cases.
The tinyproxy log format is assumed (debian:12 tinyproxy); both scripts dump raw
logs and print a "confirm format on first real run" notice. 1154/1154 bats green;
shellcheck + shfmt clean.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Tooling for the v0.4.0 egress-jail release gates G1 (empirical baseline CONNECT
capture) and G2 (runtime double-gate smoke). Maintainer-run, bare Linux, NOT in
CI. The egress jail itself already shipped (#154/#155/#156). No production file
is touched — three new files only.
Files
scripts/egress-capture.sh(G1) —enable/collect/finalize/disablesubcommands.enablebacks up~/.config/drydock/egress-allowlistand appends a temporary
.*allow-all so the per-session sidecar (which alreadyruns
LogLevel Connect) logs every CONNECT;collectharvests unique requestedhosts from
docker logs;finalizeprints anchored-ERE baseline candidates notalready in the shipped baseline;
disablerestores the backup. Idempotent;double-enable guarded so the real backup can't be clobbered.
scripts/egress-smoke.sh(G2) — brings up a standalone sidecar on the realdrydock_internal/drydock_egressnetworks, mirroring prod hardening(
cap_drop ALL,no-new-privileges,read_only+ tmpfs/run+/tmp), andprobes through the proxy: allowlisted host tunnels (CONNECT 200),
non-allowlisted + IP-literal are refused (CONNECT 403). Block-detection reads
curl
%{http_connect}(the proxy CONNECT code) — not%{http_code}(thetunneled GET, which is
000on refusal). Cleanup trap removes the smoke sidecar;the shared fixed-name networks are left in place.
test/egress_gate.bats— 17 unit tests for the pure capture helpers(
_extract_connect_hosts,_to_ere_baseline_pattern): both tinyproxy lineforms, dedup, IP-literals, noise rejection, a malformed-line no-raw-leak guard,
and ERE anchoring/dot-escaping.
Verification
scripts/test.sh— 1154/1154 green (1137 prior + 17 new).was keying off
%{http_code}instead of%{http_connect}, so the block gatescould never pass) plus four WARNINGs (temp-file leak on missing baseline, smoke
sidecar hardening fidelity, a parser raw-line leak on a malformed log line, and a
grep -qF '.*'substring false-positive inenable). All applied.Honest caveat
The tinyproxy
LogLevel Connectline format is assumed (debian:12 tinyproxy);it cannot be verified in WSL2. Both scripts dump raw
docker logsand print a"confirm log format on first real run" notice, and the bats tests validate parser
internal consistency only — not real tinyproxy output. The first real
collectrun is the format gate.
Size
size:exception— 757 insertions, but all-new additive tooling that touches noproduction code, is cohesive (G1+G2+tests as one harness), and has already passed
an adversarial review. Splitting would be artificial (G1 alone is ~488 lines).
Not in this PR
Running the gates (G1/G2) and the v0.4.0 release (G3) remain maintainer steps on a
bare-Linux host. Does not close #149. Refs #149.