Nftables Part 1: Difference between revisions

From BitFolk
Jump to navigation Jump to search
No edit summary
No edit summary
 
(9 intermediate revisions by the same user not shown)
Line 107: Line 107:
This still has the disadvantage of having to type lots of repetitive text unnecessarily, which brings us to the recommended method editing the automatically installed descriptive file nftables.conf. Which is what we will do from now on. It has 2 big advantages, less typing but very readable seeing where each rule fits. It is still possible to intersperse the file with verbose text rules, nft does not mind.  So let's analyse a near complete ruleset file and get to grips with the syntax and structure.
This still has the disadvantage of having to type lots of repetitive text unnecessarily, which brings us to the recommended method editing the automatically installed descriptive file nftables.conf. Which is what we will do from now on. It has 2 big advantages, less typing but very readable seeing where each rule fits. It is still possible to intersperse the file with verbose text rules, nft does not mind.  So let's analyse a near complete ruleset file and get to grips with the syntax and structure.


==Dissecting a Ruleset Script==
==What next==


<syntaxhighlight lang="text">
[[Nftables Part 2]] will look at a near complete but fully workable ruleset and analyse the sections and rules to explain the syntax. Further pages will then look at more advanced configurations and how to get '''fail2ban''' working with nftables.
#!/usr/sbin/nft -f
flush ruleset
define web = {http,https}
define mail = {smtp,pop3,imap3,submission}
define altssh = 22
define ftpports = {ftp,ftps}
define portmap = 111
table inet filter {
        chain input {
                type filter hook input priority 0; policy drop;
                meta iif lo accept
                tcp dport $altssh accept; counter
                ct state established,related accept
                ct state invalid drop
                tcp dport {$web,$mail,$ftpports,webmin,domain} accept
                udp dport domain accept
                ip protocol icmp limit rate 10/second accept
                ip6 nexthdr icmpv6 limit rate 10/second accept
                ip saddr 85.119.82.237 accept
                ip6 saddr 2001:ba8:1f1:f29d::/64 accept; counter
                tcp dport $portmap drop
                udp dport $portmap drop
        }


        chain output {
==Other Resources==
                type filter hook output priority 0; policy accept;
        tcp dport $portmap drop
        udp dport $portmap drop


        }
https://wiki.nftables.org/wiki-nftables/index.php/Main_Page is the wiki of the nftables project
}</syntaxhighlight>
This wiki entry is based upon Debian .deb packages. For details of .rpm packages see https://apps.fedoraproject.org/packages/nftables
 
This is a near complete firewall script for a VPS not operating as a router we will take it apart line by line and look at the syntax. Where as any of the text input methods will need to describe and action for nft and a relative position for the rule or chain to be placed, a descriptive ruleset file will not need that as it is already placed in the diagram.
 
===Definition block===
 
The first 2 lines have been explained already. Next come the variable definitions. Each consists of a variable name = followed by the value(s) assigned. When referenced in a rule, the name has to be prefixed with $. These definitions contain many references to built in constants for readability. NFTables uses its own table of aliases for port numbers. These can be viewed using the command
 
<syntaxhighlight lang="text">:~#  nft describe tcp dport
payload expression, datatype inet_service (internet network service) (basetype integer), 16 bits
 
pre-defined symbolic constants (in decimal):
        tcpmux                                            1
        echo                                              7
        ...</syntaxhighlight>
The other feature demonstrated here is the set. There are two types of sets, named and anonymous. Both are enclosed in curly braces and elements are comma separated. Anonymous sets, as illustrated here are static and form an integral part of the rule. They cannot have rules added or deleted (except by removing and re-adding the rule) and only exist within the rule where they are defined. Named sets, however, must be defined before use and may be referenced (''@name'') in any rule following their definition. They can be added to or have elements deleted dynamically.
NOTE There are two definitions that will need a little further explanation
''define altssh = 22'' This may seem surplus to requirements. Afterall, sshd is already defined internally as port 22. It therefore seems pointless defining another name for it when sshd could be added to the rule allowing access to certain fixed ports anyway. The reason I have done this is that I actually have sshd listening on a different non-standard port. Port 22 therefore remains closed and there is no one who has a legitimate reason to attempt to use it. Being such an important service though it does attract a lot of attention from hackers attempting dictionary attack, or it may also have been tested by port scanners. Neither of which do I want approaching my VPS I have therefore set up a system using a named set and dynamic editing of the set to block them for a while. I will introduce and describe this later in the article.
''define portmap = 111'' An embarrassing legacy item this. Some years ago, I received a notification from Bitfolk that my VPS was running a very insecure open service on port 111. Not only was it insecure but totally unnecessary. I removed the service and blocked the port, the block has remained as a legacy item in every firewall since. This definition and the rules referencing it are probably not needed any more.
 
===Table and Chain definitions===
 
<syntaxhighlight lang="text">nft add table inet filter</syntaxhighlight>
 
'''table inet filter {'''
The initial definition merely needs the family and a name as it only acts as a container for the chains within it. It defines the family of packets which it will handle. There are 5 different table families, ip, ip6, inet (a super family of the two previous), arp and bridge. The default is ip.
 
<syntaxhighlight lang="text">nft add table inet filter</syntaxhighlight>

Latest revision as of 08:10, 28 November 2018

Introduction

STILL NOT COMPLETE

Iptables (and its sister ip6tables) or programs based upon it has for many years been the standard firewall product for Linux machines. Its reign is coming to an end. Debian has announced that the next incarnation of its OS (Debian 10) will see its replacement by nftables. Current kernels already have the nftables engine powering their firewalls with iptables and firewalld rulesets running on this. Nftables offers many new features, incuding simpler syntax, integration of all the old xtables family into one unified package. It has reached a stage of development and maturity that now is the time to make the move Having replaced iptables I have produced the guide below as an aid to those considering it. This is based on my experience with Debian 9 and kernel 4.9.0-8-amd64 other distributions will vary slightly especially in methods of installation. The other thing to note is that nft the front end requires root (or sudo su)

Getting and installing

The stretch repository contains nftables but a more recent version is available from stretch-backports, and as there has been a lot of recent development, this is the one to go for. If the backports repository is not in your sources.list then it will need to be added before you can install

 ~# echo "deb http://ftp.debian.org/debian stretch-backports main" >> /etc/apt/sources.list
~# apt-get update
~# apt-get -t stretch-backports install nftables

This will install all that is necessary. It sets up a new service nftables.service which is disabled on installation. That allows you to set up rules etc and clear iptables before you start the service.(It is not recommended to run both at the same time if there is conflict between any of the rules) On starting or restarting the service loads a minimalist ruleset, so we need to build our rules before running it.


Editing The Ruleset

The basic structure is the same as iptables – tables hold chains which are, in turn, containers for rules. The major difference is that iptables has tables predefined but nft has none. /etc/nftables.conf sets up a basic table and 3 empty chains which we will need to edit

 #!/usr/sbin/nft -f

flush ruleset

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

The table and chains can have any name you like (there are length restrictions though), but these names are descriptive, they do what they say on the can. My VPS does not act as a router at the moment so I can safely remove the forward chain. The easiest way to do that is edit the file, I could of course use a command line instruction to do it. But we will look at that later. The other thing that needs doing is setting the policy for each chain. Again I will just do this by editing the file.

~#nano /etc/nftables.conf

So it will end up looking like this:-

 #!/usr/sbin/nft -f

flush ruleset

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

So we save it. NOTE I have set the policy to accept, first time round I set it to drop and of course cut myself off.

And load it up

~# nft -f /etc/nftables.conf

No error messages means it was all OK. But we can check by using the command

~# nft list ruleset

There is now a ruleset in operation, albeit very sparse and in fact doing nothing to filter traffic.

Adding a New Rule

As mentioned already there are a number of ways of adding a rule. Let's look at adding a simple rule to allow any packets coming in on port 80, the http port. This rule will be added to the input chain in table "filter". Looking at the definition of the table "filter" above table inet filter this inet defines the family meaning rules within it unless specified differently apply to ip packets (ipv4) and ip6 (ipv6).

Commandline shell

~# nft add rule filter input tcp dport http accept
  • nft call the nft commandline processor
  • filter output to the table "filter" place it in the chain "input"
  • tcp dport http The match condition = if it is protocol tcp and the destination port is http. (nft has its own table of port definitions built in)
  • accept The verdict. This is the action to be taken if a match is made

Remember when using this method or any using the normal shell, semicolons must be escaped "\;"

Interactive command line

~# nft -i
nft>

then rules can be added one at a time as above, just excluding the nft at the beginning, typing quit will take you out of interactive mode

Shell script

Listing all the commands to build the firewall in a shell script and making it executable was a favoured method with iptables It is possible with nftables but not recommended.

#!/bin/bash
nft flush ruleset
nft add table <tabledefinition>
nft add chain <chain definition>
...

This has an advantage over the previous methods in that it can easily be edited then executed again.

Nftables rules script

This is similar to the shell script except that the first line differs. Instead of invoking the bash shell to interpret the instructions, it invoke nft to do so. If you remember to include also "flush ruleset" as the second line. nftables will read in the whole file, parse and compile it into memory then in a single atomic action replace the whole of the current ruleset with this one.

#!/usr/sbin/nft
flush ruleset
add table <tabledefinition>
add chain <chaindefinition>
add rule ...

This still has the disadvantage of having to type lots of repetitive text unnecessarily, which brings us to the recommended method editing the automatically installed descriptive file nftables.conf. Which is what we will do from now on. It has 2 big advantages, less typing but very readable seeing where each rule fits. It is still possible to intersperse the file with verbose text rules, nft does not mind. So let's analyse a near complete ruleset file and get to grips with the syntax and structure.

What next

Nftables Part 2 will look at a near complete but fully workable ruleset and analyse the sections and rules to explain the syntax. Further pages will then look at more advanced configurations and how to get fail2ban working with nftables.

Other Resources

https://wiki.nftables.org/wiki-nftables/index.php/Main_Page is the wiki of the nftables project This wiki entry is based upon Debian .deb packages. For details of .rpm packages see https://apps.fedoraproject.org/packages/nftables