概述 通过nftables规则对特定端口范围做计数流量统计,可以借此计算瞬时流量.
写规则 假设这里我统计的是11000-19000端口范围的流量,入站和出站都统计,然后用计数器来计算流量.
大概流程就是创一个名字叫portstats的表,然后创两个链,一个叫input_chain,一个叫output_chain,
然后创两个计数器,一个叫input_tcp_range,一个叫output_tcp_range,然后创两个规则,一个叫input_tcp_range,一个叫output_tcp_range.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 nft add table inet portstats nft add chain inet portstats input_chain { type filter hook input priority 0\; } nft add chain inet portstats output_chain { type filter hook output priority 0\; } nft add table inet portstats nft add chain inet portstats input_chain { type filter hook input priority 0\; } nft add chain inet portstats output_chain { type filter hook output priority 0\; } nft add counter inet portstats input_tcp_range nft add counter inet portstats output_tcp_range nft add counter inet portstats input_udp_range nft add counter inet portstats output_udp_range nft add rule inet portstats input_chain tcp dport 11000-19000 counter name input_tcp_range nft add rule inet portstats input_chain udp dport 11000-19000 counter name input_udp_range nft add rule inet portstats output_chain tcp sport 11000-19000 counter name output_tcp_range nft add rule inet portstats output_chain udp sport 11000-19000 counter name output_udp_range
创建完成后,可以查看这个表,能直接看到他的流量统计.
在输出中,能看到counter的流量统计,packets是包的数量,bytes是字节数.
input_tcp_range 入站 TCP 流量统计
output_tcp_range 出站 TCP 流量统计
input_udp_range 入站 UDP 流量统计
output_udp_range 出站 UDP 流量统计
当然,你可以直接通过他的 bytes 来计算计数流量,包括瞬时流量你也能记录到.
1 nft list table inet portstats
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 root@localhost:~# nft list table inet portstats table inet portstats { counter input_tcp_range { packets 3646743 bytes 234844099 } counter output_tcp_range { packets 2718337 bytes 7699060368 } counter input_udp_range { packets 83 bytes 12353 } counter output_udp_range { packets 96 bytes 7375 } chain input_chain { type filter hook input priority filter; policy accept; tcp dport 11000-19000 counter name "input_tcp_range" udp dport 11000-19000 counter name "input_udp_range" tcp dport 11000-19000 counter name "input_tcp_range" udp dport 11000-19000 counter name "input_udp_range" } chain output_chain { type filter hook output priority filter; policy accept; tcp sport 11000-19000 counter name "output_tcp_range" udp sport 11000-19000 counter name "output_udp_range" tcp sport 11000-19000 counter name "output_tcp_range" udp sport 11000-19000 counter name "output_udp_range" } } root@localhost:~#
流量计算 比如上面的output_tcp_range当前流量在7699060368字节,如果要转换到 Mb 单位,你应该:
1 echo 'scale=2; 7699060368 / 1048576' | bc
单位是 Mb,这样计算出来的结果仅仅只是计数器记录的流量,并不是瞬时流量.
计算瞬时流量 原理也很简单,先获取当前计数器记录的流量,然后 sleep10 秒后,再获取一次计数器记录的流量,然后计算两次的差值.
1 2 3 nft list table inet portstats sleep 10 nft list table inet portstats
比如我这里两次执行结果的input_tcp_range.
第一次 234844099
第二次 4346338221
那么瞬时流量计算方式直接参考以下脚本
第二次的结果减去第一次的结果,并且除以 10 的延迟秒,得到瞬时流量(如果要到 Mb 单位则再除以 1048576).
如果你的延迟设置的不是 10 秒,而是 60 秒,那你就得除以 60.
1 echo 'scale=2; (4346338221 - 234844099) / 1048576 / 10' | bc
删除规则 如果后续你不想要这个表或者这些规则了,可以直接删除这张表,他会将这个表下的规则,链,计数器一并清理.
1 nft delete table inet portstats