iptables
has the statistic module that allows doing operations on packets based on a probability, how would I go about and do this with nftables?
- 193
- 1
- 11
-
1Why the downvote? This is a good question for those that want to migrate to nftables from iptables. – Avamander Jun 18 '19 at 12:42
1 Answers
numgen
nftables has all features in place, but for some unknown reason, it's not documented in any version of the nft
manpage.
The kernel side handling this, nft_numgen has been available since Linux 4.9 and the userland side since the nftables 0.7 release:
Add number generation support. Useful for round-robin packet mark setting, eg.
# nft add rule filter prerouting meta mark set numgen inc mod 2
You can also specify an offset to indicate from what value you want to start from.
The modulus provides the scale of the counting sequence. You can
also use this from maps, eg.# nft add rule nat prerouting \ dnat to numgen inc mod 2 map { 0 : 192.168.10.100, 1 : 192.168.20.200 }
So this is distributing new connections in a round-robin fashion
between 192.168.10.100 and 192.168.20.200. Don't forget the special NAT chain semantics: Only the first packet evaluates the rule, follow up packets rely on conntrack to apply the NAT information.You can also emulate flow distribution with different backend weights using intervals, eg.
# nft add rule nat prerouting \ dnat to numgen inc mod 10 map { 0-5 : 192.168.10.100, 6-9 : 192.168.20.200 }
There's also support for random numbers. Example: replacing in a previous example inc
(used for round-robin) with random
:
nft add rule nat prerouting dnat to numgen random mod 2 map { 0 : 192.168.10.100, 1 : 192.168.20.200 }
Further documentation and related stuff:
- Math operations - Number generator - nftables wiki
- Load balancing - nftables wiki
- Initial presentation from the author of the numgen module at Netdev 1.2: Load Balancing with nftables II (PDF)
- Load balancer using nftables: nftlb (from same person / company).
Back to the question
The random number is a 32 bits integer (big enough to ignore modulus bias) on which is applied a modulus. Its value can then be compared. To drop 5% of all non-local incoming IPv4 packets that would then be:
#!/usr/sbin/nft -f
flush ruleset
table ip filter {
chain input {
type filter hook input priority 0; policy accept;
iif "lo" accept
numgen random mod 100 < 5 drop
}
}
Example when pinging from its host a container with this ruleset:
# ping -q -f 10.0.3.66
PING 10.0.3.66 (10.0.3.66) 56(84) bytes of data.
^C
--- 10.0.3.66 ping statistics ---
34351 packets transmitted, 32592 received, 5% packet loss, time 19744ms
rtt min/avg/max/mdev = 0.004/0.017/0.481/0.018 ms, ipg/ewma 0.574/0.017 ms
- 9,037
- 2
- 19
- 37
-
Thank you so much for your answer, I hope they'll add this module to the list of things `iptables-translate` can translate to save others the trouble when they're trying to simulate packet loss with nftables. – Avamander Jun 20 '19 at 00:37