Nftables: Difference between revisions

From Wiki
Jump to navigation Jump to search
Created page with "= nftables Cheat Sheet = Config: <code>/etc/nftables.conf</code> · table <code>inet filter</code> · chains <code>input</code> / <code>forward</code> / <code>output</code> Input policy is '''drop'''; SSH allowed only from <code>$ssh_nets_v4</code>. Out-of-band rescue: IPMI/BMC console (H5Viewer or Serial-over-LAN). == Everyday commands == <syntaxhighlight lang="bash"> # Syntax-check the config WITHOUT applying (always do this first) sudo nft -c -f /etc/nftables.con..."
 
 
Line 49: Line 49:
Options, in order of preference:
Options, in order of preference:


# '''UCI VPN''' — connect, then SSH from the VPN address (10.0.0.0/8 and campus ranges are in <code>$ssh_nets_v4</code>).
# '''VPN''' — connect, then SSH from the VPN address (campus ranges are in <code>$ssh_nets_v4</code>).
# '''IPMI console''' — log in via BMC, then fix from the console.
# '''IPMI console''' — log in via BMC, then fix from the console.
# '''Temporary runtime rule''' from the console (does NOT survive reload/reboot):
# '''Temporary runtime rule''' from the console (does NOT survive reload/reboot):

Latest revision as of 22:56, 2 July 2026

nftables Cheat Sheet

Config: /etc/nftables.conf · table inet filter · chains input / forward / output

Input policy is drop; SSH allowed only from $ssh_nets_v4.

Out-of-band rescue: IPMI/BMC console (H5Viewer or Serial-over-LAN).

Everyday commands

# Syntax-check the config WITHOUT applying (always do this first)
sudo nft -c -f /etc/nftables.conf

# Check + reload in one line (reload only runs if check passes)
sudo nft -c -f /etc/nftables.conf && sudo systemctl reload nftables

# Show the live ruleset
sudo nft list ruleset

# Show live ruleset WITH handles (needed for deleting single rules)
sudo nft -a list ruleset

# Just the input chain
sudo nft list chain inet filter input

# Service status / enabled at boot?
systemctl status nftables
systemctl is-enabled nftables

Am I being firewalled? (diagnosis)

# Watch the drop log live (rules log with prefix "nft drop: ")
sudo journalctl -kf | grep 'nft drop'

# Recent drops
sudo journalctl -k --since "1 hour ago" | grep 'nft drop'

# Counters: add a counter to a rule temporarily, or check conntrack
sudo conntrack -L | grep <ip>        # is there an established session?

Remember: broadcast/multicast is dropped silently (no log). Everything else that's dropped is logged at max 5/minute — absence of log lines does not mean absence of drops during a flood.

TRAVEL SCENARIO: my current IP can't SSH in

Options, in order of preference:

  1. VPN — connect, then SSH from the VPN address (campus ranges are in $ssh_nets_v4).
  2. IPMI console — log in via BMC, then fix from the console.
  3. Temporary runtime rule from the console (does NOT survive reload/reboot):
# Allow one address into SSH, inserted before the drop logic takes effect
sudo nft insert rule inet filter input ip saddr <MY.IP.ADDR.HERE>/32 tcp dport 22 ct state new accept

# Verify
sudo nft list chain inet filter input

# Remove it later: find its handle, then delete
sudo nft -a list chain inet filter input
sudo nft delete rule inet filter input handle <N>

For a permanent change, edit $ssh_nets_v4 in /etc/nftables.conf, check, reload (see above). Runtime rules are lost on the next reload because the config starts with flush ruleset.

Emergency: firewall is broken / I need it out of the way

# From the IPMI console ONLY — this leaves the box wide open:
sudo nft flush ruleset

# Restore known-good config
sudo nft -c -f /etc/nftables.conf && sudo nft -f /etc/nftables.conf

Reload interactions

  • flush ruleset (any reload) wipes fail2ban's ban sets too. Restore them: sudo systemctl restart fail2ban
  • Established connections (incl. your live SSH session) survive reloads — they match ct state established, not the new rules.

After-reboot sanity check

systemctl is-active nftables && sudo nft list ruleset | head -20

Empty ruleset after boot = config failed to parse = sshd exposed to everything. Check journalctl -u nftables -b for the parse error.

Config gotchas (this file specifically)

  • Comment block and define ssh_nets_v4 must be kept in sync — every CIDR needs a documented reason.
  • ICMPv6 rules are load-bearing: IPv6 breaks without NDP/PMTU. Don't trim.
  • output policy is accept (egress open) — intentional, matches old script.
  • SSH rate-limiting is fail2ban's job, not nft's. Don't add limit rules to the SSH accept line; they'll fight with ThinLinc multi-connections.