|
本帖最后由 lgs2007m 于 2022-3-16 21:12 编辑
外网IPv4访问内网IPv4设备,需要在LuCI页面 防火墙->端口转发 设置端口转发。
单独设置端口转发(未启用NAT环回)会有NAT环回(NAT Loopback / Hairpin NAT / NAT Reflection)的问题:
内网设备通过wan口IP访问被端口转发的内网设备,因为访问数据是从区域lan进入的,不会匹配到从区域wan输入的端口转发规则,因此相当于访问wan口本身,所以访问不到被端口转发的内网设备。
LuCI页面添加端口转发是默认勾选启用NAT环回的,则防火墙除了添加端口转发还会添加一对SNAT(源地址转换)和DNAT(目的地址转换)规则来处理NAT环回的问题。
例如wan公网IP+端口是22.22.22.22:2222,设置端口转发给内网NAS+端口192.168.1.5:5555,协议tcp,
这样会在防火墙nat表添加3条规则(只在nat表添加,没有在filter表添加规则):
SSH登录或者TTYD终端登录使用命令 iptables-save | grep 5555 查看防火墙包含文本5555的规则
- *nat
- -A zone_lan_prerouting -s 192.168.1.0/24 -d 22.22.22.22/32 -p tcp -m tcp --dport 2222 -m comment --comment "!fw3: test (reflection)" -j DNAT --to-destination 192.168.1.5:5555
- -A zone_lan_postrouting -s 192.168.1.0/24 -d 192.168.1.5/32 -p tcp -m tcp --dport 5555 -m comment --comment "!fw3: test (reflection)" -j SNAT --to-source 192.168.1.1
- -A zone_wan_prerouting -p tcp -m tcp --dport 2222 -m comment --comment "!fw3: test" -j DNAT --to-destination 192.168.1.5:5555
复制代码
假设内网PC 192.168.1.3从内网访问NAS域名+2222,域名解析为22.22.22.22,即192.168.1.3:3333->22.22.22.22:2222,则PC需要得到22.22.22.22:2222->192.168.1.3:3333的回复数据包才能正常建立通信,否则会被PC丢弃。
下面来看这3条规则如何处理:
防火墙的一些知识可以去看我的另一篇帖子:
小白对OpenWrt防火墙基本设置的ip6tables IPv6规则的一点思考理解
https://www.right.com.cn/forum/thread-8183481-1-1.html
数据经过防火墙的流程:
--->PREROUTING------>[ROUTE]------->FORWARD---------->POSTROUTING------>
raw | mangle ^ mangle
mangle | filter | nat
nat | |
| [ROUTE]
v |
INPUT mangle OUTPUT raw
| nat ^ mangle
| filter | nat
v ------------>local--------->| filter
#----------------------------------------------------------------
# 首先内网PC访问NAS域名+2222,域名被解析为公网IP 22.22.22.22,因为不在同一网段,数据包会直接发给网关192.168.1.1,然后数据包从区域lan输入路由器防火墙,
# 数据包输入防火墙会查询连接跟踪表(conntrack table),没有就新建一条连接跟踪表条目(conntrack entry),
# 这个条目需要数据包出INPUT或者POSTROUTING链才最终确认生成,
# 在没有经过DNAT和SNAT的情况下,数据包从防火墙INPUT链输出后最终conntrack entry是这样的:
- cat /proc/net/nf_conntrack | grep 2222 #查看conntrack table
- ipv4 2 tcp 6 118 TIME_WAIT src=192.168.1.3 dst=22.22.22.22 sport=3333 dport=2222 packets=4 bytes=172 src=22.22.22.22 dst=192.168.1.3 sport=2222 dport=3333 packets=3 bytes=132 [ASSURED] mark=0 zone=0 use=2
复制代码
# 数据包会被当成访问wan口
#----------------------------------------------------------------
# 当添加了DNAT规则,数据包输入防火墙后先输入PREROUTING链,然后会匹配这条规则:
- -A zone_lan_prerouting -s 192.168.1.0/24 -d 22.22.22.22/32 -p tcp -m tcp --dport 2222 -m comment --comment "!fw3: test (reflection)" -j DNAT --to-destination 192.168.1.5:5555
复制代码
# 防火墙判定是从区域lan输入的,是内网192.168.1.0/24访问wan口地址22.22.22.22:2222的数据包,
# 则进行DNAT目的地址转换,修改目标地址和端口为192.168.1.5:5555,
# 经过DNAT后还会查询并修改对应的conntrack entry的后半部分源和目标的地址端口,
# 在没有SNAT的情况下,数据包从防火墙POSTROUTING链输出后最终conntrack entry是这样的:
- cat /proc/net/nf_conntrack | grep 5555 #查看conntrack table
- ipv4 2 tcp 6 113 SYN_SENT src=192.168.1.3 dst=22.22.22.22 sport=3333 dport=2222 packets=2 bytes=104 [UNREPLIED] src=192.168.1.5 dst=192.168.1.3 sport=5555 dport=3333 packets=0 bytes=0 mark=0 zone=0 use=2
复制代码
# 【返回的数据包】因为192.168.1.3是同一网段,NAS的回复数据包直接发给PC,不会发给路由器,则没有经过路由器防火墙,没有进行NAT反转,
# PC访问NAS的数据包:192.168.1.3:3333->22.22.22.22:2222
# 进行DNAT后变成了 :192.168.1.3:3333->192.168.1.5:5555
# NAS发出回复数据包:192.168.1.5:5555->192.168.1.3:3333
# PC直接收到源地址是192.168.1.5的回复数据包,不是22.22.22.22的,会丢弃。
#----------------------------------------------------------------
# 在DNAT基础上添加SNAT规则,数据包经过PREROUTING链进行了DNAT后会到FORWARD链,最后从区域lan输出前,到POSTROUTING链,会匹配这条规则:
- -A zone_lan_postrouting -s 192.168.1.0/24 -d 192.168.1.5/32 -p tcp -m tcp --dport 5555 -m comment --comment "!fw3: test (reflection)" -j SNAT --to-source 192.168.1.1
复制代码
# 防火墙判断是从区域lan输出的,内网192.168.1.0/24访问主机192.168.1.5:5555的tcp数据包,
# 则进行SNAT源地址转换,源地址192.168.1.3会被修改为192.168.1.1,
# 经过SNAT后,再查询修改conntrack entry的后半部分地址端口,
# 经过DNAT和SNAT的情况下,数据包从防火墙POSTROUTING链输出后最终conntrack entry是这样的:
- ipv4 2 tcp 6 39 TIME_WAIT src=192.168.1.3 dst=22.22.22.22 sport=3333 dport=2222 packets=0 bytes=0 src=192.168.1.5 dst=192.168.1.1 sport=5555 dport=3333 packets=0 bytes=0 [ASSURED] mark=0 zone=0 use=2
复制代码
# 【返回的数据包】因为NAS的回复数据包会发送回网关192.168.1.1,路由器防火墙就能根据conntrack entry将NAT转换反转过来,
# PC访问NAS的数据包:192.168.1.3:3333->22.22.22.22:2222
# 进行DNAT后变成了: 192.168.1.3:3333->192.168.1.5:5555
# 再进行SNAT后变成: 192.168.1.1:3333->192.168.1.5:5555
# NAS发出回复数据包:192.168.1.5:5555->192.168.1.1:3333
# 防火墙NAT反转后是:22.22.22.22:2222->192.168.1.3:3333
# 这样PC就可以收到22.22.22.22的回复,不会丢弃,通信建立了。
#----------------------------------------------------------------
# 这里是端口转发的那条规则,用于处理wan口输入的外网访问内网NAS的数据包。
# 数据包输入防火墙会查询conntrack table,没有就新建一条conntrack entry,
# 接着数据包先输入PREROUTING链,然后会匹配这条规则:
- -A zone_wan_prerouting -p tcp -m tcp --dport 2222 -m comment --comment "!fw3: test" -j DNAT --to-destination 192.168.1.5:5555
复制代码
# 防火墙判断是从区域wan输入的,访问tcp 2222端口的数据包,修改目标地址端口为192.168.1.5:5555。
# 经过DNAT后还会查询并修改对应的conntrack entry的后半部分源和目标的地址端口,
# 数据包从防火墙POSTROUTING链输出后最终conntrack entry是这样的:
- ipv4 2 tcp 6 1 TIME_WAIT src=11.11.11.11 dst=22.22.22.22 sport=1111 dport=2222 packets=0 bytes=0 src=192.168.1.5 dst=11.11.11.11 sport=5555 dport=1111 packets=0 bytes=0 [ASSURED] mark=0 zone=0 use=2
复制代码
# 【返回的数据包】这里NAS回复外网的数据包,因为不是同一网段,会先发给网关,路由器防火墙就能根据conntrack entry将NAT转换反转过来,
# 外网访问NAS数据包:11.11.11.11:1111->22.22.22.22:2222
# 进行DNAT后变成了: 11.11.11.11:1111->192.168.1.5:5555
# NAS发出回复数据包:192.168.1.5:5555->11.11.11.11:1111
# 防火墙NAT反转后是:22.22.22.22:2222->11.11.11.11:1111
# 外网设备也可以收到22.22.22.22的回复,通信建立。
How does NAT reflection (NAT loopback) work?
https://unix.stackexchange.com/q ... n-nat-loopback-work
Port forwarding for IPv4 (DNAT)
https://openwrt.org/docs/guide-u ... rding_for_ipv4_dnat
linux 连接跟踪nf_conntrack 与 NAT和状态防火墙
https://blog.csdn.net/whatday/article/details/105251137
Iptables之nf_conntrack模块
https://clodfisher.github.io/2018/09/nf_conntrack/
When does iptable's conntrack module track states of packets?
https://serverfault.com/question ... k-states-of-packets
|
评分
-
查看全部评分
|