Podman is no longer supporting iptables so I am trying to learn how to set up nftables in its place. It’s been a struggle to get it to work properly. I can not ping my own server after starting the nftables rules. I am using Alpine Linux v2.24.1 and nftables v1.1.6 (Commodore Bullmoose #7).

nftables has a config file with basic rules which include receiving pings:
/etc/nftables.nft

#!/usr/sbin/nft -f
# vim: set ts=4 sw=4:
# You can find examples in /usr/share/nftables/.

# Clear all prior state
flush ruleset

# Basic IPv4/IPv6 stateful firewall for server/workstation.
table inet filter {
	chain input {
		type filter hook input priority 0; policy drop;

		iifname lo accept \
		comment "Accept any localhost traffic"

		ct state { established, related } accept \
		comment "Accept traffic originated from us"

		ct state invalid drop \
		comment "Drop invalid connections"

		tcp dport 113 reject with icmpx type port-unreachable \
		comment "Reject AUTH to make it fail fast"

		# ICMPv4

		ip protocol icmp icmp type {
			echo-reply,  # type 0
			destination-unreachable,  # type 3
			echo-request,  # type 8
			time-exceeded,  # type 11
			parameter-problem,  # type 12
		} accept \
		comment "Accept ICMP"

		# ICMPv6

		icmpv6 type {
			destination-unreachable,  # type 1
			packet-too-big,  # type 2
			time-exceeded,  # type 3
			parameter-problem,  # type 4
			echo-request,  # type 128
			echo-reply,  # type 129
		} accept \
		comment "Accept basic IPv6 functionality"

		icmpv6 type {
			nd-router-solicit,  # type 133
			nd-router-advert,  # type 134
			nd-neighbor-solicit,  # type 135
			nd-neighbor-advert,  # type 136
		} ip6 hoplimit 255 accept \
		comment "Allow IPv6 SLAAC"

		icmpv6 type {
			mld-listener-query,  # type 130
			mld-listener-report,  # type 131
			mld-listener-reduction,  # type 132
			mld2-listener-report,  # type 143
		} ip6 saddr fe80::/10 accept \
		comment "Allow IPv6 multicast listener discovery on link-local"

		ip6 saddr fe80::/10 udp sport 547 udp dport 546 accept \
		comment "Accept DHCPv6 replies from IPv6 link-local addresses"
	}

	chain forward {
		type filter hook forward priority 0; policy drop;
	}

	chain output {
		type filter hook output priority 0; policy accept;
	}
}

# The state of stateful objects saved on the nftables service stop.
include "/var/lib/nftables/*.nft"

# Rules
include "/etc/nftables.d/*.nft"

I also have a small config file:
/etc/nftables.d/firewall.nft

#!/usr/sbin/nft -f

define WIREGUARD_PORT = 51820
define WIREGUARD_ADDRESS = 10.0.0.0/24
define SSH_PORT = 5025
define SSH_ADDRESSES = { $WIREGUARD_ADDRESS . $SSH_PORT, 192.168.40.204 . $SSH_PORT }
define PUBLIC_PORTS = { 5050 }

table inet filter {
	chain input {
		udp dport $WIREGUARD_PORT accept \
		comment "Accept WireGuard connections"

		ip saddr . tcp dport $SSH_ADDRESSES accept \
		comment "Accept SSH connections from known devices or WireGuard"

		tcp dport $PUBLIC_PORTS accept \
		comment "Accept public connections"
	}
}

After loading the new rules, I get the following output while listing the ruleset:

21:23 server-pi:~ $ doas nft list ruleset
table inet filter {
	chain input {
		type filter hook input priority filter; policy drop;
		iifname "lo" accept comment "Accept any localhost traffic"
		ct state { established, related } accept comment "Accept traffic originated from us"
		ct state invalid drop comment "Drop invalid connections"
		tcp dport 113 reject comment "Reject AUTH to make it fail fast"
		ip protocol icmp icmp type { echo-reply, destination-unreachable, echo-request, time-exceeded, parameter-problem } accept comment "Accept ICMP"
		icmpv6 type { destination-unreachable, packet-too-big, time-exceeded, parameter-problem, echo-request, echo-reply } accept comment "Accept basic IPv6 functionality"
		icmpv6 type { nd-router-solicit, nd-router-advert, nd-neighbor-solicit, nd-neighbor-advert } ip6 hoplimit 255 accept comment "Allow IPv6 SLAAC"
		icmpv6 type { mld-listener-query, mld-listener-report, mld-listener-done, mld2-listener-report } ip6 saddr fe80::/10 accept comment "Allow IPv6 multicast listener discovery on link-local"
		ip6 saddr fe80::/10 udp sport 547 udp dport 546 accept comment "Accept DHCPv6 replies from IPv6 link-local addresses"
		udp dport 51820 accept comment "Accept WireGuard connections"
		ip saddr . tcp dport { 10.0.0.0/24 . 5025, 192.168.40.204 . 5025 } accept comment "Accept SSH connections from known devices or WireGuard"
		tcp dport 5050 accept comment "Accept public connections"
	}

	chain forward {
		type filter hook forward priority filter; policy drop;
	}

	chain output {
		type filter hook output priority filter; policy accept;
	}
}
21:23 server-pi:~ $ doas netstat -tunlp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
tcp        0      0 127.0.0.1:8000          0.0.0.0:*               LISTEN      3515/rootlessport   
tcp        0      0 127.0.0.1:8080          0.0.0.0:*               LISTEN      3584/rootlessport   
tcp        0      0 0.0.0.0:5025            0.0.0.0:*               LISTEN      3743/sshd: /usr/sbi 
tcp6       0      0 :::5025                 :::*                    LISTEN      3743/sshd: /usr/sbi 
tcp6       0      0 :::5050                 :::*                    LISTEN      3515/rootlessport   
udp        0      0 0.0.0.0:51820           0.0.0.0:*                           -                   
udp6       0      0 :::51820                :::*                                -                   
21:23 server-pi:~ $ 

I can connect perfectly fine with SSH, WireGuard and my reverse proxy on port 5050 but if I ping the server I don’t get any response at all. Pings worked as normal when I was using iptables so I am not sure what I am doing wrong with nftables. I’ve tried to keep the rules as simple as possible to figure out what is happening but I have not been able to make any progress. Any help would be appreciated.

  • confusedpuppy@lemmy.dbzer0.comOP
    link
    fedilink
    English
    arrow-up
    1
    ·
    11 hours ago

    I tried your suggested rules and still nothing

    I went a step further and simply enabled all incoming connections with:

    table inet filter {
    	chain input {
    		type filter hook input priority 0; policy allow;
    	}
    }
    

    Again I can connect with SSH and WireGuard but I still can’t ping my server. If I restore to my last backup with iptables, I can get a response from ping again.

    I also tried directly translating the rules from iptables with:

    iptables-save > /tmp/iptables.dump
    iptables-restore-translate -f /tmp/iptables.dump > nftables.dump
    

    and adding the rules:

    #!/usr/sbin/nft -f
    
    define WIREGUARD_PORT = 51820
    define WIREGUARD_ADDRESS = 10.0.0.0/24
    define SSH_PORT = 5025
    define SSH_ADDRESSES = { $WIREGUARD_ADDRESS . $SSH_PORT, 192.168.40.204 . $SSH_PORT }
    define PUBLIC_PORTS = { 5050 }
    
    table inet filter {
            chain input {
                    udp dport $WIREGUARD_PORT accept \
                    comment "Accept WireGuard connections"
    
                    ip saddr . tcp dport $SSH_ADDRESSES accept \
                    comment "Accept SSH connections from known devices or WireGuard"
    
                    tcp dport $PUBLIC_PORTS accept \
                    comment "Accept public connections"
    
                    icmp type echo-request limit rate 5/second burst 10 packets counter accept
                    icmp type echo-request limit rate 30/minute burst 120 packets counter accept
                    icmp type echo-request limit rate 1/minute burst 2 packets counter log prefix " PING-PONG-FLOOD "
                    icmp type echo-request counter drop
    
                    icmp type destination-unreachable counter accept
                    icmp type time-exceeded counter accept
                    icmp type parameter-problem counter accept
                    icmp type echo-request counter accept
            }
            chain forward {
                    icmp type destination-unreachable counter accept
                    icmp type time-exceeded counter accept
                    icmp type parameter-problem counter accept
                    icmp type echo-request counter accept
            }
    }
    

    and still no ping from my server…

    I will agree, the documentation for nftables is just not as accessible or consistent as iptables. It’s a bit frustrating.

    • pHr34kY@lemmy.world
      link
      fedilink
      English
      arrow-up
      2
      ·
      11 hours ago

      Run nft list ruleset and make sure that the final (compiled) result matches your config. Maybe it’s misinterpreting or discarding something?