#!/sbin/nft -f # References: # https://wiki.nftables.org/wiki-nftables/index.php/Main_Page # https://wiki.gentoo.org/wiki/Nftables/Examples # https://wiki.archlinux.org/title/Nftables # https://github.com/krabelize/nftables-firewall-config/blob/master/nftables.conf # https://github.com/atweiden/archvault/blob/master/resources/etc/nftables.conf # Libvirt: # https://libvirt.org/firewall.html flush ruleset # TCP ports to accept (both IPv4 and IPv6) #define ACCEPT_TCP_PORTS = {} # UDP ports to accept (both IPv4 and IPv6) #define ACCEPT_UDP_PORTS = {} table inet filter { chain libvirt_input { iifname "virbr0" udp dport 53 counter accept iifname "virbr0" tcp dport 53 counter accept iifname "virbr0" udp dport 67 counter accept iifname "virbr0" tcp dport 67 counter accept } chain libvirt_forward { oifname "virbr0" ip daddr 192.168.122.0/24 ct state { established, related } counter accept iifname "virbr0" ip saddr 192.168.122.0/24 counter accept iifname "virbr0" oifname "virbr0" counter accept oifname "virbr0" counter reject with icmpx type port-unreachable iifname "virbr0" counter reject with icmpx type port-unreachable } chain libvirt_postrouting { ip saddr 192.168.122.0/24 ip daddr != 192.168.122.0/24 counter masquerade } # Default to drop all inbound traffic, unless they meet our criteria chain input { type filter hook input priority 0; policy drop; ct state invalid counter drop ct state { established, related } counter accept ct status dnat accept iif lo accept iif != lo ip daddr 127.0.0.1/8 counter drop iif != lo ip6 daddr ::1/128 counter drop counter jump libvirt_input # Reject AUTH to make it fail fast tcp dport 113 reject with icmpx type port-unreachable # Accept user-defined ports #tcp dport $ACCEPT_TCP_PORTS counter accept #udp dport $ACCEPT_UDP_PORTS counter accept # Rate limit on SSH port #tcp dport ssh ct state new limit rate 6/minute accept # Mitigate ping floods ip protocol icmp icmp type { echo-reply, echo-request } limit rate over 1/second burst 4 packets drop ip6 nexthdr icmpv6 icmpv6 type { echo-reply, echo-request } limit rate over 1/second burst 4 packets drop # Accept ICMPv4 ip protocol icmp icmp type { echo-reply, echo-request, destination-unreachable, time-exceeded, parameter-problem, router-advertisement, router-solicitation } counter accept # Accept basic ICMPv6 functionality ip6 nexthdr icmpv6 icmpv6 type { echo-reply, echo-request, destination-unreachable, packet-too-big, time-exceeded, parameter-problem } counter accept # Allow ICMPv6 SLAAC ip6 nexthdr icmpv6 icmpv6 type { nd-router-solicit, nd-router-advert, nd-neighbor-solicit, nd-neighbor-advert, } ip6 hoplimit 255 counter accept # Allow ICMPv6 multicast listener discovery on link-local ip6 nexthdr icmpv6 icmpv6 type { mld-listener-query, mld-listener-report, mld-listener-reduction, mld2-listener-report, } ip6 saddr fe80::/10 counter accept counter comment "Count dropped packets" #log prefix "[nftables] Inbound Denied: " flags all counter drop } # Route your own packets! I'm not your router. # Can be enabled while using VPN (for tunneling) chain forward { type filter hook forward priority 0; policy drop; ct state { related, established } accept ct status dnat accept oif lo accept oif != lo ip daddr 127.0.0.1/8 counter drop oif != lo ip6 daddr ::1/128 counter drop counter jump libvirt_forward counter comment "Count dropped packets" #log prefix "[nftables] Forward Denied: " flags all counter drop } # Accept all outbound traffic chain output { type filter hook output priority 0; policy accept; counter comment "Count accepted packets" #log prefix "[nftables] Outbound Accepted: " flags all counter accept } chain postrouting { type nat hook postrouting priority 100; policy accept; counter jump libvirt_postrouting } }