#!/usr/bin/nft -f # vim:set ts=2 sw=2 et: # IPv4/IPv6 Simple & Safe firewall ruleset. # More examples in /usr/share/nftables/ and /usr/share/doc/nftables/examples/. # add a variable for each interface: define ext_if = eth0 define vict_if = eth1 define dmz_if = eth2 define all_if = { $ext_if, $vict_if, $dmz_if } # ct state invalid drop comment "early drop of invalid connections" # ct state {established, related} accept comment "allow tracked connections" # iifname lo accept comment "allow from loopback" # ip protocol icmp accept comment "allow icmp" # meta l4proto ipv6-icmp accept comment "allow icmp v6" # tcp dport ssh accept comment "allow sshd" # pkttype host limit rate 5/second counter reject with icmpx type admin-prohibited # counter # Block all ipv6, don't allow any ipv6 to either enter or leave the gateway. # It is useless because /proc/sys/net/ipv6/conf/disable_ipv6 = 1 # but we're never too sure so it's better to block here. table ip6 block_all_ipv6 delete table ip6 block_all_ipv6 table ip6 block_all_ipv6 { chain block_input { type filter hook input priority filter policy drop } chain block_output { type filter hook output priority filter policy drop } chain block_forward { type filter hook forward priority filter policy drop } } # filter ipv4 table. table ip global delete table ip global table ip global { set denylist { type ipv4_addr flags dynamic, timeout timeout 2m } chain input { type filter hook input priority filter policy drop # if somebody sent to many new connections to the gateway, it an attack. ip protocol tcp ct state new, untracked limit rate over 10/minute add @denylist { ip saddr } ip saddr @denylist drop ct state established accept iifname $vict_if icmp type echo-request limit rate 5/second accept iifname $vict_if tcp dport 22 accept iifname lo accept } chain output { type filter hook output priority filter policy drop udp dport 53 limit rate 20/second accept tcp dport 80 limit rate 20/second accept tcp dport 443 limit rate 20/second accept icmp type echo-request limit rate 5/second accept oifname $vict_if ct state established accept # accept to say on the victim interface that the gateway is up. # oifname $vict_if icmp type echo-reply limit rate 5/second accept oifname lo accept } chain forward { type filter hook forward priority filter policy drop # Block temporarly ip addresses that attemps more than 10 tcp connection per minutes from external network iifname $ext_if ip protocol tcp ct state new, untracked limit rate over 10/minute add @denylist { ip saddr } ip saddr @denylist drop # general authorisations icmp type echo-reply accept # dmz interface specific oifname $dmz_if icmp type echo-request limit rate 5/second accept oifname $dmz_if tcp dport 80 accept iifname $dmz_if ct state established tcp sport 80 accept # external interface specific oifname $ext_if icmp type echo-request accept oifname $ext_if udp dport 53 accept iifname $ext_if ct state established udp sport 53 accept oifname $ext_if tcp dport 80 accept iifname $ext_if ct state established tcp sport 80 accept oifname $ext_if tcp dport 443 accept iifname $ext_if ct state established tcp sport 443 accept # victim interface specific iifname $vict_if tcp dport 22 accept oifname $vict_if ct state established tcp sport 22 accept # block for two minutes everything else that is from the public interface. iifname { $ext_if, $dmz_if } add @denylist { ip saddr } } } #table inet my_nat #delete table inet my_nat #table inet my_nat { # chain postrouting { # type nat hook postrouting priority srcnat; # oifname "eth0" masquerade; # } #}