Difference between revisions of "Atomic rule replacement"

From nftables wiki
Jump to navigation Jump to search
m (Match existing formatting)
(Noted the 2 possible formats for 'nft -f', reworked the Notes section, expanded on shell scripting vs atomic replacement)
Line 1: Line 1:
== Warning about Shell scripting + nftables ==
With iptables it was common to use a bash script comprised of multiple iptables commands to configure a firewall. This is sub-optimal because it is not atomic, that is to say that during the few fractions of a second that your bash script takes to run your firewall is in a partially configured state. Nftables introduces atomic rule replacement with the ''-f'' option. This is different from bash scripts because nftables will read in all of the included config files, create the config object in memory alongside the existing config, and then in one atomic operation it swaps the old config for the new one meaning there is no moment when the firewall is partially configured.
== Atomic Rule Replacement ==
You can use the ''-f'' option to atomically update your rule-set:
You can use the ''-f'' option to atomically update your rule-set:


Line 19: Line 25:
</source>
</source>


You can also add comments to the ''filter-table'' file. Comments are bash style, starting with # and go to the end of the line.
'''Notes:'''
 
'''''Table Creation''''' - you may have to create the table with ''nft create table ip filter'' before you can load the file exported with ''nft list table filter > filter-table'' otherwise you will hit errors because the table does not exist.
 
'''''Comments''''' - You can also add comments to the ''filter-table'' file. Comments are bash style, starting with # and go to the end of the line.
 
'''''Duplicate Rules''''' - If you prepend the ''flush table filter'' line at the very beginning of the ''filter-table'' file, you achieve atomic rule-set replacement equivalent to what ''iptables-restore'' provides. The kernel handles the rule commands in the file in one single transaction, so basically the flushing and the load of the new rules happens in one single shot. If you choose not to flush your tables then you will see duplicate rules for each time you reloaded the config.
 
'''''Flushing Sets''''' - ''flush table filter'' will not flush any sets defined in that table. To flush sets as well, use ''flush ruleset'' (not available in Linux 3.16 or below) or delete the sets explicitly. Early versions (Linux <=3.16) do not allow you to import a set if it already exists, but this is allowed in later versions.
 
'''''Nftables Config File Formats''''' - ''nft -f <filename>'' accepts 2 formats, the first is the format seen in the output of ''nft list table''. The second is [[Scripting]] and is the format you typically see on this website.
 
Example of nftables output format:


If you prepend the ''flush table filter'' line at the very beginning of the ''filter-table'' file, you achieve atomic rule-set replacement equivalent to what ''iptables-restore'' provides. The kernel handles the rule commands in the file in one single transaction, so basically the flushing and the load of the new rules happens in one single shot.
<source lang="bash">
% nft list table ip nat
table ip nat {
chain prerouting {
type filter hook prerouting priority 0; policy accept;
}


Note: ''flush table filter'' will not flush any sets defined in that table. To flush sets as well, use ''flush ruleset'' (not available in Linux 3.16 or below) or delete the sets explicitly. Early versions (Linux <=3.16) do not allow you to import a set if it already exists, but this is allowed in later versions.
chain postrouting {
type filter hook postrouting priority 100; policy accept;
}
}
</source>


Example of scripted config format:
<source lang="bash">
% nft add table nat
% nft add chain nat prerouting { type nat hook prerouting priority 0 \; }
% nft add chain nat postrouting { type nat hook postrouting priority 100 \; }
</source>


== Shell Scripting ==
'''Converting between formats'''


Some people prefer to maintain a shell script file with the rule-set. '''Beware of that approach, you cannot achieve atomic rule-set updates with a shell script file'''. Therefore, the best way to go is to use the native [[Scripting|nftables scripting capabilities]] and to restore your rule-set via ''nft -f''.
The easiest way to convert from scripted config format to output-based is to run the commands and then show the nftables config with ''nft list table <table name>'' and then copy/paste that into your config file.
The easiest way to convert from output-based to scripted based is to lookup the equivalent on this wiki.

Revision as of 00:39, 26 January 2018

Warning about Shell scripting + nftables

With iptables it was common to use a bash script comprised of multiple iptables commands to configure a firewall. This is sub-optimal because it is not atomic, that is to say that during the few fractions of a second that your bash script takes to run your firewall is in a partially configured state. Nftables introduces atomic rule replacement with the -f option. This is different from bash scripts because nftables will read in all of the included config files, create the config object in memory alongside the existing config, and then in one atomic operation it swaps the old config for the new one meaning there is no moment when the firewall is partially configured.

Atomic Rule Replacement

You can use the -f option to atomically update your rule-set:

% nft -f file

Where file contains your rule-set.

You can save your rule-set by storing the existing listing in a file, ie.

% nft list table filter > filter-table

Then you can restore it by using the -f option:

% nft -f filter-table

Notes:

Table Creation - you may have to create the table with nft create table ip filter before you can load the file exported with nft list table filter > filter-table otherwise you will hit errors because the table does not exist.

Comments - You can also add comments to the filter-table file. Comments are bash style, starting with # and go to the end of the line.

Duplicate Rules - If you prepend the flush table filter line at the very beginning of the filter-table file, you achieve atomic rule-set replacement equivalent to what iptables-restore provides. The kernel handles the rule commands in the file in one single transaction, so basically the flushing and the load of the new rules happens in one single shot. If you choose not to flush your tables then you will see duplicate rules for each time you reloaded the config.

Flushing Sets - flush table filter will not flush any sets defined in that table. To flush sets as well, use flush ruleset (not available in Linux 3.16 or below) or delete the sets explicitly. Early versions (Linux <=3.16) do not allow you to import a set if it already exists, but this is allowed in later versions.

Nftables Config File Formats - nft -f <filename> accepts 2 formats, the first is the format seen in the output of nft list table. The second is Scripting and is the format you typically see on this website.

Example of nftables output format:

% nft list table ip nat
table ip nat {
	chain prerouting {
		type filter hook prerouting priority 0; policy accept;
	}

	chain postrouting {
		type filter hook postrouting priority 100; policy accept;
	}
}

Example of scripted config format:

% nft add table nat
% nft add chain nat prerouting { type nat hook prerouting priority 0 \; }
% nft add chain nat postrouting { type nat hook postrouting priority 100 \; }

Converting between formats

The easiest way to convert from scripted config format to output-based is to run the commands and then show the nftables config with nft list table

and then copy/paste that into your config file. The easiest way to convert from output-based to scripted based is to lookup the equivalent on this wiki.