#!/usr/sbin/nft -f # Optionally blacklist ip_tables in modprobe.d (https://bugs.freedesktop.org/show_bug.cgi?id=89269) # On pristine setup through SSH bring up connection tracking: $ sudo ./ct.nft # Install the final rule set: $ sudo ./firewall.nft # Save the resolved rule set: $ sudo nft --stateless -nnn list ruleset | sudo tee /etc/nftables.conf; sudo chmod -x /etc/nftables.conf # Load it on boot: $ sudo systemctl enable nftables.service # # Ansible idea: create the resolved rule set by templating and load it under # unshare with a local-only nsswitch.conf to exclude network-reliance (DNS, # LDAP, etc.) Even better: patch nft to provide this function. Or resolution # instead of loading. flush ruleset table inet filter { chain FORWARD { type filter hook forward priority 0; policy drop; } chain INPUT { type filter hook input priority 0; policy drop; limit rate 15/hour burst 1 packets log prefix "Firewall heartbeat: " level info iif "lo" accept udp sport ntp udp dport ntp accept meta l4proto ipv6-icmp accept ct state related,established accept ct state new jump new-in ip saddr != { 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16, 146.110.0.0/16, 148.6.0.0/16, 152.66.0.0/16, 157.181.0.0/16, 160.114.0.0/16, 192.146.134.0/24, 192.146.135.0/24, 192.153.18.0/24, 192.160.172.0/24, 192.188.242.0/23, 192.188.244.0/22, 192.190.173.0/24, 193.6.0.0/16, 193.224.0.0/15, 195.111.0.0/16, 193.224.152.0/23, 193.224.154.0/23 } drop ip daddr 255.255.255.255 udp dport 2223 counter drop ip protocol igmp ip daddr 224.0.0.1 counter drop ip6 daddr ff00::/8 counter drop jump log-drop } chain OUTPUT { type filter hook output priority 0; policy drop; oif "lo" accept udp sport ntp udp dport ntp accept meta l4proto ipv6-icmp accept ct state related,established accept ct state new jump new-out jump log-drop } chain new-in { tcp flags & (syn|ack) == syn|ack counter reject with tcp reset tcp flags & (fin|syn|rst|ack) != syn counter jump bad-new ip saddr { noc6.vh.hbone.hu, noc7.vh.hbone.hu, gum.vh.hbone.hu, jujube.noc.einfra.hu } tcp dport { ssh, munin, nrpe } accept ip6 saddr { noc6.vh.hbone.hu, noc7.vh.hbone.hu, gum.vh.hbone.hu, jujube.noc.einfra.hu } tcp dport { ssh, munin, nrpe } accept tcp dport { ssh, https, smtp, submission } accept tcp dport { auth, http } reject ip saddr baas-dir1.niif.hu tcp dport bacula-fd accept icmp type echo-request accept } chain new-out { tcp dport { telnet, ssh, http, https, smtp, ldaps, whois, mysql, git } accept udp dport { domain, snmp, 33434-33600 } accept ip protocol icmp accept ip daddr rspamd.mail.einfra.hu tcp dport 11333 accept ip daddr { baas-sd1.niif.hu, baas-sd2.niif.hu } tcp dport bacula-sd accept ip daddr ingest.logger.niif.hu tcp dport 9200 accept ip6 daddr ingest.logger.niif.hu tcp dport 9200 accept } chain bad-new { limit rate 3/hour burst 5 packets log prefix "New not syn: " counter drop } chain log-drop { limit rate 3/hour burst 5 packets log prefix "Dropped: " flags tcp sequence flags skuid counter drop } }