RouterOS Hairpin NAT实现案例

背景需求

描述

有一工厂网络拓扑如下所示:

工厂整体网络比较简单,主要为服务器区域及办公区域。网络出口使用了双出口,网关采用了Mikrotik CHR软路由系统,网络策略为:

  • 服务器区域走固定IP出口
  • 办公网络走ADSL拨号出口

现状

内网中有个供内部访问的服务,DNAT规则配置上去,外部访问也正常,然而有个差强人意的是,在自己的内网环境中无法访问--补充点说就是自己无法访问自己出口的DNAT服务。

举例:内网服务器IP为172.20.100.15的SSH服务映射出去,外部网络环境访问如丝般顺滑,然而在内部网络中就是无法访问。

通过资料了解到,这种需求在国内叫NAT 回流,使用专业点的术语叫Hairpin NAT

实现过程

1、新增内网地址列表

将内网中的所有的地址段使用address-list标记,如下所示:

/ip firewall address-list add address=172.20.100.0/24 comment=Server list=LANs
/ip firewall address-list add address=172.20.10.0/24 comment=Work1 list=LANs
/ip firewall address-list add address=172.20.20.0/24 comment=Work1 list=LANs

2、新增外网地址列表

外网出口地址通常有几种类型,最常见的类型固定公网IP、PPPoE拨号(动态公网IP),以下就以这两种类型场景为例:

  • 固定公网IP类型

此类似与内网地址段一致,直接将ISP分配的地址添加到地址列表即可

/ip firewall address-list add address=59.36.185.xx/32 comment=CT-100M list=WANs
  • PPPoE 动态公网IP

进入到ppp->Profiles,以default 为模板克隆一个新的Profile,名命名为:pppoe-profile,点开该模板,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=Hairpin 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 client连接,选择Dial Out选项卡,将profile改为pppoe-profile。这样每次PPPoE客户端连接或断开连接时,它都会自动更新地址列表。

提示:内网网络有固定出口IP,可以不使用动态公网IP。

3、标记内网到公网的连接(LANs -> WANs)

规则如下:

/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=yes src-address-list=LANs

4、执行 Hairpin NAT

使用以下规则,将覆盖其它的NAT规则()

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

提示:place-before=0意为本规则为第1条规则,优先级最高。

5、配置端口转发

参照以下来配置端口转发:

/ip firewall nat add action=dst-nat chain=dstnat comment="描述" dst-address-list=WANs dst-port=映射的服务器端口 protocol=tcp to-addresses=内网服务器IP to-ports=内网服务器端口

示例:将内网服务器IP为172.20.100.15的SSH服务映射出去,映射端口为2222

/ip firewall nat add action=dst-nat chain=dstnat comment="Port forward: dssh" dst-address-list=WANs dst-port=2222 protocol=tcp to-addresses=172.20.100.15 to-ports=22

6、内部访问配置测试

TCP端口探测

# </dev/tcp/59.36.185.xx/2222

业务访问测试

# ssh 59.36.185.xx -p 2222
# echo $SSH_CLIENT
10.10.9.1 34302 22

提示:可以看到SSH远程的源IP正是RouterOS的地址

参考引用: