防火墙与网络安全
防火墙分类
| 类型 | 代表 | 工作层级 | 特点 |
|---|---|---|---|
| 包过滤防火墙 | iptables/nftables | 网络层/传输层 | 根据 IP、端口、协议过滤 |
| 状态检测防火墙 | iptables conntrack | 传输层 | 跟踪连接状态 |
| 应用层防火墙 | WAF (ModSecurity) | 应用层 | 检测 HTTP 内容 |
| 云安全组 | AWS SG / 阿里云 SG | 网络层/传输层 | 虚拟网络层面隔离 |
iptables
核心概念
四表五链
| 表(Table) | 功能 | 包含的链 |
|---|---|---|
| filter | 包过滤(默认表) | INPUT、FORWARD、OUTPUT |
| nat | 网络地址转换 | PREROUTING、OUTPUT、POSTROUTING |
| mangle | 修改包头信息 | 所有链 |
| raw | 跳过连接跟踪 | PREROUTING、OUTPUT |
匹配优先级
表的优先级:raw → mangle → nat → filter
同一链中的规则从上到下逐条匹配,匹配到即停止(除 LOG)。
iptables 常用操作
# === 查看规则 ===
iptables -L -n -v # 查看 filter 表所有链
iptables -t nat -L -n -v # 查看 nat 表
iptables -L -n --line-numbers # 显示行号(方便删除)
# === 添加规则 ===
# -A 追加到链末尾 -I 插入到指定位置(默认第1条)
# 允许 SSH(端口 22)
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
# 允许 HTTP/HTTPS
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
iptables -A INPUT -p tcp --dport 443 -j ACCEPT
# 允许已建立的连接和相关连接
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
# 允许本地回环
iptables -A INPUT -i lo -j ACCEPT
# 允许 ICMP(ping)
iptables -A INPUT -p icmp -j ACCEPT
# 允许特定 IP 段
iptables -A INPUT -s 10.0.0.0/8 -j ACCEPT
# 限制连接速率(防 DDoS)
iptables -A INPUT -p tcp --dport 80 -m limit --limit 100/s --limit-burst 200 -j ACCEPT
# 设置默认策略(最后设置!)
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT
# === 删除规则 ===
iptables -D INPUT 3 # 删除 INPUT 链第 3 条
iptables -D INPUT -p tcp --dport 8080 -j ACCEPT # 精确匹配删除
# === 清空规则 ===
iptables -F # 清空所有规则
iptables -X # 删除自定义链
iptables -Z # 清零计数器
远程操作 iptables 注意事项
远程 SSH 配置 iptables 时,务必:
- 先允许 SSH 再设 DROP 策略,否则会把自己锁在外面
- 建议使用
at命令设置定时清空,防止失联:
# 10 分钟后自动恢复(保险措施)
at now + 10 minutes <<< "iptables -F; iptables -P INPUT ACCEPT"
iptables 完整服务器配置示例
iptables-setup.sh
#!/bin/bash
# 清空现有规则
iptables -F
iptables -X
iptables -Z
# 默认策略
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT
# 允许本地回环
iptables -A INPUT -i lo -j ACCEPT
# 允许已建立的连接
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
# 允许 ICMP
iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT
# 允许 SSH(限制来源 IP)
iptables -A INPUT -p tcp --dport 22 -s 10.0.0.0/8 -j ACCEPT
# 允许 HTTP/HTTPS
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
iptables -A INPUT -p tcp --dport 443 -j ACCEPT
# 允许 DNS
iptables -A INPUT -p udp --dport 53 -j ACCEPT
iptables -A INPUT -p tcp --dport 53 -j ACCEPT
# 日志记录被拒绝的包(调试用)
iptables -A INPUT -j LOG --log-prefix "iptables-DROP: " --log-level 4
# 保存规则
# Debian/Ubuntu
iptables-save > /etc/iptables/rules.v4
# CentOS/RHEL
service iptables save
NAT 配置
# === SNAT(源地址转换)===
# 场景:内网机器通过 NAT 网关访问外网
# 开启 IP 转发
echo 1 > /proc/sys/net/ipv4/ip_forward
# 或持久化
echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf && sysctl -p
# SNAT:内网 10.0.0.0/24 通过 eth0 (公网IP 1.2.3.4) 出去
iptables -t nat -A POSTROUTING -s 10.0.0.0/24 -o eth0 -j SNAT --to-source 1.2.3.4
# 或使用 MASQUERADE(动态 IP 场景)
iptables -t nat -A POSTROUTING -s 10.0.0.0/24 -o eth0 -j MASQUERADE
# === DNAT(目标地址转换)===
# 场景:端口转发,将外网访问转发到内网服务器
# 将访问本机 80 端口的流量转发到内网 10.0.0.100:8080
iptables -t nat -A PREROUTING -p tcp --dport 80 -j DNAT --to-destination 10.0.0.100:8080
# 还需允许 FORWARD
iptables -A FORWARD -p tcp -d 10.0.0.100 --dport 8080 -j ACCEPT
firewalld
firewalld 是 CentOS 7+ / RHEL 7+ 的默认防火墙管理工具,底层使用 nftables。
区域(Zone)概念
| 区域 | 默认行为 | 典型用途 |
|---|---|---|
| drop | 丢弃所有入站 | 最严格 |
| block | 拒绝所有入站(返回拒绝消息) | 严格 |
| public | 仅允许 SSH、DHCPv6 | 默认区域 |
| external | 仅允许 SSH,启用 NAT | 外网接口 |
| dmz | 仅允许 SSH | 非军事区 |
| work | 允许 SSH、DHCP | 工作网络 |
| home | 允许更多服务 | 家庭网络 |
| internal | 类似 home | 内部网络 |
| trusted | 允许所有流量 | 完全信任 |
常用命令
# 查看状态
firewall-cmd --state
firewall-cmd --get-active-zones
firewall-cmd --list-all # 查看当前区域所有规则
# 添加服务(预定义)
firewall-cmd --add-service=http --permanent
firewall-cmd --add-service=https --permanent
# 添加端口
firewall-cmd --add-port=8080/tcp --permanent
firewall-cmd --add-port=3000-3100/tcp --permanent # 端口范围
# 允许特定来源 IP
firewall-cmd --add-rich-rule='rule family="ipv4" source address="10.0.0.0/8" accept' --permanent
# 端口转发
firewall-cmd --add-forward-port=port=80:proto=tcp:toport=8080:toaddr=10.0.0.100 --permanent
# NAT 伪装
firewall-cmd --add-masquerade --permanent
# 删除规则
firewall-cmd --remove-service=http --permanent
firewall-cmd --remove-port=8080/tcp --permanent
# 重载配置(使 --permanent 规则生效)
firewall-cmd --reload
# 紧急模式(阻断所有网络流量,含 SSH)
firewall-cmd --panic-on # 开启
firewall-cmd --panic-off # 关闭
firewalld vs iptables
- 不要同时使用 firewalld 和直接操作 iptables
- firewalld 运行时会重写 iptables 规则
- CentOS 7+ 推荐使用 firewalld
- 如果必须使用 iptables,先停用 firewalld:
systemctl disable --now firewalld
nftables
nftables 是 iptables 的继任者(Linux 3.13+),语法更现代:
# 查看规则
nft list ruleset
# 基础配置示例
nft add table inet filter
nft add chain inet filter input { type filter hook input priority 0 \; policy drop \; }
nft add rule inet filter input iif lo accept
nft add rule inet filter input ct state established,related accept
nft add rule inet filter input tcp dport 22 accept
nft add rule inet filter input tcp dport { 80, 443 } accept
nft add rule inet filter input icmp type echo-request accept
# 保存
nft list ruleset > /etc/nftables.conf
云安全组
安全组 vs 传统防火墙
| 维度 | 安全组 | iptables/firewalld |
|---|---|---|
| 作用层面 | 虚拟网络层 | 主机层 |
| 规则类型 | 白名单(只允许) | 白名单 + 黑名单 |
| 状态检测 | 有状态(自动放行返回包) | 需配置 conntrack |
| 生效范围 | 可关联多台 ECS | 单机 |
| 优先级 | 在 iptables 之前 | 在安全组之后 |
安全组最佳实践
# 最小权限原则
1. 默认拒绝所有入站
2. 仅开放必要端口
3. 限制来源 IP 范围
4. SSH 仅允许跳板机 IP
5. 数据库端口仅对应用服务器开放
# 典型配置
入站规则:
| 协议 | 端口 | 来源 | 说明 |
|-----|------|------|------|
| TCP | 22 | 跳板机 SG | SSH 管理 |
| TCP | 80, 443 | 0.0.0.0/0 | Web 服务 |
| TCP | 3306 | 应用服务器 SG | MySQL |
| TCP | 6379 | 应用服务器 SG | Redis |
常见面试问题
Q1: iptables 的四表五链是什么?数据包经过 iptables 的流程?
答案:
四表:raw → mangle → nat → filter(按优先级排序)
五链:PREROUTING → INPUT → FORWARD → OUTPUT → POSTROUTING
数据包流程:
- 进入本机:PREROUTING → INPUT → 本机进程
- 本机发出:本机进程 → OUTPUT → POSTROUTING
- 转发:PREROUTING → FORWARD → POSTROUTING
每个链中按表优先级依次匹配规则,命中即执行动作(ACCEPT/DROP/REJECT)。
Q2: SNAT 和 DNAT 的区别?各适用什么场景?
答案:
- SNAT(源地址转换):修改数据包的源 IP。用于内网机器通过 NAT 网关访问外网。在 POSTROUTING 链操作。
- DNAT(目标地址转换):修改数据包的目标 IP。用于将外网请求转发到内网服务器(端口映射)。在 PREROUTING 链操作。
- MASQUERADE:特殊的 SNAT,自动使用出接口 IP,适合动态 IP 场景。
Q3: 远程配置防火墙时如何避免把自己锁在外面?
答案:
- 先放行 SSH 再设置默认 DROP
- 使用
at命令设置定时恢复:at now + 10 minutes <<< "iptables -F; iptables -P INPUT ACCEPT" - 使用
iptables-apply命令(自动回滚) - 通过带外管理(IPMI/KVM/云控制台)应急
- 测试验证后再
iptables-save持久化
Q4: 安全组和 iptables 的关系?哪个先生效?
答案:
云环境中,数据包先经过安全组过滤,再到达 ECS 实例的 iptables。两者是叠加关系,必须同时允许才能通过。最佳实践是安全组做粗粒度控制(IP 段 + 端口),iptables 做细粒度控制(速率限制、日志记录等)。