旁路由开启Clash,外网访问内网服务无法建立连接(connection refused)

旁路由开启Clash,外网访问内网服务无法建立连接(connection refused)

LonelyMan 4649 2023-02-16

环境

我的使用环境是有一台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.118888

现象

在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指令