【博客524】iptables nat的实现根基:conntrack

148 篇文章 19 订阅
130 篇文章 12 订阅

iptables nat的实现根基:conntrack

conntrack

conntrack 是 Linux 下的一个内核模块,这个名字是 connection track 的缩写, 顾名思义,这个模块就是用来做连接跟踪的。 然而这里的链接需要同 TCP 协议中的连接区分开来, 它指的是通信的两个端点之间用于传输数据的连接, 因此它不止可以用来跟踪 TCP 的连接,还可以跟踪 UDP、ICMP 协议保报文这样”连接“。 conntrack实现跟踪的原理是conntrack 维护一张连接表(conntrack table)。

先提netfilter框架

netfilter是linux内核中的一个数据包处理框架,用于替代原有的ipfwadm和ipchains等数据包处理程序。netfilter的功能包括数据包过滤,修改,SNAT/DNAT等。netfilter在内核协议栈的不同位置实现了5个hook点,其它内核模块(比如ip_tables)可以向这些hook点注册处理函数,这样当数据包经过这些hook点时,其上注册的处理函数就被依次调用,用户层工具像iptables一般都需要相应内核模块ip_tables配合以完成与netfilter的交互。netfilter hooks、ip{6}_tables、connection tracking、和NAT子系统一起构成了netfilter框架的主要部分。

详情见:netfilter框架解析

netfilter转发链路

   --->PRE------>[ROUTE]--->FWD---------->POST------>
       Conntrack    |       Mangle   ^    Mangle
       Mangle       |       Filter   |    NAT (Src)
       NAT (Dst)    |                |    Conntrack
       (QDisc)      |             [ROUTE]
                    v                |
                    IN Filter       OUT Conntrack
                    |  Conntrack     ^  Mangle
                    |  Mangle        |  NAT (Dst)
                    v                |  Filter

netfilter全链路图

在这里插入图片描述

conntrack在流量转发中有着比nat更高的优先级

/* hook函数默认优先级设置,数值越小优先级越高 */
enum nf_ip_hook_priorities {
    NF_IP_PRI_FIRST = INT_MIN, /* 最高优先级 */
    NF_IP_PRI_RAW_BEFORE_DEFRAG = -450, /* 涉及IP分片重组的RAW */
    NF_IP_PRI_CONNTRACK_DEFRAG = -400, /* 涉及IP分片重组的连接跟踪 */
    NF_IP_PRI_RAW = -300, /* RAW表,用于取消连接跟踪 */
    NF_IP_PRI_SELINUX_FIRST = -225,
    NF_IP_PRI_CONNTRACK = -200, /* 连接跟踪开始 */
    NF_IP_PRI_MANGLE = -150,
    NF_IP_PRI_NAT_DST = -100, /* NAT的改变目的地址, DNAT or de-SNAT */
    NF_IP_PRI_FILTER = 0, /* IPTABLES的数据包过滤 */
    NF_IP_PRI_SECURITY = 50,
    NF_IP_PRI_NAT_SRC = 100, /* NAT的改变源地址, SNAT or de-DNAT */
    NF_IP_PRI_SELINUX_LAST = 225,
    NF_IP_PRI_CONNTRACK_HELPER = 300,
    NF_IP_PRI_CONNTRACK_CONFIRM = INT_MAX, /* 连接确认 */
    NF_IP_PRI_LAST = INT_MAX, /* 最低优先级 */
};
优先级CONNTRACK > DNAT > FILTER > SNAT > CONNTRACK_CONFIRM

分析:

我们知道NAT是在连接跟踪的基础上实现的,所以连接跟踪肯定是在NAT之前建立的。从这里注册的钩子函数的优先级可以看到,NAT的优先级是NF_IP_PRI_NAT_SRC = -100而连接跟踪的优先级是NF_IP_PRI_CONNTRACK = -200,在Netfilter框架中优先级数值越小,优先级越高,越先被调用。所以可以看到NAT是在连接跟踪建立之后进行的。

融入了conntrack的iptables四表五链

conntrack虽然不属于iptables四表五链,但他维护的连接状态可以被四表五链使用,且四表五链在做NAT的时候,是依赖于conntrack的
在这里插入图片描述

conntrack table

conntrack 维护一张连接表——conntrack table。 通过 netfilter 的 hook 机制,conntrack 模块可以检查系统中进出的每个网络数据包。 当发现一条新的连接建立时,比如检查到一个 TCP SYNC 数据包, conntrack 就在 conntrack table 中添加一条连接记录。 可以用 Linux 中的 conntrack 指令查看 conntrack table, conntrack table 表项中记录的格式如下:

example:

tcp 6 48 SYN_SENT src=192.168.199.132 dst=172.217.24.14 sport=58074 dport=443 [UNREPLIED] src=172.217.24.14 dst=192.168.199.132 sport=443 dport=58074 mark=0 use=1

在这里插入图片描述

conntrack中的连接不等于tcp中的连接

Netfilter 中每个 flow 都称为一个 connection,即使是对那些非面向连接的协议(例 如 UDP)
在这里插入图片描述

conntrack工作原理

conntrack 是一个非常重要的模块,它是 ipvs 负载均衡、NAT 的核心依赖模块。 以 SNAT 为例我们来说明 conntrack 的一个应用场景。 当 NAT 模块收到一个新的报文时,它先查看 conntrack table, 如果其中存在相关连接信息的表项,它会根据这个表项修改报文的 ip 和 端口信息。 当相关表项不存在时,遍历iptabls NAT表规则判断是否需要对报文做地址转换, 如果符合 NAT 地址转换规则,那么 NAT 会在 conntrack talbe 中写入转换后的地址, 后续地址转换直接查 conntrack table 即可完成。

Linux 的连接跟踪是在 Netfilter 中实现的

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

Tuple 是连接跟踪中最重要的概念之一:

一个 tuple 定义一个单向(unidirectional)flow。

在这里插入图片描述

Netfilter 中的连接跟踪点

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

进入 NAT

在这里插入图片描述

工作原理:

首先查询 conntrack 记录,如果不存在,就意味着无法跟踪这个连接,那就更不可能做 NAT 了,因此直接返回。如果找到了 conntrack 记录,并且是 IP_CT_RELATED、IP_CT_RELATED_REPLY 或 IP_CT_NEW 状态,就去获取 NAT 规则。如果没有规则,直接返回 NF_ACCEPT,对包不 做任何改动;如果有规则,最后执行 nf_nat_packet,这个函数会进一步调用 manip_pkt 完成对包的修改,如果失败,包将被丢弃。

conntrack监控

在这里插入图片描述

conntrack常见问题:连接太多导致 conntrack table 被打爆

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值