Scripting

From nftables wiki
Jump to: navigation, search

Many people like to maintain their ruleset in shell scripts, this allows them to add comments and arrange rules in more human-friendly way. This is problematic though since shell scripts break atomicity when applying the ruleset, thus, the filtering policy is applied in an inconsistent way during the ruleset loading time.

Fortunately, nftables provides a native scripting environment to address these concerns which basically allows you to include other ruleset files, define variables and add comments. You have to restore the content of this native script through the nft -f my-ruleset.file command.

To create a nftables script, you have to add the following header to your script file:

#!/usr/sbin/nft -f

Adding comments

You can add comments to your file using the '#' character. Everything after the '#' will be ignored.

#!/usr/sbin/nft -f

#
# table declaration
#
add table filter

#
# chain declaration
#
add chain filter input { type filter hook input priority 0; policy drop; }

#
# rule declaration
#
add rule filter input ct state established,related counter accept

Including files

The example below shows how to include other ruleset files:

#!/usr/sbin/nft -f

include "ipv4-nat.ruleset"
include "ipv6-nat.ruleset"

Defining variables

You can use the define keyword to define variables, the following example shows a very simple ruleset to account the traffic that comes from 8.8.8.8 (the popular Google DNS server):

#!/usr/sbin/nft -f

define google_dns = 8.8.8.8

add table filter
add chain filter input { type filter hook input priority 0; }
add rule filter input ip saddr $google_dns counter

You can also define a variable for sets:

#!/usr/sbin/nft -f

define ntp_servers = { 84.77.40.132, 176.31.53.99, 81.19.96.148, 138.100.62.8 }

add table filter
add chain filter input { type filter hook input priority 0; }
add rule filter input ip saddr $ntp_servers counter

Don't forget that brackets have special semantics when used from rules, since they indicate that this variable represents a set. Therefore, avoid things like:

define google_dns = { 8.8.8.8 }

It is simply overkill to define a set that only stores one single element, instead use the singleton definition:

define google_dns = 8.8.8.8