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.