下文提到的IP皆经过替换,不为真实IP,且为测试环境,仅作参考作用
问题现象
用户设置了IP白名单后,仍然连接不上MySQL Router
,telnet
发现无响应,但是实例运行正常,因此猜测大概率是防火墙的问题
问题定位
假设业务方IP为:10.66.66.120
业务方接入的Router
IP及端口为:10.17.65.219:6500
agent
代码如下:
ipRuleDport := "-m multiport --dport 6446,6447"
// mysql-router 使用docker端口映射, 走DOCKER-DY规则
rule = fmt.Sprintf("-I DOCKER-DY -s %s -p tcp %s -j RETURN\n", ip, ipRuleDport) // 问题修复前复制
该问题主要涉及到iptables
的
相关链:
基础链: PREROUTING
和FORWARD
链自定义链: DOCKER-DY
个DOCKER
其中PREROUTING
链和DOCKER
链中的相关规则由docker维护
DOCKER-DY
链的规则由我们维护,FORWARD
链的相关规则由其他部门在iptables更新时进行相应的调整
相关表:
nat filter
PREROUTING
查看raw
表和mangle
表中的所有规则
iptables -nL -t raw > raw.log
iptables -nL -t mangle > mangle.log复制
raw
表和mangle
表的规则都是空的我们先直接跳过
DOCKER链
iptables -nL -t nat > nat.log
复制
查看nat
表中的所有规则

数据包经过PREROUTING
链时,会先匹配nat
表的规则,命中图1中①处的规则

此时会进入到DOCKER
链中进行规制的匹配(该链的规则由docker daemon维护),与图2中划线处规则匹配,会进行DNAT
操作(端口映射),将数据包的destination
修改为172.80.0.4
(系统分配给docker的网段)
FORWARD
DOCKER-DY链 DOCKER链
接下来进入到FORWARD
链中,nat
表沒有FORWARD
的规则,我们看一下filter
表的FORWARD
规则


此时匹配到图3划线规则,并且将会跳转到filter
表中的DOCKER-DY
链中,

关键: 命中了图4划线规则后,会正常RETURN
回FORWARD
链,并回到图5处,继续往下匹配FORWARD
链的规则,而之前的业务中没有添加该规则,导致数据包被DROP

于是就顺利的进入到DOCKER
链,并成功匹配对应规则,因此数据包被转发到对应的应用程序上(也就是我们的Router
程序)
原因
原先的逻辑并未在DOCKER-DY
链中设置相应的规则,即没有在该链中设置destination
为Router
容器在docker内部IP的规则,导致不能正常匹配,最后被DROP
掉

解决
rule = fmt.Sprintf("-I DOCKER-DY -s %s -d %s -p tcp %s -j RETURN\n", ip, containerIP, ipRuleDport) // 问题修复后
复制
另外:
这些规则其实都可以放到基础链中,但是不方便管理,所以一般都会额外的设置自定义链来进行管理 在哪张表上设置规则取决于规则想要在哪条链上命中,例如实际上 PREROUTING
是不经过filter
表的,类似的情况得注意