iptables 是 netfilter 的一个子项目,在 Linux 内核 3.13 之后 推出了 nftables 作为 iptables 的后继项目。
在较新的 RHEL 发行版中,iptables 依然存在,只不过其 backend 已经切换成了 nftable:
|  |  | 
规则结构
iptables 的可以用于对 IP 包(IP 协议的包)进行过滤、转发、修改,最常见的用途是作为防火墙,但是它的功能不仅仅局限于此。
iptables 的执行依赖于一系列规则,结构是:Table > Chain > Rule > Target
- Table:
- 内置 Table 有 filter、nat、mangle、raw。
- 不允许用户自定义 table。
 
- Chain:
- 内置 Chain:INPUT、FORWARD、PREROUTING、POSTROUTING、OUTPUT。
- 用户也可以自定义 Chain。
- 每个 Table 能使用的内置 Chain 不同。
- Chain 下面有一系列 Rule 列表。
- IP 包进入 Chain 后按照顺序匹配 Rule。
- 把所有 Rule 都过了一遍之后没有找到 Target,那么 Chain 的 Policy 就是 Target。
 
- Rule:
- IP 包匹配规则,并决定 Target。
- 如果匹配,把 IP 包交给设定的 Target。
- 如果匹配但是没有设定 Target,则 Chain 会继续执行后面的 Rule。
 
- Target:
- 决定 IP 包的去向。
- 可以是内置 Target,比如 ACCEPT、DROP、SNAT、DNAT、MASQUERADE。
- 也可以用户自定义 Chain。
- 内置 Target 的使用受限于当前在哪个 Table 和哪个 Chain。
 
内置 Table
iptables 内置了 4 大 table:raw、filter、nat、mangle。
每个内置 table 所内置的 Chain 不同,看下表:
| Chain | raw | filter | nat | mangle | 
|---|---|---|---|---|
| PREROUTING | Y | Y | Y | |
| INPUT | Y | Y | ||
| OUTPUT | Y | Y | Y | Y | 
| POSTROUTING | Y | Y | ||
| FORWARD | Y | Y | 
Chain 的顺序
下图从内置 Chain 的角度出发,描述了 IP 包如何进入、流出 Chain 的过程,以及 Table 和 Chain 的关系。
比如 Chain PREROUTING 在 Table raw、mangle、nat 中存在:
 
Chain 对应 Target
下图从另一个角度描述了 IP 包如何经过内置 Chain 和 Table,以及允许的内置 Target。
比如 Table nat 的 Chain PREROUTING,的可用 Target 有 DNAT、REDIRECT、BALANCE、NETMAP。
 
基本命令
iptables 的基本命令结构如下:
|  |  | 
- -t <table>代表操作的是哪个 table,如果不指定则默认是- filtertable。
- cmd代表对 chain 的操作,比如新建、删除、添加规则、插入规则 等等,后面会讲。
- <chain>代表是对哪个 chain 进行操作。
列出规则:
|  |  | 
清空 chain 的包和字节计数:
|  |  | 
追加规则,在 chain 的尾部添加新规则:
|  |  | 
插入规则,在 chain 的某个位置插入规则:
|  |  | 
删除规则:
|  |  | 
替换规则:
|  |  | 
设置 chain 的 policy:
|  |  | 
规则定义
规则的定义是由参数组成的,举个例子:
|  |  | 
上面的 -s 172.19.0.1 -j DROP 就是规则,意思是 DROP 来自 172.19.0.1 的包,两个参数的意思是:
- -s:来源 IP 地址
- -j:jump 到哪个 target,大多数规则都会有- -j这个参数
规则还可以用 ! 取反,DROP 不是来自 172.19.0.1 的包,比如:
|  |  | 
基本参数
下面将几个 iptables 规则的基本参数:
-p, --protocol [!] protocol
协议,比如 tcp、udp、icmp、all。注意 ! 取反标记的位置。下同。
-s, --source [!] address[/mask]
来源 IP 地址,可以是具体某个 IP (前面看到过了),也可以是子网,比如 192.168.0.0/16。
-d, --destination [!] address[/mask]
目标 IP 地址。
-j, --jump target
结果 Target,可以是内置 Target ACCPET、DROP、REJECT 也可以是用户自定义 Chain。
-i, --in-interface [!] name
流入包的网卡名字。比如 -i eth0。用在 ingress 流量上。
-o, --out-interface [!] name
流出包的网卡名字。用在 egress 流量上。
更多参数可以在 iptables(8) 里找到。
扩展模块
如果想拒绝 192.168.0.0 访问本机的 tcp/80 端口:
|  |  | 
上面的 --dport 就是扩展参数。
只有当加载某个扩展匹配模块的时候才可以使用扩展参数。
在使用 -p, --protocol 的时候会隐式地加载扩展匹配模块,也可以使用 -m, --match <module> 来显式地加载扩展匹配模块。
你可以通过 iptables -p <protocol> -h 或者 iptables -m <module> -h 来查看扩展匹配模块 有哪些参数可以使用。
比如 iptables -p tcp -h 或者 iptables -m tcp -h:
|  |  | 
又比如 iptables -m set -h:
|  |  | 
下面举几个例子:
|  |  | 
扩展模块的清单可以在 iptables-extensions(8) 里找到。
评论