RouterOS 网络配置:Hairpin NAT 原理与实战指南

AI 辅助润色:本文的核心思想与初稿均由作者独立完成,后期借助人工智能进行了语言润色与排版优化。

发表于 2026年04月10日 16:12

一、前言

很多 RouterOS(ROS)玩家在搭建家庭网络或工作室机房时,经常会遇到一个问题:明明已经配置好了外网端口映射(Port Forwarding),用手机的流量访问自己的公网域名时一切正常;可一旦连上家里的内网 WiFi,再去访问同一个域名,网页却一直在转圈圈,怎么也打不开。

“诶,为什么外网能访问,内网反倒访问不了自己的公网域名呢?”

遇到这种情况,千万别怀疑是自己的端口映射做错了。这其实是因为路由器默认不知道该如何处理这种“从内网发往自己公网 IP,又要折返回内网”的数据包。为了解决这个痛点,我们需要配置 ​Hairpin NAT(回环 NAT / 发卡 NAT)

二、Hairpin NAT(回环NAT)原理

Hairpin 网络地址转换(Hairpin NAT,又称 NAT 回环 / NAT Loopback)是指局域网(LAN)上的设备可以通过网关路由器的公网 IP 地址访问同一局域网上的另一台机器。

基础 NAT 网络拓扑结构,展示了办公区客户端、服务器、网关和外部家庭用户的 IP 分配与连接状态
基础 NAT 网络拓扑结构,展示了办公区客户端、服务器、网关和外部家庭用户的 IP 分配与连接状态

2.1 外部访问示例

在上述示例中,网关路由器配置了以下 dst-nat(目标地址转换)规则:

/ip firewall nat add chain=dstnat action=dst-nat dst-address=172.16.16.1 dst-port=443 to-addresses=10.0.0.3 to-ports=443 protocol=tcp

当用户从家里的 PC 与 Web 服务器建立连接时,路由器会按照配置执行目标地址转换(DST NAT):

  1. 客户端发送一个数据包,源 IP 地址为 192.168.88.1,目标 IP 地址为 172.16.16.1,端口为 443,以请求某些 Web 资源;
  2. 路由器对该数据包进行目标地址转换(DST NAT),将其指向 10.0.0.3,并相应地替换数据包中的目标 IP 地址。源 IP 地址保持不变,仍为 192.168.88.1;
  3. 服务器对客户端的请求作出响应,回复的数据包中源 IP 地址为 10.0.0.3,目标 IP 地址为 192.168.88.1;
  4. 路由器判定该数据包属于先前的连接,从而撤销目标地址转换,将原始的目标 IP 地址填入源 IP 地址字段。此时,目标 IP 地址为 192.168.88.1,源 IP 地址为 172.16.16.1;
  5. 客户端收到了它所期望的回复数据包,连接成功建立。

内部访问出现问题的流量路径图,红线展示了服务器直接向同网段客户端回复数据包从而导致连接被丢弃的过程
内部访问出现问题的流量路径图,红线展示了服务器直接向同网段客户端回复数据包从而导致连接被丢弃的过程

2.2 内部访问的问题

但是,当与 Web 服务器处于同一网络的客户端请求连接 Web 服务器的公网 IP 地址时,就会出现问题

  1. 客户端发送一个数据包,源 IP 地址为 10.0.0.2,目标 IP 地址为 172.16.16.1,端口为 443,以请求某些 Web 资源;
  2. 路由器对该数据包进行目标地址转换,将其指向 10.0.0.3,并相应地替换数据包中的目标 IP 地址。源 IP 地址保持不变,仍为 10.0.0.2;
  3. 服务器对客户端的请求作出响应。然而,由于请求的源 IP 地址与 Web 服务器位于同一子网中,Web 服务器不会将回复发回给路由器,而是直接发回给 10.0.0.2,该回复数据包的源 IP 地址为 10.0.0.3;
  4. 客户端收到了回复数据包,但会将其丢弃,因为它期望收到的是来自 172.16.16.1 的数据包,而不是来自 10.0.0.3 的数据包。

2.3 解决方案:配置 Hairpin NAT 规则

为了解决这个问题,我们需要配置一条新的 src-nat(源地址转换)规则(即Hairpin NAT 规则),如下所示:

/ip firewall nat add action=masquerade chain=srcnat dst-address=10.0.0.3 out-interface=LAN protocol=tcp src-address=10.0.0.0/24

配置上述规则后,流程如下:

  1. 客户端发送一个数据包,源 IP 地址为 10.0.0.2,目标 IP 地址为 172.16.16.1,端口为 443,以请求某些 Web 资源;
  2. 路由器对该数据包进行目标地址转换(DST NAT),将其指向 10.0.0.3,并相应地替换数据包中的目标 IP 地址。同时,它还会对该数据包进行源地址转换(SRC NAT),将数据包中的源 IP 地址替换为其 LAN 接口的 IP 地址。此时,目标 IP 地址为 10.0.0.3,源 IP 地址为 10.0.0.1;
  3. Web 服务器对请求作出响应,并将源 IP 地址为 10.0.0.3 的回复数据包发送回路由器的 LAN 接口 IP 地址 10.0.0.1;
  4. 路由器判定该数据包属于先前的连接,从而同时撤销源地址和目标地址转换,将原始的目标 IP 地址 10.0.0.3 填入源 IP 地址字段,并将原始的源 IP 地址 172.16.16.1 填入目标 IP 地址字段。

三、PPPoE 动态公网Hairpin NAT 配置指南

注意:在配置 Hairpin NAT 之前,请确保你已经成功配置好了常规的端口映射(dst-nat),即外网已经可以通过公网 IP 正常访问你的内网服务。

3.1 添加内网、外网 地址列表(Address Lists)

3.1.1 添加内网地址

/ip firewall address-list
add address=192.168.12.0/24 list=LANs

添加内网地址
添加内网地址

3.1.2 配置 PPPoE Profile 自动更新外网地址

为了应对 PPPoE 动态拨号 IP 变化的问题,我们需要在 /ppp profile​ 中新建(或修改)一个配置文件,利用 On Up​ 和 On Down​ 脚本自动将当前的公网 IP 同步到 WANs 地址列表中。

On Up 脚本(拨号成功时执行):

:local Name [/interface pppoe-client get $interface name]
/ip firewall address-list remove [find where list=WANs comment=$Name]
/ip firewall address-list add list=WANs address=$"local-address" comment=$Name

On Down 脚本(断开拨号时执行):

:local Name [/interface pppoe-client get $interface name]
/ip firewall address-list remove [find where list=WANs comment=$Name]

PPPoE连接配置文件新建示意图
PPPoE连接配置文件新建示意图

3.1.3 在PPPoE接口中 选择 新建的配置文件

PPPoE 接口配置示意图
PPPoE 接口配置示意图

3.2 配置 Hairpin NAT 核心防火墙规则

提示:请将 192.168.12.0/24替换为你路由器实际使用的内网网段(例如 RouterOS 默认的 192.168.88.0/24)。

3.2.1 配置 Mangle 规则:建立 Hairpin NAT 连接标记

/ip firewall mangle
add action=mark-connection chain=prerouting comment="Mark connections for hairpin NAT" dst-address-list=WANs new-connection-mark="Hairpin NAT" passthrough=no \
    src-address-list=LANs

Hairpin NAT Mangle配置示意图 1
Hairpin NAT Mangle配置示意图 1

Hairpin NAT Mangle配置示意图 2
Hairpin NAT Mangle配置示意图 2

3.2.2 配置 SRC-NAT 规则:执行源地址伪装 (Masquerade)

/ip firewall nat
add action=masquerade chain=srcnat comment="Hairpin NAT" connection-mark="Hairpin NAT"

Hairpin NAT NAT配置示意图1
Hairpin NAT NAT配置示意图1
Hairpin NAT NAT配置示意图2
Hairpin NAT NAT配置示意图2

到此为止,针对 PPPoE 动态公网 IP 的 Hairpin NAT 核心规则已经全部配置完毕。现在,拿起你的手机或电脑,尝试在局域网内再次通过公网 IP(或绑定的 DDNS 域名)去访问你的内网服务器,你会发现一切都已经畅通无阻了。

附录:参考链接

发表回复* 必填项

评论列表(0条)