一、iptables 基础概念
1.1 防火墙概述
防火墙是一种位于内部网络与外部网络之间的网络安全系统,依照特定的规则,允许或是限制传输的数据通过。在 Linux 系统中,iptables 是一款广泛使用的防火墙管理工具。它工作在网络层,通过匹配数据包的源地址、目的地址、端口号、协议等信息来决定对数据包的处理方式,如允许通过(ACCEPT)、拒绝通过(REJECT)、直接丢弃(DROP)等。
1.2 iptables 与 netfilter 关系
netfilter 是 Linux 内核中的包过滤功能体系,处于内核态,负责实际的数据包过滤操作。iptables 则是位于 /sbin/iptables 的用户态工具,用于管理防火墙规则,用户通过 iptables 命令来添加、删除、查看防火墙规则,这些规则最终由 netfilter 在内核中执行。
二、iptables 规则链与表结构
2.1 规则链
规则链是容纳各种防火墙规则的容器,根据处理数据包的不同时机,iptables 默认包括 5 种规则链:
- INPUT 链:处理进入本机的数据包,例如外部网络访问本机服务的数据包。
- OUTPUT 链:处理从本机发出的数据包,如本机访问外部网络的请求。
- FORWARD 链:处理转发的数据包,当本机充当路由器,数据包从一个网络接口进入,需要转发到另一个网络接口时,由该链处理。
- POSTROUTING 链:在进行路由选择后处理数据包,通常用于源地址转换(SNAT),例如局域网内多台主机共享一个公网 IP 上网时,在数据包离开路由器前修改源 IP 地址。
- PREROUTING 链:在进行路由选择前处理数据包,常用于目的地址转换(DNAT),比如将发往公网 IP 的特定端口的数据包转发到内网的特定服务器。
2.2 规则表
规则表是容纳各种规则链的容器,根据防火墙规则的作用相似性进行划分,iptables 默认包括 4 个规则表:
- raw 表:确定是否对该数据包进行状态跟踪,常用于关闭某些连接跟踪,以提高性能。例如,如果有一些不需要进行连接跟踪的 UDP 流量,可以在 raw 表中设置规则,使其不被连接跟踪机制处理。
- mangle 表:为数据包设置标记,可用于对数据包进行特殊处理,如修改数据包的 TOS(Type of Service)字段。例如,对于视频流数据包,可以通过 mangle 表设置其 TOS 字段,以便在网络中给予更高的优先级。
- nat 表:主要用于修改数据包中的源、目标 IP 地址或端口,实现网络地址转换(NAT)功能。如前面提到的 SNAT 和 DNAT 操作都在 nat 表中完成。
- filter 表:确定是否放行该数据包(过滤),这是最常用的表,INPUT、OUTPUT 和 FORWARD 链默认都在 filter 表中。例如,设置允许或拒绝特定 IP 地址访问本机的 SSH 服务(端口 22)的规则就写在 filter 表的 INPUT 链中。
2.3 数据包过滤匹配流程
- 规则表之间的顺序:数据包首先经过 raw 表,然后是 mangle 表,接着是 nat 表,最后是 filter 表。在实际应用中,例如当需要对某个特定的数据包不进行连接跟踪时,就可以在 raw 表中设置规则,让该数据包跳过后续表中与连接跟踪相关的处理。
- 规则链之间的顺序:
- 入站数据包:先经过 PREROUTING 链,然后进入 INPUT 链。例如,外部主机访问本机 Web 服务(假设 IP 为 192.168.1.100,端口 80),数据包先到达 PREROUTING 链,若在此链中没有匹配到修改目的地址等规则,就进入 INPUT 链进行是否允许访问的判断。
- 出站数据包:先经过 OUTPUT 链,然后进入 POSTROUTING 链。当本机访问外部网站时,数据包从应用程序发出后,先由 OUTPUT 链处理,例如可以在此链中设置规则限制某些应用程序访问特定网站,之后数据包进入 POSTROUTING 链,若需要进行源地址转换(如共享上网场景),则在此链进行处理。
- 转发数据包:先经过 PREROUTING 链,再进入 FORWARD 链,最后进入 POSTROUTING 链。当一台 Linux 主机作为路由器,将一个子网的数据包转发到另一个子网时,数据包先在 PREROUTING 链进行可能的目的地址转换等操作,然后进入 FORWARD 链判断是否允许转发,若允许,最后在 POSTROUTING 链进行源地址转换等操作。
- 规则链内的匹配顺序:按顺序依次检查规则,一旦匹配到规则,就停止匹配(LOG 策略例外,记录日志后会继续匹配下一条规则)。若找不到相匹配的规则,则按该链的默认策略处理。例如,在 INPUT 链中有多条规则,从上到下依次检查,若第一条规则是允许特定 IP 段(192.168.1.0/24)访问本机,第二条规则是拒绝所有其他 IP 访问,当 192.168.1.50 的主机访问本机时,第一条规则匹配成功,就不再检查第二条规则,直接允许该主机访问。
三、iptables 常用命令参数
3.1 管理选项
- 添加新规则:
- -A:在链的末尾追加一条规则。例如,要在 filter 表的 INPUT 链末尾添加一条允许所有 TCP 流量通过的规则,可以使用命令iptables -t filter -A INPUT -p tcp -j ACCEPT。
- -I:在链的开头(或指定序号)插入一条规则。如果想在 INPUT 链的开头插入一条拒绝 192.168.2.10 主机访问的规则,命令为iptables -t filter -I INPUT -s 192.168.2.10 -j DROP。若要指定插入到第 3 条规则的位置,可使用iptables -t filter -I INPUT 3 -s 192.168.2.10 -j DROP。
- 查看规则列表:
- -L:列出所有的规则条目。如执行iptables -t filter -L INPUT可查看 filter 表中 INPUT 链的所有规则。
- -n:以数字形式显示地址、端口等信息。例如iptables -t filter -L INPUT -n,原本显示的主机名可能会以 IP 地址形式展示,端口名称也会以数字端口号显示,便于更直观地查看规则。
- -v:以更详细的方式显示规则信息,包括数据包的数量、字节数等统计信息。iptables -t filter -L INPUT -v会显示每个规则匹配到的数据包数量和总字节数等。
- --line-numbers:查看规则时,显示规则的序号。使用iptables -t filter -L INPUT --line-numbers,会在每条规则前显示其在链中的序号,方便后续删除或修改规则时指定位置。
- 删除、清空规则:
- -D:删除链内指定序号(或内容)的一条规则。若要删除 INPUT 链中序号为 5 的规则,命令为iptables -t filter -D INPUT 5;若要删除允许 192.168.3.0/24 网段访问的规则(假设该规则完整内容已知),可使用iptables -t filter -D INPUT -s 192.168.3.0/24 -j ACCEPT。
- -F:清空所有的规则。执行iptables -t filter -F INPUT会清空 filter 表中 INPUT 链的所有规则。
- 设置默认策略:
- -P:为指定的链设置默认规则。比如将 filter 表的 INPUT 链默认策略设置为 DROP(拒绝所有未匹配规则的数据包进入),命令是iptables -t filter -P INPUT DROP;将 OUTPUT 链默认策略设置为 ACCEPT(允许所有未匹配规则的数据包发出),命令为iptables -t filter -P OUTPUT ACCEPT。
3.2 匹配条件
- 通用匹配:可直接使用,不依赖于其他条件或扩展。
- 协议匹配:-p协议名,例如-p tcp表示匹配 TCP 协议的数据包,-p udp匹配 UDP 协议数据包。
- 地址匹配:-s源地址,-d目的地址。如-s 192.168.1.10表示匹配源地址为 192.168.1.10 的数据包,-d 192.168.2.0/24匹配目的地址在 192.168.2.0/24 网段的数据包。
- 网络接口匹配:-i网卡名称匹配从这块网卡流入的数据,-o网卡名称匹配从这块网卡流出的数据。例如-i eth0表示匹配从 eth0 网卡流入的数据包,-o eth1匹配从 eth1 网卡流出的数据包。
- 隐含匹配:要求以特定的协议匹配作为前提。
- 端口匹配:当使用-p tcp或-p udp后,可使用--sport源端口号、--dport目的端口号来进一步匹配。例如iptables -t filter -A INPUT -p tcp --dport 80 -j ACCEPT表示允许目的端口为 80(通常是 Web 服务端口)的 TCP 数据包进入。
- TCP 标记匹配:如--tcp-flags,用于匹配 TCP 数据包的标志位。例如iptables -t filter -A INPUT -p tcp --tcp-flags SYN,RST,ACK SYN -j ACCEPT,表示只允许带有 SYN 标志位(即发起新连接请求)的 TCP 数据包通过,防止一些异常的 TCP 连接。
- ICMP 类型匹配:当-p icmp时,可使用--icmp-type匹配 ICMP 数据包的类型。例如iptables -t filter -A INPUT -p icmp --icmp-type 8 -j ACCEPT允许 ICMP 请求(类型 8,通常是 ping 请求)的数据包进入。
- 显式匹配:要求以 “-m 扩展模块” 的形式明确指出类型。
- 多端口匹配:使用-m multiport,可以同时匹配多个端口。例如iptables -t filter -A INPUT -p tcp -m multiport --dports 80,443,8080 -j ACCEPT,允许目的端口为 80(HTTP)、443(HTTPS)、8080 的 TCP 数据包进入。
- MAC 地址匹配:使用-m mac,--mac-sourceMAC 地址,可根据源 MAC 地址进行匹配。比如iptables -t filter -A INPUT -m mac --mac-source 00:11:22:33:44:55 -j ACCEPT,只允许源 MAC 地址为 00:11:22:33:44:55 的设备访问。
- IP 范围匹配:使用-m iprange,--src-range起始 IP 地址 - 结束 IP 地址,可匹配源 IP 地址在指定范围内的数据包。例如iptables -t filter -A INPUT -m iprange --src-range 192.168.1.10 - 192.168.1.20 -j ACCEPT,允许源 IP 地址在 192.168.1.10 到 192.168.1.20 之间的数据包进入。
- 数据包状态匹配:使用-m state,--state状态,可根据数据包的连接状态进行匹配。常见状态有ESTABLISHED(已建立连接的数据包)、NEW(新连接的数据包)等。例如iptables -t filter -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT,允许已建立连接和相关联的数据包进入,这样可以保证合法的连接通信正常进行,同时阻止非法的新连接尝试。
3.3 数据包控制类型
- ACCEPT:允许数据包通过,当规则匹配到数据包且控制类型为 ACCEPT 时,数据包将被放行,继续后续的网络传输。
- DROP:直接丢弃数据包,不给出任何回应。当数据包匹配到 DROP 规则时,就像数据包进入了 “黑洞”,发送方不会收到任何关于数据包被拒绝的提示,只是感觉数据包好像丢失了,常用于阻止一些恶意或不需要的连接,同时避免向者暴露服务器的一些信息。
- REJECT:拒绝数据包通过,必要时会给出提示。与 DROP 不同,REJECT 会向数据包发送方回复一条拒绝信息,如端口不可达等。例如,当外部主机尝试连接本机被拒绝访问的端口时,若规则是 REJECT,发送方会收到类似 “Destination Port Unreachable” 的提示,这种方式可以让发送方明确知道连接被拒绝,但也可能会向者暴露一些端口信息。
- LOG:记录日志信息,然后传给下一条规则继续匹配。当规则匹配到数据包且控制类型为 LOG 时,系统会将该数据包的相关信息记录到日志文件中,便于后续分析网络流量情况,之后数据包会继续匹配下一条规则。例如,可以通过设置 LOG 规则记录所有尝试连接本机但被拒绝的数据包信息,以便排查网络行为。
四、iptables 安装与配置示例
4.1 安装 iptables
- 关闭 firewalld 防火墙(如果已安装并启用):在 CentOS 等系统中,可使用以下命令关闭并禁用 firewalld 服务:
TypeScript
取消自动换行复制
systemctl stop firewalld.service
systemctl disable firewalld.service
- 安装 iptables 防火墙:使用 yum 包管理器安装 iptables 及相关服务,命令如下:
TypeScript
取消自动换行复制
yum -y install iptables iptables-services
- 设置 iptables 开机启动:
TypeScript
取消自动换行复制
systemctl enable iptables.service
4.2 配置示例
- 允许特定 IP 访问本机 SSH 服务:假设允许 192.168.1.0/24 网段的主机访问本机的 SSH 服务(端口 22),在 filter 表的 INPUT 链中添加规则:
TypeScript
取消自动换行复制
iptables -t filter -A INPUT -s 192.168.1.0/24 -p tcp --dport 22 -j ACCEPT
- 禁止特定 IP 访问本机所有服务:若要禁止 192.168.2.10 主机访问本机,在 filter 表的 INPUT 链中添加规则:
TypeScript
取消自动换行复制
iptables -t filter -A INPUT -s 192.168.2.10 -j DROP
- 设置 INPUT 链默认策略为拒绝所有:先将 filter 表的 INPUT 链默认策略设置为 DROP,然后再添加允许特定流量的规则,以提高系统安全性:
TypeScript
取消自动换行复制
iptables -t filter -P INPUT DROP
之后再根据实际需求添加允许的规则,如上面允许 192.168.1.0/24 访问 SSH 服务的规则。
4. 实现端口转发(DNAT):假设本机有一个 Web 服务运行在内网 IP 192.168.1.100 的 80 端口,要将公网 IP 202.100.1.1 的 80 端口访问转发到内网的 Web 服务器,在 nat 表的 PREROUTING 链中添加规则:
TypeScript
取消自动换行复制
iptables -t nat -A PREROUTING -i eth0 -p tcp -d 202.100.1.1 --dport 80 -j DNAT --to-destination 192.168.1.100:80
这里eth0是公网网卡接口,根据实际情况修改。
5. 实现共享上网(SNAT):若本机作为路由器,连接内网 192.168.1.0/24 网段和公网,要实现内网主机共享公网 IP 上网,在 nat 表的 POSTROUTING 链中添加规则:
TypeScript
取消自动换行复制
iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -o eth0 -j SNAT --to-source 202.100.1.1
其中eth0为公网网卡接口,202.100.1.1为公网 IP 地址,同样根据实际情况调整。
4.3 保存与加载规则
- 保存规则:在修改完 iptables 规则后,需要将规则保存,以便下次开机时生效。在 CentOS 系统中,使用以下命令保存规则:
TypeScript
取消自动换行复制
service iptables save
- 加载规则:开机时,iptables 服务会自动加载保存的规则。如果在运行过程中需要手动加载规则,可使用:
TypeScript
取消自动换行复制
service iptables restart
此命令会先停止 iptables 服务,