这是《Linux 零基础实战指南》的独立章节版。本章从概念、实操和生产排查三个视角展开,代码块保留了原书可直接运行的版本。 防火墙控制主机或网络边界上的流量。Linux 上常见 nftables、iptables、firewalld、ufw,同时云平台还有安全组。排障时必须同时看这两层,否则容易得出错误结论。
23.1 netfilter
Packet
-> Prerouting
-> Input / Forward
-> Output
-> Postrouting
iptables 表:
| 表 | 用途 |
|---|---|
| filter | 过滤 |
| nat | 地址转换 |
| mangle | 修改包 |
| raw | 连接跟踪前处理 |
| security | SELinux 相关 |
链:
| 链 | 时机 |
|---|---|
| PREROUTING | 路由前 |
| INPUT | 发往本机 |
| FORWARD | 转发 |
| OUTPUT | 本机发出 |
| POSTROUTING | 路由后 |
23.2 iptables
查看:
sudo iptables -L -n -v
sudo iptables -t nat -L -n -v
sudo iptables -S
放行:
sudo iptables -A INPUT -p tcp --dport 443 -j ACCEPT
sudo iptables -A INPUT -p tcp -s 203.0.113.0/24 --dport 22 -j ACCEPT
拒绝:
sudo iptables -A INPUT -p tcp --dport 3306 -j DROP
保存与恢复:
sudo iptables-save > firewall.rules
sudo iptables-restore < firewall.rules
新系统更推荐 nftables 或 firewalld。iptables 命令在很多发行版上是兼容工具。
23.3 nftables
查看:
sudo nft list ruleset
sudo nft list tables
示例:
sudo nft add table inet filter
sudo nft add chain inet filter input '{ type filter hook input priority 0; policy drop; }'
sudo nft add rule inet filter input iifname "lo" accept
sudo nft add rule inet filter input ct state established,related accept
sudo nft add rule inet filter input tcp dport 443 accept
保存:
sudo nft list ruleset > /etc/nftables.conf
修改远程主机防火墙时,必须先放行 SSH 和已建立连接,再切换默认策略。
23.4 firewalld
sudo firewall-cmd --state
sudo firewall-cmd --get-active-zones
sudo firewall-cmd --list-all
开放:
sudo firewall-cmd --permanent --add-service=https
sudo firewall-cmd --permanent --add-port=8080/tcp
sudo firewall-cmd --reload
限制来源:
sudo firewall-cmd --permanent --new-zone=sshadmin
sudo firewall-cmd --permanent --zone=sshadmin --add-source=203.0.113.0/24
sudo firewall-cmd --permanent --zone=sshadmin --add-service=ssh
sudo firewall-cmd --reload
runtime 与 permanent 要区分:
| 模式 | 生效范围 |
|---|---|
| 默认 runtime | 立即生效,重载可能丢失 |
--permanent |
写配置,需 reload |
23.5 ufw
sudo ufw status verbose
sudo ufw allow 443/tcp
sudo ufw allow from 203.0.113.0/24 to any port 22 proto tcp
sudo ufw deny 3306/tcp
sudo ufw enable
查看编号:
sudo ufw status numbered
sudo ufw delete 3
ufw 适合简单主机,不适合表达复杂网络策略。
23.6 云安全组
云安全组通常在虚拟化或 SDN 层生效,主机内 iptables 不一定能看到。
排查连接:
ip route get <peer>
nc -vz <peer> <port>
curl -v http://<peer>:<port>
变更原则:
- 最小开放;
- 命名带业务和方向;
- 避免大段 0.0.0.0/0;
- 入方向默认拒绝;
- 记录变更原因;
- 定期清理过期规则;
- 与主机防火墙责任分层。
23.7 NAT
查看:
sudo iptables -t nat -L -n -v
sudo nft list table ip nat
SNAT:
sudo iptables -t nat -A POSTROUTING \
-s 10.0.0.0/24 -o eth0 -j MASQUERADE
DNAT:
sudo iptables -t nat -A PREROUTING \
-p tcp --dport 8080 -j DNAT --to-destination 10.0.0.10:80
转发开关:
sudo sysctl -w net.ipv4.ip_forward=1
23.8 连接跟踪
sudo conntrack -L
sudo conntrack -C
sudo conntrack -S
sysctl net.netfilter.nf_conntrack_max
常见问题:
- 表满丢新建连接;
- 长连接被超时清理;
- NAT 端口耗尽;
- 规则不对称导致回包丢;
- 双栈规则只配了 IPv4。
IPv6:
sudo ip6tables -L -n -v
sudo nft list ruleset
23.9 防火墙设计
主机入方向基线:
1. 允许 lo
2. 允许 established,related
3. 允许 ICMP / ICMPv6 必要类型
4. 允许 SSH 限制来源
5. 允许业务端口
6. 其他默认拒绝
应用部署模型:
Internet
-> LB: 443
-> App: 8080 only from LB
-> DB: 3306 only from App
-> Admin: 22 only from bastion
23.10 排障流程
1. 确认源、目标、端口、协议
2. ip route get 确认路径
3. nc / curl 分层探测
4. 查云安全组
5. 查主机防火墙
6. 查 conntrack
7. tcpdump 确认包是否到达
8. 修复后双向验证
抓包:
sudo tcpdump -ni any host <peer> and port <port>
能收到 SYN 但没有 SYN-ACK,通常是服务未监听、应用拒绝或防火墙丢弃。收到 RST 则更可能是应用或端口未开放。
本章小结
防火墙策略要按路径、方向、协议、端口和来源精确描述。Linux 主机可能同时存在 nftables、firewalld、ufw 和云安全组,多层策略都要检查。远程变更必须先保住管理通道和已建立连接。
思考题
- INPUT 和 FORWARD 链分别处理什么流量?
- firewalld runtime 和 permanent 有什么区别?
- 云安全组为什么在主机 iptables 中看不到?
- DROP 和 REJECT 的排障表现有什么不同?
- 设计一个 Web、App、DB 三层主机防火墙策略。