blog

用 RouterOS 将访问外网某端口/地址的请求重定向到内网机器

为了将访问外网端口(假设是 1688)的所有请求都重定向到内网的某台机器,今天足足折腾了一整天。所幸终于搞定了。

目标

假设外网有多个服务,都运行在端口 1688 上,而我内网能够模拟这个服务,运行在 192.168.0.14 上,端口也是 1688,那么我希望所有访问外网服务的请求都重定向回内网,提高访问速度,应该怎么做呢?

目标

步骤

  1. 要重定向访问,首先得将请求包的 dst-address 重写为 192.168.0.14。使用 dst-nat 就可以重写包的目标地址
/ip firewall nat
add chain=dstnat dst-address=!192.168.0.0/24 protocol=tcp dst-port=1688 \
  action=dst-nat to-address=192.168.0.14

包改变情况如下:

192.168.0.2 > 8.8.8.8   --->  192.168.0.2 > 192.168.0.14

8.8.8.8 的目标地址信息丢失了。 (并没有丢失,信息还保存在路由器中,这是之前的误解。)

  1. 重写目标地址之后,笔记本发的包能顺利到达 0.14 了,但这里有个问题,就是 0.14 回应的包直接发给 0.2 了,因为它们在同一个内网,包不需要经过路由器。但 0.2 并不知道它的包已经给了 0.14,它还在等待 8.8.8.8 的包。当 0.14 的包到了之后,不是它等待的包,直接就被它抛弃了。
192.168.0.14 > 192.168.0.2 ---> 废弃   #此路不通
  1. 怎么办呢?为了能够让回复的包的源地址能顺利写回 8.8.8.8,就要将出口到 lan 的包也做一次 masquerade/srcnat ,这样它在离开路由器去 0.14 的时候,源地址会变成 0.1,回来的包也会经过路由,再由之前保存的连接信息将源地址变回 8.8.8.8
/ip firewall nat
add chain=srcnat src-address=192.168.0.0/24 \
  dst-address=192.168.0.14 protocol=tcp dst-port=1688 \
  out-interface=lan action=masquerade

包改变情况如下:

192.168.0.2 > 8.8.8.8   --->  192.168.0.1 > 192.168.0.14
192.168.0.14 > 192.168.0.1   --->  8.8.8.8 > 192.168.0.2

这样包就能够顺利来回了。

参考

Hairpin NAT