firewalld 配置 internal 到 public 区域的流量转发
firewalld 支持通过 Policy 对象实现跨区域流量转发。本文介绍如何配置策略,允许 internal 区域的流量转发到 public 区域,使内网主机可以通过防火墙访问外部网络。
前提条件
- firewalld 已安装并运行(
systemctl status firewalld) - 有 root 或 sudo 权限
- 了解 firewalld 的 Zone 和 Policy 概念
创建转发策略
firewalld 的 Zone 控制接口上的流量方向,而 Policy 用于定义跨区域的流量转发规则。我们需要创建一个 Policy,将 internal 作为入口区域,public 作为出口区域。
# 创建新策略
sudo firewall-cmd --permanent --new-policy allow-internal-to-public
# 设置入口区域(源)为 internal,出口区域(目标)为 public
sudo firewall-cmd --permanent --policy allow-internal-to-public --add-ingress-zone internal
sudo firewall-cmd --permanent --policy allow-internal-to-public --add-egress-zone public
# 设置动作为 ACCEPT,并给予高优先级(确保不被其他策略覆盖)
sudo firewall-cmd --permanent --policy allow-internal-to-public --set-target ACCEPT
sudo firewall-cmd --permanent --policy allow-internal-to-public --set-priority -100
关键参数说明:
| 参数 | 说明 |
|---|---|
--add-ingress-zone | 流量进入的区域(源区域) |
--add-egress-zone | 流量出去的区域(目标区域) |
--set-target ACCEPT | 匹配该策略的流量默认放行 |
--set-priority -100 | 优先级数值越小越优先,负数确保优先于默认策略 |
开启伪装(MASQUERADE)
为了让内网 IP 的流量通过 public 区域的出口 IP 访问外部网络,需要为 public 区域开启源地址伪装(SNAT):
sudo firewall-cmd --permanent --zone=public --add-masquerade
启用 IP 转发
Linux 内核默认关闭 IP 转发功能,需要手动开启:
# 临时启用(重启后失效)
sudo sysctl -w net.ipv4.ip_forward=1
# 永久启用
echo net.ipv4.ip_forward=1 | sudo tee -a /etc/sysctl.d/99-ipforward.conf
重载防火墙
以上所有 --permanent 操作需要重载后才会生效:
sudo firewall-cmd --reload
验证配置
# 查看策略列表
sudo firewall-cmd --get-policies
# 查看策略详情
sudo firewall-cmd --info-policy allow-internal-to-public
# 查看 public 区域是否开启伪装
sudo firewall-cmd --zone=public --query-masquerade
# 查看 IP 转发状态
sysctl net.ipv4.ip_forward
常见问题
内网主机无法访问外部? 检查以下几点:
- 确认
net.ipv4.ip_forward已设为1 - 确认 public 区域的伪装已开启
- 确认 internal 区域的接口绑定正确:
sudo firewall-cmd --zone=internal --list-all - 确认内网主机的默认网关指向防火墙的 internal 接口 IP
策略优先级被覆盖? 使用更小的优先级数值(如 -200),firewalld 优先级范围是 -32768 到 32767,数值越小越优先。