Octet

Write a minimal stateful host firewall that allows SSH from a management subnet and blocks everything else inbound.

Show the answer

Say this first

Default drop on input, then in order: allow loopback, allow established and related traffic, drop invalid, allow ICMP echo, allow TCP 22 only from the management subnet. Outbound stays open. The established rule near the top lets replies to the host's own connections back in and makes the rule set cheap, because most packets match it first. ICMP errors for existing flows arrive as RELATED, so PMTUD keeps working.

Go deeper

iptables

Shell
iptables -A INPUT -i lo -j ACCEPT
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -m conntrack --ctstate INVALID -j DROP
iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT
iptables -A INPUT -p tcp -s 10.0.50.0/24 --dport 22 -j ACCEPT
iptables -P INPUT DROP

The policy is set last so an SSH session building the rules is never cut off halfway.

nftables, same logic, IPv4 and IPv6 together

Output
#!/usr/sbin/nft -f
flush ruleset

table inet host {
    chain input {
        type filter hook input priority filter; policy drop;
        iif "lo" accept
        ct state established,related accept
        ct state invalid drop
        meta l4proto { icmp, ipv6-icmp } accept
        ip saddr 10.0.50.0/24 tcp dport 22 accept
    }
}

Saved as /etc/nftables.conf (Debian, Ubuntu) or /etc/sysconfig/nftables.conf (RHEL), loaded at boot by nftables.service.

Why ICMPv6 must be open

IPv6 neighbour discovery and router advertisements are ICMPv6. Drop them and IPv6 stops working entirely, not just ping.

Traps

  • Dropping all ICMP. IPv4 PMTUD and the whole of IPv6 depend on it.
  • Forgetting loopback. Local services talking to each other on 127.0.0.1 break in odd ways.
How did you do?Book 8.5 Example Systems