The new Netfilter Linux system of 4.x NFTables, a few simple tips for your server

In 2008, a new project has been introduced titled as nftables designed to replace for iptables administrators familiar linux. At the lapse of 10 years, it began to emerge in Linux distributives with core version later than 3.20 (debian, ubuntu, fedora).

In the middle of 2018, developers of NetFilter subsystem from Linux decided to consider iptables a legacy.  This has been announced on their Netfilter Workshop 2018 on June 16 (http://ral-arturo.org/2018/06/16/nfws2018.html).

There is every likelihood that in the future core revisions, the xt_ * modules development for iptables will be suspended with only hotfixes being acceptable. Instead, the developers will focus on the evolvement of a new nftables subsystem and functionality upgrade.

Let us leave ‘off screen’ those things about the time-proved ‘old ox’ that did not sit well with the developers and simply take up enumerating new system’s features visible to the administrators, i.e. the ultimate users familiar with the iptables:

  • The absence of the usual built-in chains of algorithms and tables such as INPUT, FORWARD, OUTPUT, etc. The user specifies and names the tables (raw, filter, nat, mangle) and chains himself. For this you need a deeper understanding of the Netfilter system running and a more contemplative reading of a diagram in its documentation. It is possible to specify the customarily used chains with customary names, in which case the unused tables and algorithm chains in your firewall configuration simply will not occupy corememory space and thus save some CPU resources too.
  • A built-in host of functions that is partially covering the ipset utility capabilities.
  • A consolidation of iptables, ebtables, arptables, ip6tables in 1 utility with a single core and userspace codebase, which is essential for the users of KVM + Linux bridge visualization with complex anti-spoofing filters and MAC and IP whitelists.
  • Packet and byte counters are optional and, if considered necessary, have to be specified explicitly – in the new terminology, it is a nonterminating action.
  • Completely rewritten syntax, which can be considered as a plus as well as a minus depending on the standpoint, as will be referred to below.
  • Covers about 75% of all the iptables modules host of functions. For more information visit https://wiki.nftables.org/wiki-nftables/index.php/Supported_features_compared_to_xtables . Functional support is gradually increasing and new filter modules appear in the later versions of the core.

New syntax drawbacks:

  • The necessity to learn another syntax, which takes up time. And you still need to remember both syntaxes, since the old one is still in use. This drawback is partially compensated by the iptables-translate program.

Here are advantages of the new syntax, though it is not merely a syntax but also support for some things in the new core subsystem:

  • It is possible to carry out several non-terminating actions in one algorithm. For example, logging, adding an inside address to the list and only at the close a skip or drop (DROP) of a network packet. In a common IPTABLES for such cases we have to create a separate chain, in which all the 3 algorithms will have to be already added. It is obvious that these algorithms are trickier to read and they probably consume more resources.
  • Numeric values (port numbers, even IP addresses) can be compared not only for equality but also for > , >=, <, <=. 
  • Built-in support for IP ranges.
  • When reading from a file,  ‘include’ is possible
  • A more readable (for novices) complex package filter writing, compare:

iptables -A INPUT -p tcp -s 192.168.0.0/24 -m conntrack –ctstate NEW -m muliport –dports 22:23,8081,873 -j REJECT –reject-with tcp-reset

and

nft add rule filter INPUT ip saddr 192.168.0.0/24 tcp dport {22-23, 8081 ,873} ct state new reject with tcp reset

Sure enough, the simple algorythms in iptables are  relatively easy to read for an IT specialist and are roughly evident from the context, but with complication the abundance of -m (–match) keys – <Long and pretty parameter> and arcane abbreviations look disheartening.

Algorithms can be written into a file in hierarchical logical blocks separated by “{” “}” ”, which can be found in such well-known products as nginx (Hello from JunOS world), the totall readability thus all the more increases:

table ip filter {
chain INPUT {
type filter hook input priority 0; policy accept;
ip saddr 192.168.0.0/24 tcp dport { ssh-telnet, rsync, tproxy} ct state new reject with tcp reset
}
}

Simple tips for your Linux server

1) Save to file and restore algorithms:

Analog iptables-save > iptables.save

# nft list ruleset > nftables.save

Analog iptables-restore < iptables.save

# nft -f nftables.save

In the beginning of the resulting algorithms you should preferably add this lineflush ruleset

otherwise, it is possible that the loaded algorithms will be added to the existing ones.

2) Transmission of the default supplier rule with CentOS 5/6/7 – the files contents and comparison with iptables.

  • NFTables (nft list ruleset)
flush ruleset

table ip filter {
   chain INPUT {
    type filter hook input priority 0; policy accept;
    ct state established,related accept
    ip protocol icmp accept
    iif "lo" accept
    tcp dport ssh accept	
    reject with icmp type host-prohibited
   }
   chain FORWARD {
     type filter hook forward priority 0; policy accept;
     reject with icmp type host-prohibited
   }
}
  • NFTables (nft list ruleset)
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A INPUT -p icmp -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT
-A INPUT -j REJECT --reject-with icmp-host-prohibited
-A FORWARD -j REJECT --reject-with icmp-host-prohibited
COMMIT
iptables (END)

3) A web server with access via ssh for the white list IP 15.14.13.12, 132.12.10.5, access to MySQL from 15.14.13.12, 132.12.10.5, 172.16.1.12, 54.61.75.3, access to the web server is open to all, other ports are closed

  • NFTables  (nft list ruleset)
flush ruleset
table ip filter {
	set ssh_white_list {
		type ipv4_addr
		elements = { 15.14.13.12, 132.12.10.5}
	}
	set mySQL_white_list {
		type ipv4_addr
		elements = { 15.14.13.12, 132.12.10.5, 172.16.1.12,
54.61.75.3 }
	}

	chain INPUT {
	   type filter hook input priority 0; policy drop;
	   ct state established,related accept
	   iif "lo" accept
	   ip tcp dport {http, https } accept
	   ip saddr @ssh_white_list tcp dport ssh accept
	   ip saddr @mySQL_white_list tcp dport 3306 accept
	   ip protocol tcp reject with tcp reset
	}
}
  • IPSET (ipset list)
Name: ssh_white_list
Type: hash:net
Revision: 6
Header: family inet hashsize 1024 maxelem 65536
Size in memory: 480
References: 0
Members:
15.14.13.12
132.12.10.5

Name: mySQL_white_list
Type: hash:net
Revision: 6
Header: family inet hashsize 1024 maxelem 65536
Size in memory: 608
References: 0
Members:
172.16.1.12
54.61.75.3
132.12.10.5
15.14.13.12
  • IPTABLES (iptables-save)
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A INPUT -p icmp -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -p tcp -m set —match-set ssh_white_list scr -m tcp --dport 22 -j ACCEPT
-A INPUT -p tcp -m set —match-set mySQL_white_list  scr -m tcp --dport 3306 -j ACCEPT
-A INPUT -j REJECT --reject-with icmp-host-prohibited
-A FORWARD -j REJECT --reject-with icmp-host-prohibited
COMMIT
iptables (END)

4) A simple gateway for accessing computers on a local network to the Internet through it using NAT to IP 15.16.17.18:

  • NFTables (nft list ruleset)
flush ruleset
table ip nat {
   chain POSTROUTING {
	type filter hook postrouting priority 100; policy accept;
	ip saddr 192.168.0.0/24 counter oif «eth1» snat to 15.16.17.18
   }
}
  • IPTABLES (iptables-save)
*nat
:PREROUTING ACCEPT [1146:211488]
:INPUT ACCEPT [30:7156]
:OUTPUT ACCEPT [3:252]
:POSTROUTING ACCEPT [3:252]
-A POSTROUTING -s 192.168.0.0/24 -j SNAT --to-source 15.16.17.18
COMMIT
# Completed on Tue Feb 19 10:29:36 2019
# Generated by iptables-save v1.6.0 on Tue Feb 19 10:29:36 2019
*filter
:INPUT ACCEPT [209:23149]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [134:15650]
COMMIT

5) Port forwarding to a local server:

  • FTables (nft list ruleset)
flush ruleset
table ip nat {
   chain PREROUTING {
	type filter hook prerouting priority 100; policy accept;
	ip daddr 15.16.17.18 tcp dport 8080 dnat to 192.168.0.15:80 
    }		
}
  • IPTABLES (iptables-save)
*nat
:PREROUTING ACCEPT [2:363]
:INPUT ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
-A PREROUTING -d 15.16.17.18/32 -p tcp -m tcp --dport 8080 -j DNAT --to-destination 192.168.0.15:80
COMMIT
*filter
:INPUT ACCEPT [532:52024]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [294:30682]
COMMIT

6) Examples 4 and 5 can be combined into:

  • FTables (nft list ruleset)
flush ruleset
table ip nat {
   chain POSTROUTING {
	type filter hook postrouting priority 100; policy accept;	ip saddr 192.168.0.0/24 counter oif «eth1» snat to 15.16.17.18
   }		
   chain PREROUTING {
	type filter hook prerouting priority 100; policy accept;
	ip daddr 15.16.17.18 tcp dport 8080 dnat to 192.168.0.15:80 
	}
}
  • IPTABLES (iptables-save)
*nat
:PREROUTING ACCEPT [2:363]
:INPUT ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
-A POSTROUTING -s 192.168.0.0/24 -j SNAT --to-source 15.16.17.18
-A PREROUTING -d 15.16.17.18/32 -p tcp -m tcp --dport 8080 -j DNAT --to-destination 192.168.0.15:80
COMMIT
*filter
:INPUT ACCEPT [532:52024]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [294:30682]
COMMIT

In all the examples above, the titles of tables and chains (nat, filter, INPUT, PREROUTING, POSTROUTING) may have other meanings, as they are titled so for recognition of those well acquainted with legacy iptables. The ‘type filter hook postrouting priority 100; policy accept;’ lines at the beginning of the chains have real meaning for the algorithm operation.