You are not logged in.

#1 2022-09-04 06:11:11

jkbach
Member
Registered: 2022-09-04
Posts: 2

Trouble validating that nftables is working as expected

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?

Detailed description

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
Expected behavior

No ports are open.

Actual behavior

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
Attempted troubleshooting steps

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

#2 2022-09-04 07:09:53

-thc
Member
Registered: 2017-03-15
Posts: 499

Re: Trouble validating that nftables is working as expected

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

#3 2022-09-05 08:43:02

jkbach
Member
Registered: 2022-09-04
Posts: 2

Re: Trouble validating that nftables is working as expected

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

#4 2022-09-05 13:17:11

-thc
Member
Registered: 2017-03-15
Posts: 499

Re: Trouble validating that nftables is working as expected

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

Board footer

Powered by FluxBB