Debugging Iptables

iptables 是个很有用的工具。可以可以方便的操纵包的走向,作为 ops 不可避免的需要了解如何 debug 一些问题。

首先肯定是需要对 iptables 的包在各个 table 和 chain 的走向需要有了解。这个随便一搜就有很多的图片,不过各个图可能还是有些许差别,另外有些理解起来没那么好懂。不过想要了解 iptables 还是需要硬着头皮去看看。

img:https://stuffphilwrites.com/wp-content/uploads/2014/09/FW-IDS-iptables-Flowchart-v2019-04-30-1.png

对于理解这些图,有一些 tips。

  1. iptables 有几个 table:raw,mangle,nat,filter,加上几个默认的 chain:PREROUTING,FORWARD,INPUT,OUTPUT,POSTROUTING。
  2. 各种图里面一般都是这几个东西的笛卡尔积,当然有的组合可能不存在,但是大致是这个意思。
  3. 一个 host 一般会有很多个网卡,简单区分开这些网卡为 lo 和其他。lo 的流量就是图里面 localhost 相关的。其他网卡的,就是都是外部的流量。例如 docker 会创建一些网卡,那么 docker container 里面的流量进入系统的时候也是外部流量。
  4. 所以并不是只有通过外网网卡进入的才是外部流量,即使本机也可以产生这样的流量。

这样就非常好理解了。一个 docker container 里面,需要访问外网的时候,可能需要经过如下的路径:container 内部自己的网卡,host 上面对应的网桥网卡,host 的外网网卡。这个过程里面,进入 host 上面对应的网桥网卡的时候就需要进入 host 的 raw PREROUTING 这个 chain 了。

需要 debug 一个规则的匹配情况的时候,可以在那条规则前面增加一条规则,使用 -J log --log-prefix xx 会把匹配情况记录到日志,一般是会记录的 syslog 里面。

如果需要追踪一个包的整体流向的时候,可以在 raw PREROUTING chain 增加一条 -J trace 的记录。这个会记录所有进入系统的包到 syslog 里面。要注意这个记录会非常多。

Feb  7 12:13:39 Host1 kernel: [4319670.459630] TRACE: filter:cali-pro-kns.sandbox:rule:1 IN=cali289ea3d6da9 OUT=ens5 MAC=ee:ee:ee:ee:ee:ee:a2:3a:07:e5:58:f3:08:00 SRC=10.42.87.16 DST=142.250.190.78 LEN=60 TOS=0x00 PREC=0x00 TTL=63 ID=17395 DF PROTO=TCP SPT=36738 DPT=80 SEQ=1138025950 ACK=0 WINDOW=35764 RES=0x00 SYN URGP=0 OPT (020422ED0402080AFCAC930C0000000001030309)

日志大概如上面,会记录经过的 table(filter)chain(cali-pro-kns.sandbox)和 rule(1 表示是第一条 rule)。IN 和 OUT 分别表示出入的网卡。OUT 一般是在经过 nat 表之后才会有。其他的就不多说了,有一个比较重要的 ID 需要注意,这个可以标记一个包。所以如果想看一个包的情况,可以根据 id 过滤下。把这些数据按照顺序整理到表格里面的话,就会更加清晰了。

我为了分析 iptables 的规则,还写了一个小工具 https://github.com/wd/iptables-parser.