
参考博客:《一篇搞懂》系列之一 —— iptables - 知乎 (zhihu.com)
iptables 是 linux 中的防火墙工具,用于管理网络流量,配置内核提供的 IPv4 和 IPv6 包过滤功能,
iptables 组成:表<–链<–规则
表 将处理同一类型的数据包规则聚合在一起。内核中内置有4 张表,分别是raw 、mangle、nat、filter。每一张表都只包含同一类型的数据包规则,比如nat 表只包含与网络地址转换相关的规则。链,其规定了相关规则在什么时候执行。内核中内置有5 条链,分别对应 netfilter 提供的 5 个 Hook 点。链能够让管理员在数据包传输过程中的某一个点通过相关规则控制数据包的走向。INPUT、OUTPUT、FORWARD、PREROUTING、POSTROUTING规则存在于链中,每一条链包含若干规则。当链被调用时,数据包处理函数将按照顺序依次匹配对应链中的所有规则。每条规则都由匹配部分+动作部分组成,如果数据包满足匹配规则,则会执行相关动作对数据包进行处理。iptables 的作用:
优先级:
表的优先级:由高到低排列为,**raw -> mangle -> nat -> filter**
规则优先级:某一规则触发的优先级,首先取决于链所在的位置,其次通过包含了该 chain 类型的 table 中所对应的实际的 chain 下的规则进行规则匹配和动作执行
raw 表提供的功能很简单:提供且仅提供一个让数据包绕过连接跟踪的框架。
iptables 提供一个有状态的防火墙,基于 netfilter 上建立了连接跟踪的特性,即 connection tracking,简称 conntrack。iptables 在处理数据包时都会依赖之前已经判断过的数据包。例如一条 NAT 记录,在第一次处理过后就会被存储在 conntrack 的哈希表中,下次有相同的数据包,则复用处理结果
mangle 表提供 **修改数据包 IP 头部** 的功能,例如,修改数据包的 TTL 等。此外,mangle 表中的规则还可以对数据包打一个 仅在内核内有效的标记(mark),后续对于该数据包的处理可以用到这些标记。
用于网络地址转换(NAT),当数据包进入协议栈后,nat 表中的相关规则将决定是否修改以及如何修改数据包的源/目标地址,从而改变数据包被路由的行为。nat 表通常用于将数据包路由到外部网络无法直接访问到的局域网络中。
filter 表是 iptables 中最常用的表,用来 **判断一个数据包是否可以通过**。在防火墙领域,filter 表提供的功能通常被称为“过滤”包。这个表提供了防火墙的一些常见功能。Filter 表负责的主要是和主机自身相关的数据包处理手段,是真正负责主机防火墙功能的一张表。
security 表的作用是 **给数据包打上 SELinux 标记**。SELinux 以及可以解读 SELinux 安全上下文的系统在处理由 security 表做了标记的数据包时,行为会相应做出改变。
内核中内置的 5 条链分别对应 netfilter 提供的 5 个 hook 点
PREROUTING: 由 NF_IP_PRE_ROUTING hook 触发;INPUT: 由 NF_IP_LOCAL_IN hook 触发;FORWARD: 由 NF_IP_FORWARD hook 触发;OUTPUT: 由 NF_IP_LOCAL_OUT hook 触发;POSTROUTING: 由 NF_IP_POST_ROUTING hook 触发。链位于表中
五条内置链和五个内置表的包含关系
| Tables | PREROUTING | INPUT | FORWARD | OUTPUT | POSTROUTING |
|---|---|---|---|---|---|
| raw | ✅ | ✅ | |||
| mangle | ✅ | ✅ | ✅ | ✅ | ✅ |
| nat | ✅ | ✅ | ✅ | ||
| filter | ✅ | ✅ | ✅ | ||
| security | ✅ | ✅ | ✅ |
filter 表中有三条链:input、forward 和 output。
net.ipv4.ip_forward=1nat 表中有三条链:prerouting,postrouting 和 output。
规则是最终影响数据包的地方,一条有效的规则必须由匹配规则+动作目标组成:
linux 内核提供如下的终止目标动作
| 动作 | 含义 |
|---|---|
| ACCEPT | 允许数据包通过 |
| DROP | 直接丢弃数据包,不给任何回应信息,这时候客户端 会感觉自己的请求没有响应,过了超时时间才会有反应。 |
| REJECT | 拒绝数据包通过,必要时会给数据发送端一个响应的信息,客户端刚请求就会收到拒绝的信息 |
| SNAT | 源地址转换,解决内网用户用同一个公网地址上网的问题 |
| MASQUERADE | 是 SNAT 的一种特殊形式,适用于动态的、临时会变的 ip 上 |
| DNAT | 目标地址转换 |
| REDIRECT | 在本机做端口映射 |
| LOG | 在/var/log/messages 文件中记录日志信息(其实就是写入系统日志,通过 dmesg 也可以看到),然后将数据包传递给下一条规则,也就是说除了记录日志以外不对数据包做任何其他操作,仍然让下一条规则去匹配 |
Linux 内核内置的链只有 5 条,且这 5 条链是 netfilter hooks 触发的唯一方式。那如果我想在不影响其他链的情况下使用自己定义的链,该如何操作呢?这时就可以在内置链上配置一个 Jumping Target。实际上这里指定的就是我自定义的链的名字。例如下面的配置:
[root@localhost ~]# iptables -L
Chain INPUT(policy ACCEPT)
target prot opt source destination
KUBE-FIREWALL all -- anywhere anywhere
Chain KUBE-FIREWALL(2 references)
target prot opt source destination
DROP all -- anywhere anywhere /* kubernetes firewall for dropping marked packets */ mark match 0x8000/0x8000
上面的配置中,INPUT 链的 target 为一条自定义的名为 KUBE-FIREWALL 的链,这样,从 INPUT 入口进入的数据包将会沿着链到达 KUBE-FIREWALL 链,然后将所有带有 0x8000/0x8000标记的包丢弃。
考虑最常用的 filter 和 nat 两张表


查看使用手册:man iptables
查看详细参数使用手册:man iptables-extensions
查看 filter 表中的所有链和规则: iptables -nL --line-numbers
-n:将主机信息(IP 地址,端口等)以数字的形式打印出来。默认会以 hostname 等方式打印出来; -L:显示规则链中已有的条目; --line-numbers:显示条目序号。