ky818smKy818sm  2025-10-08 11:48 旷野小站 隐藏边栏 |   抢沙发  1 
文章评分 0 次,平均分 0.0

1. 理解 iptables 的基本结构

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

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

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

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

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

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

语法概览:

iptables <span class="token parameter variable">-t</span> <span class="token operator"><</span>table<span class="token operator">></span> <span class="token parameter variable">-A</span> <span class="token operator"><</span>chain<span class="token operator">></span> <span class="token punctuation">[</span>matches<span class="token punctuation">]</span> <span class="token parameter variable">-j</span> <span class="token operator"><</span>target<span class="token operator">></span>
  • -t <table>: 指定表,默认为 filter

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

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

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


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

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

2.1 state - 连接状态跟踪

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

  • 模块名: state

  • 常用匹配: --state

  • 状态类型

    • NEW: 新建立的连接。

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

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

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

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

<span class="token comment"># 允许本机发起的出站流量(NEW 状态)</span>
iptables <span class="token parameter variable">-A</span> OUTPUT <span class="token parameter variable">-m</span> state <span class="token parameter variable">--state</span> NEW,ESTABLISHED <span class="token parameter variable">-j</span> ACCEPT
<span class="token comment"># 允许属于已建立连接的回包进入(ESTABLISHED, RELATED 状态)</span>
iptables <span class="token parameter variable">-A</span> INPUT <span class="token parameter variable">-m</span> state <span class="token parameter variable">--state</span> ESTABLISHED,RELATED <span class="token parameter variable">-j</span> ACCEPT

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

实例2: 允许 SSH 入站连接

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

2.2 multiport - 多端口匹配

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

  • 模块名: multiport

  • 常用匹配

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

    • --sports: 源端口列表。

实例: 允许访问多个服务

<span class="token comment"># 允许访问 HTTP(80), HTTPS(443), 和 SSH(22) 端口</span>
iptables <span class="token parameter variable">-A</span> INPUT <span class="token parameter variable">-p</span> tcp <span class="token parameter variable">-m</span> multiport <span class="token parameter variable">--dports</span> <span class="token number">22,80</span>,443 <span class="token parameter variable">-m</span> state <span class="token parameter variable">--state</span> NEW <span class="token parameter variable">-j</span> ACCEPT

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

2.3 limit - 速率限制

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

  • 模块名: limit

  • 常用匹配

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

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

实例: 限制 ICMP (Ping) 请求

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

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

2.4 connlimit - 连接数限制

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

  • 模块名: connlimit

  • 常用匹配

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

实例: 防止 SSH 暴力破解

<span class="token comment"># 限制每个 IP 地址同时只能有 3 个 SSH 连接</span>
iptables <span class="token parameter variable">-A</span> INPUT <span class="token parameter variable">-p</span> tcp <span class="token parameter variable">--dport</span> <span class="token number">22</span> <span class="token parameter variable">-m</span> connlimit --connlimit-above <span class="token number">3</span> <span class="token parameter variable">-j</span> REJECT

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

2.5 recent - 动态列表

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

  • 模块名: recent

  • 常用参数

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

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

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

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

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

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

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

<span class="token comment"># 目标:如果某个 IP 在 60 秒内对超过 5 个不同的端口发送 SYN 包,则封禁该 IP 5 分钟。</span>

<span class="token comment"># 1. 创建一个名为 'portscan’ 的列表,记录扫描者 IP</span>
iptables <span class="token parameter variable">-A</span> INPUT <span class="token parameter variable">-p</span> tcp --tcp-flags SYN,ACK,FIN,RST SYN <span class="token parameter variable">-m</span> recent <span class="token parameter variable">--name</span> portscan <span class="token parameter variable">--set</span> <span class="token parameter variable">-j</span> DROP

<span class="token comment"># 2. 检查该 IP 在 60 秒内是否已经尝试连接了超过 5 次(--hitcount 6)</span>
iptables <span class="token parameter variable">-A</span> INPUT <span class="token parameter variable">-m</span> recent <span class="token parameter variable">--name</span> portscan <span class="token parameter variable">--rcheck</span> <span class="token parameter variable">--seconds</span> <span class="token number">60</span> <span class="token parameter variable">--hitcount</span> <span class="token number">6</span> <span class="token parameter variable">-j</span> LOG --log-prefix <span class="token string">"Portscan blocked: "</span>
iptables <span class="token parameter variable">-A</span> INPUT <span class="token parameter variable">-m</span> recent <span class="token parameter variable">--name</span> portscan <span class="token parameter variable">--rcheck</span> <span class="token parameter variable">--seconds</span> <span class="token number">60</span> <span class="token parameter variable">--hitcount</span> <span class="token number">6</span> <span class="token parameter variable">-j</span> DROP

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

2.6 string - 字符串匹配

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

  • 模块名: string

  • 常用匹配

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

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

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

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

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

2.7 iprange - IP 范围匹配

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

  • 模块名: iprange

  • 常用匹配

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

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

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

<span class="token comment"># 允许 192.168.1.10 到 192.168.1.50 的 IP 访问 MySQL</span>
iptables <span class="token parameter variable">-A</span> INPUT <span class="token parameter variable">-p</span> tcp <span class="token parameter variable">--dport</span> <span class="token number">3306</span> <span class="token parameter variable">-m</span> iprange --src-range <span class="token number">192.168</span>.1.10-192.168.1.50 <span class="token parameter variable">-j</span> 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: 共享上网 (网关服务器)

<span class="token comment"># 启用 IP 转发</span>
<span class="token function">sysctl</span> <span class="token parameter variable">-w</span> <span class="token assign-left variable">net.ipv4.ip_forward</span><span class="token operator">=</span><span class="token number">1</span>

<span class="token comment"># 对从内网 (eth1) 发出,前往外网 (eth0) 的流量进行源地址转换</span>
iptables <span class="token parameter variable">-t</span> nat <span class="token parameter variable">-A</span> POSTROUTING <span class="token parameter variable">-o</span> eth0 <span class="token parameter variable">-s</span> <span class="token number">192.168</span>.1.0/24 <span class="token parameter variable">-j</span> MASQUERADE

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

<span class="token comment"># 在 PREROUTING 链中,将到达本机 8080 端口的流量目标改为内网服务器</span>
iptables <span class="token parameter variable">-t</span> nat <span class="token parameter variable">-A</span> PREROUTING <span class="token parameter variable">-p</span> tcp <span class="token parameter variable">--dport</span> <span class="token number">8080</span> <span class="token parameter variable">-j</span> DNAT --to-destination <span class="token number">192.168</span>.1.100:80

<span class="token comment"># 在 POSTROUTING 链中,修改源地址,让回包能正确返回</span>
iptables <span class="token parameter variable">-t</span> nat <span class="token parameter variable">-A</span> POSTROUTING <span class="token parameter variable">-p</span> tcp <span class="token parameter variable">-d</span> <span class="token number">192.168</span>.1.100 <span class="token parameter variable">--dport</span> <span class="token number">80</span> <span class="token parameter variable">-j</span> MASQUERADE

<span class="token comment"># 同时需要在 filter 表的 FORWARD 链中允许此流量</span>
iptables <span class="token parameter variable">-A</span> FORWARD <span class="token parameter variable">-p</span> tcp <span class="token parameter variable">-d</span> <span class="token number">192.168</span>.1.100 <span class="token parameter variable">--dport</span> <span class="token number">80</span> <span class="token parameter variable">-m</span> state <span class="token parameter variable">--state</span> NEW,ESTABLISHED <span class="token parameter variable">-j</span> ACCEPT
iptables <span class="token parameter variable">-A</span> FORWARD <span class="token parameter variable">-p</span> tcp <span class="token parameter variable">-s</span> <span class="token number">192.168</span>.1.100 <span class="token parameter variable">--sport</span> <span class="token number">80</span> <span class="token parameter variable">-m</span> state <span class="token parameter variable">--state</span> ESTABLISHED <span class="token parameter variable">-j</span> ACCEPT

3.2 mangle 表 - 数据包修改

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

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

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

<span class="token comment"># 给 SSH 流量 (端口 22) 打上标记 1</span>
iptables <span class="token parameter variable">-t</span> mangle <span class="token parameter variable">-A</span> OUTPUT <span class="token parameter variable">-p</span> tcp <span class="token parameter variable">--dport</span> <span class="token number">22</span> <span class="token parameter variable">-j</span> MARK --set-mark <span class="token number">1</span>

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


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

<span class="token shebang important">#!/bin/bash</span>

<span class="token comment"># 重置所有规则</span>
iptables <span class="token parameter variable">-F</span>
iptables <span class="token parameter variable">-t</span> nat <span class="token parameter variable">-F</span>
iptables <span class="token parameter variable">-X</span> <span class="token comment"># 删除用户自定义链</span>

<span class="token comment"># 设置默认策略(谨慎使用 DROP,可能导致自己被锁在外面)</span>
iptables <span class="token parameter variable">-P</span> INPUT DROP
iptables <span class="token parameter variable">-P</span> FORWARD DROP
iptables <span class="token parameter variable">-P</span> OUTPUT ACCEPT

<span class="token comment"># 允许本地回环接口</span>
iptables <span class="token parameter variable">-A</span> INPUT <span class="token parameter variable">-i</span> lo <span class="token parameter variable">-j</span> ACCEPT

<span class="token comment"># 允许已建立和相关的连接进入(这是状态防火墙的核心)</span>
iptables <span class="token parameter variable">-A</span> INPUT <span class="token parameter variable">-m</span> state <span class="token parameter variable">--state</span> ESTABLISHED,RELATED <span class="token parameter variable">-j</span> ACCEPT

<span class="token comment"># 允许 ICMP (Ping),但加以限制</span>
iptables <span class="token parameter variable">-A</span> INPUT <span class="token parameter variable">-p</span> icmp --icmp-type echo-request <span class="token parameter variable">-m</span> limit <span class="token parameter variable">--limit</span> <span class="token number">1</span>/second <span class="token parameter variable">-j</span> ACCEPT

<span class="token comment"># 允许 SSH,但限制每个 IP 最多 3 个连接</span>
iptables <span class="token parameter variable">-A</span> INPUT <span class="token parameter variable">-p</span> tcp <span class="token parameter variable">--dport</span> <span class="token number">22</span> <span class="token parameter variable">-m</span> state <span class="token parameter variable">--state</span> NEW <span class="token parameter variable">-m</span> connlimit --connlimit-above <span class="token number">3</span> <span class="token parameter variable">-j</span> REJECT
iptables <span class="token parameter variable">-A</span> INPUT <span class="token parameter variable">-p</span> tcp <span class="token parameter variable">--dport</span> <span class="token number">22</span> <span class="token parameter variable">-m</span> state <span class="token parameter variable">--state</span> NEW <span class="token parameter variable">-j</span> ACCEPT

<span class="token comment"># 允许 HTTP 和 HTTPS</span>
iptables <span class="token parameter variable">-A</span> INPUT <span class="token parameter variable">-p</span> tcp <span class="token parameter variable">-m</span> multiport <span class="token parameter variable">--dports</span> <span class="token number">80,443</span> <span class="token parameter variable">-m</span> state <span class="token parameter variable">--state</span> NEW <span class="token parameter variable">-j</span> ACCEPT

<span class="token comment"># 记录并丢弃所有其他流量(可选)</span>
iptables <span class="token parameter variable">-A</span> INPUT <span class="token parameter variable">-j</span> LOG --log-prefix <span class="token string">"IPTables-Dropped: "</span>
iptables <span class="token parameter variable">-A</span> INPUT <span class="token parameter variable">-j</span> DROP

<span class="token builtin class-name">echo</span> <span class="token string">"Firewall rules applied."</span>

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 最实用和强大的部分。通过组合使用这些模块和功能,你可以构建出非常精细和强大的防火墙策略。

声明:本站许多内容均从网上收集整理,若有内容侵犯到您的权益,请通过邮件【6167555@qq.com】联系本站,我们将及时删除!

有问题请点我联系站长

「点点赞赏,手留余香」
HIDE

声明:本文为原创文章,版权归所有,欢迎分享本文,转载请保留出处!

发表评论

表情 格式 链接 私密 签到
扫一扫二维码分享