iptables的一次修复日志

iptables的一次修复日志

搭建配置wireguard后,使用内网连接设备十分方便,我采用的是星型连接,即每个节点都连接到中心节点,但是突然发生了重启wg后中心节点不转发流量的问题,即每个接入的节点只能与中心节点连接,而节点与节点间无法连接。然而reboot重启中心节点机器后,wg内网却能正常工作。最后发现是iptables配置的问题。借此机会熟悉了iptables的逻辑。

1. 发现和解决问题

1.1 现象

当时中心节点上挂了 ipsec,wireguard,和docker等,当时也不知道是谁干的好事,我甚至不知道ipsec也写了这个表,最后锁定了问题出在FORWARD 链。具体是这样的
重启wireguard,复现了问题后,使用

sudo iptables -nvL

查看这个表,最后观察到这个表是这样的。

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
num   pkts bytes target     prot opt in     out     source               destination         
1     195K   51M DOCKER-USER  0    --  *      *       0.0.0.0/0            0.0.0.0/0           
2     195K   51M DOCKER-ISOLATION-STAGE-1  0    --  *      *       0.0.0.0/0            0.0.0.0/0           
3        0     0 ACCEPT     0    --  *      docker0  0.0.0.0/0            0.0.0.0/0            ctstate RELATED,ESTABLISHED
4        0     0 DOCKER     0    --  *      docker0  0.0.0.0/0            0.0.0.0/0           
5        0     0 ACCEPT     0    --  docker0 !docker0  0.0.0.0/0            0.0.0.0/0           
6        0     0 ACCEPT     0    --  docker0 docker0  0.0.0.0/0            0.0.0.0/0           
7       20   800 DROP       0    --  *      *       0.0.0.0/0            0.0.0.0/0            ctstate INVALID
8        0     0 ACCEPT     0    --  eth0   ppp+    0.0.0.0/0            0.0.0.0/0            ctstate RELATED,ESTABLISHED
9        0     0 ACCEPT     0    --  ppp+   eth0    0.0.0.0/0            0.0.0.0/0           
10       0     0 ACCEPT     0    --  ppp+   ppp+    0.0.0.0/0            0.0.0.0/0           
11       0     0 ACCEPT     0    --  eth0   *       0.0.0.0/0            192.168.43.0/24      ctstate RELATED,ESTABLISHED
12       0     0 ACCEPT     0    --  *      eth0    192.168.43.0/24      0.0.0.0/0           
13       0     0 ACCEPT     0    --  *      ppp+    192.168.43.0/24      0.0.0.0/0           
14       0     0 ACCEPT     0    --  wg2    *       0.0.0.0/0            0.0.0.0/0           
15       0     0 ACCEPT     0    --  *      wg2     0.0.0.0/0            0.0.0.0/0           
16     393 26860 DROP       0    --  *      *       0.0.0.0/0            0.0.0.0/0           
17       0     0 ACCEPT     0    --  wg2    *       0.0.0.0/0            0.0.0.0/0           
18       0     0 ACCEPT     0    --  *      wg2     0.0.0.0/0            0.0.0.0/0           
19       0     0 ACCEPT     0    --  wg0    *       0.0.0.0/0            0.0.0.0/0           
20       0     0 ACCEPT     0    --  *      wg0     0.0.0.0/0            0.0.0.0/0           
21       0     0 ACCEPT     0    --  wg0    *       0.0.0.0/0            0.0.0.0/0           
22       0     0 ACCEPT     0    --  *      wg0     0.0.0.0/0            0.0.0.0/0           

流量从上往下匹配,在匹配到wg0的规则前,匹配到了DROP,卒。
然后reboot重启了机器,FORWARD链变成了这样

1      491  106K DOCKER-USER  0    --  *      *       0.0.0.0/0            0.0.0.0/0           
2      491  106K DOCKER-ISOLATION-STAGE-1  0    --  *      *       0.0.0.0/0            0.0.0.0/0           
3        0     0 ACCEPT     0    --  *      docker0  0.0.0.0/0            0.0.0.0/0            ctstate RELATED,ESTABLISHED
4        0     0 DOCKER     0    --  *      docker0  0.0.0.0/0            0.0.0.0/0           
5        0     0 ACCEPT     0    --  docker0 !docker0  0.0.0.0/0            0.0.0.0/0           
6        0     0 ACCEPT     0    --  docker0 docker0  0.0.0.0/0            0.0.0.0/0           
7        0     0 DROP       0    --  *      *       0.0.0.0/0            0.0.0.0/0            ctstate INVALID
8        0     0 ACCEPT     0    --  eth0   ppp+    0.0.0.0/0            0.0.0.0/0            ctstate RELATED,ESTABLISHED
9        0     0 ACCEPT     0    --  ppp+   eth0    0.0.0.0/0            0.0.0.0/0           
10       0     0 ACCEPT     0    --  ppp+   ppp+    0.0.0.0/0            0.0.0.0/0           
11       0     0 ACCEPT     0    --  eth0   *       0.0.0.0/0            192.168.43.0/24      ctstate RELATED,ESTABLISHED
12       0     0 ACCEPT     0    --  *      eth0    192.168.43.0/24      0.0.0.0/0           
13       0     0 ACCEPT     0    --  *      ppp+    192.168.43.0/24      0.0.0.0/0           
14       0     0 ACCEPT     0    --  wg2    *       0.0.0.0/0            0.0.0.0/0           
15       0     0 ACCEPT     0    --  *      wg2     0.0.0.0/0            0.0.0.0/0           
16     491  106K ACCEPT     0    --  wg0    *       0.0.0.0/0            0.0.0.0/0           
17       0     0 ACCEPT     0    --  *      wg0     0.0.0.0/0            0.0.0.0/0           
18       0     0 DROP       0    --  *      *       0.0.0.0/0            0.0.0.0/0           
19       0     0 ACCEPT     0    --  wg2    *       0.0.0.0/0            0.0.0.0/0           
20       0     0 ACCEPT     0    --  *      wg2     0.0.0.0/0            0.0.0.0/0           
21       0     0 ACCEPT     0    --  wg0    *       0.0.0.0/0            0.0.0.0/0           
22       0     0 ACCEPT     0    --  *      wg0     0.0.0.0/0            0.0.0.0/0                

因为有wg0的规则出现在了DROP之前,所以流量成功的走了出来。

1.2 补充知识点

iptables中的-A和-I,一个是Insert,一个是Append,Insert会直接插在链规则的最前边,Append则是会直接插在最后边。

1.3 解决问题

看了下wg0.conf是怎么写的

Address = **.**.**.1/24
PrivateKey = *******************************************=
PostUp   = iptables -A FORWARD -i %i -j ACCEPT; iptables -A FORWARD -o %i -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -D FORWARD -o %i -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE

[Peer]
publickey = *******************************************=
AllowedIPs = **.**.**.2/32

[Peer]
publickey = *******************************************=
AllowedIPs = **.**.**.3/32

[Peer]
publickey = *******************************************=
AllowedIPs = **.**.**.4/32

[Peer]
publickey =  *******************************************=
AllowedIPs = **.**.**.5/32

... ...

其中的PostUp和PostDown被执行,-A 指定了规则append到该表该链的所有规则的后边。
所以reboot重启机器的时候,由于DROP最后才被append加进来,而wireguard的规则先append进来了,所以从上往下执行。就没事。
然而此后重启wireguard,由于重新append时append到了DROP后边,所以该规则没能先于DROP被执行
所以只要重启的时候使用Insert而不是Append就解决了,即把PostUP中的"-A"换成"-I",即

PostUp   = iptables -I FORWARD -i %i -j ACCEPT; iptables -I FORWARD -o %i -j ACCEPT; iptables -t nat -I POSTROUTING -o eth0 -j MASQUERADE

问题就解决了。

2. 问题的解释

关于wg0的规则并排的0有两条,一条是in * out wg0 ,一条是in wg0 out *,它们是冗余的,因为有路由表保证了只有来自wg0的流量才会到wg0。

3.排查docker和ipsec

缺德的DROP是谁添加的呢?为了观察这一点,首先引入了两条工具

3.1 工具

iptables的注释
语法是

iptables -m comment --comment "My comments here"

具体使用案例(直接写在wg0.conf里)

PostUp   = iptables -I FORWARD -i %i -m comment --comment "Added in wg0.conf" -j ACCEPT; iptables -I FORWARD -o %i -m comment --comment "Added in wg0.conf" -j ACCEPT; iptables -t nat -I POSTROUTING -o eth0 -j MASQUERADE

这样就可以在打印iptables表的时候看到注释。

sudo iptables -nvL
 4270  203K ACCEPT     0    --  *      wg0     0.0.0.0/0            0.0.0.0/0            /* Added in wg0.conf */
    0     0 ACCEPT     0    --  wg0    *       0.0.0.0/0            0.0.0.0/0            /* Added in wg0.conf */

TRACE功能
执行以下命令

iptables -t raw -I PREROUTING -d **.**.**.70 -j TRACE

在raw表的PREROUTING链中添加这条规则,
这样在到**.**.**.70的流量如何通过的iptables就可以观察了。观察的方法是执行以下命令

sudo xtables-monitor -t

事后我看到的是这样的情况

PACKET: 2 31ae5dec IN=wg0 SRC=11.11.11.20 DST=11.11.11.70 LEN=60 TOS=0x0 TTL=128 ID=59853
 TRACE: 2 31ae5dec raw:PREROUTING:rule:0x2:CONTINUE  -4 -t raw -A PREROUTING -d 11.11.11.70/32 -j TRACE
 TRACE: 2 31ae5dec raw:PREROUTING:return:
 TRACE: 2 31ae5dec raw:PREROUTING:policy:ACCEPT
 TRACE: 2 31ae5dec nat:PREROUTING:return:
 TRACE: 2 31ae5dec nat:PREROUTING:policy:ACCEPT
PACKET: 2 31ae5dec IN=wg0 OUT=wg0 SRC=11.11.11.20 DST=11.11.11.70 LEN=60 TOS=0x0 TTL=127 ID=59853
 TRACE: 2 31ae5dec filter:FORWARD:rule:0x25:ACCEPT  -4 -t filter -A FORWARD -o wg0 -m comment --comment "Added in wg0.conf" -j ACCEPT
 TRACE: 2 31ae5dec nat:POSTROUTING:return:
 TRACE: 2 31ae5dec nat:POSTROUTING:policy:ACCEPT
PACKET: 2 510f38f9 IN=wg0 SRC=11.11.11.20 DST=11.11.11.70 LEN=60 TOS=0x0 TTL=128 ID=59854
 TRACE: 2 510f38f9 raw:PREROUTING:rule:0x2:CONTINUE  -4 -t raw -A PREROUTING -d 11.11.11.70/32 -j TRACE
 TRACE: 2 510f38f9 raw:PREROUTING:return:
 TRACE: 2 510f38f9 raw:PREROUTING:policy:ACCEPT
PACKET: 2 510f38f9 IN=wg0 OUT=wg0 SRC=11.11.11.20 DST=11.11.11.70 LEN=60 TOS=0x0 TTL=127 ID=59854
 TRACE: 2 510f38f9 filter:FORWARD:rule:0x25:ACCEPT  -4 -t filter -A FORWARD -o wg0 -m comment --comment "Added in wg0.conf" -j ACCEPT
PACKET: 2 47202071 IN=wg0 SRC=11.11.11.20 DST=11.11.11.70 LEN=60 TOS=0x0 TTL=128 ID=59855
 TRACE: 2 47202071 raw:PREROUTING:rule:0x2:CONTINUE  -4 -t raw -A PREROUTING -d 11.11.11.70/32 -j TRACE
 TRACE: 2 47202071 raw:PREROUTING:return:
 TRACE: 2 47202071 raw:PREROUTING:policy:ACCEPT
PACKET: 2 47202071 IN=wg0 OUT=wg0 SRC=11.11.11.20 DST=11.11.11.70 LEN=60 TOS=0x0 TTL=127 ID=59855
 TRACE: 2 47202071 filter:FORWARD:rule:0x25:ACCEPT  -4 -t filter -A FORWARD -o wg0 -m comment --comment "Added in wg0.conf" -j ACCEPT
PACKET: 2 47202071 IN=wg0 SRC=11.11.11.20 DST=11.11.11.70 LEN=60 TOS=0x0 TTL=128 ID=59856
 TRACE: 2 47202071 raw:PREROUTING:rule:0x2:CONTINUE  -4 -t raw -A PREROUTING -d 11.11.11.70/32 -j TRACE
 TRACE: 2 47202071 raw:PREROUTING:return:
 TRACE: 2 47202071 raw:PREROUTING:policy:ACCEPT
PACKET: 2 47202071 IN=wg0 OUT=wg0 SRC=11.11.11.20 DST=11.11.11.70 LEN=60 TOS=0x0 TTL=127 ID=59856
 TRACE: 2 47202071 filter:FORWARD:rule:0x25:ACCEPT  -4 -t filter -A FORWARD -o wg0 -m comment --comment "Added in wg0.conf" -j ACCEPT

当时的情况是

PACKET: 2 831e9d23 IN=wg0 SRC=11.11.11.20 DST=11.11.11.70 LEN=60 TOS=0x0 TTL=128 ID=59207 
TRACE: 2 831e9d23 raw:PREROUTING:rule:0x2:CONTINUE  -4 -t raw -A PREROUTING -d 11.11.11.70/32 -j TRACE
TRACE: 2 831e9d23 raw:PREROUTING:return:
TRACE: 2 831e9d23 raw:PREROUTING:policy:ACCEPT 
TRACE: 2 831e9d23 nat:PREROUTING:return:
TRACE: 2 831e9d23 nat:PREROUTING:policy:ACCEPT 
PACKET: 2 831e9d23 IN=wg0 OUT=wg0 SRC=11.11.11.20 DST=11.11.11.70 LEN=60 TOS=0x0 TTL=127 ID=59207 
TRACE: 2 831e9d23 filter:FORWARD:rule:0x36:JUMP:DOCKER-USER  -4 -t filter -A FORWARD -j DOCKER-USER
TRACE: 2 831e9d23 filter:DOCKER-USER:return:
TRACE: 2 831e9d23 filter:FORWARD:rule:0x33:JUMP:DOCKER-ISOLATION-STAGE-1  -4 -t filter -A FORWARD -j DOCKER-ISOLATION-STAGE-1
TRACE: 2 831e9d23 filter:DOCKER-ISOLATION-STAGE-1:return:
TRACE: 2 831e9d23 filter:FORWARD:rule:0x1f:DROP  -4 -t filter -A FORWARD -j DROP

就是通过这个DROP发现的问题。

3.2 排查结果

其实上边的工具都没用上,最后发现是ipsec写的DROP,它还同时添加了两条wg0的规则,导致wg0的规则出现了四次。

它想做的是用一个DROP兜底,结果不幸的是我的wg规则append了在它后边。其实这个DROP应该写进policy。

由于iptables大家一起用,所以我感觉在最后append一个DROP这种行为其实本身就很不负责。调整了ipsec,结束维护。

4.iptables的三表五链

三表: nat,mangle,filter,(raw)
五链: PREROUTING,INPUT,FORWARD,OUTPUT,POSTROUTING
请添加图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值