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,如果不指定则默认是filter
table。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) 里找到。
评论