Simple rule management: Difference between revisions
(→Listing rules: modernize this information, will separate output modifiers to other page) |
m (→Removing all the rules in a chain: Fix flush command for removing all rules in a chain: s/flush rule/flush chain/) |
||
(5 intermediate revisions by 4 users not shown) | |||
Line 1: | Line 1: | ||
Rules take action on network packets (e.g. accepting or dropping them) based on whether they match specified criteria. | |||
Each rule consists of zero or more expressions followed by one or more statements. Each expression tests whether a packet matches a specific payload field or packet/flow metadata. Multiple expressions are linearly evaluated from left to right: if the first expression matches, then the next expression is evaluated and so on. If we reach the final expression, then the packet matches all of the expressions in the rule, and the rule's statements are executed. Each statement takes an action, such as setting the netfilter mark, counting the packet, logging the packet, or rendering a verdict such as accepting or dropping the packet or jumping to another chain. As with expressions, multiple statements are linearly evaluated from left to right: a single rule can take multiple actions by using multiple statements. Do note that a verdict statement by its nature ends the rule. | |||
Following are some basic operations and commands for configuring rules: | |||
= Appending new rules = | = Appending new rules = | ||
Line 31: | Line 37: | ||
You can also list rules by chain, for example: | You can also list rules by chain, for example: | ||
<source lang="bash"> | <source lang="bash"> | ||
Line 43: | Line 48: | ||
} | } | ||
</source> | </source> | ||
There are plenty of [[Output_text_modifiers | output text modifiers]] than can be used when listing your rules, to for example, translate IP addresses to DNS names, TCP protocols, etc. | |||
= Testing your rule = | = Testing your rule = | ||
Line 78: | Line 85: | ||
<source lang="bash"> | <source lang="bash"> | ||
% nft | % nft -n -a list table filter | ||
table filter { | table filter { | ||
chain output { | chain output { | ||
Line 97: | Line 104: | ||
<source lang="bash"> | <source lang="bash"> | ||
% nft | % nft -n -a list table filter | ||
table filter { | table filter { | ||
chain output { | chain output { | ||
Line 119: | Line 126: | ||
<source lang="bash"> | <source lang="bash"> | ||
% nft list table filter | % nft -a list table filter | ||
table ip filter { | table ip filter { | ||
chain input { | chain input { | ||
Line 150: | Line 157: | ||
<source lang="bash"> | <source lang="bash"> | ||
% nft | % nft flush chain filter output | ||
</source> | </source> | ||
Line 179: | Line 186: | ||
= Replacing rules = | = Replacing rules = | ||
You can replace any rule via the ''replace'' command by indicating the rule handle | You can replace any rule via the ''replace'' command by indicating the rule handle, which you have to find by first listing the ruleset with option ''-a'': | ||
<source lang="bash"> | <source lang="bash"> | ||
# nft list ruleset | # nft -a list ruleset | ||
table ip filter { | table ip filter { | ||
chain input { | chain input { | ||
Line 191: | Line 198: | ||
</source> | </source> | ||
To replace the rule with handle 2, specify its handle number and the new rule that you want to replace it: | |||
<source lang="bash"> | <source lang="bash"> | ||
Line 197: | Line 204: | ||
</source> | </source> | ||
Listing the ruleset after the above replacement: | |||
<source lang="bash"> | <source lang="bash"> | ||
# nft list ruleset | # nft list ruleset | ||
table ip filter { | table ip filter { | ||
chain input { | chain input { | ||
type filter hook input priority 0; policy accept; | |||
counter packets 0 bytes 0 | counter packets 0 bytes 0 | ||
} | } | ||
Line 208: | Line 216: | ||
</source> | </source> | ||
you can see that the old rule that counted TCP packets has been replaced by the new rule that counts all packets. |
Latest revision as of 10:43, 18 October 2022
Rules take action on network packets (e.g. accepting or dropping them) based on whether they match specified criteria.
Each rule consists of zero or more expressions followed by one or more statements. Each expression tests whether a packet matches a specific payload field or packet/flow metadata. Multiple expressions are linearly evaluated from left to right: if the first expression matches, then the next expression is evaluated and so on. If we reach the final expression, then the packet matches all of the expressions in the rule, and the rule's statements are executed. Each statement takes an action, such as setting the netfilter mark, counting the packet, logging the packet, or rendering a verdict such as accepting or dropping the packet or jumping to another chain. As with expressions, multiple statements are linearly evaluated from left to right: a single rule can take multiple actions by using multiple statements. Do note that a verdict statement by its nature ends the rule.
Following are some basic operations and commands for configuring rules:
Appending new rules
To add new rules, you have to specify the corresponding table and the chain that you want to use, eg.
% nft add rule filter output ip daddr 8.8.8.8 counter
Where filter is the table and output is the chain. The example above adds a rule to match all packets seen by the output chain whose destination is 8.8.8.8, in case of matching it updates the rule counters. Note that counters are optional in nftables.
For those familiar with iptables, the rule appending is equivalent to -A command in iptables.
Listing rules
You can list the rules that are contained by a table with the following command:
% nft list table filter
table ip filter {
chain input {
type filter hook input priority 0;
}
chain output {
type filter hook output priority 0;
ip daddr 8.8.8.8 counter packets 0 bytes 0
tcp dport ssh counter packets 0 bytes 0
}
}
You can also list rules by chain, for example:
% nft list chain filter ouput
table ip filter {
chain output {
type filter hook output priority 0;
ip daddr 8.8.8.8 counter packets 0 bytes 0
tcp dport ssh counter packets 0 bytes 0
}
}
There are plenty of output text modifiers than can be used when listing your rules, to for example, translate IP addresses to DNS names, TCP protocols, etc.
Testing your rule
Let's test this rule with a simple ping to 8.8.8.8:
% ping -c 1 8.8.8.8
PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
64 bytes from 8.8.8.8: icmp_req=1 ttl=64 time=1.31 ms
Then, if we list the rule-set, we obtain:
% nft -nn list table filter
table ip filter {
chain input {
type filter hook input priority 0;
}
chain output {
type filter hook output priority 0;
ip daddr 8.8.8.8 counter packets 1 bytes 84
tcp dport 22 counter packets 0 bytes 0
}
}
Note that the counters have been updated.
Adding a rule at a given position
If you want to add a rule at a given position, you have to use the handle as reference:
% nft -n -a list table filter
table filter {
chain output {
type filter hook output priority 0;
ip protocol tcp counter packets 82 bytes 9680 # handle 8
ip saddr 127.0.0.1 ip daddr 127.0.0.6 drop # handle 7
}
}
If you want to add a rule after the rule with handler number 8, you have to type:
% nft add rule filter output position 8 ip daddr 127.0.0.8 drop
Now, you can check the effect of that command by listing the rule-set:
% nft -n -a list table filter
table filter {
chain output {
type filter hook output priority 0;
ip protocol tcp counter packets 190 bytes 21908 # handle 8
ip daddr 127.0.0.8 drop # handle 10
ip saddr 127.0.0.1 ip daddr 127.0.0.6 drop # handle 7
}
}
If you want to insert a rule before the rule with handler number 8, you have to type:
% nft insert rule filter output position 8 ip daddr 127.0.0.8 drop
Removing rules
You have to obtain the handle to delete a rule via the -a option. The handle is automagically assigned by the kernel and it uniquely identifies the rule.
% nft -a list table filter
table ip filter {
chain input {
type filter hook input priority 0;
}
chain output {
type filter hook output priority 0;
ip daddr 192.168.1.1 counter packets 1 bytes 84 # handle 5
}
}
You can delete the rule whose handle is 5 with the following command:
% nft delete rule filter output handle 5
Note: There are plans to support rule deletion by passing:
% nft delete rule filter output ip saddr 192.168.1.1 counter
but this is not yet implemented. So you'll have to use the handle to delete rules until that feature is implemented.
Removing all the rules in a chain
You can delete all the rules in a chain with the following command:
% nft flush chain filter output
You can also delete all the rules in a table with the following command:
% nft flush table filter
Prepending new rules
To prepend new rules through the insert command:
% nft insert rule filter output ip daddr 192.168.1.1 counter
This prepends a rule that will update per-rule packet and bytes counters for traffic addressed to 192.168.1.1.
The equivalent in iptables is:
% iptables -I OUTPUT -t filter -d 192.168.1.1
Note that iptables always provides per-rule counters.
Replacing rules
You can replace any rule via the replace command by indicating the rule handle, which you have to find by first listing the ruleset with option -a:
# nft -a list ruleset
table ip filter {
chain input {
type filter hook input priority 0; policy accept;
ip protocol tcp counter packets 0 bytes 0 # handle 2
}
}
To replace the rule with handle 2, specify its handle number and the new rule that you want to replace it:
nft replace rule filter input handle 2 counter
Listing the ruleset after the above replacement:
# nft list ruleset
table ip filter {
chain input {
type filter hook input priority 0; policy accept;
counter packets 0 bytes 0
}
}
you can see that the old rule that counted TCP packets has been replaced by the new rule that counts all packets.