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的地址