适用场景
本教程适用于需要在 Linux 服务器上配置 iptables 防火墙规则来加固网络安全的管理员。无论你是防护 Web 服务器、数据库服务器还是 API 网关,iptables 作为 Linux 内核原生的包过滤框架,零额外依赖即可实现精细的流量控制。典型场景包括:限制 SSH 访问来源、开放指定端口、防御端口扫描、记录异常流量等。
前置条件
- Linux 服务器(CentOS 7+/Ubuntu 18.04+/Debian 10+)
- root 或 sudo 权限
- SSH 远程访问权限(配置前请确保有其他应急通道)
- iptables 已安装(多数发行版预装)
检查 iptables 是否可用:
iptables --version # 应输出类似 iptables v1.8.7
原理说明
iptables 是 Linux 内核 Netfilter 框架的用户空间管理工具。其核心概念包括:
- 表(Tables):filter(过滤)、nat(地址转换)、mangle(修改)、raw(原始包)、security(SELinux)
- 链(Chains):每个表包含若干内置链,如 INPUT(入站)、OUTPUT(出站)、FORWARD(转发)
- 规则(Rules):按顺序匹配,匹配即执行目标动作(ACCEPT/DROP/REJECT/LOG 等)
- 策略(Policy):链的默认行为,当无规则匹配时生效
iptables 防火墙的核心策略是”默认拒绝,按需放行”——先设置 INPUT 链默认策略为 DROP,然后逐条添加允许规则。这种方法能最大限度减少攻击面。
操作步骤
步骤一:查看当前规则
iptables -L -n -v --line-numbers
参数说明:-L 列出规则,-n 不解析主机名加速显示,-v 显示详细信息(包计数和字节数),–line-numbers 显示行号方便后续插入/删除。
步骤二:清空并设置默认策略
⚠️ 危险操作:以下命令会清空所有规则。如果通过 SSH 远程执行且策略设置不当,会立即断开连接。
# 清空所有规则
iptables -F
iptables -X
iptables -Z
# 设置默认策略:INPUT 和 FORWARD 默认拒绝,OUTPUT 默认允许
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT
步骤三:允许回环与已建立连接
# 允许本地回环通信(许多服务依赖 lo 接口)
iptables -A INPUT -i lo -j ACCEPT
# 允许已建立的连接和关联连接(ESTABLISHED + RELATED)
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
第二条规则至关重要——它确保你发起的出站连接(如 SSH 客户端连入)的响应包能被放行,不会因默认 DROP 策略而被拦截。
步骤四:开放 SSH 端口
在默认 DROP 策略下,必须显式允许 SSH 访问。请将 22 替换为你的实际 SSH 端口:
# 限制 SSH 仅允许特定 IP 段(更安全)
iptables -A INPUT -p tcp --dport 22 -s 192.168.1.0/24 -j ACCEPT
# 如果无固定 IP,允许所有来源(不推荐生产环境)
# iptables -A INPUT -p tcp --dport 22 -j ACCEPT
建议始终使用来源 IP 限制(-s 参数)来缩小 SSH 的攻击面。如果使用堡垒机,仅开放堡垒机 IP。
步骤五:开放 Web 服务端口
# HTTP (80)
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
# HTTPS (443)
iptables -A INPUT -p tcp --dport 443 -j ACCEPT
# 如果使用 Nginx 代理其他服务,可能需要开放其他端口
# iptables -A INPUT -p tcp --dport 8080 -s 127.0.0.1 -j ACCEPT
步骤六:限制 ICMP(Ping)防探测
# 限制 ICMP 速率,防止 ping flood
iptables -A INPUT -p icmp --icmp-type echo-request -m limit --limit 1/second -j ACCEPT
iptables -A INPUT -p icmp --icmp-type echo-request -j DROP
第一条规则允许每秒 1 个 ping 包,超过速率的被第二条规则丢弃。这样既维持了基本可达性检测,又防御了 ICMP 洪水攻击。
步骤七:防御端口扫描
# 记录并丢弃 SYN 扫描(半连接扫描)
iptables -A INPUT -p tcp --tcp-flags ALL NONE -j LOG --log-prefix "NULL_SCAN: "
iptables -A INPUT -p tcp --tcp-flags ALL NONE -j DROP
# 记录并丢弃 Xmas 扫描
iptables -A INPUT -p tcp --tcp-flags ALL ALL -j LOG --log-prefix "XMAS_SCAN: "
iptables -A INPUT -p tcp --tcp-flags ALL ALL -j DROP
# 限制同一 IP 的连接数,防止连接耗尽
iptables -A INPUT -p tcp --syn -m connlimit --connlimit-above 100 --connlimit-mask 32 -j LOG --log-prefix "CONN_LIMIT: "
iptables -A INPUT -p tcp --syn -m connlimit --connlimit-above 100 --connlimit-mask 32 -j DROP
connlimit 模块限制单个 IP 的并发连接数(示例为 100)。connlimit-mask 32 表示按单个 IP 计算(IPv4 /32)。如需要按 C 段限制,可设为 24。
步骤八:记录异常流量
# 记录被 DROP 的包到系统日志(便于事后审计)
iptables -A INPUT -j LOG --log-prefix "IPTABLES-DROP: " --log-level 4
# 注意:这条规则必须在所有放行规则之后、默认策略之前
# 它只会在没有 ACCEPT 规则匹配时执行
日志会写入 /var/log/messages 或 /var/log/syslog,可用 grep "IPTABLES-DROP" /var/log/syslog 查看。
步骤九:保存规则使其持久化
# CentOS/RHEL
yum install -y iptables-services
service iptables save
systemctl enable iptables
# Ubuntu/Debian
apt-get install -y iptables-persistent
netfilter-persistent save
配置验证
# 查看完整规则
iptables -L -n -v --line-numbers
# 测试端口可达性(在本机或另一台机器执行)
curl -I http://服务器IP # 应返回 HTTP 响应
ssh 用户@服务器IP # 应能登录
ping -c 3 服务器IP # 应收到响应(限速 1/s)
# 验证未开放端口被拒绝
curl -I http://服务器IP:3306 # 应超时或拒绝连接
nc -zv 服务器IP 3306 # 应显示连接失败
常见问题
Q1:配置后 SSH 断开怎么办?
如果你通过 SSH 远程配置且规则导致连接中断:
- 带外管理:使用 IDRAC、IPMI 或物理控制台登录恢复
- 计划任务保底:配置前先写入 crontab:
*/5 * * * * root iptables -F(每 5 分钟清空规则,留出操作窗口) - 重启恢复:如果未保存规则,重启服务器即可恢复为默认空规则(但仍需物理访问)
Q2:如何区分 DROP 和 REJECT?
DROP 静默丢弃包,客户端会一直等待直到超时(更安全,不暴露端口信息)。REJECT 返回拒绝消息(如 ICMP port-unreachable),客户端立即收到错误。生产环境建议使用 DROP,避免攻击者通过 REJECT 响应推断端口状态。
Q3:规则顺序重要吗?
非常重要。iptables 按链中的顺序逐条匹配,匹配即停止。因此:放行规则(ACCEPT)应放在前面,拒绝规则(DROP/REJECT)放在后面。如果 ACCEPT 规则在 DROP 之后,永远不会被匹配到。
总结
iptables 是 Linux 服务器安全加固的基石。通过”默认拒绝、按需放行”的策略,结合来源 IP 限制、连接数控制和异常流量日志,可以有效缩小攻击面并及时发现扫描行为。建议将 iptables 规则与 fail2ban 联动,实现自动化 IP 封禁,构建纵深防御体系。