fix(firewall): Postfix 25 is tailnet-only; staging audits all published ports #83

Merged
jfraeys merged 1 commit from jfraeys/fix/tailnet-only-ports-and-open-port-check into main 2026-10-12 23:14:44 -04:00
Owner

Postfix publishes 25:25 on all interfaces and its compose comment called that deliberate, but the role is a send-only relay whose only remote client is web over the tailnet (ACL tag:web -> services:25). Port 25 had no DOCKER-USER rule.

  • roles/firewall: the 17170 block becomes a loop over tailnet-only ports (17170, 25), v4 and v6. Container-originated traffic (-i docker0/br+) is exempted so Authelia/Vaultwarden -> Postfix on the shared bridge keeps working. Tested in a container: the rules production has now (from #78) upgrade to one clean set when the new script runs, twice, ACCEPTs above DROP.
  • validate-connectivity.yml: host-side audit (playbooks/files/published_ports.py) fails on any port published to all interfaces that is neither allowlisted (80/443/3478 udp) nor dropped in DOCKER-USER; plus a container-on-proxy -> postfix:25 check that would catch the bridge hazard. The web-side port 25 probe can pass vacuously (Linode/ISP block outbound 25), so the audit is the real assertion.
  • Postfix compose comment corrected.

Merging changes production on the next firewall deploy: tailnet relay from web and in-host mail keep working; public 25 closes.

Plan: L3 of the loose-ends track.

🤖 Generated with Claude Code

Postfix publishes 25:25 on all interfaces and its compose comment called that deliberate, but the role is a send-only relay whose only remote client is web over the tailnet (ACL tag:web -> services:25). Port 25 had no DOCKER-USER rule. - roles/firewall: the 17170 block becomes a loop over tailnet-only ports (17170, 25), v4 and v6. Container-originated traffic (-i docker0/br+) is exempted so Authelia/Vaultwarden -> Postfix on the shared bridge keeps working. Tested in a container: the rules production has now (from #78) upgrade to one clean set when the new script runs, twice, ACCEPTs above DROP. - validate-connectivity.yml: host-side audit (playbooks/files/published_ports.py) fails on any port published to all interfaces that is neither allowlisted (80/443/3478 udp) nor dropped in DOCKER-USER; plus a container-on-proxy -> postfix:25 check that would catch the bridge hazard. The web-side port 25 probe can pass vacuously (Linode/ISP block outbound 25), so the audit is the real assertion. - Postfix compose comment corrected. Merging changes production on the next firewall deploy: tailnet relay from web and in-host mail keep working; public 25 closes. Plan: L3 of the loose-ends track. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
fix(firewall): Postfix 25 is tailnet-only; staging audits published ports
All checks were successful
Lint / lint (pull_request) Successful in 1m39s
Secret scan / scan (pull_request) Successful in 16s
fd6a0bf6ec
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
jfraeys/infra!83
No description provided.