玩路由器 · 2023年11月23日 0

RouterOS 在多个上游情况下正确设置返回包的默认路由(转载)

转载来源:点我

应用场景:

一:RouterOS 接了多个上游,都是静态IP并且有 NAT(masquerade)配置。默认情况下,如果在非默认路由的上游 IP 上开了端口转发到内网,内网设备返回包的时候会直接从默认路由出去,从而要么被路由器的 reverse path filter 丢掉,要么在出口处被 masquerade 从而导致对面收到的包源 IP 错误而丢包。下面简述一个方法,让返回包从正确的出口返回。

二:用 VRF 接了管理网,想从 VRF 访问本机的 WinBox 或者 SSH 。数据包是能从 VRF 网络正确到达本机的;但是从本机返回包时,默认只会查 main 路由表。你当然可以简单地把 VRF 网的路由或静态或动态 leak 进 main,但是这样就失去了隔离管理网的功能。因此,我们可以用类似的方法来实现通过 VRF 访问本机。

关闭 Fasttrack

Fasttrack 功能和整个 mangle 表以及依赖它的所有功能( ip rule,VRF,routing-mark 等)冲突。最多只能给没有 connection mark 的开一下:

/ip firewall filter
add action=fasttrack-connection chain=forward connection-mark=no-mark connection-state=established,related

同理,其它几个 chain 上的 fasttrack 如果涉及到相应功能也需要关闭。

关闭Reverse Path Filter

RP filter 如果设置成 strict ,那么返回的数据包如果不是从默认路由回去就会被丢掉。所以要把 RP filter 设置成 loose 或者 no 。

/ip settings set rp-filter=loose 

打开Conntrack

/ip firewall connection tracking set enabled=yes

设置分运营商路由表

对每个上游分别建立一个路由表(即 connection mark ),给这个路由表设置一条默认路由( distance 或者 metrics 统一即可;如果你是想用 VRF 访问本机,那么不需要默认路由),并且用 ip rule 功能把 main 路由表优先级提到自己的路由表之前,以便 connected 路由能够正确查询到:

/ip route
add check-gateway=ping distance=1 gateway=<isp1-gateway-ip> routing-mark=isp1
/ip route rule
add routing-mark=isp1 table=main
add routing-mark=isp1 table=isp1

注意,这里main路由表就不允许有默认路由了,否则分上游路由表的路由是不会生效的。

如果你的上游运营商使用 DHCP 或者别的路由协议分发路由表,导致默认路由是动态生成的,那么可以把这个接口直接放进 VRF 里面来实现相同的配置:

/ip route vrf
add route-distinguisher=100:200 export-route-targets=100:200 import-route-targets=100:200 interfaces=<isp2-interface> routing-mark=isp2
/ip dhcp-client
add interface=<isp2-interface> use-peer-dns=no use-peer-ntp=no
/ip route rule
add routing-mark=isp2 table=main
add routing-mark=isp2 table=isp2

如果默认路由使用路由协议分发,路由协议一般有自己的VRF配置选项,也需要设置成对应的VRF。

设置主路由表

下游设备默认会走 main 路由表,我们要在 main 路由表之后接上分运营商路由表,这样下游设备就有默认路由了。这里的顺序就相当于默认路由的 fallback 顺序,优先级高的在前:

/ip route rule
add table=main
add table=isp1
add table=isp2

给进站方向连接打标签

对每个上游,在连接从上游接口进来的时候用 conntrack 打上 connection mark ,数据返回的时候根据 connection mark 设置对应的 routing mark ,这样返回包才能走正确的接口出去:

/ip firewall mangle
add action=mark-connection chain=input in-interface=<isp1-interface> connection-mark=no-mark new-connection-mark=isp1
add action=mark-routing chain=output connection-mark=isp1 new-routing-mark=isp1
add action=mark-connection chain=forward connection-state=new in-interface=<isp1-interface> connection-mark=no-mark new-connection-mark=isp1
add action=mark-routing chain=prerouting connection-mark=isp1 new-routing-mark=isp1

如果你是想用 VRF 访问本机,那么所有在该 VRF 的端口作为一个运营商处理即可,匹配规则可以用 interface list 实现。

设置端口转发

如果需要做端口转发或者 DMZ,可以直接写一条 destination NAT 规则(如果下游设备是对称路由的话,即使跨三层也不需要 source NAT ),类似这样:

/ip firewall nat
add action=dst-nat chain=dstnat in-interface-list=<WAN-interface> dst-port=<WAN-port> protocol=tcp to-addresses=<LAN-IP> to-ports=<LAN-port>

参考: