导读:全面掌握 iptables:从基础到实践
在 Linux 系统中,
iptables
是一个非常强大的工具,它不仅是系统管理员用来构建和管理网络防火墙的首选工具,而且也是一个功能丰富的网络流量处理系统。无论是进行包过滤、监控网络流量、还是实现复杂的网络地址转换 (NAT),
iptables
都能提供灵活的解决方案。本文将带你深入理解
iptables
的组成结构,掌握其常用命令,并通过具体的使用场景展示如何在实际中应用这些知识。
iptables
是 Linux 操作系统中的一个非常强大的防火墙工具,它使用表格来组织防火墙规则,这些表格中的规则用于决定如何处理穿过防火墙的数据包。
iptables
基于 Netfilter,Netfilter 是 Linux 内核的一个部分,负责处理通过网络栈的所有数据包。通过使用
iptables
,系统管理员可以定义规则,这些规则决定了如何处理进入、穿过和离开网络的数据包。
一、iptables
的主要组成
表 (Tables)
iptables
的规则分布在不同的“表”中,这些表是处理特定类型数据包的集合。每个表包含一个或多个“链”,这些链定义了数据包流经网络栈的不同点在何处应用这些规则。
filter
表- 用途: 主要用于决定数据包的基本处理,如是否允许数据包通过。- 包含的链: -INPUT
: 处理进入本机的数据包。-FORWARD
: 处理经过本机路由到其他网络的数据包。-OUTPUT
: 处理由本机产生的数据包。nat
表- 用途: 用于网络地址转换(NAT),包括源地址和目标地址的转换,主要用于路由设备。- 包含的链: -PREROUTING
: 用于目标地址转换(DNAT),处理进入网络接口的数据包。-POSTROUTING
: 用于源地址转换(SNAT),处理即将离开网络接口的数据包。-OUTPUT
: 对于生成自本地进程的数据包,处理其目标地址转换。mangle
表- 用途: 用于修改数据包的服务类型(TOS)字段或其他 IP 头信息,主要用于特殊的路由标记。- 包含的链: -PREROUTING
: 修改进入网络接口的数据包。-INPUT
: 修改到达本机的数据包。-FORWARD
: 修改经过本机的数据包。-OUTPUT
: 修改本机产生的数据包。-POSTROUTING
: 修改即将离开本机的数据包。raw
表- 用途: 主要用于配置免除连接跟踪的数据包,可以用来提高性能。- 包含的链: -PREROUTING
: 设置进入网络接口前的数据包是否避开状态跟踪。-OUTPUT
: 设置由本机产生的数据包是否避开状态跟踪。security
表- 用途: 用于设置强制访问控制网络规则,通常与 SELinux 安全策略配合使用。- 包含的链: -INPUT
: 设置进入本机的数据包的安全标记。-FORWARD
: 设置经过本机的数据包的安全标记。-OUTPUT
: 设置本机产生的数据包的安全标记。
链 (Chains)
表中的每个链代表数据包处理的一个阶段。预定义的链有:
PREROUTING
: 用于处理进入网络接口的数据包,主要用于nat
和mangle
表。INPUT
: 处理到达本机的数据包,用于filter
,mangle
, 和security
表。FORWARD
: 处理经过本机路由到其他网络的数据包,用于filter
,mangle
, 和security
表。OUTPUT
: 处理本机产生的数据包,用于filter
,nat
,mangle
,raw
, 和security
表。POSTROUTING
: 处理即将离开网络接口的数据包,用于nat
和mangle
表。
规则 (Rules)
规则定义了对特定条件下的数据包应该执行的操作。每条规则都关联到一个链,规则包含两个主要部分:
- 匹配条件: 定义了哪些数据包会被规则匹配。匹配条件可以包括多种属性:- 源和目标 IP 地址 (
-s
,-d
)- 源和目标端口 (--sport
,--dport
)- 协议类型 (-p
), 如 TCP (tcp
), UDP (udp
), ICMP (icmp
)- 网络接口 (-i
,-o
)- 更多复杂匹配,如连接状态 (-m state --state
), 包大小 (-m length --length
), 时间段 (-m time --timestart
) - 目标 (Targets): 当规则匹配到一个数据包时,定义了应采取的行动。常见的内置目标有:-
ACCEPT
: 允许数据包通过。-DROP
: 静默丢弃数据包,不给发送方任何响应。-REJECT
: 拒绝数据包,并向发送方发送一个错误响应。-LOG
: 记录数据包的信息,然后继续处理该数据包。-MASQUERADE
: 用于动态 NAT,隐藏数据包的源 IP。-REDIRECT
: 修改数据包的目标 IP/端口为本机,用于本地端口重定向。
用户定义的链
用户可以定义自己的链来组织复杂的规则集。这允许更灵活的管理,例如创建一个专用链处理特定类型的流量,然后在预定义链中调用这个用户链。
二、常用
iptables
命令
iptables
是一个功能强大的工具,用于在 Linux 上管理网络包过滤和 NAT 规则。以下是详细解释
iptables
的常用命令和参数,帮助你更好地理解如何使用这个工具。
基本
iptables
命令格式
iptables [option] [chain] [matching criteria] [action]
- [option]: 指定命令的选项,如
-A
(添加)、-D
(删除)、-L
(列出) 等。 - [chain]: 指定规则应用于哪个链,如
INPUT
,FORWARD
,OUTPUT
等。 - [matching criteria]: 指定匹配数据包的条件,如
-p tcp
(匹配 TCP 协议的数据包)。 - [action]: 指定当匹配到数据包时执行的动作,如
-j ACCEPT
(接受数据包)。
查看规则
- 查看所有规则
iptables -L -n -v
--L
: 列出所有规则。--v
: 显示详细信息,包括通过每条规则的数据包和字节数。--n
: 使用数字显示 IP 地址和端口,不进行域名解析,以加快显示速度。 - 查看特定表的规则
iptables -t nat -L
--t nat
: 指定要查看的表,这里是nat
表。
添加规则
- 允许进入的 SSH 连接
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
--A INPUT
: 在INPUT
链末尾添加规则。--p tcp
: 匹配 TCP 协议的数据包。---dport 22
: 匹配目的端口为 22 的数据包。--j ACCEPT
: 对匹配的数据包执行ACCEPT
动作。 - 允许出去的 HTTP 连接
iptables -A OUTPUT -p tcp --dport 80 -j ACCEPT
--A OUTPUT
: 在OUTPUT
链末尾添加规则。--p tcp
: 匹配 TCP 协议的数据包。---dport 80
: 匹配目的端口为 80 的数据包。
删除规则
- 删除特定的规则
iptables -D INPUT -p tcp --dport 22 -j ACCEPT
--D INPUT
: 从INPUT
链删除规则。- 其余参数定义了要删除的规则的匹配条件和动作。 - 按编号删除规则首先,使用
-L --line-numbers
查看规则及其编号:iptables -L INPUT -n --line-numbers
然后,根据编号删除规则:iptables -D INPUT 1
- 删除INPUT
链中编号为 1 的规则。
修改规则
- 使用编号修改规则
iptables -R INPUT 1 -p tcp --dport 22 -j DROP
--R INPUT 1
: 在INPUT
链中替换编号为 1 的规则。--p tcp --dport 22
: 匹配 TCP 协议且目的端口为 22 的数据包。--j DROP
: 新的动作是丢弃数据包。
插入规则
- 在链的特定位置插入规则
iptables -I INPUT 1 -p tcp --dport 80 -j ACCEPT
--I INPUT 1
: 在INPUT
链的第 1 位置插入规则。--p tcp --dport 80
: 匹配 TCP 协议且目的端口为 80 的数据包。
设置默认策略
- 设置链的默认策略
iptables -P INPUT DROPiptables -P FORWARD DROPiptables -P OUTPUT ACCEPT
--P INPUT DROP
: 设置INPUT
链的默认策略为DROP
。--P FORWARD DROP
: 设置FORWARD
链的默认策略为DROP
。--P OUTPUT ACCEPT
: 设置OUTPUT
链的默认策略为ACCEPT
。
保存和恢复规则
- 保存当前的规则
iptables-save > /etc/iptables.rules
-iptables-save
: 输出当前的iptables
规则。- 重定向到/etc/iptables.rules
文件中保存。 - 从文件恢复规则
iptables-restore < /etc/iptables.rules
-iptables-restore
: 从输入读取规则并应用。-/etc/iptables.rules
: 包含要恢复的规则。
清空规则
- 清空所有规则
iptables -F
--F
: 清空(Flush)所有链的所有规则。 - 清空特定表的规则
iptables -t nat -F
--t nat
: 指定清空nat
表的规则。 - 删除所有非默认链
iptables -X
--X
: 删除所有用户定义的链。
端口重定向和 NAT
- 将外部端口 80 重定向到本地的 8080 端口
iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 8080
--t nat
: 在nat
表操作。--A PREROUTING
: 在PREROUTING
链末尾添加规则。--p tcp --dport 80
: 匹配目的端口为 80 的 TCP 数据包。--j REDIRECT --to-port 8080
: 重定向这些数据包到本机的 8080 端口。 - 源 NAT (SNAT): 修改源 IP 地址
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
--A POSTROUTING
: 在POSTROUTING
链末尾添加规则。--o eth0
: 匹配从eth0
网络接口发出的数据包。--j MASQUERADE
: 对这些数据包执行地址伪装,常用于动态 IP 地址。 - 目标 NAT (DNAT): 修改目标 IP 地址
iptables -t nat -A PREROUTING -p tcp --dport 8080 -j DNAT --to-destination 192.168.1.10:80
--A PREROUTING
: 在PREROUTING
链末尾添加规则。--p tcp --dport 8080
: 匹配目的端口为 8080 的 TCP 数据包。--j DNAT --to-destination 192.168.1.10:80
: 修改数据包的目标 IP 和端口。
高级匹配和限速
- 防止 SSH 爆破攻击为了防止 SSH 爆破,我们可以使用
recent
模块来跟踪来自同一 IP 地址的连接尝试。如果在指定时间内超过了特定次数的连接尝试,则暂时拒绝来自该 IP 的连接。iptables -A INPUT -p tcp --dport 22 -m state --state NEW -m recent --setiptables -A INPUT -p tcp --dport 22 -m state --state NEW -m recent --update --seconds 60 --hitcount 10 -j DROP
--m state --state NEW
: 只匹配新建连接。--m recent --set
: 对匹配的每个新连接,记录其信息。--m recent --update
: 更新最近的信息,并检查条件。---seconds 60
: 指定时间窗口为 60 秒。---hitcount 10
: 如果在 60 秒内同一 IP 尝试新建连接超过 10 次,则匹配此规则。--j DROP
: 拒绝这些匹配的数据包。
日志记录
iptables
支持将匹配的数据包信息记录到系统日志中,这对于调试和安全监控非常有用。
- 记录被拒绝的数据包信息
iptables -A INPUT -j LOG --log-prefix "IPTables-Dropped: " --log-level 4
--j LOG
: 使用 LOG 目标记录数据包信息。---log-prefix "IPTables-Dropped: "
: 指定日志记录的前缀,便于在日志文件中搜索。---log-level 4
: 指定日志的级别(4 表示 warning 级别)。
状态检查
利用
state
模块,可以匹配数据包的连接跟踪状态,这是构建复杂防火墙规则的基础。
- 允许基于状态的数据包传输
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPTiptables -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
--m state --state ESTABLISHED,RELATED
: 匹配状态为ESTABLISHED
或RELATED
的数据包。-ESTABLISHED
: 表示数据包是属于已经建立的连接。-RELATED
: 表示数据包是与现有的连接相关的(例如,FTP 数据连接)。
时间条件匹配
使用
time
模块可以基于时间条件匹配数据包,这可以用于实现基于时间的访问控制策略。
- 只在工作时间允许 HTTP 访问
iptables -A INPUT -p tcp --dport 80 -m time --timestart 09:00 --timestop 17:00 --weekdays Mon,Tue,Wed,Thu,Fri -j ACCEPT
--m time
: 使用时间模块。---timestart 09:00 --timestop 17:00
: 指定允许匹配的开始和结束时间。---weekdays Mon,Tue,Wed,Thu,Fri
: 指定允许匹配的星期几。
接口匹配
可以根据数据包使用的网络接口进行匹配。
- 允许来自特定接口的数据包
iptables -A INPUT -i eth0 -p tcp --dport 80 -j ACCEPT
--i eth0
: 只匹配通过eth0
网络接口进入的数据包。--p tcp --dport 80
: 匹配目的端口为 80 的 TCP 数据包。
用户自定义链
用户可以定义自己的链来组织规则,这可以使规则集更加结构化和模块化。
- 定义和使用自定义链
iptables -N LOGGINGiptables -A INPUT -j LOGGINGiptables -A LOGGING -m limit --limit 2/min -j LOG --log-prefix "Input-Dropped: "iptables -A LOGGING -j DROP
--N LOGGING
: 创建一个名为LOGGING
的新链。--A LOGGING -m limit --limit 2/min -j LOG
: 在LOGGING
链中,使用limit
模块限制日志记录的速率,防止日志文件快速增长。--j DROP
: 在LOGGING
链的最后,丢弃所有数据包。
保存和加载规则
iptables
规则默认在系统重启后不会保存。你需要手动保存规则,并在系统启动时加载它们。
- 保存规则到文件
iptables-save > /etc/iptables.rules
-iptables-save
: 输出当前的所有iptables
规则。->
: 重定向输出到文件/etc/iptables.rules
。 - 加载规则从文件
iptables-restore < /etc/iptables.rules
-iptables-restore
: 从给定的输入加载iptables
规则。-< /etc/iptables.rules
: 从文件/etc/iptables.rules
读取规则。
清空和重置
有时你可能需要清空所有规则,重置
iptables
到初始状态。
- 清空所有规则和自定义链
iptables -Fiptables -X
--F
: 清空所有链的所有规则。--X
: 删除所有用户定义的链。
三、使用场景举例
使用
iptables
的场景非常多样,覆盖从简单的主机防火墙到复杂的网络路由和 NAT 配置。下面是一些具体的使用场景,展示如何利用
iptables
解决实际问题。
1. 基本的主机防护
在这个场景中,我们利用
iptables
设置基本的网络访问控制,以保护主机不受未授权访问。
允许特定的服务访问
假设你想在一台服务器上开放 SSH (端口 22) 和 HTTP (端口 80) 服务,同时拒绝所有其他未经授权的入站连接。
# 设置默认策略
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT
# 允许本地回环接口
iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT
# 允许已建立的和相关的连接
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
# 允许 SSH
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
# 允许 HTTP
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
# Optional: 允许 HTTPS
iptables -A INPUT -p tcp --dport 443 -j ACCEPT
2. 防止 DDoS 攻击
使用
iptables
限制单个源 IP 的连接频率,以防止简单的 DDoS 攻击或 SSH 爆破。
限制 SSH 连接尝试
# 允许每个 IP 每分钟最多新建 3 个 SSH 连接
iptables -A INPUT -p tcp --dport 22 -m state --state NEW -m recent --set
iptables -A INPUT -p tcp --dport 22 -m state --state NEW -m recent --update --seconds 60 --hitcount 4 -j DROP
这种设置能够有效减少暴力破解 SSH 密码的风险。
3. 端口转发
在某些情况下,你可能需要将到达某个端口的流量重定向到另一个端口上,例如将 80 端口的 HTTP 流量转发到 8080 端口。
将 80 端口转发到 8080 端口
# 在 nat 表的 PREROUTING 链上添加规则
iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 8080
这个操作常用于服务器上运行的 Web 应用程序,该程序绑定于非标准端口,而你希望通过标准端口访问。
4. 网络地址转换 (NAT)
在家庭或小型办公室网络中,经常需要设置 NAT 来共享访问互联网的路径。以下是一个简单的源 NAT(SNAT)配置的例子。
共享互联网访问
假设
eth1
是内部网络接口,
eth0
是连接到互联网的接口。
# 启用 IP 转发
echo 1 > /proc/sys/net/ipv4/ip_forward
# 设置 MASQUERADE
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
# 允许内部网络访问外部
iptables -A FORWARD -i eth1 -o eth0 -j ACCEPT
# 允许已建立的连接回流
iptables -A FORWARD -i eth0 -o eth1 -m state --state ESTABLISHED,RELATED -j ACCEPT
这个配置允许内部网络通过
eth0
接口访问外部网络。
5. 日志和审计
记录某些类型的网络活动对于调试和安全监控都是非常有用的。
记录被拒绝的包
# 记录被拒绝的入站连接尝试
iptables -A INPUT -j LOG --log-prefix "IPTables-Input-Denied: " --log-level 4
# 记录被拒绘的转发连接尝试
iptables -A FORWARD -j LOG --log-prefix "IPTables-Forward-Denied: " --log-level 4
这些规则会将所有被
INPUT
和
FORWARD
链拒绝的尝试记录到系统日志中。
6. 使用时间条件控制访问
在某些环境中,你可能希望基于时间来控制网络访问。
在工作时间外允许 SSH 访问
# 工作时间外允许 SSH
iptables -A INPUT -p tcp --dport 22 -m time --timestart 18:00 --timestop 09:00 -j ACCEPT
这条规则允许在晚上 6:00 到早上 9:00 之间进行 SSH 访问。
7. 防火墙绕过
在某些情况下,你可能需要临时开放或关闭防火墙的某些规则,而不是永久修改配置。
临时开放所有访问
如果需要临时允许所有流量(例如,进行某些特殊操作),可以设置:
iptables -P INPUT ACCEPT
iptables -P FORWARD ACCEPT
iptables -P OUTPUT ACCEPT
# 清空所有规则
iptables -F
然后,在操作完成后,恢复原来的规则。
8. 防止 ICMP 泛洪攻击
ICMP 泛洪是一种常见的拒绝服务攻击方法。
限制 ICMP 回显请求
# 限制 ICMP echo-request 消息
iptables -A INPUT -p icmp --icmp-type echo-request -m limit --limit 1/s -j ACCEPT
iptables -A INPUT -p icmp --icmp-type echo-request -j DROP
这些规则限制了每秒处理的 ICMP echo 请求(ping 请求)的数量,从而减轻了泛洪的影响。
9. 多网卡策略路由
在拥有多个网络接口的服务器上,你可能需要根据数据包的来源或目的地来选择不同的路由。
根据源 IP 使用特定的网络接口
# 对于从特定源 IP 发出的数据包,使用特定接口
iptables -t nat -A POSTROUTING -s 192.168.100.0/24 -o eth1 -j MASQUERADE
这个规则设置了源 NAT,允许从
192.168.100.0/24
网段出来的数据包通过
eth1
接口发送。
10. 容器和虚拟化环境
在使用 Docker 或其他容器技术时,经常需要配置
iptables
来管理和隔离网络流量。
允许特定容器访问外部网络
# 假设容器的虚拟网络接口是 veth1234
iptables -t nat -A POSTROUTING -s 172.17.0.2/32 -o eth0 -j MASQUERADE
这条规则允许 IP 地址为
172.17.0.2
的容器通过
eth0
接口访问外部网络。
通过这些场景,你可以看到
iptables
的多样性和强大功能,它能够满足从简单到复杂的多种网络需求。
版权归原作者 Coder加油! 所有, 如有侵权,请联系我们删除。