iptables 扩展模块和高级功能的详细实例教程

1. 理解 iptables 的基本结构

在深入扩展之前,请确保您理解 iptables 的基本框架:

  • Tables(表): 用于特定功能的链的集合。最常用的是 filter(过滤)、nat(网络地址转换)和 mangle(数据包修改)。

  • Chains(链): 规则的有序列表,存在于表中。例如 INPUTOUTPUTFORWARD

  • Rules(规则): 定义了对数据包进行匹配和处理的指令。

  • Matches(匹配): 规则中用于筛选数据包的条件。

  • Targets(目标): 当数据包匹配一条规则时,要执行的动作(如 ACCEPTDROPREJECT)。

语法概览:

iptables -t <table> -A <chain> [matches] -j <target>
  • -t <table>: 指定表,默认为 filter

  • -A <chain>: 向链末尾追加一条规则。

  • [matches]: 一个或多个匹配条件。

  • -j <target>: 跳转到目标。


2. 常用扩展模块详解与实例

大多数扩展模块通过 -m 选项加载。

2.1 state – 连接状态跟踪

这是最重要的模块之一,实现了“状态防火墙”,极大地简化了规则配置。

  • 模块名: state

  • 常用匹配: --state

  • 状态类型

    • NEW: 新建立的连接。

    • ESTABLISHED: 已建立的连接,即该连接的后续包。

    • RELATED: 与已建立连接相关的连接,如 FTP 的数据连接或 ICMP 错误消息。

    • INVALID: 无法识别的或无效的数据包。

实例1: 允许出站流量及其回包

# 允许本机发起的出站流量(NEW 状态)
iptables -A OUTPUT -m state --state NEW,ESTABLISHED -j ACCEPT
# 允许属于已建立连接的回包进入(ESTABLISHED, RELATED 状态)
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

这是防火墙配置的基础,确保了如果你从内部发起请求,响应包可以回来。

实例2: 允许 SSH 入站连接

# 允许外部发起的 NEW 状态的 SSH 连接进入
iptables -A INPUT -p tcp --dport 22 -m state --state NEW -j ACCEPT
# 注意:你仍然需要上面的 ESTABLISHED 规则来处理 SSH 连接的后续通信

2.2 multiport – 多端口匹配

允许在一条规则中匹配多个不连续的端口。

  • 模块名: multiport

  • 常用匹配

    • --dports: 目标端口列表。

    • --sports: 源端口列表。

实例: 允许访问多个服务

# 允许访问 HTTP(80), HTTPS(443), 和 SSH(22) 端口
iptables -A INPUT -p tcp -m multiport --dports 22,80,443 -m state --state NEW -j ACCEPT

这比写三条独立的规则更简洁、高效。

2.3 limit – 速率限制

用于限制匹配规则的速率,常用于防止洪水攻击。

  • 模块名: limit

  • 常用匹配

    • --limit: 平均速率(如 10/second5/minute2/hour)。

    • --limit-burst: 初始突发包数量。

实例: 限制 ICMP (Ping) 请求

# 前 5 个 Ping 请求正常通过(burst)
iptables -A INPUT -p icmp --icmp-type echo-request -m limit --limit 1/second --limit-burst 5 -j ACCEPT
# 超过限制的 Ping 请求将被丢弃(不记录,因为上一条规则已经“处理”了它们,只是限速)
iptables -A INPUT -p icmp --icmp-type echo-request -j DROP

这样,别人对你的服务器进行 Ping 时,前5个很快,之后就会被限制在每秒1个。

2.4 connlimit – 连接数限制

限制每个客户端 IP 地址到特定服务的并发连接数。

  • 模块名: connlimit

  • 常用匹配

    • --connlimit-above [n]: 当连接数超过 n 时匹配。

实例: 防止 SSH 暴力破解

# 限制每个 IP 地址同时只能有 3 个 SSH 连接
iptables -A INPUT -p tcp --dport 22 -m connlimit --connlimit-above 3 -j REJECT

这可以有效减缓攻击者尝试多个密码的速度。

2.5 recent – 动态列表

这是一个非常强大的模块,可以动态地创建和管理一个 IP 地址列表。常用于应对扫描和暴力攻击。

  • 模块名: recent

  • 常用参数

    • --name [listname]: 指定列表名称。

    • --set: 将源 IP 添加到列表。

    • --rcheck: 检查 IP 是否在列表中。

    • --update: 同 --rcheck,但会更新时间戳。

    • --seconds [n]: 与 --rcheck 或 --update 一起使用,指定时间窗口。

    • --hitcount [n]: 在时间窗口内命中的次数。

实例: 端口敲门 (Port Knocking) 或防扫描

# 目标:如果某个 IP 在 60 秒内对超过 5 个不同的端口发送 SYN 包,则封禁该 IP 5 分钟。

# 1. 创建一个名为 'portscan’ 的列表,记录扫描者 IP
iptables -A INPUT -p tcp --tcp-flags SYN,ACK,FIN,RST SYN -m recent --name portscan --set -j DROP

# 2. 检查该 IP 在 60 秒内是否已经尝试连接了超过 5 次(--hitcount 6)
iptables -A INPUT -m recent --name portscan --rcheck --seconds 60 --hitcount 6 -j LOG --log-prefix "Portscan blocked: "
iptables -A INPUT -m recent --name portscan --rcheck --seconds 60 --hitcount 6 -j DROP

# 3. 可选: 600 秒后将该 IP 从列表中移除
# (这通常由 `recent` 模块自动管理,但可以通过 `/proc/net/xt_recent/` 手动操作)

2.6 string – 字符串匹配

可以在数据包负载(Payload)中搜索特定字符串。

  • 模块名: string

  • 常用匹配

    • --string "[pattern]": 要匹配的字符串。

    • --algo [algorithm]: 匹配算法,如 bm (Boyer-Moore) 或 kmp

实例: 屏蔽含有 “blocked-site.com” 的 HTTP 请求

# 假设服务器是透明代理。阻止访问特定域名的 HTTP 请求。
iptables -A FORWARD -p tcp --dport 80 -m string --string "Host: blocked-site.com" --algo bm -j DROP

注意: 此模块对性能有较大影响,且不适用于加密流量(HTTPS)。

2.7 iprange – IP 范围匹配

匹配一个范围内的 IP 地址,比使用子网掩码更灵活。

  • 模块名: iprange

  • 常用匹配

    • --src-range: 源 IP 范围。

    • --dst-range: 目标 IP 范围。

实例: 允许内部一个 IP 段访问

# 允许 192.168.1.10 到 192.168.1.50 的 IP 访问 MySQL
iptables -A INPUT -p tcp --dport 3306 -m iprange --src-range 192.168.1.10-192.168.1.50 -j ACCEPT

3. 高级功能与表

3.1 nat 表 – 网络地址转换

用于修改数据包的源或目标地址。

  • SNAT (Source NAT): 修改出站数据包的源地址。常用于共享上网。

    • -j SNAT --to-source [ip]

  • DNAT (Destination NAT): 修改入站数据包的目标地址。常用于端口转发。

    • -j DNAT --to-destination [ip]:[port]

  • MASQUERADE: SNAT 的一种特殊形式,用于动态获取 IP 的接口(如 PPPoE、DHCP)。

实例1: 共享上网 (网关服务器)

# 启用 IP 转发
sysctl -w net.ipv4.ip_forward=1

# 对从内网 (eth1) 发出,前往外网 (eth0) 的流量进行源地址转换
iptables -t nat -A POSTROUTING -o eth0 -s 192.168.1.0/24 -j MASQUERADE

实例2: 端口转发 (将公网 IP 的 8080 转发到内网 Web 服务器)

# 在 PREROUTING 链中,将到达本机 8080 端口的流量目标改为内网服务器
iptables -t nat -A PREROUTING -p tcp --dport 8080 -j DNAT --to-destination 192.168.1.100:80

# 在 POSTROUTING 链中,修改源地址,让回包能正确返回
iptables -t nat -A POSTROUTING -p tcp -d 192.168.1.100 --dport 80 -j MASQUERADE

# 同时需要在 filter 表的 FORWARD 链中允许此流量
iptables -A FORWARD -p tcp -d 192.168.1.100 --dport 80 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A FORWARD -p tcp -s 192.168.1.100 --sport 80 -m state --state ESTABLISHED -j ACCEPT

3.2 mangle 表 – 数据包修改

用于修改数据包的 TTL、TOS 等字段,或结合 MARK 目标打标记,用于高级路由策略。

  • 常用目标: -j MARK --set-mark [value]

实例: 对特定端口的流量打标记,用于策略路由

# 给 SSH 流量 (端口 22) 打上标记 1
iptables -t mangle -A OUTPUT -p tcp --dport 22 -j MARK --set-mark 1

然后,你可以在路由规则(ip rule)中使用 fwmark 1 来让这些数据包走不同的路由表。


4. 综合实战: 一个简单的 Web 服务器防火墙

#!/bin/bash

# 重置所有规则
iptables -F
iptables -t nat -F
iptables -X # 删除用户自定义链

# 设置默认策略(谨慎使用 DROP,可能导致自己被锁在外面)
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 (Ping),但加以限制
iptables -A INPUT -p icmp --icmp-type echo-request -m limit --limit 1/second -j ACCEPT

# 允许 SSH,但限制每个 IP 最多 3 个连接
iptables -A INPUT -p tcp --dport 22 -m state --state NEW -m connlimit --connlimit-above 3 -j REJECT
iptables -A INPUT -p tcp --dport 22 -m state --state NEW -j ACCEPT

# 允许 HTTP 和 HTTPS
iptables -A INPUT -p tcp -m multiport --dports 80,443 -m state --state NEW -j ACCEPT

# 记录并丢弃所有其他流量(可选)
iptables -A INPUT -j LOG --log-prefix "IPTables-Dropped: "
iptables -A INPUT -j DROP

echo "Firewall rules applied."

5. 重要提示

  1. 测试规则: 在应用任何可能断开你连接的规则(尤其是默认 DROP)之前,务必在本地控制台测试,或者设置一个 cron job 在几分钟后恢复规则。

  2. 规则顺序: iptables 规则按顺序匹配,第一条匹配的规则生效。请合理安排顺序。

  3. 持久化: 上述规则在重启后会丢失。请使用 iptables-save > /etc/iptables.rules 保存,并在启动脚本中通过 iptables-restore < /etc/iptables.rules 恢复。不同发行版有不同工具(如 iptables-persistent)。

  4. 从 iptables 到 nftables: iptables 正在被 nftables 取代。建议新项目学习 nftables,但其概念和功能与 iptables 一脉相承。

这份教程涵盖了 iptables 最实用和强大的部分。通过组合使用这些模块和功能,你可以构建出非常精细和强大的防火墙策略。

发表评论

您的邮箱地址不会被公开。 必填项已用 * 标注

滚动至顶部
×
问题求助