当前位置: 首页 > news >正文

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

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 被打爆

在这里插入图片描述

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

相关文章:

  • Hive的表操作【博学谷学习记录】
  • 30 个 Python 技巧,加速你的数据分析处理速度
  • 学习unix网络编程第二章
  • 实验三.局域网的组建
  • 微服务14 Docker镜像仓库
  • Lambda详解 => {C#莱姆达表达式}
  • 6207. 统计定界子数组的数目(每日一难phase3-2)
  • java毕业设计家居体验平台的设计与实现Mybatis+系统+数据库+调试部署
  • SpringBoot测试配置属性与启动web环境
  • 11. SpringCloud Alibaba Seata
  • C++模板之——类模板详解及代码示例
  • Python推荐系统和深度学习教程
  • 基于Matlab使用雷达资源管理有效跟踪多个机动目标仿真(附源码)
  • 医院管理系统/医院药品管理系统
  • 项目中使用到的Spring注解及其作用
  • Android 控件背景颜色处理
  • echarts花样作死的坑
  • Gradle 5.0 正式版发布
  • Java的Interrupt与线程中断
  • JAVA多线程机制解析-volatilesynchronized
  • Laravel Telescope:优雅的应用调试工具
  • Less 日常用法
  • MySQL主从复制读写分离及奇怪的问题
  • Node.js 新计划:使用 V8 snapshot 将启动速度提升 8 倍
  • PHP CLI应用的调试原理
  • ReactNative开发常用的三方模块
  • Vim Clutch | 面向脚踏板编程……
  • vue-loader 源码解析系列之 selector
  • Work@Alibaba 阿里巴巴的企业应用构建之路
  • 七牛云 DV OV EV SSL 证书上线,限时折扣低至 6.75 折!
  • 使用parted解决大于2T的磁盘分区
  • 终端用户监控:真实用户监控还是模拟监控?
  • gunicorn工作原理
  • mysql面试题分组并合并列
  • ​一帧图像的Android之旅 :应用的首个绘制请求
  • # Swust 12th acm 邀请赛# [ E ] 01 String [题解]
  • #Linux杂记--将Python3的源码编译为.so文件方法与Linux环境下的交叉编译方法
  • #NOIP 2014# day.1 T2 联合权值
  • (1)Android开发优化---------UI优化
  • (33)STM32——485实验笔记
  • (pojstep1.1.1)poj 1298(直叙式模拟)
  • (二)Eureka服务搭建,服务注册,服务发现
  • (非本人原创)我们工作到底是为了什么?​——HP大中华区总裁孙振耀退休感言(r4笔记第60天)...
  • (附源码)springboot工单管理系统 毕业设计 964158
  • (附源码)springboot码头作业管理系统 毕业设计 341654
  • (附源码)ssm本科教学合格评估管理系统 毕业设计 180916
  • (规划)24届春招和25届暑假实习路线准备规划
  • (未解决)jmeter报错之“请在微信客户端打开链接”
  • (原)Matlab的svmtrain和svmclassify
  • .bat批处理(七):PC端从手机内复制文件到本地
  • .NET 使用 ILRepack 合并多个程序集(替代 ILMerge),避免引入额外的依赖
  • .NET 中让 Task 支持带超时的异步等待
  • .NET导入Excel数据
  • .sh文件怎么运行_创建优化的Go镜像文件以及踩过的坑
  • @Autowired和@Resource的区别