You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何配置firewalld使内部网络及路由器本地发起的连接应用公网端口转发规则?

如何配置firewalld使内部网络及路由器本地发起的连接应用公网端口转发规则?

这个问题其实是典型的**发夹NAT(Hairpin NAT)**场景——当内部设备或者路由器自身访问网关的公网IP时,流量默认会被网关识别为发往自身的请求,走INPUT链而不是FORWARD链,所以你配置在external zone的端口转发规则根本不会生效。加上公网IP是DHCP动态分配的,不能硬编码写死,得用更灵活的配置方式,我给你分步解决:

一、搞定内部网络设备的访问需求

针对trusted zone里的内部设备,我们需要让发往网关公网IP的流量触发转发规则,同时做源地址转换(SNAT)确保回包能正确回到内部设备:

  1. 添加firewalld富规则,匹配trusted zone源、external zone目标的流量,自动转发到内部服务器,同时开启masquerade实现SNAT:

    # 转发80端口
    sudo firewall-cmd --permanent --zone=trusted --add-rich-rule='rule family="ipv4" source zone="trusted" destination zone="external" forward-port port="80" protocol="tcp" to-port="80" to-addr="192.168.0.2" masquerade'
    # 转发443端口
    sudo firewall-cmd --permanent --zone=trusted --add-rich-rule='rule family="ipv4" source zone="trusted" destination zone="external" forward-port port="443" protocol="tcp" to-port="443" to-addr="192.168.0.2" masquerade'
    # 转发8443端口
    sudo firewall-cmd --permanent --zone=trusted --add-rich-rule='rule family="ipv4" source zone="trusted" destination zone="external" forward-port port="8443" protocol="tcp" to-port="8443" to-addr="192.168.0.2" masquerade'
    

    这里用destination zone="external"就不用硬编码公网IP了,firewalld会自动匹配external zone接口(也就是wan)的所有地址,完美适配DHCP动态IP的情况。

  2. 重新加载firewalld规则生效:

    sudo firewall-cmd --reload
    

这时候内部设备再访问gateway.mydomain.tld或者网关公网IP,应该就能正常转发到192.168.0.2了。

二、解决路由器自身的访问问题

路由器本地(包括用公网IP、localhost访问)的流量默认走INPUT链,需要单独在nat表的OUTPUT链添加DNAT规则,而且同样要适配动态公网IP:

方案1:用脚本动态更新规则(推荐)

因为公网IP会变,我们写个脚本自动获取当前wan接口的IP,更新DNAT规则:

  1. 创建脚本/usr/local/bin/update_local_dnat.sh:

    #!/bin/bash
    # 获取当前wan接口的公网IP
    WAN_IP=$(ip -br addr show wan | awk '{print $3}' | cut -d/ -f1)
    # 先删除旧的规则(避免重复)
    sudo firewall-cmd --direct --remove-rule ipv4 nat OUTPUT 0 -d 0.0.0.0/0 -p tcp --dport 80 -j DNAT --to-destination 192.168.0.2:80 2>/dev/null
    sudo firewall-cmd --direct --remove-rule ipv4 nat OUTPUT 0 -d 0.0.0.0/0 -p tcp --dport 443 -j DNAT --to-destination 192.168.0.2:443 2>/dev/null
    sudo firewall-cmd --direct --remove-rule ipv4 nat OUTPUT 0 -d 0.0.0.0/0 -p tcp --dport 8443 -j DNAT --to-destination 192.168.0.2:8443 2>/dev/null
    # 添加新的DNAT规则
    sudo firewall-cmd --direct --add-rule ipv4 nat OUTPUT 0 -d $WAN_IP -p tcp --dport 80 -j DNAT --to-destination 192.168.0.2:80
    sudo firewall-cmd --direct --add-rule ipv4 nat OUTPUT 0 -d $WAN_IP -p tcp --dport 443 -j DNAT --to-destination 192.168.0.2:443
    sudo firewall-cmd --direct --add-rule ipv4 nat OUTPUT 0 -d $WAN_IP -p tcp --dport 8443 -j DNAT --to-destination 192.168.0.2:8443
    # 保存规则到永久配置
    sudo firewall-cmd --runtime-to-permanent
    
  2. 给脚本加执行权限:

    sudo chmod +x /usr/local/bin/update_local_dnat.sh
    
  3. 配置定时任务自动更新:
    比如用systemd定时器每小时执行一次,或者在NetworkManager的钩子脚本里添加,当wan接口IP变化时自动触发脚本。

方案2:添加localhost访问的固定规则

如果你需要用localhost访问,还要单独添加针对127.0.0.1的规则:

sudo firewall-cmd --permanent --direct --add-rule ipv4 nat OUTPUT 0 -d 127.0.0.1 -p tcp --dport 80 -j DNAT --to-destination 192.168.0.2:80
sudo firewall-cmd --permanent --direct --add-rule ipv4 nat OUTPUT 0 -d 127.0.0.1 -p tcp --dport 443 -j DNAT --to-destination 192.168.0.2:443
sudo firewall-cmd --permanent --direct --add-rule ipv4 nat OUTPUT 0 -d 127.0.0.1 -p tcp --dport 8443 -j DNAT --to-destination 192.168.0.2:8443
sudo firewall-cmd --reload

三、验证配置

  • 内部设备测试:

    curl -sS -D - https://gateway.mydomain.tld -o /dev/null -L
    

    应该返回200状态码,和访问hq.mydomain.tld的结果一致。

  • 路由器本地测试:

    # 用公网IP测试
    curl -sS -D - https://$(ip -br addr show wan | awk '{print $3}' | cut -d/ -f1) -o /dev/null -L
    # 用localhost测试
    curl -sS -D - https://localhost -o /dev/null -L
    

    同样应该返回正常的200响应。

备注:内容来源于stack exchange,提问作者3dg3

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.20 12:49:38