Welcome to Snooda's Blog
iptables规则延迟生效/不生效问题-conntrack
[| 2021/07/21 20:04]
生产环境线上一般是不允许开启conntrack的,因为默认的连接跟踪表也就万级别,不小心打满后,容易导致很难排查的网络问题。(iptables -t nat只查看也会不知不觉启用conntrack)所以很多团队是规定禁止线上运行iptables的。 但是某些设备上,conntrack是必备的一项功能,比如网关,用来做防火墙、包转发等。 今天就遇到了一个很特殊的场景。。表现特征是iptables配的MASQUERADE看起来并不生效。有时不知怎么回事生效以后,删掉规则居然仍然能转发。。明明删除了规则,居然还能ping通,新增了规则,居然还转发到老的地方。。
后来研究了一下,发现原来对于iptables的nat表来讲,只有连接新建时,才会查表进行一次匹配。当连接被conntrack后,就不再走nat表匹配了。
对于icmp来讲,默认conntrack会保留30s,所以如果添加规则前30s如果ping了一下。那么添加完并不会生效已有的。。。。反之亦然。
可以使用conntrack -E作为验证手段。该命令会打印conntrack模块对连接的跟踪情况。
如果想手动移除映射关系,可以使用conntrack -D
后来研究了一下,发现原来对于iptables的nat表来讲,只有连接新建时,才会查表进行一次匹配。当连接被conntrack后,就不再走nat表匹配了。
对于icmp来讲,默认conntrack会保留30s,所以如果添加规则前30s如果ping了一下。那么添加完并不会生效已有的。。。。反之亦然。
可以使用conntrack -E作为验证手段。该命令会打印conntrack模块对连接的跟踪情况。
如果想手动移除映射关系,可以使用conntrack -D
openvpn不小心多开的挽救手段-iptables的使用
[| 2016/12/07 20:17]
今天写了一个自动拉起脚本,调试的时候出了点状况,导致启动了很多个openvpn实例,并且还在不断启动中。对于使用同证书的实例,默认会后面的踢掉前面的,所以网络就陷入了还没连上就被踢掉的循环,无法登陆,也就失去了控制。
首先尝试打开server端的duplicate-cn支持。这样每个连接都会分配到一个单独ip,不会互相踢掉。但由于进程太多,每个进程连接上后都试图刷新路由表,导致路由表不停变更,网络依然不能连通。
这时就需要从server端限制:只能有一个客户端连接上。首先调研了下是否支持只接受第一个连接上的实例而忽略掉后面的连接请求,发现是没有这个特性的。因为如果正常使用中客户网络闪断,这种情况下就不得不等待很久session超时后才能连上,用户体验太差。
对于网络层面的控制,iptables是个很有效的利器。于是采用了如下的方式:
1,首先设置DROP掉指定机器所有入包 iptables -I INPUT 1 -p udp -s xxx.xxx.xxx.xxx -j DROP
这时候所有连入请求都会timeout。
2,然后使用tcpdump host xxx.xxx.xxx.xxx
查看所有连入请求的来源端口,选取其中一个。
3,执行 iptables -I INPUT 1 -p udp -s xxx.xxx.xxx.xxx --source-port yyyyy -j ACCEPT
为这个实例单独开一个入口。
等待几秒,等待其重试连接,这时候只有这一个实例可以连入。成功恢复连接。
这里需要注意,第一步应使用DROP而不是REJECT,因为前者会让请求方重试的时间间隔更长一些,为后续操作赢得更多时间。
首先尝试打开server端的duplicate-cn支持。这样每个连接都会分配到一个单独ip,不会互相踢掉。但由于进程太多,每个进程连接上后都试图刷新路由表,导致路由表不停变更,网络依然不能连通。
这时就需要从server端限制:只能有一个客户端连接上。首先调研了下是否支持只接受第一个连接上的实例而忽略掉后面的连接请求,发现是没有这个特性的。因为如果正常使用中客户网络闪断,这种情况下就不得不等待很久session超时后才能连上,用户体验太差。
对于网络层面的控制,iptables是个很有效的利器。于是采用了如下的方式:
1,首先设置DROP掉指定机器所有入包 iptables -I INPUT 1 -p udp -s xxx.xxx.xxx.xxx -j DROP
这时候所有连入请求都会timeout。
2,然后使用tcpdump host xxx.xxx.xxx.xxx
查看所有连入请求的来源端口,选取其中一个。
3,执行 iptables -I INPUT 1 -p udp -s xxx.xxx.xxx.xxx --source-port yyyyy -j ACCEPT
为这个实例单独开一个入口。
等待几秒,等待其重试连接,这时候只有这一个实例可以连入。成功恢复连接。
这里需要注意,第一步应使用DROP而不是REJECT,因为前者会让请求方重试的时间间隔更长一些,为后续操作赢得更多时间。