nftables firewall setup linux

Many of you might have utilized Iptables before and likely encountered its cumbersome nature:

Fortunately, there exists a superior alternative to Iptables – nftables, abbreviated as “nft” (though the abbreviation hasn’t aged well). Despite its simplicity and user-friendliness, surprisingly few individuals are acquainted with it.

In this tutorial, we will demonstrate the setup of a straightforward firewall that permits all outgoing ports along with incoming HTTP, HTTPS, SSH, and DNS traffic.

nftables firewall setup
Prerequisites:

You’ll need any Linux distribution that supports nftables, which encompasses virtually any Linux distribution updated within the last decade.

For Debian and Ubuntu users, install the nftables package:

sudo apt install nftables

Ensure that no frontends like UFW are active. To deactivate UFW, execute the following command:

sudo ufw disable

You can verify their status using nft --version and sudo ufw status.

Example Terminology:

Main network interface: enp5s0

Step 1 – Accessing the Configuration File:

Most distributions contain either /etc/nftables.conf or /etc/sysconfig/nftables.conf. Open the relevant file using your preferred text editor:

sudo editor /etc/nftables.conf

Step 2 – Removing the Skeleton:

The file may either be empty or contain the following structure:

#!/usr/sbin/nft -f

flush ruleset

table inet filter {
        chain input {
                type filter hook input priority filter;
        }
        chain forward {
                type filter hook forward priority filter;
        }
        chain output {
                type filter hook output priority filter;
        }
}

If this is the case, clear the file before proceeding. Otherwise, if the file contains existing rules, handle them accordingly. However, ensure not to delete any crucial rules, especially those pertaining to virtualization.

Step 3 – Crafting the Firewall Configuration:

Below is a template that can be pasted into the configuration file:

#!/usr/sbin/nft -f

# Variables
define main_interface = "enp5s0"

# Delete previous table
table ip my_filter
delete table ip my_filter

# Create new table
table ip my_filter {
    # Filter ingoing traffic
    chain input {
        type filter hook input priority 0;

        iifname $main_interface tcp dport {22, 80, 443} accept
        iifname $main_interface udp dport 53 accept
        iifname $main_interface ip protocol icmp accept # Accept all ICMP traffic
        iifname $main_interface ct state established,related accept # Accept any input traffic originated from us
        iifname $main_interface ct state invalid drop # Drop invalid packets...
        iifname $main_interface icmpv6 type {echo-request,nd-neighbor-solicit} accept # Accept IPv6 neighbour discovery
        iifname $main_interface drop # Drop everything else
    }

    # Drop all packages to be forwarded (we're not a gateway!)
    chain forward {
        type filter hook forward priority 0; policy drop;
    }

    # Allow all outgoing traffic
    chain output {
        type filter hook output priority 0; policy accept;
    }
}

Step 3.1 – Customizing the Configuration File:

Replace enp5s0 with your public-facing network interface. For multiple interfaces, specify them as follows:

define main_interface = {"enp5s0", "enp7s0"}

Adjust the port configurations according to your requirements:

iifname $main_interface tcp dport {22, 80, 443} accept
iifname $main_interface udp dport 53 accept

Note that port ranges can be specified using {}. If UDP ports aren’t required, the entire line can be omitted.

Port ranges can also be specified like so:

iifname $main_interface udp dport {53, 1000-1999} accept

Step 3.2 – Allowing Forwarding to Bridges (Optional):

If bridge networking for virtual machines is in use, forwarding to those bridges must be permitted. Add the following rule to the end of the forward chain for each bridge interface (replace br0 with your bridge interface):

iifname $main_interface oifname "br0" accept

Uncomment the line above the chain.

Applying the Firewall Rules:

Step 4 – Applying the Firewall Rules:

Make the configuration file executable:

sudo chmod a+x /etc/nftables.conf

Execute the configuration file:

sudo /etc/nftables.conf

You can repeat this step whenever modifications to the rules are necessary. The rules will also be applied automatically upon rebooting.

Step 5 – Troubleshooting:

If connectivity issues arise, consider disabling the firewall temporarily. For cloud servers, use the cloud web interface and execute:

sudo nft delete table ip my_filter

For dedicated servers, utilize KVM or reboot into the rescue system via the SarvHost Robot web interface to manually delete the firewall configuration.

If the firewall configuration seems ineffective, ensure that main_interface corresponds to the public-facing network interface.

Conclusion:

You’ve successfully established a modern and efficient firewall using nftables. Refer to the nftables wiki for additional insights and information.

Leave a Reply

Your email address will not be published. Required fields are marked *