Repository navigation
fix(egress): plain HTTP reaches a listed host on port 80 only, and doctor proves it (#508) - #514
Merged
Merged
Conversation
edgehero
force-pushed
the
fix/508-plain-http-port-80
branch
3 times, most recently
from
September 30, 2026 14:27
5489961 to
0d1ae6b
Compare
…ctor proves it (#508) The proxy's `http_access allow allowed` had no port rule, so any client that forwards plain HTTP (curl -x, package managers, git over http://, npm undici's EnvHttpProxyAgent from 8.7 without proxyTunnel) reached every port of a listed host in clear text. The rules now carry `acl Safe_ports port 80` and `http_access deny !Safe_ports !CONNECT` directly before that allow: it resolves nothing and never matches a CONNECT, so the tunnel rules are untouched. A plain forward `GET https://` is now refused too. doctor's egress canary gains a third probe, plainhttp: a raw node:http forward request to http://api.anthropic.com:443/, counted as refused only on squid's 403 with X-Squid-Error ERR_ACCESS_DENIED. egressVerdict requires each of the three probes exactly once, by name, and words a wrong one by its probe. doctor warns when egress is armed and a triggered forge's GITLAB_URL or FORGEJO_URL is anything but https:// on 443: the job image's git ignores the uppercase HTTP_PROXY for an http:// remote, so a job's push and fetch fail (its API calls too, off port 80), and the proxy refuses a CONNECT off 443. docs/egress.md's sample doctor lines are now pinned to the code. Specs: REQ-EGRESS-ALLOWLIST AMENDED; INT-EGRESS-POLICY-CONTRACT AMENDED; INT-LIVE-PROBE-CONTRACT AMENDED; DES-EGRESS-DENY-ON-A-DEDICATED-NETWORK AMENDED (owner decision: port 80 kept over HTTPS only). Signed-off-by: Rob Boerman <robboerman@live.nl>
edgehero
force-pushed
the
fix/508-plain-http-port-80
branch
from
September 30, 2026 14:49
0d1ae6b to
cbb51e8
Compare
3 tasks
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.
Closes #508.
What changes
The egress proxy let a plain (untunnelled) request reach an allowlisted host on any port.
http_access allow allowedhad no port rule. Now exactly two shapes pass, both only to listed hosts:a CONNECT tunnel on port 443;
a plain request on port 80.
deploy/egress-proxy.conf(and its mirror) gainsacl Safe_ports port 80andhttp_access deny !Safe_ports !CONNECT, directly beforeallow allowed. The rule names only port and method ACLs, so no unlisted name is ever resolved. It never matches a CONNECT, so pi's tunnelled calls are untouched.A side effect, now documented: a forward
GET https://host/is refused. Before this change it made squid open the TLS connection itself.doctoranddoctor --liverun a third egress probe. It sends a raw plain-HTTPGET http://api.anthropic.com:443/through the proxy, and it counts as refused only on a 403 withX-Squid-Error: ERR_ACCESS_DENIED. The live verdict now needs each of the three probes exactly once, by name.doctorwarns when egress is on and a triggered forge'sGITLAB_URLorFORGEJO_URLis anything buthttps://on 443. A job gets the proxy variables in uppercase only, and git ignoresHTTP_PROXYfor anhttp://remote (measured in the job image, git 2.39.5), so anhttp://forge fails on any port, 80 included. That was already so before this change. The proxy also refuses aCONNECTto any port but 443. The clone runs on the host, so what fails is a job's git push and fetch, and its API calls too off port 80 (glab and tea do useHTTP_PROXY). A URL with any other scheme gets its own "not an https:// URL" line. The ways out arehttps://on 443, orPI_EGRESS=0.docs/gitlab.md,docs/forgejo.mdanddocs/egress.mdsay so.The issue asked for the new case in the canary rows. Those rows (
CANARY_LINES) describe the leftover sweep's lines only, so the new case lives in the probe loop and indocs/egress.md's sample doctor output. A new test pins that sample output to the code.docs/egress.mdsays exactly what passes. The specs INT-EGRESS-POLICY-CONTRACT, INT-LIVE-PROBE-CONTRACT, REQ-EGRESS-ALLOWLIST and DES-EGRESS-DENY-ON-A-DEDICATED-NETWORK are amended.Measured before and after (2026-09-30)
Runtimes: squid 6.13 (the pinned digest) on Docker 29.1.3 and rootless Podman 4.9.3 (Ubuntu 24.04), and rootless Podman 5.8.1 (Fedora). All three gave the same results.
Upgrading
egress-proxy.conf.doctornames the difference andpi-dispatch upoffers a refresh; on the podman venue useservice install --force.Tests
!CONNECTdroppedfetchinstead of a raw request