赞
踩
在 Linux 系统中,iptables
是一个非常强大的工具,它不仅是系统管理员用来构建和管理网络防火墙的首选工具,而且也是一个功能丰富的网络流量处理系统。无论是进行包过滤、监控网络流量、还是实现复杂的网络地址转换 (NAT),iptables
都能提供灵活的解决方案。本文将带你深入理解 iptables
的组成结构,掌握其常用命令,并通过具体的使用场景展示如何在实际中应用这些知识。
目录
iptables
是 Linux 操作系统中的一个非常强大的防火墙工具,它使用表格来组织防火墙规则,这些表格中的规则用于决定如何处理穿过防火墙的数据包。iptables
基于 Netfilter,Netfilter 是 Linux 内核的一个部分,负责处理通过网络栈的所有数据包。通过使用 iptables
,系统管理员可以定义规则,这些规则决定了如何处理进入、穿过和离开网络的数据包。
一、iptables
的主要组成iptables
的规则分布在不同的“表”中,这些表是处理特定类型数据包的集合。每个表包含一个或多个“链”,这些链定义了数据包流经网络栈的不同点在何处应用这些规则。
filter
表
INPUT
: 处理进入本机的数据包。FORWARD
: 处理经过本机路由到其他网络的数据包。OUTPUT
: 处理由本机产生的数据包。nat
表
PREROUTING
: 用于目标地址转换(DNAT),处理进入网络接口的数据包。POSTROUTING
: 用于源地址转换(SNAT),处理即将离开网络接口的数据包。OUTPUT
: 对于生成自本地进程的数据包,处理其目标地址转换。mangle
表
PREROUTING
: 修改进入网络接口的数据包。INPUT
: 修改到达本机的数据包。FORWARD
: 修改经过本机的数据包。OUTPUT
: 修改本机产生的数据包。POSTROUTING
: 修改即将离开本机的数据包。raw
表
PREROUTING
: 设置进入网络接口前的数据包是否避开状态跟踪。OUTPUT
: 设置由本机产生的数据包是否避开状态跟踪。security
表
INPUT
: 设置进入本机的数据包的安全标记。FORWARD
: 设置经过本机的数据包的安全标记。OUTPUT
: 设置本机产生的数据包的安全标记。表中的每个链代表数据包处理的一个阶段。预定义的链有:
PREROUTING
: 用于处理进入网络接口的数据包,主要用于 nat
和 mangle
表。INPUT
: 处理到达本机的数据包,用于 filter
, mangle
, 和 security
表。FORWARD
: 处理经过本机路由到其他网络的数据包,用于 filter
, mangle
, 和 security
表。OUTPUT
: 处理本机产生的数据包,用于 filter
, nat
, mangle
, raw
, 和 security
表。POSTROUTING
: 处理即将离开网络接口的数据包,用于 nat
和 mangle
表。规则定义了对特定条件下的数据包应该执行的操作。每条规则都关联到一个链,规则包含两个主要部分:
匹配条件: 定义了哪些数据包会被规则匹配。匹配条件可以包括多种属性:
-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]
-A
(添加)、-D
(删除)、-L
(列出) 等。INPUT
, FORWARD
, OUTPUT
等。-p tcp
(匹配 TCP 协议的数据包)。-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 DROP
- iptables -P FORWARD DROP
- iptables -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
: 删除所有用户定义的链。将外部端口 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 --set
- iptables -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 ACCEPT
- iptables -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 LOGGING
- iptables -A INPUT -j LOGGING
- iptables -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 -F
- iptables -X
-F
: 清空所有链的所有规则。-X
: 删除所有用户定义的链。使用 iptables
的场景非常多样,覆盖从简单的主机防火墙到复杂的网络路由和 NAT 配置。下面是一些具体的使用场景,展示如何利用 iptables
解决实际问题。
在这个场景中,我们利用 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
使用 iptables
限制单个源 IP 的连接频率,以防止简单的 DDoS 攻击或 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 密码的风险。
在某些情况下,你可能需要将到达某个端口的流量重定向到另一个端口上,例如将 80 端口的 HTTP 流量转发到 8080 端口。
- # 在 nat 表的 PREROUTING 链上添加规则
- iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 8080
这个操作常用于服务器上运行的 Web 应用程序,该程序绑定于非标准端口,而你希望通过标准端口访问。
在家庭或小型办公室网络中,经常需要设置 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
接口访问外部网络。
记录某些类型的网络活动对于调试和安全监控都是非常有用的。
- # 记录被拒绝的入站连接尝试
- 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
链拒绝的尝试记录到系统日志中。
在某些环境中,你可能希望基于时间来控制网络访问。
- # 工作时间外允许 SSH
- iptables -A INPUT -p tcp --dport 22 -m time --timestart 18:00 --timestop 09:00 -j ACCEPT
这条规则允许在晚上 6:00 到早上 9:00 之间进行 SSH 访问。
在某些情况下,你可能需要临时开放或关闭防火墙的某些规则,而不是永久修改配置。
如果需要临时允许所有流量(例如,进行某些特殊操作),可以设置:
- iptables -P INPUT ACCEPT
- iptables -P FORWARD ACCEPT
- iptables -P OUTPUT ACCEPT
-
- # 清空所有规则
- iptables -F
然后,在操作完成后,恢复原来的规则。
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 请求)的数量,从而减轻了泛洪的影响。
在拥有多个网络接口的服务器上,你可能需要根据数据包的来源或目的地来选择不同的路由。
- # 对于从特定源 IP 发出的数据包,使用特定接口
- iptables -t nat -A POSTROUTING -s 192.168.100.0/24 -o eth1 -j MASQUERADE
这个规则设置了源 NAT,允许从 192.168.100.0/24
网段出来的数据包通过 eth1
接口发送。
在使用 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
的多样性和强大功能,它能够满足从简单到复杂的多种网络需求。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。