iptables 使用方式整理
iptables
是 Linux 系统上的 IP 信息包过滤系统。如果 Linux 系统连接到因特网或 LAN、服务器或连接 LAN 和因特网的代理服务器,则该系统有利于在 Linux 系统上更好地控制 IP 信息包过滤,其可以说是 Linux 的网络防火墙。广义上的 iptables 实际上是由 netfilter 和 iptables 两个组件组成。而狭义上的 iptables
是指一个命令行工具,用于配置管理信息包的过滤规则。真正起到信息包过滤作用的是 netfilter 组件。
netfilter/iptables
netfilter
是内核的一个子系统,其工作在内核空间,核心是一个报文过滤架构,它包含了一组分布在报文处理各个阶段的钩子函数,报文经过网络协议栈时进入 netfilter 处理架构,会调用其他模块在各个阶段注册的钩子函数,并返回处理结果,netfilter 根据返回结果进行不同的处理。
报文处理的五个不同阶段:
- (1)pre-routing: 经过 ip 合法性检查的报文
- (2)local-input: 经过选路后,目的地址指向本机的报文
- (3)forward: 经过选路需要转发出去的报文
- (4)local-output: 从本协议栈发送出去的报文
- (5)post-routing: 经过选路后需要转发出去的报文,最终送给这个钩子函数处理
iptables
工作在用户空间,用于设置、维护和检查信息包的过滤规则,其是一个与 netfilter 子系统交互的工具,它使插入、修改和除去信息包过滤表中的规则变得容易。由于在使用过程中通常只接触 iptables 这个命令工具,所以通常所说的 iptables 即指 netfilter 子系统与 iptables 工具组成的信息包过滤系统。
表/链/规则
使用 iptables 需要先理解表(table)、链(chain)、规则(rule)这三个概念。netfilter/iptables
系统可以理解成是 表 的容器,这也是它被称为 iptables 的原因,而表则是 链 的容器,即所有的链都属于其对应的表,链又是 规则 的容器。
表(tables)
iptables
大致有 raw, filter, nat, mangle, security 等五类表,常用的表有 filter、nat、mangle 三个表。
- raw 表: 用于配置数据包,raw 中的数据包不会被系统跟踪。其优先级最高,设置 raw 时一般是为了不再让 iptables 做数据包的链接跟踪处理,提高性能
- filter 表: 为 iptables 默认的表,在操作时如果没有指定使用哪个表,iptables 默认使用 filter 表来执行所有的命令。filter 表根据预定义的一组规则过滤符合条件的数据包。在 filter 表中只允许对数据包进行接收、丢弃的操作,而无法对数据包进行更改
- nat 表: 即 Network Address Translation,主要是用于网络地址转换(例如:端口转发),该表可以实现一对一、一对多、多对多等 NAT 工作
- mangle 表: 主要用于对指定包的传输特性进行修改。某些特殊应用可能需要改写数据包的一些传输特性,例如更改数据包的 TTL 和 TOS 等
- security 表: 用于强制访问控制网络规则(例如: SELinux)
在大多数使用情况下都不会用到 raw 和 security 表,而 filter 和 nat 表则是会常用到的,mangle 表次之。
链(chains)
链(chains)是数据包传输的路径,对应着前面提到的报文处理的五个阶段,也相当于是五个不同的关卡:
- INPUT: 处理入站数据包,当接收到访问本机地址的数据包(入站)时,应用此链中的规则
- OUTPUT: 处理出站数据包,当本机向外发送数据包(出站)时,应用此链中的规则
- FORWARD: 处理转发数据包,当接收到需要通过本机发送给其他地址的数据包(转发)时,应用此链中的规则
- PREROUTING: 在对数据包作路由选择之前,应用此链中的规则
- POSTROUTING: 在对数据包作路由选择之后,应用此链中的规则
链是规则的容器,一条链中可能包含着众多的规则,当一个数据包到达一个链时,iptables 就会从链中第一条规则开始匹配,如果满足该规则的条件,系统就会根据该条规则所定义的方法处理该数据包,否则将继续匹配下一条规则,如果该数据包不符合链中任一条规则,iptables 就会根据该链预先定义的默认策略来处理数据包。
INPUT, OUTPUT 链更多的应用在本机的网络控制中,即主要针对本机进出数据的安全控制。而 FORWARD, PREROUTING, POSTROUTING 链更多地应用在对我的网络控制中,特别是机器作为网关使用时的情况。
表是链的容器,不同的表中包含着不同的链:
Filter 表 是 iptables 的默认表,因此如果没有指定表,那么默认操作的是 filter 表,其包含以下三种内建链:
- INPUT 链 – 处理来自外部的数据
- OUTPUT 链 – 处理向外发送的数据
- FORWARD 链 – 将数据转发到本机的其他网卡设备上
NAT 表 包含以下三种内建链:
- PREROUTING 链 – 处理刚到达本机并在路由转发前的数据包。它会转换数据包中的目标 IP 地址(destination ip address),通常用于 DNAT(destination NAT)
- POSTROUTING 链 – 处理即将离开本机的数据包。它会转换数据包中的源 IP 地址(source ip address),通常用于 SNAT(source NAT)
- OUTPUT 链 – 处理本机产生的数据包
Mangle 表 指定如何处理数据包。它能改变 TCP 头中的 QoS 位。Mangle 表包含五种内建链:PREROUTING, OUTPUT, FORWARD, INPUT, POSTROUTING.
Raw 表 包含两个内建链:PREROUTING, OUTPUT.
规则(rules)
规则(rules)是一些预定义的数据包过滤条件。规则存储在内核空间的信息包过滤表中,数据包每经过一个链(关卡)时,系统会根据链中规则指定的匹配条件来尝试匹配,一旦匹配成功,则由规则后面指定的处理动作进行处理。
规则分别指定了源地址、目的地址、传输协议(如TCP、UDP、ICMP)和服务类型(如HTTP、FTP和SMTP)等。当数据包与规则匹配时,iptables就根据规则所定义的方法来处理这些数据包,如放行(accept)、拒绝(reject)和丢弃(drop)等。配置防火墙的主要工作就是添加、修改和删除这些规则。
规则由 匹配条件 和 处理动作 组成。匹配条件 又分为 基本匹配条件 与 扩展匹配条件。基本匹配条件如:源地址 Source IP,目标地址 Destination IP;扩展匹配条件通常以模块的形式存在,这些模块可以按需安装,源端口 Source Port, 目标端口 Destination Port。
处理动作(target) 也分为基本动作和扩展动作。以下列举一些常用的动作:
- ACCEPT: 允许数据包通过
- DROP: 直接丢弃数据包,不给任何回应信息,这时候客户端会感觉自己的请求泥牛入海了,过了超时时间才会有反应
- QUEUE: 将数据包移交到用户空间
- RETURN: 停止执行当前链中的后续规则,并返回到调用链(The Calling Chain)中
- REJECT: 拒绝数据包通过,必要时会给数据发送端一个响应的信息,客户端刚请求就会收到拒绝的信息
- DNAT: 目标地址转换
- SNAT: 源地址转换,解决内网用户用同一个公网地址上网的问题
- MASQUERADE: 是 SNAT 的一种特殊形式,适用于动态的、临时会变的 ip 上
- REDIRECT: 在本机做端口映射
- LOG: 记录日志信息,除记录外不对数据包做任何其他操作,仍然匹配下一条规则
由此,已知 tables 由 chains 组成,而 chains 又由 rules 组成。常用的表有 filter、nat、mangle 三种,链有五种,对应报文处理的五个阶段。对规则理解的关键则需记住以下三点:
- 1、一条规则包括一个条件和一个动作(target)
- 2、如果满足条件,就执行处理动作
- 3、如果不满足条件,就继续匹配下一条规则
几个常用表单的优先级顺序是 mangle –>nat –> filter.
数据包流向
以下简略图描述了网络数据包经过 netfilter/iptables 的过程:
XXXXXXXXXXXXXXXXXX
XXX Network XXX
XXXXXXXXXXXXXXXXXX
+
|
v
+-------------+ +------------------+
|table: filter| <---+ | table: nat |
|chain: INPUT | | | chain: PREROUTING|
+-----+-------+ | +--------+---------+
| | |
v | v
[local process] | **************** +--------------+
| +---------+ Routing decision +------> |table: filter |
v **************** |chain: FORWARD|
**************** +------+-------+
Routing decision |
**************** |
| |
v **************** |
+-------------+ +------> Routing decision <---------------+
|table: nat | | ****************
|chain: OUTPUT| | |
+-----+-------+ | |
| | v
v | +-------------------+
+--------------+ | | table: nat |
|table: filter | +----+ | chain: POSTROUTING|
|chain: OUTPUT | +--------+----------+
+--------------+ |
v
XXXXXXXXXXXXXXXXXX
XXX Network XXX
XXXXXXXXXXXXXXXXXX
由图可知,当一个数据包进入计算机的网络接口时,数据首先进入 POSTROUTING 链,然后内核根据路由表决定数据包的目标。若数据包的目的地址是本机,则将数据包送往 INPUT 链进行规则匹配,当数据包进入 INPUT 链后,系统的任何进程都可以收到它,本机上运行的程序可以发送该数据包,这些数据包会经过 OUTPUT 链,再从 POSTROUTING 链发出;若数据包的目的地址不是本机,则检查内核是否允许转发,若允许,则将数据包送 FORWARD 链进行规则匹配,若不允许,则丢弃该数据包。若是主机本地进程产生并准备发出的包,则数据包被送往 OUTPUT 链进行规则匹配。
- 本机发出的包:本机进程 -> OUTPUT 链 -> 路由选择 -> POSTROUTING 链 -> 出口网卡
- 本机收到的包:入口网卡 -> PREROUTING 链 -> 路由选择 -> 此时有两种可能的情况:
- 目的地址为本机:INPUT 链 -> 本机进程
- 目的地址不为本机:FORWARD 链 -> POSTROUTING 链 -> 网卡出口(内核允许网卡转发的情况下)
使用简介
iptables
工具的操作命令是比较复杂的,但大致的格式如下所示:
iptables [-t 表]
命令选项
[链]
[匹配选项]
[操作选项]
命令选项:
选项名 | 功能及特点 | |
---|---|---|
-A –append | 在指定链的末尾添加一条新的规则 | |
-D –delete | 删除指定链中的某一条规则,按规则序号或内容确定要删除的规则 | |
-I –insert | 在指定链中插入一条新的规则,默认在链的开头插入 | |
-R –replace | 修改、替换指定链中的一条规则,按规则序号或内容确定 | |
-F –flush | 清空指定链中的所有规则,默认清空表中所有链的内容 | |
-N –new | 新建一条用户自己定义的规则链 | |
-X –delete-chain | 删除指定表中用户自定义的规则链 | |
-P –policy | 设置指定链的默认策略 | |
-F, –flush | 清空指定链上面的所有规则,如果没有指定链,清空表上所有链的所有规则 | |
-Z, –zero | 把指定链或表中的所有链上的所有计数器清零 | |
-L –list | 列出指定链中的所有的规则进行查看,默认列出表中所有链的内容 | |
-S –list-rules | 以原始格式列出链中所有规则 | |
-v –verbose | 查看规则列表时显示详细的信息 | |
-n –numeric | 用数字形式显示输出结果,如显示主机的 IP 地址而不是主机名 | |
–line-number | 查看规则列表时,同时显示规则在链中的顺序号 | 、 |
匹配选项:
选项名 | 功能及特点 |
---|---|
-i –in-interface | 匹配输入接口,如 eth0,eth1 |
-o –out-interface | 匹配输出接口 |
-p –proto | 匹配协议类型,如 TCP、UDP 和 ICMP等 |
-s –source | 匹配的源地址 |
–sport | 匹配的源端口号 |
-d –destination | 匹配的目的地址 |
–dport | 匹配的目的端口号 |
-m –match | 匹配规则所使用的过滤模块 |
部分过滤模块使用简介:
- -m limit –limit
iptables -A INPUT -m limit –limit 3/hour
匹配某段时间内封包的平均流量,以上示例匹配:每小时平均流量是否超过一次 3 个封包。除了每小时平均次外,也可以每秒钟、每分钟或每天平均一次,默认值为每小时平均一次,参数如后: /second、 /minute、/day。除了进行封包数量的匹配外,设定这个参数也会在条件达成时,暂停封包的匹配动作,以避免因骇客使用洪水攻击法,导致服务被阻断。
- -m limit –limit-burst
iptables -A INPUT -m limit –limit-burst 5
匹配瞬间大量封包的数量,上例匹配一次同时涌入的封包是否超过 5 个(这是默认值),超过此上限的封包将被直接丢弃。使用效果同上。
- -m mac –mac-source
iptables -A INPUT -m mac –mac-source 00:00:00:00:00:01
匹配封包来源网络接口的硬件地址,这个参数不能用在 OUTPUT 和 POSTROUTING 规则链上,因为封包要送到网卡后,才能由网卡驱动程序透过 ARP 通讯协议查出目的地的 MAC 地址,所以 iptables 在进行封包匹配时,并不知道封包会送到哪个网络接口去。
- -m mac –mark
iptables -t mangle -A INPUT -m mark –mark 1
匹配封包是否被表示某个号码,当封包被匹配成功时,可以透过 MARK 处理动作,将该封包标示一个号码,号码最大不可以超过 4294967296。
- -m owner –uid-owner
iptables -A OUTPUT -m owner –uid-owner 500
匹配来自本机的封包,是否为某特定使用者所产生的,这样可以避免服务器使用 root 或其它身分将敏感数据传送出,可以降低系统被黑的损失。可惜这个功能无法匹配出来自其它主机的封包。
- -m owner –gid-owner
iptables -A OUTPUT -m owner –gid-owner 0
匹配来自本机的封包,是否为某特定使用者群组所产生的,使用时机同上。
- -m owner –pid-owner
iptables -A OUTPUT -m owner –pid-owner 78
匹配来自本机的封包,是否为某特定进程所产生的,使用时机同上。
- -m owner –sid-owner
iptables -A OUTPUT -m owner –sid-owner 100
匹配来自本机的封包,是否为某特定 连接(Session ID)的响应封包,使用时机同上。
- -m state –state
iptables -A INPUT -m state –state RELATED,ESTABLISHED
匹配连接状态,连接状态共有四种:INVALID、ESTABLISHED、NEW 和 RELATED。INVALID: 表示该封包的连接编号(Session ID)无法辨识或编号不正确;ESTABLISHED: 表示该封包属于某个已经建立的连接;NEW: 表示该封包想要起始一个连接(重设连接或将连接重导向);RELATED 表示该封包是属于某个已经建立的连接,所建立的新连接。
操作选项 一般为 -j 处理动作
的形式,处理动作包括 ACCEPT、DROP、RETURN、REJECT、DNAT、SNAT 等。不同的处理动作可能还有额外的选项参数,如指定 DNAT、SNAT 动作则还需指定 --to
参数用以说明要装换的地址,指定 REDIRECT 动作则需指定 –to-ports 参数用于说明要跳转的端口。
使用 iptables -j 动作名 --help
可以查看处理动作帮助。
常用命令
查看帮助:
iptables --help # 查看 iptables 的帮助
iptables -m 模块名 --help # 查看指定模块的可用参数
iptables -j 动作名 --help # 查看指定动作的可用参数
查看规则:
iptables -nvL
iptables -t nat -nvL
# 显示规则序号
iptables -nvL INPUT --line-numbers
iptables -t nat -nvL --line-numbers
iptables -t nat -nvL PREROUTING --line-numbers
# 查看规则的原始格式
iptables -t filter -S
iptables -t nat -S
iptables -t mangle -S
iptables -t raw -S
清除所有规则:
iptables -F # 清空表中所有的规则
iptables -X # 删除表中用户自定义的链
iptables -Z # 清空计数
iptables -t nat -F
iptables -t nat -X
iptables -t mangle -F
iptables -t mangle -X
iptables -t raw -F
iptables -t raw -X
iptables -t security -F
iptables -t security -X
设置默认规则:
iptables -P INPUT DROP # 配置默认丢弃访问的数据表
iptables -P FORWARD DROP # 配置默认禁止转发
iptables -P OUTPUT ACCEPT # 配置默认允许向外的请求
增加、删除、修改规则:
# 增加一条规则到最后
iptables -A INPUT -i eth0 -p tcp --dport 80 -m state --state NEW,ESTABLISHED -j ACCEPT
# 注:以下几条操作都需要使用规则的序号,需要使用 -L --line-numbers 参数先查看规则的顺序号
# 添加一条规则到指定位置
iptables -I INPUT 2 -i eth0 -p tcp --dport 80 -m state --state NEW,ESTABLISHED -j ACCEPT
# 删除一条规则
iptabels -D INPUT 2
# 修改一条规则
iptables -R INPUT 3 -i eth0 -p tcp --dport 80 -m state --state NEW,ESTABLISHED -j ACCEPT
开放指定端口:
# 允许本地回环接口(即运行本机访问本机)
iptables -A INPUT -i lo -j ACCEPT
# 允许已建立的或相关连接的通行
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
# 允许所有本机向外的访问
iptables -A OUTPUT -j ACCEPT
# 允许 22,80,443 端口的访问
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
iptables -A INPUT -p tcp --dports 80,443 -j ACCEPT
# 如果有其他端口的需要开放,则同上
iptables -A INPUT -p tcp --dport 8000:8010 -j ACCEPT
# 允许 ping
iptables -A INPUT -p icmp -m icmp --icmp-type 8 -j ACCEPT
# 禁止其他未允许的规则访问
iptables -A INPUT -j REJECT
iptables -A FORWARD -j REJECT
# 注:以上操作需要安装顺序,确保规则顺序正确
目的地址转换,首先需要在开启中开启转发功能(源地址转换也需要开启):
echo 1 > /proc/sys/net/ipv4/ip_forward
# 把从 eth0 进来要访问 TCP/80 的数据包的目的地址转换到 192.168.1.18
iptables -t nat -A PREROUTING -p tcp -i eth0 --dport 80 -j DNAT --to 192.168.1.18
# 把从 123.57.172.149 进来要访问 TCP/80 的数据包的目的地址转换到 192.168.1.118:8000
iptables -t nat -A PREROUTING -p tcp -d 123.57.172.149 --dport 80 -j DNAT --to 192.168.1.118:8000
源地址转换:
# 最典型的应用是让内网机器可以访问外网:
# 将内网 192.168.0.0/24 的源地址修改为 1.1.1.1 (可以访问互联网的机器的 IP)
iptables -t nat -A POSTROUTING -s 192.168.0.0/24 -j SNAT --to 1.1.1.1
# 将内网机器的源地址修改为一个 IP 地址池
iptables -t nat -A POSTROUTING -s 192.168.0.0/24 -j SNAT --to 1.1.1.1-1.1.1.10
持久化规则:
# 保存当前规则
iptables-save > iptables.20190721
# 恢复备份规则
iptables-restore < iptables.20190721