You are not logged in.
Hi all,
tl;dr: nftables looks like it's correctly configured to drop (almost) all incoming traffic. I thought I could validate it by running an "nmap" scan from the machine itself against the router-assigned IP address and confirming that I don't see any open ports. To my suprise, I'm finding that ports are still open! My intuition is that a request against the router-assigned IP address, even from the machine itself, would trip the firewall rules. However, I suppose it's also possible that the networking stack knows that it's making a request to itself, and skips the firewall. If this is the case, how can I validate that the rules are working?
I want to configure a firewall for my laptop and validate that the rules are in effect. I installed `nftables`, enabled and started `nftables.service`, and configured my rules in `/etc/nftables.conf/`. Since this is my laptop, I don't expect any connections to be initiated from the outside, except for maybe mDNS, so the rules are very restrictive. Basically drop everything except for pings and mDNS:
#!/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/.
# inet includes both ip and ip6
table inet filter
delete table inet filter
table inet filter {
chain input {
type filter hook input priority filter
policy drop
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"
# These two lines supposedly prevent spoofed loopback requests that don't actually come from localhost.
iif != lo ip daddr 127.0.0.1/8 counter drop comment "drop connections to loopback not coming from loopback"
iif != lo ip6 daddr ::1/128 counter drop comment "drop connections to loopback not coming from loopback"
ip protocol icmp accept comment "allow icmp"
meta l4proto ipv6-icmp accept comment "allow icmp v6"
# Probably don't ever need to ssh into this machine.
# tcp dport ssh accept comment "allow sshd"
pkttype host limit rate 5/second counter reject with icmpx type admin-prohibited
counter
udp dport mdns accept
}
chain forward {
type filter hook forward priority filter
policy drop
}
}
I restart my computer, confirm that the rules are in place:
# sudo nft list ruleset
table inet filter {
chain input {
type filter hook input priority filter; policy drop;
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"
iif != "lo" ip daddr 127.0.0.0/8 counter packets 0 bytes 0 drop comment "drop connections to loopback not coming from loopback"
iif != "lo" ip6 daddr ::1 counter packets 0 bytes 0 drop comment "drop connections to loopback not coming from loopback"
ip protocol icmp accept comment "allow icmp"
meta l4proto ipv6-icmp accept comment "allow icmp v6"
meta pkttype host limit rate 5/second counter packets 506 bytes 28482 reject with icmpx admin-prohibited
counter packets 7287 bytes 1478235
udp dport 5353 accept
}
chain forward {
type filter hook forward priority filter; policy drop;
}
}
Looks good so far!
Kick off a little python http server on 8080:
python3 -m http.server 8080
And then run "nmap" on the IP address assigned by DHCP:
nmap -A -v 172.23.0.24
No ports are open.
Port 8080 shows up as open!
# ... from the output of the above nmap command:
8080/tcp open http SimpleHTTPServer 0.6 (Python 3.10.6)
|_http-title: Site doesn't have a title (text/html).
| http-methods:
|_ Supported Methods: GET HEAD
|_http-server-header: SimpleHTTP/0.6 Python/3.10.6
1. Restarted the computer.
2. Checked if I had "iptables" installed as well. I did, so I ran
sudo pacman -S iptables-nft
to uninstall it and prevent it from conflicting with "nftables", as suggested in https://wiki.archlinux.org/title/Nftables#Installation.
Anyone have any ideas to either resolve this or, if it's actually my validation method that's flawed, validate that the firewall rules are what I expect them to be?
Last edited by jkbach (2022-09-05 09:20:25)
Offline
The nmap scan packets traverse via loopback device (explicitly allowed) - you can verify this by adding a counter to the "loopback allow rule" and monitor the packet count before and after the nmap scan.
While this rule
iif != "lo" ip daddr 127.0.0.0/8 counter packets 0 bytes 0 drop comment "drop connections to loopback not coming from loopback"
drops packets coming from 127.0.0.0/8 via non-loopback devices it doesn't drop packets from 172.23.0.24 via loopback.
You need to perform the nmap scan from another machine in your network.
Offline
Thanks a ton -thc, I added the counter to the "accept loopback" rule and was able to verify that things are exactly as you said: local nmap scans on my router-assigned IP are still going through the loopback interface.
For anyone else who wants to do a local nmap scan on a non-loopback interface: after I RTFM'd, I discovered that nmap does allow specifying a specific interface using the "-e" flag, I was able to use this to test against my wireless interface and simulate an outside request to validate that the firewall rule is working as expected:
nmap -A -v -e wlan0 localhost
The above command scans TCP ports. Unfortunately, when I try to scan UDP ports (the "-sU" flag) and also specify the interface with "-e", nmap does an ARP Ping Scan on a single port, instead of scanning all the UDP ports. Ideally I could use the above technique for UDP as well, anyone have any ideas?
Last edited by jkbach (2022-09-05 08:45:13)
Offline
nmap uses an ARP ping scan to determine if a host is "up" - this fails and no scan is performed.
If you order nmap to use IP packets and skip the "up" detection it works:
sudo nmap -sU -Pn --send-ip local_ip_address -v -e eno1 local_ip_address
Last edited by -thc (2022-09-05 13:17:41)
Offline