当前位置: 首页 > news >正文

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:

firewall-cmd --get-zone-of-interface=ens36
firewall-cmd --get-zone-of-interface=ens160

ens36 加入 external 区域(永久):

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

ens160 加入 internal 区域(永久):

firewall-cmd --permanent --zone=internal --change-interface=ens160

external 区域启用伪装(masquerade):

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

查询并确认设置生效:

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,先确认当前状态能帮助我们判断是否需要修改。

示例:

[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 等。

示例:

[root@Server02 ~]# firewall-cmd --zone=external --list-all
external (active)target: defaulticmp-block-inversion: nointerfaces: ens36sources:services: sshports:protocols:masquerade: yes

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

把内网接口放到 internal:

命令:

firewall-cmd --permanent --zone=internal --change-interface=ens160
firewall-cmd --reload

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

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

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

查看当前状态:

sysctl net.ipv4.ip_forward
# 或
cat /proc/sys/net/ipv4/ip_forward

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

sysctl -w net.ipv4.ip_forward=1

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

echo 'net.ipv4.ip_forward = 1' >> /etc/sysctl.conf
sysctl -p

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

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

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

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 执行:

    # 查看接口 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 命令临时设置):

    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 规则管理端口映射和访问控制。

http://www.dtcms.com/a/548523.html

相关文章:

  • Java 学习29:方法
  • Kafka 全方位详细介绍:从架构原理到实践优化
  • Obsidian 入门教程(二)
  • [测试工具] 如何把离线的项目加入成为git项目的新分支
  • 让数据导入导出更智能:通用框架+验证+翻译的一站式解决方案
  • 今天我们学习Linux架构keepalived实现LVS代理双击热备
  • [Linux]内核队列实现详解
  • 【Spring Cloud】Spring Cloud Config
  • MySQL | 数据查询DQL语言:分组统计
  • 阿里云灵码IDE技术测评:从v0.1.0到v0.1.5的进化之路
  • 江门网站推广技巧asp网站服务建设
  • C++: inline 与 ODR,冲突的诞生
  • 营销型 展示类网站企业网站建设空间
  • 从单体到微服务:Java的分布式演进与工程实战
  • 【论文笔记】扩散模型——如何通俗理解传统概率模型的核心矛盾
  • android15 实现截屏功能
  • 工业4.0数据中枢:重构产品全生命周期的智能设计范式
  • 深度解析《AI+Java编程入门》:一本为零基础重构的Java学习路径
  • 架构论文《论数字孪生系统架构设计与应用》
  • 郑州网站建设汉狮如何让百度收录自己的网站信息
  • 英一2017年真题学习笔记
  • PaddleOCR-VL对标DeepSeek-OCR?
  • DeepSeek-OCR 论文精读与实践:用“光学上下文压缩”把长文本变成图片,再由 VLM 高效还原
  • 创新网站内容建设企业建网站的案例
  • 沈阳建站模板系统包括如何自己创建一个网页
  • NLP模型优化
  • 运行当前位置,显示文件全名,检查是否扩展名多次重叠
  • 基于ubuntu22构建spark镜像 —— 筑梦之路
  • Iterable<Result<Item>>讲一下
  • mstscax!CMCS==MCSSendConnectInitial函数分析之mstsc.exe源代码分析第二次交互