具体来说,需要在 mangle 表中标记外部进入的连接,并在 route 表中为这些连接创建一个专属的、指定了源IP和网关的路由,从而强制回程流量从正确的接口出去。
⚙️ 详细配置步骤
- 基础网络设置
确保所有WAN口已经正确配置了IP地址、网关,并确保网络通畅。 标记连接
进入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,重复此步骤。
- Chain:
标记路由
在同一个Mangle表中,创建规则,将上一步的“连接标记”转换为“路由标记”。- Chain:
output - Connection Mark: 选择上一步创建的标记名,例如
conn_public_ip_1 - Action:
mark routing - New Routing Mark: 为路由表起一个名字,例如
route_public_ip_1 - Passthrough:
no - 为其他公网IP,重复此步骤。
- Chain:
创建专属路由表
进入IP->Routes标签页,为每个公网IP创建一个新的路由表。- Dst. Address:
0.0.0.0/0(默认路由) - Gateway: 选择该公网IP对应的网关地址
- Routing Mark: 选择上一步创建的“路由标记”,例如
route_public_ip_1 - 为其他公网IP,重复此步骤。
- Dst. Address:
配置端口映射
最后,创建端口映射(dstnat)规则。- Chain:
dstnat - Dst. Address: 填写要映射的公网IP地址
- Protocol: 选择要映射的协议(如
tcp) - Dst. Port: 填写要映射的端口号
- Action:
dst-nat - To Addresses: 填写内网服务器的IP地址
- To Ports: 填写内网服务器的端口号
- Chain:
📝 完整配置脚本示例
假设你有两条线路,线路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⚠️ 注意事项
outputvsprerouting:标记路由时,必须使用output链而非prerouting,因为对于发往本地服务或内网的回包,路由决策在output链进行,标记必须作用在这里才能生效。- 关于 UDP 协议:在处理 UDP 流量时(例如 WireGuard),上述基于
connection-mark的方法可能偶尔失效。建议改用IP->Routing->Rules创建基于源地址的策略,或者在防火墙中增加对 UDP 协议的专门处理规则。 src-natvsmasquerade:多个公网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链标记,同样有效。