环境
我的使用环境是有一台ROS主路由器负责PPPoE
拨号、DHCP
、端口转发等。WAN
口为公网IP,内网IP为10.0.0.1。
内网中设置了一台openWRT虚拟机作为旁路由,只有一个LAN
口连接到主路由,IP为10.0.0.2,网关指向10.0.0.1,开启了NAT转发,同时Clash也运行在这台虚拟机上。
然后内网中有一台运行Docker的CentOS虚拟机,IP为10.0.0.11
,网关为10.0.0.2
,开启了8888
,在主路由上设置端口映射,将公网8888
映射到10.0.0.11
的8888
。
现象
在Clash正常运行,openWRT正常工作的情况下,无法通过外网访问内网服务器,连接超时,同时Clash中没有任何日志记录。
关闭Clash,通过外网访问内网服务器正常
分析
外网进来的连接没有通过openWRT的PREROUTING
链,而是通过主路由(10.0.0.1
)的转发直接到了CentOS(10.0.0.11
)上。
当CentOS接收到连接命令之后,通过openWRT发出响应,这时连接进入到openWRT的PREROUTING
链,最终进入到了Clash中,但是这个TCP连接只有响应,Clash应该是丢弃了(瞎猜)。
解决方案
-
方法一:让外网进来的连接也通过openWRT的
PREROUTING
链。在主路由上做端口映射,将公网的8888
映射到openWRT的8888
,然后再在openWRT上将端口DNAT到CentOS主机的8888
端口上,让外网进来的连接也通过了Clash。 -
方法二: 保持之前的主路由映射规则,在openWRT中设置iptables规则,将CentOS发出的响应连接不通过Clash(根据源端口过滤,可以一次性设置多个端口(在8888后加
,
再加上端口号即可,例如8888,9999,1111
))iptables -t nat -I PREROUTING -p tcp -m multiport --sports 8888 -j RETURN
参考
开启clash后,由外网访问内网服务,无法建立连接,connection refused #432
【小知识】20分钟掌握iptables指令