Linux 防火墙实战:用 firewalld 配置 External/Internal 区域,实现 NAT 内网共享上网

摘要

本文以一个真实的实验场景为背景,讲解如何在一台充当路由/网关角色的 Linux 主机(本文为 Server02)上通过 firewalld 配置外网接口和内网接口,并开启伪装(masquerade)实现 NAT,从而让内网主机(Server01)能够访问外网。文章以口语化、接近日常交流的方式呈现,包含配置命令、配置解析、实践示例与测试结果,并对代码模块和重要命令做详细讲解,帮助你在类似场景中快速复现并理解原理。

描述(场景说明)

假设你在一个小型办公室或实验室里,有两台主机:

  • Server02:作为网关/防火墙主机(装了 Kylin / CentOS / RHEL 等支持 firewalld 的发行版),有两个网卡:

    • ens36:连接到外网(互联网或公司外网)
    • ens160:连接到内网(192.168.10.0/24 之类的内部网段),负责和内网主机通信并为其提供上网能力
  • Server01:内网主机,默认网关指向 Server02 的内网接口 ens160,没有直接路由到外网的能力。

目标是:

  1. 将 Server02 的外网接口 ens36 设置为 firewalld 的 external 区域(该区域表示不信任外部连接),并启用伪装(masquerade),这样对来自内网的流量进行地址转换(SNAT)------把源地址改为 ens36 的 IP。
  2. 将 Server02 的内网接口 ens160 设置为 internal 区域,默认允许较多来自内网的连接。
  3. 验证内网主机(Server01)是否能够通过 Server02 上网。

为什么要这样做?因为内网主机的私有地址(比如 192.168.x.x)不会被互联网路由。通过 NAT(伪装)把这些地址转换成外网 IP,就能让内网主机发起外网连接并接收响应。

题解答案(简要操作步骤)

查询接口当前所属的 zone:

bash 复制代码
firewall-cmd --get-zone-of-interface=ens36
firewall-cmd --get-zone-of-interface=ens160

ens36 加入 external 区域(永久):

bash 复制代码
firewall-cmd --permanent --zone=external --change-interface=ens36

ens160 加入 internal 区域(永久):

bash 复制代码
firewall-cmd --permanent --zone=internal --change-interface=ens160

external 区域启用伪装(masquerade):

bash 复制代码
firewall-cmd --permanent --zone=external --add-masquerade
firewall-cmd --reload

查询并确认设置生效:

bash 复制代码
firewall-cmd --zone=external --list-all
firewall-cmd --zone=internal --list-all
firewall-cmd --permanent --zone=external --query-masquerade

以上步骤是本文给出的"题解"部分的核心命令,下面会对每个命令、原理和示例输出作详细解释。

题解代码分析(命令详细解析与原理)

firewall-cmd --get-zone-of-interface=接口

用途:查看指定接口当前被分配到哪个 zone。很多时候 NetworkManager 会在接口激活时默认分配 public 或其他 zone,先确认当前状态能帮助我们判断是否需要修改。

示例:

bash 复制代码
[root@Server02 ~]# firewall-cmd --get-zone-of-interface=ens36
public

解析:输出 public 表示目前该接口被分配到 public 区域,可能不适合直接面向外网的信任与策略。我们希望把它放到 external 区域以便启用伪装并将其视为不可信的外部网络。

firewall-cmd --permanent --zone=external --change-interface=ens36

用途:把接口永久挂到指定 zone(这里是 external)。--permanent 表示写入到配置文件,需要 --reload--complete-reload 后生效到运行时(不过有些 NetworkManager 提示会即时生效)。

示例输出说明:

复制代码
The interface is under control of NetworkManager, setting zone to 'external'.
success

解析:这表示 NetworkManager 管理该接口,firewalld 已将该接口的 zone 设置为 external 并返回成功。后续 firewall-cmd --reload 会保证配置在下一次启动仍然有效。

注意事项:如果你使用的是系统网络配置工具(比如 NetworkManager、ifcfg 脚本等),也可以直接在这些工具里指定 zone。比如 NetworkManager 的 nmcli 可以做相同操作。

firewall-cmd --permanent --zone=external --add-masquerade

用途:为 external 区域开启 masquerade(伪装)。这实际在后端为 iptables/nftables 添加 NAT 规则(SNAT/POSTROUTING)------把来自被信任区(如 internal)的流量在出外网时修改源地址为外网接口地址。

为什么用 masquerade 而不是直接 SNAT?masquerade 更适合动态 IP(比如 PPPoE、DHCP 获得的公网 IP 会变动),firewalld 会自动使用出接口的当前 IP。而静态 SNAT 规则需要指定固定的外网 IP。

常见组合:把外网接口放到 external,启用 masquerade;把内网接口放到 internal(或 trusted),然后允许必要的转发和端口转发(如果需要做端口映射)。

firewall-cmd --reload--zone=... --list-all

--reload 会把 --permanent 改动加载到运行时;--list-all 用于显示 zone 的当前配置,包含 interfaces、services、ports、masquerade 等。

示例:

bash 复制代码
[root@Server02 ~]# firewall-cmd --zone=external --list-all
external (active)
  target: default
  icmp-block-inversion: no
  interfaces: ens36
  sources:
  services: ssh
  ports:
  protocols:
  masquerade: yes

解析:masquerade: yes 表示伪装已启用;services: ssh 说明该 zone 允许 ssh 服务(如果你远程管理网关,这一点非常重要)。

把内网接口放到 internal:

命令:

bash 复制代码
firewall-cmd --permanent --zone=internal --change-interface=ens160
firewall-cmd --reload

解析:internal 区域默认比 public 更信任内部网络。你可以根据需要对 internal 区域添加允许的服务(DNS、DHCP、HTTP 等),或保留默认设置。

使能 IP 转发(系统级设置,firewalld 之外)

除了上面 firewalld 的配置外,还必须在内核层面开启 IP 转发,否则 NAT 无法生效。查看与开启的方法:

查看当前状态:

bash 复制代码
sysctl net.ipv4.ip_forward
# 或
cat /proc/sys/net/ipv4/ip_forward

临时开启(重启后失效):

bash 复制代码
sysctl -w net.ipv4.ip_forward=1

永久开启(修改 /etc/sysctl.conf):

bash 复制代码
echo 'net.ipv4.ip_forward = 1' >> /etc/sysctl.conf
sysctl -p

解析:firewalld 添加了 NAT 规则,但内核必须允许转发包从内网接口转到外网接口,ip_forward=1 是必要条件。

如果需要做端口转发(DNAT),示例:

假设你希望把外网的 80 端口映射到内网某台 Web 服务器(192.168.10.20:80),可以使用:

bash 复制代码
firewall-cmd --permanent --zone=external --add-forward-port=port=80:proto=tcp:toaddr=192.168.10.20:toport=80
firewall-cmd --reload

解析:这会在外面接口上把到达 80 的连接转发到指定内网地址。注意同时需要在 internal 区域允许相应服务或策略(内网服务器可能需要允许来自 Server02 的流量)。

示例测试及结果

以下给出一个完整的演练流程(假设 Server02 的外网接口 ens36 的 IP 是 203.0.113.10,内网 ens160 的 IP 是 192.168.10.1,Server01 IP 为 192.168.10.20):

  1. 在 Server02 执行:

    bash 复制代码
    # 查看接口 zone
    firewall-cmd --get-zone-of-interface=ens36
    firewall-cmd --get-zone-of-interface=ens160
    
    # 修改 zone
    firewall-cmd --permanent --zone=external --change-interface=ens36
    firewall-cmd --permanent --zone=internal --change-interface=ens160
    
    # 启用 masquerade 并重载
    firewall-cmd --permanent --zone=external --add-masquerade
    firewall-cmd --reload
    
    # 开启内核转发
    sysctl -w net.ipv4.ip_forward=1
    echo 'net.ipv4.ip_forward = 1' >> /etc/sysctl.conf
    sysctl -p
    
    # 查看外网 zone 配置
    firewall-cmd --zone=external --list-all
  2. 在 Server01 上设置网关为 Server02 的内网 IP(例子用 ip 命令临时设置):

    bash 复制代码
    ip route replace default via 192.168.10.1 dev eth0
    # 或修改 /etc/sysconfig/network-scripts/ifcfg-xxx 或 /etc/netplan/(视发行版而定)
  3. 测试连通性:

    • 从 Server01 ping 8.8.8.8(测试是否能到达外网 IP)
    • 从 Server01 curl http://ifconfig.mecurl https://ipinfo.io/ip(查看对方看到的源 IP,应该是 203.0.113.10)

测试结果示例(预期):

复制代码
# ping 8.8.8.8
PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
64 bytes from 8.8.8.8: icmp_seq=1 ttl=54 time=30.2 ms

# curl http://ifconfig.me  -> 返回 203.0.113.10

如果能看到外网 IP,说明 NAT 已经正常工作。

常见问题排查:

  • 如果 ping 无法通过但 Server02 能连外网,检查 sysctl net.ipv4.ip_forward 是否为 1。
  • 检查防火墙规则:firewall-cmd --list-all-zones,看是否有阻断 FORWARD 的规则。
  • 如果使用 nftables/iptables 后端,查看 iptables -t nat -L -n -vnft list ruleset 来调试 NAT 规则。

时间复杂度

这里不是算法题,但如果非要给出一个关于配置操作的"时间复杂度"类比:

  • 执行单条 firewall-cmd 命令的时间主要受系统负载和配置文件大小影响,可视为 O(1)(常数时间)。
  • 整个配置流程包含固定数量的命令(查询、修改、重载),总体也是 O(1)。

因此,从工程角度看,该任务的时间复杂度是常数级别。

空间复杂度

配置不会占用明显的额外磁盘或内存空间,firewalld 的配置文件会在 /etc/firewalld/ 下写入少量文本,属于 O(1) 级别的空间使用。

总结

本文从一个具体案例入手,说明了如何将 Server02 的外网接口 ens36 加入 external 区域,并开启 masquerade 来实现 NAT,使内部主机能够通过 Server02 上网。文章重点覆盖了:

  • firewalld 的接口与 zone 的绑定操作与解释;
  • 为什么要启用 masquerade(适用于动态公网 IP);
  • 必须在内核层面开启 IP 转发;
  • 如何验证 NAT 是否生效以及常见排错方法;
  • 如果需要端口映射(DNAT)应如何设置。

实践建议:在生产环境更改防火墙和 NAT 配置前,请先在测试环境验证,确保不会误断远程管理(例如 ssh)连接。对于长期可靠的公网服务,考虑把外网接口使用静态 IP 并在必要时使用更严格的 iptables/nftables 规则管理端口映射和访问控制。

相关推荐
苹果xyz7 小时前
IDS车载入侵检测系统
网络
-芒果酱-8 小时前
中兴电信F7607P、F4607P、G6611、G7611、G7611V2、G7615、G7615V2等FTTR型号光猫充当简单OLT光纤服务器总结
网络
NOVAnet20238 小时前
南凌科技SD-WAN全球组网方案技术解析:助力JINS完成600+门店数字化升级
网络·web安全·智能流量调度
陌路208 小时前
操作系统(6)虚拟内存-缓存工具-页表(2)
linux
林一百二十八8 小时前
Win11配置VMware-workstation以及Ubuntu环境
linux·运维·ubuntu
奋斗的蛋黄9 小时前
TCP/IP 四层模型:网络协议的分工与协作
网络·网络协议·tcp/ip
铜豌豆_Y9 小时前
嵌入式Linux驱动开发之I2C子系统(3)--I2C子系统框架
linux·运维·驱动开发
在坚持一下我可没意见9 小时前
Java 网络编程:TCP 与 UDP 的「通信江湖」(基于UDP回显服务器)
java·服务器·开发语言·tcp/ip·udp·java-ee
国科安芯9 小时前
光电传感器领域国产MCU芯片抗辐照技术考量
网络·人工智能·单片机·嵌入式硬件·安全