面试还是要面的,工作还是要正常进行的。最近hw要来了,要求做安全加固,与防火墙纠缠,把AI都绕晕了...索性把firewall这个知识点搞清楚,写下来,以后护网、面试都能用上。
本文有的内容借助AI辅助完成,如有介意,咱就不往下读了,不准确的地方,欢迎评论区指出。
一、先搞清楚:防火墙有几种?
| 工具 | 特点 | 适用场景 |
|---|
| iptables | 老牌经典,命令复杂 | CentOS 6、老系统 |
| firewalld | 动态更新、区域概念、命令简洁 | CentOS 7/8(本文重点) |
| ufw | 命令最简单 | Ubuntu/Debian系 |
检查你的系统用的是哪个:
systemctl status firewalldsystemctl status iptables
哪个是 active 就用哪个,别两个同时开,会打架。
二、核心概念:区域
区域就是预设的规则模板,不同区域对应不同的安全级别。
| 区域 | 安全级别 | 默认行为 | 适用场景 |
|---|
| trusted | 最低 | 允许所有流量 | 内网核心服务器、白名单IP |
| home | 较低 | 允许SSH、MDNS等 | 家庭网络 |
| work | 中等 | 允许SSH、DHCP等 | 办公网络 |
| public | 默认区域 | 只允许SSH、dhcpv6-client | 公网服务器 |
| internal | 中高 | 类似work,多允许一些内网服务 | 内网服务器 |
| external | 较高 | 允许SSH,默认会做NAT伪装 | 外网网关 |
| dmz | 高 | 只允许SSH | DMZ隔离区 |
| block | 最高 | 拒绝所有流量 | 紧急隔离 |
| drop | 最高 | 丢弃所有入站流量 | 严格隔离 |
⚠️ 注意: CentOS 7 默认区域是 public,SSH默认是开放(不然你连不上服务器)。
三、常用命令
3.1 查看状态
firewall-cmd --state # 查看状态firewall-cmd --get-default-zone # 查看默认区域firewall-cmd --get-active-zones # 查看激活区域firewall-cmd --zone=public --list-all # 查看区域所有规则
3.2 开放端口
# 开放端口(永久)firewall-cmd --zone=public --add-port=8080/tcp --permanentfirewall-cmd --reload# 查看已开放的端口firewall-cmd --zone=public --list-ports
⚠️ 易错点: 加了 --permanent 必须 reload 才生效。
| 参数 | 含义 | 生效时机 |
|---|
| 无 --permanent | 临时规则 | 立即生效,重启失效 |
| --permanent | 永久规则 | 写入配置文件,需reload才生效 |
3.3 开放服务
firewalld 预设了一些常用服务的规则:
# 开放服务(永久)firewall-cmd --zone=public --add-service=http --permanentfirewall-cmd --reload# 查看已开放的服务firewall-cmd --zone=public --list-services
常用预设服务:ssh(22)、http(80)、https(443)、mysql(3306)
四、富规则:限制来源IP
比端口规则更精细,可以指定来源IP、端口、动作等。
4.1 常用语法
# 允许指定IP访问指定端口firewall-cmd --zone=public --add-rich-rule='rule family="ipv4" source address="192.168.1.100" port protocol="tcp" port="22" accept' --permanent# 拒绝指定IP访问firewall-cmd --zone=public --add-rich-rule='rule family="ipv4" source address="10.0.0.5" reject' --permanent# 允许指定IP段访问firewall-cmd --zone=public --add-rich-rule='rule family="ipv4" source address="192.168.1.0/24" port protocol="tcp" port="3306" accept' --permanent# 查看富规则firewall-cmd --zone=public --list-rich-rules# 删除富规则(把add改成remove)firewall-cmd --zone=public --remove-rich-rule='rule family="ipv4" source address="192.168.1.100" port protocol="tcp" port="22" accept' --permanent
4.2 reject vs drop 区别
(面试易问)
| 动作 | 行为 | 客户端感知 | 安全性 |
|---|
| reject | 拒绝并返回错误消息 | 客户端知道被拒绝 | 较低(暴露防火墙存在) |
| drop | 直接丢弃,不返回消息 | 客户端超时等待 | 较高(隐蔽) |
五、护网实战场景
场景1:只允许特定IP访问SSH
护网时,SSH端口必须限制来源IP,防止被爆破。
# 先移除默认的SSH服务开放firewall-cmd --zone=public --remove-service=ssh --permanent# 只允许指定IP访问SSHfirewall-cmd --zone=public --add-rich-rule='rule family="ipv4" source address="192.168.1.0/24" service name="ssh" accept' --permanentfirewall-cmd --reload
⚠️ 警告: 执行前先确认你的IP在允许范围内,不能把自己锁外面。
场景2:紧急封禁某个攻击IP
发现攻击源,紧急封掉:
# 紧急封禁(临时,立即生效)firewall-cmd --zone=public --add-rich-rule='rule family="ipv4" source address="恶意IP" drop'# 确认后再写成永久规则firewall-cmd --zone=public --add-rich-rule='rule family="ipv4" source address="恶意IP" drop' --permanentfirewall-cmd --reload
场景3:仅允许白名单IP访问整台服务器
有些服务器需要严格隔离,只允许白名单IP访问所有端口,其他所有IP全部拒绝。
有两种实现方式,效果一样:
方式一:改默认区域为drop + trusted区域添加白名单
原理:
# 1. 设置默认区域为drop(拒绝所有不在白名单的流量)firewall-cmd --set-default-zone=drop# 2. 在trusted区域添加白名单IPfirewall-cmd --zone=trusted --add-source=192.168.1.100 --permanentfirewall-cmd --zone=trusted --add-source=192.168.2.0/24 --permanent# 3. 重载生效firewall-cmd --reload
验证:
# 查看默认区域firewall-cmd --get-default-zone# 输出:drop# 查看trusted区域的白名单firewall-cmd --zone=trusted --list-all# 输出应包含 sources: 192.168.1.100 192.168.2.0/24
工作逻辑:
流量进来 → 检查来源IP ↓ ┌─────────────────────────────────────────┐ │ 来源IP在trusted区域的sources? │ │ ├─ 是 → trusted区域 → 允许所有端口 │ │ └─ 否 → 默认区域 → 全部丢弃 │ └─────────────────────────────────────────┘
优点:
方式二:改public区域的target为DROP + public区域添加白名单
原理:
# 1. 设置public区域的默认行为为DROPfirewall-cmd --zone=public --set-target=DROP --permanent# 2. 在public区域添加白名单IPfirewall-cmd --zone=public --add-source=192.168.1.100 --permanentfirewall-cmd --zone=public --add-source=192.168.2.0/24 --permanent# 3. 重载生效firewall-cmd --reload
验证:
# 查看public区域配置firewall-cmd --zone=public --list-all# 输出应包含:# target: DROP# sources: 192.168.1.100 192.168.2.0/24
工作逻辑:
流量进来 → 检查来源IP ↓ ┌─────────────────────────────────────────┐ │ 来源IP在public区域的sources? │ │ ├─ 是 → 匹配规则 → 允许 │ │ └─ 否 → target=DROP → 全部丢弃 │ └─────────────────────────────────────────┘
优点:
不改变默认区域,影响范围可控
只用一个区域,配置集中
两种方式对比
| 对比项 | 方式一(默认区域=drop) | 方式二(target=DROP) |
|---|
| 涉及区域 | 两个:trusted + drop | 一个:public |
| 配置位置 | 白名单在trusted,拒绝在drop | 都在public |
| 默认区域 | 会改变(改成drop) | 不改变(仍是public) |
| 新接口绑定 | 自动绑定到drop区域 | 仍是public区域 |
| 逻辑清晰度 | 更清晰(白名单和拒绝分开) | 更集中(都在一个区域) |
⚠️ 两种方式的共同注意点:
执行前务必把自己的IP加进白名单,不然会被锁外面
添加白名单后要reload:firewall-cmd --reload
验证是否生效:用白名单外的IP测试是否能访问(应该不能)
六、踩坑经历
白名单配好了,过会儿又失效。
配好白名单后测试正常,结果过几分钟白名单外的IP又能访问了。反复检查配置、重启防火墙都没用。
排查发现是服务器上的软件有定时任务,在偷偷调firewall服务,改防火墙配置。
排查方向:
firewall-cmd --zone=trusted --list-sources # 监控白名单是否变化firewall-cmd --get-default-zone # 监控默认区域是否变化ls -la /etc/firewalld/zones/ # 检查配置文件ps aux | grep firewall # 检查调用进程
教训: 配完要持续观察,规则莫名失效要排查软件侵入问题。
七、附录:常用命令速查表
# ========== 状态查看 ==========firewall-cmd --state # 查看状态firewall-cmd --get-default-zone # 查看默认区域firewall-cmd --get-active-zones # 查看激活区域firewall-cmd --zone=public --list-all # 查看区域所有规则firewall-cmd --zone=public --list-ports # 查看开放的端口firewall-cmd --zone=public --list-services # 查看开放的服务firewall-cmd --zone=public --list-rich-rules # 查看富规则firewall-cmd --zone=trusted --list-sources # 查看白名单IP# ========== 接口绑定查看 ==========firewall-cmd --get-zone-of-interface=eth0 # 查看接口绑定的区域firewall-cmd --zone=public --list-interfaces # 查看区域绑定的接口# ========== 端口操作 ==========firewall-cmd --zone=public --add-port=8080/tcp --permanent # 开放端口firewall-cmd --zone=public --remove-port=8080/tcp --permanent # 关闭端口# ========== 服务操作 ==========firewall-cmd --get-services # 查看预设服务firewall-cmd --zone=public --add-service=http --permanent # 开放服务firewall-cmd --zone=public --remove-service=http --permanent # 关闭服务# ========== 富规则 ==========firewall-cmd --zone=public --add-rich-rule='rule family="ipv4" source address="192.168.1.100" port protocol="tcp" port="22" accept' --permanentfirewall-cmd --zone=public --remove-rich-rule='rule family="ipv4" source address="192.168.1.100" port protocol="tcp" port="22" accept' --permanent# ========== 白名单控制整台服务器(方式一)==========firewall-cmd --set-default-zone=drop # 设置默认区域为dropfirewall-cmd --zone=trusted --add-source=192.168.1.100 --permanent # 添加白名单firewall-cmd --zone=trusted --remove-source=192.168.1.100 --permanent # 移除白名单# ========== 白名单控制整台服务器(方式二)==========firewall-cmd --zone=public --set-target=DROP --permanent # 设置默认拒绝firewall-cmd --zone=public --add-source=192.168.1.100 --permanent # 添加白名单firewall-cmd --zone=public --remove-source=192.168.1.100 --permanent # 移除白名单# ========== 重载配置 ==========firewall-cmd --reload # 重载永久规则# ========== 紧急操作 ==========firewall-cmd --panic-on # 开启恐慌模式(拒绝所有)firewall-cmd --panic-off # 关闭恐慌模式