同网段双DHCP服务器/路由器环境下端口转发失败的解决方案咨询
看起来你遇到了典型的不对称路由问题,这在同网段多网关的场景里很常见——当公网请求从Router A转发到交换机后,交换机却用Router B作为默认网关回包,Router B没有这个请求的会话记录,自然会丢弃流量;反过来也是一样的道理。我结合你用的MikroTik设备(RB5009和CRS354),给你几个可行的解决方案:
方案一:基于入接口的策略路由(交换机端配置)
这个思路是让交换机根据请求进来的接口,决定回包用哪个网关,完美匹配你的“响应请求来源”需求。
具体操作步骤:
- 先在交换机上创建两个专用路由表,分别对应两个路由器的网关:
ip route add dst-address=0.0.0.0/0 gateway=10.0.19.1 routing-table=via-router-a ip route add dst-address=0.0.0.0/0 gateway=10.0.19.2 routing-table=via-router-b
- 添加Mangle规则,标记从不同接口进来的流量,让它们走对应的路由表:
# 替换eth-router-a为交换机连接Router A的实际接口名 ip firewall mangle add chain=prerouting in-interface=eth-router-a action=mark-routing new-routing-mark=via-router-a # 替换eth-router-b为交换机连接Router B的实际接口名 ip firewall mangle add chain=prerouting in-interface=eth-router-b action=mark-routing new-routing-mark=via-router-b
这样一来,从Router A过来的请求会用Router A回包,从Router B过来的请求会用Router B回包,彻底解决不对称路由问题。
方案二:利用已配置的VRRP虚拟IP(推荐长期使用)
你提到已经配置了VRRP vIP(9.10.11.12),这其实是解决多网关问题最优雅的方案,不仅能解决端口转发的问题,还能实现网关冗余。
具体操作步骤:
- 把交换机的默认网关改成VRRP的虚拟IP
9.10.11.12,去掉之前手动添加的默认网关。 - 确保两个路由器的VRRP配置正确:
- 同一VRRP组ID
- 虚拟IP绑定在内网桥接接口上
- 优先级配置合理(比如Router A设为100,Router B设为90,让Router A作为主网关,Router B作为备份)
- 保持两个路由器上的DNAT规则不变,依然指向交换机的IP
10.0.19.20。
原理是:不管哪个路由器收到公网请求,DNAT到交换机后,交换机的回包都会发给VRRP虚拟IP,VRRP协议会自动把流量转发到对应的活动路由器,保证会话的对称性。
方案三:在路由器上配置针对性的SNAT
这个思路是让路由器在做DNAT的同时,把请求的源IP转换成自己的内网IP,这样交换机回包时会直接发给对应的路由器,而不会受默认网关影响。
具体操作步骤(以Router A为例):
在Router A上添加一条SNAT规则,针对转发到交换机的80端口流量:
# 替换bridge为Router A的内网桥接接口名 ip firewall nat add chain=srcnat dst-address=10.0.19.20 protocol=tcp dst-port=80 action=masquerade out-interface=bridge
然后在Router B上做同样的配置,把out-interface换成Router B的内网桥接接口即可。
为什么你之前的SNAT尝试没生效?
大概率是因为你的SNAT规则没有精准匹配到DNAT的流量,或者out-interface设置错误——必须指定内网桥接接口,才能只对转发到内网的流量生效。
总结
- 如果追求长期稳定和冗余能力,优先选方案二(VRRP);
- 如果不想改动网关配置,**方案一(策略路由)**最直接;
- 如果想快速验证效果,**方案三(SNAT)**可以快速见效。
备注:内容来源于stack exchange,提问作者DrLime2k10

