Skip to content

Commit 6aa4643

Browse files
committed
firewall: Add CT states
1 parent c3a7ee8 commit 6aa4643

File tree

1 file changed

+45
-5
lines changed

1 file changed

+45
-5
lines changed

docs/ops/network/firewall.md

Lines changed: 45 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ POSTROUTING / `NF_INET_POST_ROUTING`
9090
需要注意的是,尽管数据包可能在 mangle 表和 nat 表中已经经过了至多两次额外路由决策,但其在 filter 表中时,`-o` 参数所匹配的输出接口始终是最初的路由决策结果。
9191
这是因为最终生效的路由决策存储在数据包的 `skb->_skb_refdst` 字段中[^skb._skb_refdst],而 Netfilter 在进行匹配时使用的是 `nf_hook_state->out` 字段[^ipt_do_table],该字段在数据包进入 OUTPUT 阶段之前就已经确定,并不会随着后续的 reroute check 而改变。
9292

93-
在搞清楚这些细节后,我们就能理解为什么以下两种理解方式都是正确的
93+
在搞清楚这些细节后,我们就知道为什么以下两种理解方式都是正确的
9494

9595
1. 路由决策位于 OUTPUT 之后:因为数据包最终的路由结果是基于经过 OUTPUT 阶段修改后的状态决定的。
9696
2. 路由决策位于 OUTPUT 之前,且 OUTPUT 后另有重新路由:因为 OUTPUT 阶段需要支持 `-o` 匹配方式,该信息依赖于初步的路由决策结果。
@@ -131,6 +131,32 @@ Conntrack 表的一个重要作用是支持有状态防火墙,允许 Netfilter
131131
nft add rule ip filter input ct state established,related accept
132132
```
133133

134+
在 conntrack 看来,数据包与连接的关系有以下几种:
135+
136+
NEW
137+
138+
: 该数据包将要建立一个新连接
139+
140+
ESTABLISHED
141+
142+
: 该数据包属于一个已经建立的连接
143+
144+
RELATED
145+
146+
: 该数据包将要建立一个新连接,但是由某一项 helper 认为是与一个已有连接相关联的,例如 FTP 的数据连接。
147+
148+
INVALID
149+
150+
: 该数据包不属于任何连接,conntrack 无法辨认
151+
152+
UNTRACKED
153+
154+
: 该数据包在 raw 表中已经被标记为 notrack(不要跟踪)
155+
156+
DNAT、SNAT
157+
158+
: 两个特殊的状态,仅用于匹配数据包(`--ctstate`),表示数据包经过了 DNAT / SNAT。
159+
134160
#### 连接标记 {#conntrack-mark}
135161

136162
Conntrack 除了记录连接的五元组(四层协议、源地址、目的地址、源端口、目的端口)外,还可以为连接记录一个「标记」(conntrack mark,`CONNMARK`)。
@@ -150,6 +176,8 @@ Conntrack 除了记录连接的五元组(四层协议、源地址、目的地
150176
nft add rule ip mangle postrouting ct mark set mark
151177
```
152178

179+
对于经过 NAT 的连接,CONNMARK 在实现「源进源出」时非常重要,
180+
153181
#### NAT 支持 {#conntrack-nat}
154182

155183
在 Netfilter 中,用户定义的 NAT 规则只会对**新连接**生效,而已建立的连接的后续数据包则由 conntrack 负责处理 NAT,确保同一连接内的所有数据包都能被正确处理。
@@ -204,6 +232,10 @@ conntrack -L -p udp --dport 53
204232

205233
另外,`conntrack -E` 命令可以实时监控 conntrack 表的变化,适合用于调试和分析网络连接的动向。`-E` 操作同样支持匹配条件,可以过滤出特定的连接事件,方便查找和分析。
206234

235+
### IPset {#ipset}
236+
237+
IPset 是
238+
207239
## iptables {#iptables}
208240

209241
iptables 是 Netfilter 的用户空间工具,用于管理防火墙规则。
@@ -298,6 +330,14 @@ iptables -P OUTPUT ACCEPT
298330

299331
[^output-oif]: 还记得[上文](#wikipedia-netfilter-packet-flow)为什么说 Wikipedia 的图更准确吗?
300332

333+
`-m conntrack --ctstate`
334+
335+
: 调用 conntrack 模块判断当前数据包所属的连接类型,参见上文的 [conntrack 段落](#connection-tracking)
336+
337+
`-m set --match-set set_name src`
338+
339+
: 调用 `set` 模块从 IPset 中匹配数据包的地址和端口,参见上文的 [IPset 段落](#ipset)
340+
301341
#### 动作 {#iptables-jump}
302342

303343
若一个数据包满足某条规则的所有匹配条件,就会进执行该规则的目标(`-j` / `-g` 参数)。目标可以是内置目标(如 ACCEPT、DROP、REJECT 等),也可以是用户自定义链的名称(跳转至自定义链继续处理)。
@@ -322,7 +362,7 @@ iptables -P OUTPUT ACCEPT
322362

323363
每条内置链都有一个**默认策略**`-P` / `--policy`),当数据包经过该链但未匹配到任何规则时,会由该默认策略处理。默认策略只能是 ACCEPT 或 DROP。
324364

325-
!!! example "例:科大镜像站上限制 80 / 443 端口并发连接数"
365+
???+ example "例:科大镜像站上限制 80 / 443 端口并发连接数"
326366

327367
```shell
328368
iptables -A LIMIT \
@@ -340,7 +380,7 @@ iptables -P OUTPUT ACCEPT
340380

341381
- `-p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK SYN`:匹配 TCP 协议的数据包,且匹配仅有 SYN 标志位被设置的数据包(即新连接请求)。
342382
- 等价的写法是 `-p tcp --syn`
343-
- 另一个(几乎)等价的写法是 `-m conntrack --ctstate NEW`,该写法事实上调用了连接跟踪模块,匹配将要建立新连接的数据包
383+
- 另一个(几乎)等价的写法是 `-m conntrack --ctstate NEW`,该写法调用了 conntrack 模块,由 conntrack 判断什么样的数据包是新连接请求
344384
- `-m multiport --dports 80,443`:调用 `multiport` 模块,匹配目的端口为 80 或 443 的数据包。
345385
- `-m connlimit --connlimit-above 12 --connlimit-mask 29 --connlimit-saddr`:调用 `connlimit` 模块,匹配来自同一子网(掩码长度 29,即每 8 个 IP 地址为一个子网)且当前已建立连接数超过 12 的数据包。
346386
- `-j REJECT --reject-with tcp-reset`:目标为 REJECT,即主动拒绝匹配的数据包,并发送 TCP RST 响应给对端。
@@ -371,9 +411,9 @@ mangle
371411

372412
raw
373413

374-
: 用于处理原始数据包,将包标记为不经过连接跟踪(`-j CT --notrack`),或引入其他连接跟踪帮助模块(如 `-j CT --helper`)。
414+
: 改变 conntrack 对当前数据包的行为,可以标记为不经过 conntrack(不进行跟踪,`-j CT --notrack`),或引入其他 conntrack 帮助模块(如 `-j CT --helper`)。
375415

376-
另有 security 表用于 SELinux 等安全模块的集成,但在大多数系统中不常用。Security 表与 filter 表适用于相同的阶段(Netfilter hook 点),且运行在 filter 表之后,即能够进入 security 表中的数据包都已由 filter 表标记为接受(ACCEPT)了。
416+
另有 security 表用于 SELinux 等安全模块的集成,但在大多数系统(尤其是 Debian 系列发行版)中不常用,因此本文不作详细讨论。Security 表与 filter 表适用于相同的阶段(Netfilter hook 点),且运行在 filter 表之后,即能够进入 security 表中的数据包都已由 filter 表标记为接受(ACCEPT)了。
377417

378418
iptables 的每个表都会注册到对应的 Netfilter hook 优先级上,因此同一个阶段(例如 PREROUTING)中,不同表的处理顺序与 [hook 的优先级](#netfilter-hook-priorities)相同。
379419

0 commit comments

Comments
 (0)