#!/usr/sbin/nft -f # # Initially based on: https://wiki.nftables.org/wiki-nftables/index.php/Simple_ruleset_for_a_server # flush ruleset # Lists updated daily by update-spamhaus-nftables.sh include "/etc/nftables/spamhaus-ipv4.nft" include "/etc/nftables/spamhaus-ipv6.nft" # Lists updated monthly (manually) include "/etc/nftables/abuseipdb-ipv4.nft" include "/etc/nftables/abuseipdb-ipv6.nft" # Lists updated daily by update-abusech-nftables.sh include "/etc/nftables/abusech-ipv4.nft" # Notes: # - tables hold chains, chains hold rules # - inet is for both ipv4 and ipv6 table inet filter { set spamhaus-ipv4 { type ipv4_addr # if the set contains prefixes we need to use the interval flag flags interval elements = $SPAMHAUS_IPV4 } set spamhaus-ipv6 { type ipv6_addr flags interval elements = $SPAMHAUS_IPV6 } set abusech-ipv4 { type ipv4_addr elements = $ABUSECH_IPV4 } set abuseipdb-ipv4 { type ipv4_addr elements = $ABUSEIPDB_IPV4 } set abuseipdb-ipv6 { type ipv6_addr elements = $ABUSEIPDB_IPV6 } chain input { type filter hook input priority 0; ct state {established, related} accept comment "Allow traffic from established and related packets" ct state invalid counter drop comment "Early drop of invalid connections" ip saddr @spamhaus-ipv4 counter drop comment "Early drop of incoming packets matching spamhaus-ipv4 list" ip6 saddr @spamhaus-ipv6 counter drop comment "Early drop of incoming packets matching spamhaus-ipv6 list" ip saddr @abusech-ipv4 counter drop comment "Early drop of packets matching abusech-ipv4 list" ip saddr @abuseipdb-ipv4 counter drop comment "Early drop of incoming packets matching abuseipdb-ipv4 list" ip6 saddr @abuseipdb-ipv6 counter drop comment "Early drop of incoming packets matching abuseipdb-ipv6 list" iifname lo accept comment "Allow from loopback" ip protocol icmp limit rate 4/second accept comment "Allow ICMP" ip6 nexthdr ipv6-icmp limit rate 4/second accept comment "Allow IPv6 ICMP" ip protocol igmp limit rate 4/second accept comment "Allow IGMP" {# SSH rules #} ip saddr 0.0.0.0/0 ct state new tcp dport 22 counter accept comment "Allow SSH" ip6 saddr ::/0 ct state new tcp dport 22 counter accept comment "Allow SSH" {# Web rules #} {% if 'web' in group_names %} ip saddr 0.0.0.0/0 ct state new tcp dport 80 counter accept comment "Allow HTTP" ip saddr 0.0.0.0/0 ct state new tcp dport 443 counter accept comment "Allow HTTPS" ip6 saddr ::/0 ct state new tcp dport 80 counter accept comment "Allow HTTP" ip6 saddr ::/0 ct state new tcp dport 443 counter accept comment "Allow HTTPS" {% endif %} {# Extra rules #} {% if extra_iptables_rules is defined %} {% for rule in extra_iptables_rules %} ip saddr {{ ghetto_ipsets[rule.acl].src }} ct state new {{ rule.protocol }} dport {{ rule.port }} counter accept {% if ghetto_ipsets[rule.acl].ipv6src is defined %} ip6 saddr {{ ghetto_ipsets[rule.acl].ipv6src }} ct state new {{ rule.protocol }} dport {{ rule.port }} counter accept {% endif %} {% endfor %} {% endif %} # everything else reject with icmpx type port-unreachable } chain forward { type filter hook forward priority 0; } chain output { type filter hook output priority 0; ip daddr @spamhaus-ipv4 counter drop comment "Drop outgoing packets matching spamhaus-ipv4 list" ip6 daddr @spamhaus-ipv6 counter drop comment "Drop outgoing packets matching spamhaus-ipv6 list" ip daddr @abusech-ipv4 counter drop comment "Drop outgoing packets matching abusech-ipv4 list" ip daddr @abuseipdb-ipv4 counter drop comment "Drop outgoing packets matching abuseipdb-ipv4 list" ip6 daddr @abuseipdb-ipv6 counter drop comment "Drop outgoing packets matching abuseipdb-ipv6 list" } }