39 lines
1.9 KiB
Markdown
39 lines
1.9 KiB
Markdown
# Host firewall (Infrastructure as Code)
|
|
|
|
Canonical copies of the prod app-host firewall (see `docs/vm-security-hardening.md`
|
|
for the full rationale). These are the source of truth; the live host should
|
|
match. Installed as a boot-enabled systemd service.
|
|
|
|
## Files
|
|
- `pw-firewall.nft` -> `/etc/pw-firewall/pw-firewall.nft`
|
|
nftables `inet pw_fw` table (input hook, priority -150). Public allow-list
|
|
`{22, 22022, 80, 443}`, a `trusted_admin` set allow-listing git/forgejo (3022),
|
|
internal subnets + loopback fully trusted, everything else on `ens18` dropped.
|
|
- `pw-docker-fw.sh` -> `/usr/local/sbin/pw-docker-fw.sh`
|
|
Adds DOCKER-USER rules so external (ens18) NEW inbound to Docker-published
|
|
container ports is dropped (postgres/listmonk/api/forgejo were accidentally
|
|
on 0.0.0.0); trusted_admin IPs are allow-listed to forgejo first.
|
|
- `pw-firewall.service` -> `/etc/systemd/system/pw-firewall.service`
|
|
Applies both at boot (After=docker). Also re-applied on docker restart via
|
|
`/etc/systemd/system/docker.service.d/pw-firewall.conf` (ExecStartPost).
|
|
|
|
## Install / update on the host
|
|
```
|
|
sudo install -D -m 0644 pw-firewall.nft /etc/pw-firewall/pw-firewall.nft
|
|
sudo install -D -m 0755 pw-docker-fw.sh /usr/local/sbin/pw-docker-fw.sh
|
|
sudo install -D -m 0644 pw-firewall.service /etc/systemd/system/pw-firewall.service
|
|
sudo systemctl daemon-reload
|
|
sudo systemctl enable --now pw-firewall.service
|
|
```
|
|
|
|
## Add / remove a trusted admin IP (for git push over :3022)
|
|
```
|
|
sudo nft add element inet pw_fw trusted_admin { <IP> } # live
|
|
# then add <IP> to TRUSTED_ADMIN in pw-docker-fw.sh + the set in pw-firewall.nft
|
|
# and re-run: sudo systemctl restart pw-firewall.service
|
|
```
|
|
|
|
## Safety
|
|
Roll out with an auto-rollback timer (`setsid sh -c 'sleep 300; nft delete table
|
|
inet pw_fw; iptables -F DOCKER-USER; ...'`) so a bad rule can't lock you out;
|
|
cancel it only after verifying SSH + git still work from off-network.
|