nftables配置NAT Hairpinning实现局域网内访问本地网站的问题求助
看起来你在配置nftables的NAT hairpinning时卡壳了——局域网内没法访问本地的网站服务器(192.168.1.3),我来帮你捋捋解决方案,分两种思路给你说:
一、调整nftables规则实现Hairpinning
你当前的配置里,prerouting链只处理了WAN口(enp1s0)进来的公网流量,但局域网内的设备用公网IP访问网站时,流量是从LAN口(enp2s0)进入路由器的,这部分流量没触发DNAT规则,所以服务器收不到正确的请求。咱们需要修改配置补上这部分规则:
修改后的完整nftables配置如下(记得把<你的公网IP>替换成你实际的公网IP):
#!/sbin/nft -f flush ruleset table ip nat { chain prerouting { type nat hook prerouting priority -100; policy accept; # 处理公网用户从WAN口进来的访问请求 iifname "enp1s0" tcp dport { 80, 443 } dnat to 192.168.1.3 # 处理局域网用户用公网IP访问时的流量(关键补充) iifname "enp2s0" ip daddr <你的公网IP> tcp dport { 80, 443 } dnat to 192.168.1.3 meta nftrace set 1 } chain postrouting { type nat hook postrouting priority 100; policy accept; # Hairpinning核心:让服务器返回的流量通过路由器转发回客户端 ip saddr 192.168.1.0/24 ip daddr 192.168.1.3 tcp dport { http, https } counter snat to 192.168.1.1 # WAN口的伪装规则,保证内网设备能访问公网 oifname "enp1s0" masquerade meta nftrace set 1 } }
原理说明:
当局域网内的设备用公网IP访问你的网站时,路由器的prerouting链会把目标地址转换成服务器的局域网IP(192.168.1.3);然后postrouting链会把请求的源地址改成路由器的LAN口地址(192.168.1.1),这样服务器收到的请求来自路由器,返回的流量会先发给路由器,再由路由器转发回发送请求的局域网设备,完成整个hairpinning流程。
二、用Split DNS实现更优雅的局域网访问
如果你觉得NAT hairpinning配置麻烦,或者担心有延迟问题,Split DNS是个更简单高效的方案——让局域网内的设备访问你的域名时,直接解析到服务器的局域网IP,跳过NAT流程:
如果你的路由器自带DNS服务(比如常用的dnsmasq):
找到路由器的DNS配置文件(比如/etc/dnsmasq.conf),添加一条自定义解析规则:address=/你的域名.com/192.168.1.3保存后重启DNS服务,这样局域网内所有设备访问你的域名时,都会直接解析到192.168.1.3,直接和服务器通信,不需要经过路由器的NAT。
如果不用路由器DNS:
可以在局域网内每台设备的hosts文件里添加一行:192.168.1.3 你的域名.com不过这个方法需要逐个设备配置,适合设备少的场景。
备注:内容来源于stack exchange,提问作者whitleystriber

