在 上一篇博客 中,我概述了 Istio ambient 模式中 pod 网络命名空间内注入的 iptables 规则。本文将深入解析这些规则,探讨它们是如何在 pod 内实现透明流量拦截和重定向的。
在 pod 的网络命名空间内,Istio CNI node agent 会设置一系列 iptables 规则,以实现流量的透明拦截与重定向。下面的规则展示了 Istio 在 mangle 和 nat 表中注入的内容,确保入站和出站流量经过适当的处理。
# Generated by iptables-save v1.8.9 (nf_tables) on Thu Nov 14 08:43:17 2024
*mangle
:PREROUTING ACCEPT [99138:22880045] # mangle 表中的 PREROUTING 链,默认策略为 ACCEPT。
:INPUT ACCEPT [0:0] # mangle 表中的 INPUT 链,默认策略为 ACCEPT。
:FORWARD ACCEPT [0:0] # mangle 表中的 FORWARD 链,默认策略为 ACCEPT。
:OUTPUT ACCEPT [100900:34940164] # mangle 表中的 OUTPUT 链,默认策略为 ACCEPT。
:POSTROUTING ACCEPT [0:0] # mangle 表中的 POSTROUTING 链,默认策略为 ACCEPT。
:ISTIO_OUTPUT - [0:0] # 自定义的 ISTIO_OUTPUT 链,用于处理 Istio 的出站流量。
:ISTIO_PRERT - [0:0] # 自定义的 ISTIO_PRERT 链,用于处理 Istio 的预路由流量。
-A PREROUTING -j ISTIO_PRERT # 将所有 PREROUTING 流量跳转到 ISTIO_PRERT 链。
-A OUTPUT -j ISTIO_OUTPUT # 将所有 OUTPUT 流量跳转到 ISTIO_OUTPUT 链。
-A ISTIO_OUTPUT -m connmark --mark 0x111/0xfff -j CONNMARK --restore-mark --nfmask 0xffffffff --ctmask 0xffffffff
# 如果连接标记为 0x111/0xfff,则恢复连接标记,用于连接追踪的一致性。
-A ISTIO_PRERT -m mark --mark 0x539/0xfff -j CONNMARK --set-xmark 0x111/0xfff
# 如果数据包标记为 0x539/0xfff,在 PREROUTING 链中将其连接标记设置为 0x111/0xfff。
COMMIT # 应用 mangle 表规则。
# Completed on Thu Nov 14 08:43:17 2024
# Generated by iptables-save v1.8.9 (nf_tables) on Thu Nov 14 08:43:17 2024
*nat
:PREROUTING ACCEPT [2:120] # nat 表中的 PREROUTING 链,默认策略为 ACCEPT。
:INPUT ACCEPT [0:0] # nat 表中的 INPUT 链,默认策略为 ACCEPT。
:OUTPUT ACCEPT [119:9344] # nat 表中的 OUTPUT 链,默认策略为 ACCEPT。
:POSTROUTING ACCEPT [0:0] # nat 表中的 POSTROUTING 链,默认策略为 ACCEPT。
:ISTIO_OUTPUT - [0:0] # 自定义的 ISTIO_OUTPUT 链,用于处理 Istio 的出站 NAT 流量。
:ISTIO_PRERT - [0:0] # 自定义的 ISTIO_PRERT 链,用于处理 Istio 的预路由 NAT 流量。
-A PREROUTING -j ISTIO_PRERT # 将所有 PREROUTING 流量跳转到 ISTIO_PRERT 链。
-A OUTPUT -j ISTIO_OUTPUT # 将所有 OUTPUT 流量跳转到 ISTIO_OUTPUT 链。
-A ISTIO_OUTPUT -d 169.254.7.127/32 -p tcp -m tcp -j ACCEPT
# 如果目标地址为 169.254.7.127(可能是 Istio 内部地址),允许 TCP 流量通过。
-A ISTIO_OUTPUT -p tcp -m mark --mark 0x111/0xfff -j ACCEPT
# 如果数据包标记为 0x111/0xfff,允许 TCP 流量通过。
-A ISTIO_OUTPUT ! -d 127.0.0.1/32 -o lo -j ACCEPT
# 允许发往本地回环接口(但不包括 127.0.0.1)的流量通过。
-A ISTIO_OUTPUT ! -d 127.0.0.1/32 -p tcp -m mark ! --mark 0x539/0xfff -j REDIRECT --to-ports 15001
# 将发往非 127.0.0.1 的出站 TCP 流量(且标记不是 0x539/0xfff)重定向到端口 15001(Istio 出站流量入口)。
-A ISTIO_PRERT -s 169.254.7.127/32 -p tcp -m tcp -j ACCEPT
# 如果源地址为 169.254.7.127,允许 TCP 流量通过 PREROUTING 链。
-A ISTIO_PRERT ! -d 127.0.0.1/32 -p tcp -m tcp ! --dport 15008 -m mark ! --mark 0x539/0xfff -j REDIRECT --to-ports 15006
# 将非 127.0.0.1 且目标端口不是 15008 的入站 TCP 流量(标记不是 0x539/0xfff)重定向到端口 15006(Istio 入站流量入口)。
COMMIT # 应用 nat 表规则。
# Completed on Thu Nov 14 08:43:17 2024
这些 iptables 规则通过特定的端口号来区分并处理不同类型的流量:
这些端口使得 Istio 能够对入站、出站及内部流量进行透明的管理与控制,从而实现细粒度的安全策略与流量控制。更多关于端口号的使用请参考 Istio 应用要求。
0x539
的作用0x539
是用于标识 Istio 代理发出的流量的标记。这一标记在流量进入 iptables 规则时被设置,用于区分由代理(如 ztunnel)处理过的数据包,防止其被重复代理或误处理。
0x111
的作用0x111
用于连接级别的标记管理,在 Istio 网格中标识已由代理处理过的整个连接。通过 iptables 的 CONNMARK
模块,0x111
标记能够从单个数据包扩展到整个连接的生命周期,从而加速后续数据包的匹配。
下图展示了流量在 iptables 规则中的执行路径,帮助理解流量的匹配和重定向过程:
想进一步了解 Istio CNI 如何处理 iptables,请参考代码 istio/cni/pkg/iptables/iptables.go at master · istio/istio · GitHub。
以下是同节点与跨节点的加密和明文流量路径的可视化图示:
跨节点的加密流量路径
跨节点的明文流量路径
同节点的加密流量路径
同节点的明文流量路径
OUTPUT
链中被匹配,符合条件的流量被重定向到 ISTIO_OUTPUT
链。ISTIO_OUTPUT
链中,流量被标记并被接受。通过解析 Istio ambient 模式下的 iptables 规则,我们可以看到,Istio 通过 CNI 插件在 pod 内设置了一系列透明的流量拦截规则。这些规则确保了流量在进出 pod 时能够按预期被 ztunnel 代理处理,从而实现更细粒度的流量管理和安全策略应用。未来我们将继续探索更多关于 Istio ambient 模式下的网络细节,敬请关注。
最后更新于 2024/12/03