具体来说,需要在 mangle 表中标记外部进入的连接,并在 route 表中为这些连接创建一个专属的、指定了源IP和网关的路由,从而强制回程流量从正确的接口出去。

⚙️ 详细配置步骤

  1. 基础网络设置
    确保所有WAN口已经正确配置了IP地址、网关,并确保网络通畅。
  2. 标记连接
    进入 IP -> Firewall -> Mangle 标签页,为从每个公网IP进入的连接打上“连接标记”。

    • Chain: prerouting
    • Src. Address: 留空(或填写特定公网IP)
    • Dst. Address: 填写你要映射的公网IP地址,子网掩码为 /32
    • In. Interface: 选择该公网IP所在的物理接口(如 ether1
    • Action: mark connection
    • New Connection Mark: 为这个连接起一个名字,例如 conn_public_ip_1
    • Passthrough: yes(必须选“是”,让标记继续传递)
    • 为其他公网IP,重复此步骤。
  3. 标记路由
    在同一个 Mangle 表中,创建规则,将上一步的“连接标记”转换为“路由标记”。

    • Chain: output
    • Connection Mark: 选择上一步创建的标记名,例如 conn_public_ip_1
    • Action: mark routing
    • New Routing Mark: 为路由表起一个名字,例如 route_public_ip_1
    • Passthrough: no
    • 为其他公网IP,重复此步骤。
  4. 创建专属路由表
    进入 IP -> Routes 标签页,为每个公网IP创建一个新的路由表。

    • Dst. Address: 0.0.0.0/0(默认路由)
    • Gateway: 选择该公网IP对应的网关地址
    • Routing Mark: 选择上一步创建的“路由标记”,例如 route_public_ip_1
    • 为其他公网IP,重复此步骤。
  5. 配置端口映射
    最后,创建端口映射(dstnat)规则。

    • Chain: dstnat
    • Dst. Address: 填写要映射的公网IP地址
    • Protocol: 选择要映射的协议(如 tcp
    • Dst. Port: 填写要映射的端口号
    • Action: dst-nat
    • To Addresses: 填写内网服务器的IP地址
    • To Ports: 填写内网服务器的端口号

📝 完整配置脚本示例

假设你有两条线路,线路A的接口是ether1,IP为203.0.113.1,网关203.0.113.254;线路B的接口是ether2,IP为198.51.100.1,网关198.51.100.254。你想把内网192.168.1.100的80端口分别映射到这两个公网IP的80端口上。

你可以在New Terminal中执行以下脚本:

# --- 1. 标记连接 (Mangle) ---
/ip firewall mangle add chain=prerouting dst-address=203.0.113.1 in-interface=ether1 action=mark-connection new-connection-mark=conn_lineA passthrough=yes
/ip firewall mangle add chain=prerouting dst-address=198.51.100.1 in-interface=ether2 action=mark-connection new-connection-mark=conn_lineB passthrough=yes

# --- 2. 标记路由 (Mangle) ---
/ip firewall mangle add chain=output connection-mark=conn_lineA action=mark-routing new-routing-mark=route_lineA passthrough=no
/ip firewall mangle add chain=output connection-mark=conn_lineB action=mark-routing new-routing-mark=route_lineB passthrough=no

# --- 3. 创建策略路由 (Routes) ---
/ip route add dst-address=0.0.0.0/0 gateway=203.0.113.254 routing-mark=route_lineA
/ip route add dst-address=0.0.0.0/0 gateway=198.51.100.254 routing-mark=route_lineB

# --- 4. 端口映射 (NAT) ---
/ip firewall nat add chain=dstnat dst-address=203.0.113.1 protocol=tcp dst-port=80 action=dst-nat to-addresses=192.168.1.100 to-ports=80
/ip firewall nat add chain=dstnat dst-address=198.51.100.1 protocol=tcp dst-port=80 action=dst-nat to-addresses=192.168.1.100 to-ports=80

# --- 5. 配置回程源地址转换 (SRCNAT) ---
/ip firewall nat add chain=srcnat out-interface=ether1 action=src-nat to-addresses=203.0.113.1
/ip firewall nat add chain=srcnat out-interface=ether2 action=src-nat to-addresses=198.51.100.1

⚠️ 注意事项

  • output vs prerouting:标记路由时,必须使用output链而非prerouting,因为对于发往本地服务或内网的回包,路由决策在output链进行,标记必须作用在这里才能生效。
  • 关于 UDP 协议:在处理 UDP 流量时(例如 WireGuard),上述基于 connection-mark 的方法可能偶尔失效。建议改用 IP -> Routing -> Rules 创建基于源地址的策略,或者在防火墙中增加对 UDP 协议的专门处理规则。
  • src-nat vs masquerade:多个公网IP时,必须使用明确的 action=src-nat 并指定 to-addresses,不能使用 masquerade,否则路由器会错误地使用主接口IP发出回程流量。
  • 简化配置:如果你的公网IP是直接配置在WAN接口上的(如静态IP),可以创建更简洁的规则,例如:

    /ip firewall mangle add chain=input in-interface=ether1 action=mark-connection new-connection-mark=conn_lineA passthrough=yes
    /ip firewall mangle add chain=output connection-mark=conn_lineA action=mark-routing new-routing-mark=route_lineA passthrough=no
    /ip route add gateway=203.0.113.254 routing-mark=route_lineA

    此方法利用 input 链标记,同样有效。

最后修改:2026 年 04 月 18 日
如果觉得我的文章对你有用,请随意赞赏