Linux下使用iptables统计网络流量

Linux 内建的封包过滤机制除了可以架设 NAT、防火墙外, 可能只有少数人知道它也具备传输量统计的功能, 本节将说明其运作的机制, 以及如何使用iptables 指令, 统计特定 IP 或通讯端口的传输总量。

核心内建的传输量统计机制

当核心的网络功能开始运作后, 便已经开始统计传输量了, 您可以如下使用 iptables 指令观察目前统计状况:

[root@unixnotes ~]# iptables -L -vn

“-L” 参数列出链中的规则, 因为没有指定链名, 所以预设列出 filter 链的规则
“-v” 参数将显示完整的信息, 以便观察传输量统计的状况, 一般不使用”-v “参数时, 只会显示如来源地址等简要的信息
“-n” 参数设定 iptables 不要将 IP 反查为域名

Chain INPUT (policy ACCEPT 35463 packets, 2608K bytes)
pkts bytes target prot opt in out source destination

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination

Chain OUTPUT (policy ACCEPT 45808 packets, 65M bytes)

“45808 packets”从开机至今已经有 45808 个封包通过 OUTPUT 链
“65M bytes”总计 65M bytes 的传输量通过 OUTPUT 链

  pkts bytes target prot opt in out source destination

当传输量较大时, iptables 预设会以 K、M、G 等单位来显示传输量, 与一般的计算不同, 这些单位分别代表 1000、1,000,000 与 1,000,000,000 bytes。就阅读上, 使用这些单位能让我们更容易地判断数量大小, 但是未来如果以程序统计传输总量, 使用较精确的数字才能方便地进行数字的比较。此时可以如下使用 “-x” 参数, 强迫 iptables 显示精确的传输量:

[root@unixnotes ~]# iptables -L -vxn  ←加上 “-x” 参数

Chain OUTPUT (policy ACCEPT 58388 packets, 74888452 bytes)

“74888452 bytes”共有 74888452 bytes 的传输量通过 OUTPUT 链

  pkts bytes target prot opt in out source destination

计量器的运作方式

核心所内建的传输量统计机制, 主要是依靠计量器 (counter) 来进行统计的工作。每一个 iptables 规则都伴随着一组计量器, 当封包符合 iptables 内的某一个规则时, 核心便会将封包大小与数量累加于该规则所属的计量器。

以下将以实例说明计量器的运作方式, 笔者于 unixnotes 主机执行下面指令, 在 iptables 中新增一条规则:

[root@unixnotes ~]# iptables -A OUTPUT -p tcp –sport 80 -j ACCEPT

于 OUTPUT 链中设定凡是 TCP 协议, 来源埠号为 80 的封包皆可允许通过

上面规则设定 unixnotes 主机 HTTP 服务器发出的封包皆予放行, 此处并不是设定防火墙进行联机阻挡, 所以姑且不讨论该规则是否有意义。新增规则后可执行下面指令, 列出目前所有规则:

[root@unixnotes ~]# iptables -L -vxn

Chain OUTPUT (policy ACCEPT 58539 packets, 74901820 bytes)

OUTPUT 链预设的原则是允许封包通过, 这也是一个 『规则』, 所以也有一个计量器

pkts bytes target prot opt in out source destination
0 0 ACCEPT tcp — * * 0.0.0.0/0 0.0.0.0/0 tcp spt:80

“0 0 “此为伴随着新规则的计量器
“0 tcp spt”这是刚才新增的规则

新规则的计量器会记录所有来源端口号为 80 的封包, 所以可用来统计 HTTP 服务器的外送传输量。笔者从其他主机使用浏览器, 下载 unixnotes 主机一个大小为 30 Mbytes 的档案, 完成后如下观察传输量的统计情形:

[root@unixnotes ~]# iptables -L -vxn
Chain INPUT (policy ACCEPT 98068 packets, 5555372 bytes)
pkts bytes target prot opt in out source destination

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source  destination

Chain OUTPUT (policy ACCEPT 58539 packets, 74901820 bytes)

有 74888452 bytes 的传输量通过 OUTPUT 链

pkts bytes target prot opt in out source destination
20883 31318041 ACCEPT tcp — * * 0.0.0.0/0 0.0.0.0/0 tcp spt:80

“31318041”共有 31318041 bytes 的传输量通过此规则
“0 tcp spt”这是刚才新增的规则

上面可以看到通过 OUTPUT 链的传输量为 74888452 bytes, 与未下载文件之前相同, 反而是新规则的计量器中, 传输量由 0 增加为 31318041 bytes, 与被下载的档案大小相仿, 所以刚才下载文件的传输量, 全部被记录在新规则的计量器中, 而 OUTPUT 链的计量器则维持不变。于是笔者再多次进行下载, 发现传输量确实只记录于新规则:

[root@unixnotes ~]# iptables -L -vxn

Chain OUTPUT (policy ACCEPT 59158 packets, 74957780 bytes)
pkts bytes target prot opt in out source destination
62649 93954123 ACCEPT tcp — * * 0.0.0.0/0 0.0.0.0/0 tcp spt:80

传输量只记录于此规则的计量器中

为了研究这个状况, 笔者再次于 unixnotes 主机如下新增一个规则 (为了解说上的需要, 随后说明时, 将这个最新规则称为规则 2, 刚才增加的称为规则 1):

[root@unixnotes ~]# iptables -I OUTPUT
-p tcp –sport 80 -d 192.168.0.32 -j ACCEPT

于 OUTPUT 链的第一行插入一个规则, 设定 凡是 TCP 协议, 来源埠号为 80, 目的地址为 192.168.0.32的封包皆可允许通过

然后笔者在 192.168.0.32 主机使用浏览器, 下载 unixnotes 主机上大小为 30 Mbytes 的档案, 完成后如下观察传输量统计状态:

[root@unixnotes ~]# iptables -L -vxn

Chain OUTPUT (policy ACCEPT 59400 packets, 74981620 bytes)
pkts bytes target prot opt in out source destination
20884 31318081 ACCEPT tcp — * * 0.0.0.0/0 192.168.0.32 tcp spt:80←这是最新增加的规则 2

“31318081”传输量被记录于规则 2 的计量器

62649 93954123 ACCEPT tcp — * * 0.0.0.0/0 0.0.0.0/0 tcp spt:80←这是原先的规则 1

“93954123”规则 1 的计量器维持不变

由此可以发现, 传输量只会被纪录于单一计量器中, 也就是符合该联机的第一个规则才会统计其传输量