Scheduled Maintenance: We are aware of an issue with Google, AOL, and Yahoo services as email providers which are blocking new registrations. We are trying to fix the issue and we have several internal and external support tickets in process to resolve the issue. Please see: viewtopic.php?t=158230

 

 

 

Howto: Set up a basic nftables firewall (Buster)

Share your HowTo, Documentation, Tips and Tricks. Not for support questions!.
Post Reply
Message
Author
User avatar
Hallvor
Global Moderator
Global Moderator
Posts: 2020
Joined: 2009-04-16 18:35
Location: Kristiansand, Norway
Has thanked: 138 times
Been thanked: 204 times

Howto: Set up a basic nftables firewall (Buster)

#1 Post by Hallvor »

Who is this for?
This is a basic firewall for desktop computers and aimed at beginners.

What will it result in?
* An extra layer of security.
* Your services will be unreachable. You choose when you want to expose them to the Internet.
* All outgoing traffic is open. (This is OK for most users, but if you want top notch firewall security, you should restrict outgoing traffic as well.)

Let's do this

Remove all traces of Iptables and flush all iptables rules:

Code: Select all

# iptables -F && apt remove iptables iptables-persistent
Nftables should be installed by default, but just in case...

Code: Select all

# apt install nftables
We can see that there are no rules by pressing

Code: Select all

# nft list ruleset
We will now copy the nftables configuration file to the correct location:

Code: Select all

# cp /usr/share/doc/nftables/examples/workstation.nft /etc/nftables.conf
Now we will edit the file:

Code: Select all

# nano /etc/nftables.conf
It will look like this:

Code: Select all

#!/usr/sbin/nft -f

flush ruleset

table inet filter {
        chain input {
                type filter hook input priority 0;

                # accept any localhost traffic
                iif lo accept

                # accept traffic originated from us
                ct state established,related accept

                # activate the following line to accept common local services
                #tcp dport { 22, 80, 443 } ct state new accept

                # accept neighbour discovery otherwise IPv6 connectivity breaks.
                ip6 nexthdr icmpv6 icmpv6 type { nd-neighbor-solicit,  nd-router-advert, nd-neighbor-advert } accept

                # count and drop any other traffic
                counter drop
        }
}
The default configuration file will allow all traffic to the loopback interface, allow all traffic originating from your desktop and drop everything else.


Opening ports

You may need to open ports in your firewall to make everything work. Fortunately, there are several tools to make this easy.

Code: Select all

# netstat -tulpn
-t means display TCP ports, -u means display UDP ports, -l means show listening ports, -p means show PID and name of the listener's process (requires root or sudo) and -n means show numerical addresses instead of resolving hosts.

Here is example output from my computer.

Code: Select all

root@debian-thinkpad:~# netstat -tulpn
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
tcp6       0      0 :::1740                 :::*                    LISTEN      1620/kdeconnectd    
tcp6       0      0 :::1741                 :::*                    LISTEN      1620/kdeconnectd    
tcp6       0      0 :::1716                 :::*                    LISTEN      1620/kdeconnectd    
udp        0      0 0.0.0.0:41203           0.0.0.0:*                           854/avahi-daemon: r 
udp        0      0 0.0.0.0:5353            0.0.0.0:*                           854/avahi-daemon: r 
udp6       0      0 :::40776                :::*                                854/avahi-daemon: r 
udp6       0      0 :::5353                 :::*                                854/avahi-daemon: r 
udp6       0      0 :::1716                 :::*                                1620/kdeconnectd 


I see here that Kdeconnect is listening for connections on ports 1740, 1741 and 1716. That will not work properly if it can't be reached, so I need to open ports in the firewall.

Avahi-daemon is framework to help discover services available on the local network, for instance networked scanners, without needing any manual configuration.

A different variation is here (as sudo or root):

Code: Select all

# lsof -nP -iTCP -sTCP:LISTEN
-n means do not convert port numbers to port names, -p means di not resolve host names, and -iTCP -sTCP:LISTEN means only show network files with TCP state LISTEN.

Code: Select all

root@debian-thinkpad:~# lsof -nP -iTCP -sTCP:LISTEN
COMMAND    PID    USER   FD   TYPE  DEVICE SIZE/OFF NODE NAME
kdeconnec 1620 hallvor   13u  IPv6 2895898      0t0  TCP *:1716 (LISTEN)
kdeconnec 1620 hallvor   26u  IPv6 2451199      0t0  TCP *:1740 (LISTEN)
kdeconnec 1620 hallvor   28u  IPv6 2453134      0t0  TCP *:1741 (LISTEN)
As we can see, we get the same TCP-results for kdeconnect as above.

Many tutorials show that one should open ports 22, 80 and 443. However, it is not necessary to open port 22 unless you want to SSH into it, and 80 and 443 do not need to be opened to browse the web. It will work just fine with those ports closed.

As we can see, Kdeconnect uses different ports, so we can search online to find out what port range it uses. It says that Kdeconnect will use 1714-1764 for UDP and TCP.

https://userbase.kde.org/KDEConnect/en

If you for instance want to open the firewall for kdeconnect, we can then uncomment and edit this line

Code: Select all

 #tcp dport { 22, 80, 443 } ct state new accept
to this:

Code: Select all

tcp dport 1714-1764 ct state new accept
Edit the file if needed, and save it by pressing Ctrl + x and then y to exit.

Enabling and starting the firewall


Enable start on boot

Code: Select all

# systemctl enable nftables.service
Start nftables now

Code: Select all

# systemctl start nftables.service
Check that everything is OK

Code: Select all

# nft list ruleset
It should look like this if you haven't opened any ports:

Code: Select all

table inet filter {
        chain input {
                type filter hook input priority 0; policy accept;
                iif "lo" accept
                ct state established,related accept
                ip6 nexthdr ipv6-icmp icmpv6 type { nd-router-advert, nd-neighbor-solicit, nd-neighbor-advert } accept
                counter packets 410 bytes 31247 drop
        }
}
Last edited by Hallvor on 2022-10-02 10:42, edited 3 times in total.
[HowTo] Install and configure Debian bookworm
Debian 12 | KDE Plasma | ThinkPad T440s | 4 × Intel® Core™ i7-4600U CPU @ 2.10GHz | 12 GiB RAM | Mesa Intel® HD Graphics 4400 | 1 TB SSD

User avatar
None1975
df -h | participant
df -h | participant
Posts: 1387
Joined: 2015-11-29 18:23
Location: Russia, Kaliningrad
Has thanked: 45 times
Been thanked: 64 times

Re: Howto: Set up a basic nftables firewall (Buster)

#2 Post by None1975 »

Thank you for sharing it. Works as they should.
OS: Debian 12.4 Bookworm / DE: Enlightenment
Debian Wiki | DontBreakDebian, My config files on github

duhok1
Posts: 2
Joined: 2020-03-12 00:15

Re: Howto: Set up a basic nftables firewall (Buster)

#3 Post by duhok1 »

Hallvor wrote:
You can also try pinging your computer, and there should be a 100% packet loss. Replace with your internal address, for instance:

Code: Select all

ping -c3 192.168.1.x
PING 192.168.1.x (192.168.1.x) 56(84) bytes of data.

--- 192.168.1.x ping statistics ---
3 packets transmitted, 0 received, 100% packet loss, time 50ms
It works.
I am getting 100% received pinging my local IP (192.168.0.xx). Appreciate your input.

User avatar
Hallvor
Global Moderator
Global Moderator
Posts: 2020
Joined: 2009-04-16 18:35
Location: Kristiansand, Norway
Has thanked: 138 times
Been thanked: 204 times

Re: Howto: Set up a basic nftables firewall (Buster)

#4 Post by Hallvor »

What is the output of the following?

Code: Select all

# nft list ruleset

Code: Select all

# systemctl status nftables.service
[HowTo] Install and configure Debian bookworm
Debian 12 | KDE Plasma | ThinkPad T440s | 4 × Intel® Core™ i7-4600U CPU @ 2.10GHz | 12 GiB RAM | Mesa Intel® HD Graphics 4400 | 1 TB SSD

duhok1
Posts: 2
Joined: 2020-03-12 00:15

Re: Howto: Set up a basic nftables firewall (Buster)

#5 Post by duhok1 »

Hallvor wrote:What is the output of the following?

Code: Select all

# nft list ruleset

Code: Select all

# systemctl status nftables.service

Code: Select all

table inet filter {
	chain input {
		type filter hook input priority filter; policy accept;
		iif "lo" accept
		ct state established,related accept
		ip6 nexthdr ipv6-icmp icmpv6 type { nd-router-advert, nd-neighbor-solicit, nd-neighbor-advert } accept
		counter packets 2 bytes 112 drop
	}
}

Code: Select all

● nftables.service - Netfilter Tables
     Loaded: loaded (/usr/lib/systemd/system/nftables.service; enabled; vendor preset: disabled)
     Active: active (exited) since Thu 2020-03-12 09:38:25 EDT; 6min ago
       Docs: man:nft(8)
    Process: 807 ExecStart=/usr/bin/nft -f /etc/nftables.conf (code=exited, status=0/SUCCESS)
   Main PID: 807 (code=exited, status=0/SUCCESS)

Mar 12 09:38:25 cheebo systemd[1]: Starting Netfilter Tables...
Mar 12 09:38:25 cheebo systemd[1]: Finished Netfilter Tables.

User avatar
Hallvor
Global Moderator
Global Moderator
Posts: 2020
Joined: 2009-04-16 18:35
Location: Kristiansand, Norway
Has thanked: 138 times
Been thanked: 204 times

Re: Howto: Set up a basic nftables firewall (Buster)

#6 Post by Hallvor »

It is both running and dropping traffic. Unless you have altered the default settings, it should work.
[HowTo] Install and configure Debian bookworm
Debian 12 | KDE Plasma | ThinkPad T440s | 4 × Intel® Core™ i7-4600U CPU @ 2.10GHz | 12 GiB RAM | Mesa Intel® HD Graphics 4400 | 1 TB SSD

gijsg
Posts: 1
Joined: 2020-08-22 09:13

Re: Howto: Set up a basic nftables firewall (Buster)

#7 Post by gijsg »

My local IP adress is 192.168.0.161, the ping test failes for this IP adress but not for 192.168.1.161. Any idea why?

My nftables.conf is an exact copy of the tutorial.

Here are the commands I've used:

https://i.imgur.com/OVDWDR7.png

~~~~

Mod Note: image changed to URL, please post actual text (using code tags) rather than pictures of text — HoaS

User avatar
Head_on_a_Stick
Posts: 14114
Joined: 2014-06-01 17:46
Location: London, England
Has thanked: 81 times
Been thanked: 132 times

Re: Howto: Set up a basic nftables firewall (Buster)

#8 Post by Head_on_a_Stick »

gijsg wrote:My local IP adress is 192.168.0.161, the ping test failes for this IP adress but not for 192.168.1.161. Any idea why?
Your (redacted) image shows the exact opposite.

The workstation ruleset does not block ICMP echo requests (because they shouldn't be blocked[0]) so your result is as expected.

And please note that Raspbian is not supported here.
deadbang

User avatar
Hallvor
Global Moderator
Global Moderator
Posts: 2020
Joined: 2009-04-16 18:35
Location: Kristiansand, Norway
Has thanked: 138 times
Been thanked: 204 times

Re: Howto: Set up a basic nftables firewall (Buster)

#9 Post by Hallvor »

Saving my configurations for future reference. elements = {1714-1764} is KDE Connect, so edit at will and list further ports by adding new ports or port ranges with commas, for instance

Code: Select all

elements = {1714-1764,80,22,443}

Code: Select all

#!/sbin/nft -f
flush ruleset 

table inet filter {
    chain base_checks {
        # Drop invalid connections and allow established/related connections
                ct state invalid drop
                ct state {established, related} accept
    }

        chain input {
                type filter hook input priority 0; policy drop;

        jump base_checks

        # Allow from loopback
                iifname lo accept
        iifname != lo ip daddr 127.0.0.1/8 drop

        # New UDP traffic will jump to the UDP chain
                ip protocol udp ct state new jump UDP
        # New TCP traffic will jump to the TCP chain
                tcp flags & (fin | syn | rst | ack) == syn ct state new jump TCP

        # Everything else
                ip protocol udp reject
                ip protocol tcp reject with tcp reset
        reject with icmpx type port-unreachable
        }

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

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

    # ---------------------------------------------------------------------------------

    # TCP chain
    set TCP_accepted {
        type inet_service; flags interval; 
        elements = {1714-1764}
    }
        chain TCP {
        tcp dport @TCP_accepted accept
        } 

    # UDP chain
    set UDP_accepted {
        type inet_service; flags interval;
         elements = {1714-1764}
    }
        chain UDP {
        udp dport @UDP_accepted accept
        }
}
[HowTo] Install and configure Debian bookworm
Debian 12 | KDE Plasma | ThinkPad T440s | 4 × Intel® Core™ i7-4600U CPU @ 2.10GHz | 12 GiB RAM | Mesa Intel® HD Graphics 4400 | 1 TB SSD

sys$hobbit
Posts: 1
Joined: 2021-11-30 17:59

Re: Howto: Set up a basic nftables firewall (Buster)

#10 Post by sys$hobbit »

This thread is helpful, thanks. I've actually managed to setup nftables and get a simple rule set working. There is, however, one issue surrounding setting up NAT that has stumped me. I believe I'm trying to configure what is called source NAT with masquerading, however, the configuration examples I have been able to find do not seem to do what I want. If anybody can read the cisco router config below, that is exactly the kind of NAT configuration I want to setup in nftables. If anybody can help, I'd be obliged.

config term
interface gi1/0/1
descr Connects to Internet via GigE/DOCSIS bridge
ip addr 172.16.1.1/24
ip nat outside
exit
interface gi1/0/2
descr Connects to LabNet
ip addr 192.168.8.1/24
ip nat inside
exit
interface gi1/0/3
descr Connects to SecurityNet, IoT
ip addr 192.168.9.1/24
ip nat inside
exit
interface gi1/0/4
descr Connects to LabNet2
ip addr 192.168.10.1/24
ip nat inside
exit
interface gi1/0/4
descr Connects to HomeNet
192.168.11.1/24
ip nat inside
exit
access-list 100 remark ==[Control NAT Service]==
access-list 100 permit ip 192.168.8.0 0.0.15.255 any
ip nat inside source list 100 interface gi1/0/1 overload

User avatar
Hallvor
Global Moderator
Global Moderator
Posts: 2020
Joined: 2009-04-16 18:35
Location: Kristiansand, Norway
Has thanked: 138 times
Been thanked: 204 times

Re: Howto: Set up a basic nftables firewall (Buster)

#11 Post by Hallvor »

Something like this? https://www.adamintech.com/configure-na ... -iptables/

The guide is for Iptables, but it can be adapted for nftables with a few adjustments.
[HowTo] Install and configure Debian bookworm
Debian 12 | KDE Plasma | ThinkPad T440s | 4 × Intel® Core™ i7-4600U CPU @ 2.10GHz | 12 GiB RAM | Mesa Intel® HD Graphics 4400 | 1 TB SSD

User avatar
Hallvor
Global Moderator
Global Moderator
Posts: 2020
Joined: 2009-04-16 18:35
Location: Kristiansand, Norway
Has thanked: 138 times
Been thanked: 204 times

Re: Howto: Set up a basic nftables firewall (Buster)

#12 Post by Hallvor »

A simple ruleset for a workstation with open port ranges for KDE Connect:

Code: Select all

#!/sbin/nft -f
flush ruleset

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

        iifname lo accept
        ct state {established, related} accept
        iifname != lo ip daddr 127.0.0.1/8 drop
        tcp dport {1714-1764} accept
        udp dport {1714-1764} accept
        ip protocol udp reject
        ip protocol tcp reject with tcp reset
        reject with icmpx type port-unreachable
    }

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

    chain output {
        type filter hook output priority 0; policy accept;
    }
}
[HowTo] Install and configure Debian bookworm
Debian 12 | KDE Plasma | ThinkPad T440s | 4 × Intel® Core™ i7-4600U CPU @ 2.10GHz | 12 GiB RAM | Mesa Intel® HD Graphics 4400 | 1 TB SSD

User avatar
fabien
Forum Helper
Forum Helper
Posts: 604
Joined: 2019-12-03 12:51
Location: Anarres (Toulouse, France actually)
Has thanked: 60 times
Been thanked: 141 times

Re: Howto: Set up a basic nftables firewall (Buster)

#13 Post by fabien »

Hallvor wrote: 2023-01-13 21:28A simple ruleset for a workstation with open port ranges for KDE Connect
Do you have IPv6 connectivity? Is your local IPv4 network behind NAT? KDE Connect is not used on the Internet I guess? In this case you could take advantage of separating rules for IPv6 (direct Internet connection) and IPv4 (local network behind the router). This allows you to not worry about the complexity of setting up rules for a local network and in the end it may seem more secure because you don't have to open ports unnecessarily.

Important: many people blindly copy firewall rules from sites like this, and none of us are security experts (a Netfilter guru I mean). So if you spot an error, please comment, if you have any doubts, please PM.

This is my simple nftables firewall for a machine on a LAN behind NAT. Only SSH is allowed to accept new connections from the Internet.

Code: Select all

#!/usr/sbin/nft -f

### man 8 nft
### https://wiki.debian.org/nftables
### https://wiki.archlinux.org/index.php/Nftables
### https://wiki.gentoo.org/wiki/Nftables/Examples
### https://xdeb.org/post/2019/09/26/setting-up-a-server-firewall-with-nftables-that-support-wireguard-vpn/
### https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/8/html/configuring_and_managing_networking/getting-started-with-nftables_configuring-and-managing-networking

### networking settings /etc/sysctl.d/98-networking.conf
### copy and adapt /etc/sysctl.conf. e.g.:
#net.ipv4.conf.default.rp_filter=1
#net.ipv4.conf.all.rp_filter=1
#net.ipv4.tcp_syncookies=1
#net.ipv4.conf.default.accept_redirects = 0
#net.ipv4.conf.all.accept_redirects = 0
#net.ipv6.conf.default.accept_redirects = 0
#net.ipv6.conf.all.accept_redirects = 0
#net.ipv4.conf.default.send_redirects = 0
#net.ipv4.conf.all.send_redirects = 0
#net.ipv4.conf.default.accept_source_route = 0
#net.ipv4.conf.all.accept_source_route = 0
#net.ipv6.conf.default.accept_source_route = 0
#net.ipv6.conf.all.accept_source_route = 0
### sysctl --system #to apply new rules added to this file

### nft -a list table ip6 filter
### nft list ruleset
### nft -a list ruleset
###########################################################################################################

flush ruleset

define sshport = 22

# ----- IPv4 -----
table ip filter {
   chain INPUT {
      ### accept all ipv4 traffic which should be on the local network behind the gateway ###
      type filter hook input priority 0; policy drop;
      ### early drop of invalid packets
      ct state invalid counter drop
      ### drop connections to loopback not coming from loopback
      iif != lo ip daddr 127.0.0.1/8 counter drop
      ### accept loopback - Mandatory !
      iif lo accept
      ### Force SYN checks
      tcp flags & (fin|syn|rst|ack) != syn ct state new counter drop
      ### Drop XMAS packets
      tcp flags & (fin|syn|rst|psh|ack|urg) == fin|syn|rst|psh|ack|urg counter drop
      ### Drop NULL packets
      tcp flags & (fin|syn|rst|psh|ack|urg) == 0x0 counter drop
      ### Avoid brute force on SSH
      tcp dport $sshport ct state new limit rate over 5/minute log prefix "NFT_IPV4_input_ssh{$sshport}_RateLimit_drop " counter drop
      tcp dport $sshport ct state new log prefix "NFT_IPV4_input_ssh{$sshport}_accept " counter accept
      ### we are on a local network already filtered, accept all
      ct state {new, established, related} accept
   }

   chain FORWARD {
      ### we are not a gateway
      type filter hook forward priority 0; policy drop;
      counter comment "ipv4 forward dropped packets"
   }

   chain OUTPUT {
      type filter hook output priority 0; policy accept;
      ct state invalid counter drop
      #counter comment "ipv4 output accepted packets"
   }
}


# ----- IPv6 -----
table ip6 filter {
   chain INPUT {
      ### Internet - accept all connections related to connections made by us ###
      type filter hook input priority 0; policy drop;
      ct state invalid counter drop comment "ipv6 early drop of invalid packets"
      iif != lo ip6 daddr ::1/128 counter drop comment "ipv6 drop connections to loopback not coming from loopback"
      ### accept loopback - Mandatory !
      iif lo accept comment "ipv6 accept loopback"
      ### Force SYN checks
      tcp flags & (fin|syn|rst|ack) != syn ct state new counter drop comment "Force SYN checks"
      ### Drop XMAS packets
      tcp flags & (fin|syn|rst|psh|ack|urg) == fin|syn|rst|psh|ack|urg counter drop comment "Drop XMAS packets"
      ### Drop NULL packets
      tcp flags & (fin|syn|rst|psh|ack|urg) == 0x0 counter drop comment "Drop NULL packets"
      ### ICMP - accept all but echo requests
      icmpv6 type echo-request counter drop comment "ipv6 input dropped ICMP echo-request"
      ip6 nexthdr icmpv6 accept comment "ipv6 accept all ICMP types"
      ### Avoid brute force on SSH
      tcp dport $sshport ct state new limit rate over 2/minute log prefix "NFT_IPV6_input_ssh{$sshport}_RateLimit_drop " counter drop
      tcp dport $sshport ct state new log prefix "NFT_IPV6_input_ssh{$sshport}_accept " counter accept
      ### alternatively, if you don't want your syslog to be flooded with dropped connections: (comment out the above lines in that case)
      #tcp dport $sshport ct state new limit rate 2/minute log prefix "NFT_IPV6_input_ssh{$sshport}_accept " counter accept
      ct state {established, related} accept
      log prefix "NFT_IPV6_input_DroppedPacket " counter comment "ipv6 input dropped packets"
   }

   chain FORWARD {
      type filter hook forward priority 0; policy drop;
      counter comment "ipv6 forward dropped packets"
   }

   chain OUTPUT {
      type filter hook output priority 0; policy accept;
      icmpv6 type echo-reply counter drop comment "ipv6 output dropped ICMP echo-reply"
      ct state invalid counter drop
      #counter comment "ipv6 output accepted packets"
   }
}

And I have a script (to be put in /usr/local/sbin/) that makes nft list ruleset easier to read:

Code: Select all

#!/usr/bin/env bash

declare -a RULES=()
declare -r NFT="/usr/sbin/nft"
[[ "$("$NFT" -v)" =~ ^nftables[[:blank:]] ]] || { echo -e "\nnft command not found, exit\n"; exit 1; }


while IFS='' read -r RULE; do

   while IFS='' read -r PART; do
      [[ "$PART" == "${PART#\"}" ]] || PART="${PART// accept / ¿accept }" PART="${PART// drop / ¿drop }" \
                                       PART="${PART// accept;/ ¿accept;}" PART="${PART// drop;/ ¿drop;}"
      LINE="$LINE$PART"
   done < <(sed 's/"[^"]\+"/\n&\n/g' <<<"$RULE")
   RULES+=( "$LINE" ) LINE=""

done < <("$NFT" -a list ruleset)


PATTERN1='\([[:blank:]]\)\(counter packets \)\(0\)\( bytes \)\(0\)'
REPLACE1='\1\x1b\[0;37m\2\x1b\[0m\x1b\[1;32m\3\x1b\[0m\x1b\[0;37m\4\x1b\[0m\x1b\[1;32m\5\x1b\[0m'
PATTERN2='\([[:blank:]]\)\(counter packets \)\([[:digit:]]\+\)\( bytes \)\([[:digit:]]\+\)'
REPLACE2='\1\x1b\[0;37m\2\x1b\[0m\x1b\[1;31m\3\x1b\[0m\x1b\[0;37m\4\x1b\[0m\x1b\[1;31m\5\x1b\[0m'

sed -e's/'"$PATTERN1"'/'"$REPLACE1"'/g' \
    -e's/'"$PATTERN2"'/'"$REPLACE2"'/g' \
    -e's/\([[:blank:]]\)\(comment "[^"]\+"\)/\1\x1b\[0;37m\2\x1b\[0m/g' \
    -e's/\([[:blank:]]\)\(log prefix "[^"]\+"\)/\1\x1b\[0;37m\2\x1b\[0m/g' \
    -e's/\( \)\(# handle [[:digit:]]\+\)\( \)$/\1\x1b\[1;90m\2\x1b\[0m/' \
    -e's/\( \)\(accept\|drop\)\( \|;\)/\1\x1b\[1m\2\x1b\[0m\3/g' \
    -e's/\( ¿\)\(accept[ ;]\|drop[ ;]\)/ \2/g' <<<"${RULES[@]/#/$'\n'}"

Attachments
nftables_ruleset.png

User avatar
Hallvor
Global Moderator
Global Moderator
Posts: 2020
Joined: 2009-04-16 18:35
Location: Kristiansand, Norway
Has thanked: 138 times
Been thanked: 204 times

Re: Howto: Set up a basic nftables firewall (Buster)

#14 Post by Hallvor »

I don't think there is any need to differentiate between IPv4 and IPv6 to accomplish this. One could simply add the router's subnet to the ruleset to only allow local connections:

Code: Select all

#!/sbin/nft -f

flush ruleset

table inet filter {
    chain input {
        type filter hook input priority 0; policy drop;
        ct state invalid drop
        iifname lo accept
        ct state {established, related} accept
        ip saddr 192.168.1.0/24 tcp dport {1714-1764} accept
        ip saddr 192.168.1.0/24 udp dport {1714-1764} accept
        ip protocol udp reject
        ip protocol tcp reject with tcp reset
        reject with icmpx type port-unreachable
    }

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

    chain output {
        type filter hook output priority 0; policy accept;
    }
}
And here is another that allows ICMP, but protects against ping floods (KDE Connect is commented out):

Code: Select all

#!/sbin/nft -f

flush ruleset

table inet filter {
    chain input {
        type filter hook input priority 0; policy drop;
        ct state invalid drop
        ip protocol icmp icmp type echo-request limit rate over 10/second drop
        ip protocol icmp accept
        iif != lo ip daddr 127.0.0.1/8 counter drop
        iifname lo accept
        ct state {established, related} accept
        #ip saddr 192.168.1.0/24 tcp dport {1714-1764} accept
        #ip saddr 192.168.1.0/24 udp dport {1714-1764} accept
        ip protocol udp reject
        ip protocol tcp reject with tcp reset
        reject with icmpx type port-unreachable
    }

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

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

Added some more security features:

Code: Select all

#!/sbin/nft -f

flush ruleset

table inet filter {
    chain input {
        type filter hook input priority 0; policy drop;
        ct state invalid drop;
        ip protocol icmp icmp type echo-request limit rate over 10/second drop;
        ip protocol icmp accept;
        iif != lo ip daddr 127.0.0.1/8 counter drop;
        iifname lo accept;
        tcp flags syn limit rate over 10/second counter drop;
        tcp flags & (fin|syn|rst|ack) != syn ct state new counter drop;
        tcp flags & (fin|syn|rst|psh|ack|urg) == fin|syn|rst|psh|ack|urg counter drop;
        tcp flags & (fin|syn|rst|psh|ack|urg) == 0x0 counter drop;
        ct state {established, related} accept;
        #ip saddr 192.168.1.0/24 tcp dport {1714-1764} accept;
        #ip saddr 192.168.1.0/24 udp dport {1714-1764} accept;
        ip protocol udp reject;
        ip protocol tcp reject with tcp reset;
        reject with icmpx type port-unreachable;
    }

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

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



Your ruleset looks OK. It has several nice security features. I wouldn't allow SSH from the Internet unless necessary, though.
[HowTo] Install and configure Debian bookworm
Debian 12 | KDE Plasma | ThinkPad T440s | 4 × Intel® Core™ i7-4600U CPU @ 2.10GHz | 12 GiB RAM | Mesa Intel® HD Graphics 4400 | 1 TB SSD

User avatar
fabien
Forum Helper
Forum Helper
Posts: 604
Joined: 2019-12-03 12:51
Location: Anarres (Toulouse, France actually)
Has thanked: 60 times
Been thanked: 141 times

Re: Howto: Set up a basic nftables firewall (Buster)

#15 Post by fabien »

Hallvor wrote: 2023-01-15 10:21I don't think there is any need to differentiate between IPv4 and IPv6 to accomplish this. One could simply add the router's subnet to the ruleset to only allow local connections
Of course, it's just a matter of choice depending on what is needed. The thing is that on a local network, desktop applications may need to communicate beyond what you thought or didn't think (think avahi or cups for example) and I just decided that I didn't want to study how all my applications were communicating and thus reduced the risk of malfunction due to this part of the problem. But you're right, there are different ways to achieve this. I just found separating IPv4 and IPv6 easier to maintain.
Hallvor wrote: 2023-01-15 10:21I wouldn't allow SSH from the Internet unless necessary, though.
I don't allow SSH unnecessarily, these lines are commented out on machines that don't need it.

Post Reply