旁路由设置好后,手机、电脑连接主路由WIFI,会无法访问外网。
但是,如果电脑用网线连接主路由,则可以正常上网。
这究竟是怎么一回事儿呢?
旁路由: 旁路由其实并不是路由,路由是用来连接不同网络的,最常用的就是用来连接互联网和局域网。旁路由起到的主要是网关的作用,是用来分流数据和扩展插件的。因此,严谨一点的叫法应该是 旁路网关,只是大家好像约定俗成了都叫做旁路由,所以我们这里也跟着叫旁路由,但是要明白它的核心是网关而不是路由。
2. 网络流量示意图
如图所示,对于普通流量,由于旁路由不修改任何内容,我们期望旁路由只转发上行数据,而下行数据由主路由直接发送给主机。对于需要代理的流量,则下行数据也得交给旁路由处理,然后才能转发给主机。
正如标题所言,旁路由设置好后,手机、电脑连接主路由WIFI,会无法访问外网。如果你去搜索引擎搜索相关问题,大概率会得到这样的解决方案(甚至你搜到的配置教程就是这样教你):
修改旁路由的防火墙设置
进入【网络】-【防火墙】-【自定义规则】,在最后添加以下代码
iptables -t nat -I POSTROUTING -j MASQUERADE
这条规则不难理解,就是对转发的数据包进行NAT处理。
这样做的确可以解决无法上网问题,但很多文章都是照猫画虎,胡乱复制粘贴,没有讲清楚为什么。其实,这种方案不是最优的网络结构,这会导致即使是普通流量也进行NAT处理,而且上行流量、下行流量都要经过旁路由,还多两次NAT。
注1:问题在主路由身上,而不是旁路由。
注2:不是所有路由器都有此问题,取决于固件及其配置参数。
我们常用的无线路由器,其无线局域网和以太网部分是由内核虚拟网桥来进行桥接的,而路由器启用了bridge的数据走iotables,因此,即使是同一 zone 的数据转发,如果是经过虚拟网桥的,也会由 iptables 进行处理,而 iptables 能够对数据包进行状态记录(ctstate),且同一数据包只会经过nat表一次,因为旁路由转发过来的数据包没有任何改动,主路由会发现此数据包已经 经过nat表了,便不再进行nat,转发到外网去了,此时数据包源地址还是192.168.31.xxx,自然收不到回复了。
举例描述一下普通流量数据包路径(PC 无线连接主路由):
主机发送一个数据分组(源ip:192.168.31.123,目标:220.181.38.251)->
主路由AP -> 主路由 虚拟网桥 -> 主路由 iptables 防火墙 (虽然经过nat表,但由于是br-lan之间转发,最终并没有修改源ip)-> 主路由 以太网交换机 ->
旁路由(普通流量,无任何修改,直接原封不动发给网关主路由)->
主路由 以太网交换机 -> 主路由 iptables 防火墙(这回没有经过虚拟网桥,但是属于lan->wan不同区域转发,所以也要经过iptables,因为有状态记录,可以识别到此数据包之前经过一次nat表,于是不再进行nat) -> 主路由转发至wan区域(此时数据包源ip还是 192.168.31.123)-> internet ->
服务器(220.181.38.251) -> 找不到 192.168.31.123
如果PC是有线连接主路由,则数据包不会经过bridge,由交换机转发至旁路由,然后旁路由再转给主路由,主路由进行防火墙过滤时,就是第一次进入了,路由后,数据包源IP会被正确修改为主路由wan口 IP,因此网络连接正常。
5. 解决方法修改配置文件,要求iptables不对bridge的数据进行处理。
步骤如下:
- ssh 登陆主路由后台,ssh root@192.168.31.1
- 执行命令
echo 'net.bridge.bridge-nf-call-ip6tables=0' >> /etc/sysctl.conf echo 'net.bridge.bridge-nf-call-iptables=0' >> /etc/sysctl.conf echo 'net.bridge.bridge-nf-call-arptables=0' >> /etc/sysctl.conf sysctl -p /etc/sysctl.conf
CSDN -> OpenStack中的防火墙 By quqi99
恩山无线论坛 -> 旁路由设置 wifi无法上网 解决方案
百家号 -> 许迎果 第213期 openwrt旁路由模式设置教程



