feat(deploy): add host firewall with per-IP connection limits#51
Merged
Conversation
Adds contrib/buffetcar.nftables, a surgical nftables ruleset installed by the Deploy workflow. The box currently has no host firewall (verified: iptables at default ACCEPT, no nftables/ufw), so only the Lightsail cloud firewall sits in front of tcp/1900 and it cannot per-IP cap. This closes the single-source worker-exhaustion / slowloris gap (#29) at the firewall layer. Design notes: - Surgical, not a perimeter firewall: input policy stays 'accept' so it can never lock out SSH or block other services. Lightsail handles port filtering. - Rules cap per-source-IP concurrent connections (ct count over 16) and new-connection rate (30/min) on tcp/1900; excess is dropped silently (no RST), preserving the no-leakage contract. - Deploy step installs nftables, validates the file with 'nft -c -f' before applying (a syntax error fails the deploy rather than half-applying), then applies atomically with 'nft -f'. Staged approach: this is the firewall layer SECURITY.md already scopes rate limiting to. The in-app per-IP concurrent cap remains open in #29, justified narrowly as making the binary safe-by-default when deployed without a firewall.
cf05da3 to
6a34366
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 the single-source worker-exhaustion / slowloris gap in #29 at the firewall layer.
Context
Verified on the box (SSH): there is no host firewall —
iptables/ip6tablesare at defaultACCEPTwith zero rules, andnftables/ufwaren't installed. So only the Lightsail cloud firewall sits in front of tcp/1900, and it structurally can't per-IP cap. The box is raw-exposed for #29.What this adds
contrib/buffetcar.nftables— a surgical ruleset (samecontrib/+ deploy-installed pattern asbuffetcar.service):accept→ cannot lock out SSH or block other services; Lightsail handles port filtering.ct count over 16) — the resource-cap sibling of the--workerspool.deploy.ymlstep — installs nftables, validates withnft -c -fbefore installing (syntax error fails the deploy rather than half-applying), then applies atomically withnft -f.Staged approach (why this is only half of #29)
This is the firewall layer
SECURITY.mdalready scopes rate limiting to. The in-app per-IP concurrent cap stays open in #29, justified narrowly as making the binary safe-by-default when deployed without a firewall.Human-merge + human first-apply, please
Touches the deploy path and the threat model. Merging triggers a deploy that installs+applies the firewall on the live box. The
nft -c -fgate makes a syntax error fail safe (policyaccept, nothing applied), but I'd rather you watch the first apply. The exact per-sourcemeter { … ct count over … }statement is validated by that check-mode step on first apply.