
核心要点(TL;DR)
- iptables 是内核 netfilter 的规则工具,firewalld 是其上的动态管理层。
- 最小化放行原则:默认拒绝入站,仅按来源放行必要端口。
- firewalld 用 zone 与 --permanent,iptables 需自行持久化规则。
- 改完规则必须验证端口暴露面并确认重启后仍生效。
很多运维和站长都遇到过这种情况:服务明明跑着,端口却时通时不通;或者为了图省事直接 iptables -F 清空规则,结果把 SSH 一起关在门外。问题往往不在命令本身,而在于没搞清服务器防火墙的层次关系,也没建立“默认拒绝、按需放行”的最小化规则习惯。下面从原理到命令,给出一套可直接照做的配置与验证流程。
一、服务器防火墙是什么:先分清三层关系
Linux 上的服务器防火墙本质是内核的 netfilter 框架,它在数据包经过协议栈的关键节点上挂载钩子,按规则决定放行、丢弃还是拒绝。我们平时敲的命令只是操作这套框架的工具:
- netfilter:内核态过滤引擎,真正干活的一层。
- iptables:用户态命令行工具,直接读写表(filter/nat)与链(INPUT/OUTPUT/FORWARD)。
- firewalld:运行在 iptables(或 nftables)之上的动态管理层,用 zone 组织规则,支持运行时与永久配置分离。
所以“iptables 与 firewalld 区别”不是二选一的替代关系,而是底层规则工具与上层管理服务的关系。理解了这点,才不会出现两套规则互相打架。
二、iptables 与 firewalld 的核心区别
| 维度 | iptables | firewalld |
|---|---|---|
| 定位 | 直接操作规则表 | 动态管理防火墙的服务 |
| 规则组织 | 表 → 链 → 规则 | zone → service/port/rich rule |
| 生效方式 | 立即生效,需自行持久化 | 运行时与 permanent 分离,reload 生效 |
| 增删体验 | 插入位置敏感,需 -I/-A 区分 | 按服务名放行,语义清晰 |
| 典型发行版 | Debian/Ubuntu 常见 | CentOS/RHEL 7+ 默认 |
实战建议:新机器优先跟随发行版默认栈,不要在同一台机器上同时手工维护 iptables 规则和 firewalld 规则,否则 firewall-cmd --reload 可能覆盖你手写的链。
三、最小化放行规则的设计原则
最小化放行的核心是三条:默认拒绝入站、只放行必要端口、尽量限定来源。先盘点监听端口,再决定放行清单:
ss -tulnp | sort -k5
# 或
netstat -tulnp
对照输出逐条问自己:这个端口是否必须对公网开放?能否只允许内网网段或固定管理 IP?典型最小化清单如下:
- SSH 22:限制管理 IP,或改高位端口并禁用密码登录。
- Web 80/443:对公网放行,但后端管理路径加访问控制。
- 数据库 3306/6379:只允许内网网段,绝不暴露公网。
- 其余端口:默认拒绝,需要时再临时放行并记录。
四、firewalld 最小化放行实操
以 CentOS/RHEL 为例,先确认服务状态与当前 zone:
systemctl status firewalld
firewall-cmd --get-default-zone
firewall-cmd --list-all
放行 SSH 并限定来源网段,再放行 Web,最后 reload 使永久配置生效:
firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="203.0.113.0/24" port port="22" protocol="tcp" accept'
firewall-cmd --permanent --add-service=http
firewall-cmd --permanent --add-service=https
firewall-cmd --reload
firewall-cmd --list-all
注意:不加 --permanent 只在运行时生效,重启即丢失;加了之后必须 --reload。删除规则用 --permanent --remove-service= 或 --remove-rich-rule=,不要直接改配置文件。
五、iptables 最小化放行实操
先看现有规则,避免盲目清空:
iptables -S
iptables -L INPUT -n -v --line-numbers
按“先放行、后拒绝”的顺序写入,默认策略最后再改,防止把自己锁死:
iptables -A INPUT -i lo -j ACCEPT
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -p tcp -s 203.0.113.0/24 --dport 22 -j ACCEPT
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
iptables -A INPUT -p tcp --dport 443 -j ACCEPT
iptables -P INPUT DROP
iptables -P FORWARD DROP
持久化是关键一步,否则重启后规则全丢:
iptables-save > /etc/iptables/rules.v4
# Debian/Ubuntu 安装 iptables-persistent 后
netfilter-persistent save
改规则前建议在另一会话执行兜底:sleep 300 && iptables -F,确认无误后再取消。
六、验证与检查清单
规则写完不等于生效正确,务必做外部验证:从另一台机器 nc -vz 目标IP 端口 测试放行与拒绝是否符合预期,并重启一次确认持久化。检查清单:
- 默认入站策略是否为 DROP/拒绝。
- SSH 是否已放行且来源受限,当前会话是否仍在线。
- 数据库等敏感端口是否仅内网可达。
- 规则是否已持久化,重启后是否仍生效。
- 云安全组与主机防火墙是否双层收敛、无冲突。
防护建议:主机防火墙只能管单机端口,面对暴力破解、异常扫描与失陷后的横向移动,还需要主机层入侵检测与规则联动。AegisX 提供的主机安全能力可与最小化放行策略配合,对异常登录和端口探测做持续监控,减少“规则配好了但没人看告警”的盲区。
行动建议:今天就登录一台服务器,用 ss -tulnp 盘点端口,按本文清单收敛到最小放行集,改完立即外部验证并重启确认。把规则变更记录进运维文档,下一次排障会省下大量时间。
常见问题(FAQ)
服务器防火墙到底该用 iptables 还是 firewalld?
结论:看发行版默认栈与团队习惯,两者底层都是 netfilter。CentOS/RHEL 7+ 默认 firewalld,适合动态增删与 zone 管理;Debian/Ubuntu 常见直接写 iptables 或用 ufw。关键不是选谁,而是不要两套同时乱写,避免规则互相覆盖、排查困难。
为什么我放行了端口,重启后又访问不了?
结论:规则没有持久化。firewalld 必须加 --permanent 再 reload,否则只在运行时生效;iptables 用 iptables-save 写入文件并由 iptables-persistent 或 systemd 单元恢复。改完用 firewall-cmd --list-all 或 iptables -S 核对,并实际重启验证一次。
最小化放行规则具体要放行哪些端口?
结论:只放行对外提供服务且限定来源的端口。典型是 SSH 22(最好限制管理 IP 或改高位端口)、Web 80/443;数据库 3306/6379 只允许内网网段;其余一律默认拒绝。先 netstat -tulnp 或 ss -tulnp 列出监听端口,再逐个确认是否必须对外。
误封 SSH 把自己关在门外怎么办?
结论:改规则前先保留一条已登录会话,并配置回滚定时任务。可在另一终端执行 sleep 300 && iptables -F 或 firewall-cmd --panic-off 兜底;云主机还可通过控制台 VNC 登录。放行 SSH 时先加规则再删旧规则,顺序不能反。
iptables 和云安全组要配哪个?
结论:两者都要,且职责不同。安全组在云平台侧做第一层过滤,主机防火墙做第二层兜底,防止安全组误放开或内网横向。建议安全组只放行必要来源,主机侧再按网段收敛,形成双层最小化放行。