`
javafan_303
  • 浏览: 957224 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

ip_conntrack的作用

 
阅读更多

修改应用层协议控制包使用了ip_conntrack,iptables的REDIRECT target也使用了ip_conntrack,另外包括iptables的state模块也是如此,使用ip_conntrack,可见ip_conntrack的重要性,ip_conntrack的一个无比重要的作用是实现nat,可以说REDIRECT target和对诸如ftp的修改以实现server回连client最终都落实到了nat上,比如,所谓的REDIRECT就是内置一个nat规则,将符合matchs的包nat到本机的特定端口,这个和iptables的nat表原理是一样的,不同的是,nat表的配置是显式的nat,而REDIRECT和ip_nat_ftp是隐式的nat而已。它们都是nat,都依赖于原始的ip_conntrack,因此原始的链接流信息并没有丢失,还是可以得到的,事实上,内核就是通过原始的链接流来匹配nat规则的,如果丢弃了原始链接流信息,何谈匹配!如果一个原始链接是a->b,而后不管是显式的nat还是隐式的REDIRECT以及nat_ftp,将a->b改为了a->c,a->b还是可以得到的,内核正是从a->b的流信息中取得了“要转换为a->c”这个信息的。
在init_conntrack中有以下逻辑:
conntrack = kmem_cache_alloc(ip_conntrack_cachep, GFP_ATOMIC);
conntrack->ct_general.destroy = destroy_conntrack;
conntrack->tuplehash[IP_CT_DIR_ORIGINAL].tuple = *tuple; //初始化tuple,记录连接地址端口信息,该tuple在nat后不会被改掉,此谓原始流
conntrack->tuplehash[IP_CT_DIR_ORIGINAL].ctrack = conntrack;
conntrack->tuplehash[IP_CT_DIR_REPLY].tuple = repl_tuple; //repl_tuple初始化成和tuple一样的,在nat之后就会被改成nat后的地址,端口信息,此谓修改后的流,repl是replace的意思.
conntrack->tuplehash[IP_CT_DIR_REPLY].ctrack = conntrack;
tuple中就包含了原始流的信息,在随后的nat表的查找后,在alloc_null_binding中初始化conntrack的nat信息,由此就将nat信息和原始流信息统一到了conntrack中了。resolve_normal_ct是ip_conntrack模块使用的,其最后一句:
skb->nfct = &h->ctrack->infos[*ctinfo];
会将连接信息设置到skb中,以备后面的nat或者REDIRECT使用,在nat中,调用ip_conntrack_get取得这个conntrack。在ip_nat_setup_info中会调用ip_conntrack_alter_reply,后者会改变conntrack->tuplehash[IP_CT_DIR_REPLY].tuple的值为一个新的nat后的值。对于REDIRECT target,netfilter提供了一个getsockopt接口可以取得原始流的信息,该接口就是SO_ORIGINAL_DST,最终调用getorigdst,在getorigdst中有以下逻辑:
struct inet_opt *inet = inet_sk(sk);
struct ip_conntrack_tuple_hash *h;
struct ip_conntrack_tuple tuple;
IP_CT_TUPLE_U_BLANK(&tuple);
tuple.src.ip = inet->rcv_saddr; //原始流的源ip
tuple.src.u.tcp.port = inet->sport; //原始流的源端口
tuple.dst.ip = inet->daddr; //本机重定向后的ip
tuple.dst.u.tcp.port = inet->dport; //本机重定向后的端口
...
h = ip_conntrack_find_get(&tuple, NULL); //在既有链接中寻找一个ip_conntrack_tuple_hash的tuple字段和参数tuple一样的,返回ip_conntrack_tuple_hash结构体
...
ip_conntrack_tuple_hash的定义如下:
struct ip_conntrack_tuple_hash
{
struct list_head list;
struct ip_conntrack_tuple tuple;
struct ip_conntrack *ctrack;
};
现在看一下ip_conntrack_find_get如何找到h,在REDIRECT target中,数据肯定要进入本机,而进入本机就要进入NF_IP_LOCAL_IN链,在NF_IP_LOCAL_IN链上注册有一个ip_conntrack_local_in_ops,其HOOK函数为ip_confirm,最终要调用到__ip_conntrack_confirm,__ip_conntrack_confirm有以下逻辑:
unsigned int hash, repl_hash;
...
hash = hash_conntrack(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple);
repl_hash = hash_conntrack(&ct->tuplehash[IP_CT_DIR_REPLY].tuple);
...
list_prepend(&ip_conntrack_hash[hash], &ct->tuplehash[IP_CT_DIR_ORIGINAL]);
list_prepend(&ip_conntrack_hash[repl_hash], &ct->tuplehash[IP_CT_DIR_REPLY]);
最后的两行将修改后的contrack信息的hash加入了ip_conntrack_hash表,在getorigdst调用ip_conntrack_find_get的时候,所使用的信息就是修改后的contrack信息,因此最终肯定能找到&ct->tuplehash[IP_CT_DIR_REPLY],而tuplehash[IP_CT_DIR_REPLY]和tuplehash[IP_CT_DIR_ORIGINAL]二者统一到了conntrack中,因此getorigdst的后半段:
sin.sin_port = h->ctrack->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.u.tcp.port;
sin.sin_addr.s_addr = h->ctrack->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.ip;
将可以得到原始流的信息。
最后看看redirect的HOOK函数:
static unsigned int redirect_target(...)
{
...
ct = ip_conntrack_get(*pskb, &ctinfo);
...
indev = (struct in_device *)(*pskb)->dev->ip_ptr;
newdst = indev->ifa_list->ifa_local;
newrange = ((struct ip_nat_multi_range)
{ 1, { { mr->range[0].flags | IP_NAT_RANGE_MAP_IPS,
newdst, newdst,
mr->range[0].min, mr->range[0].max } } });
return ip_nat_setup_info(ct, &newrange, hooknum); //重定向到本机的地址转换
}
__ip_conntrack_confirm函数不仅仅由NF_IP_LOCAL_IN链上的operations调用,在POSTROUTING链上也有调用,这就是ip_conntrack_out_ops中的HOOK函数ip_refrag,因此不管怎样,只要发生了地址转换,总逃不过将新的转换后的流信息加入到conntrack中。
作罢!

<!-- Baidu Button BEGIN -->
分享到:
评论

相关推荐

    libnetfilter_conntrack-1.0.7.tar.bz2

    conntrack将信息存在内存结构中,包括IP,端口,协议类型,状态以及超时时间。 而且conntrack不仅可以对TCP这种有状态的会话进行状态跟踪,还可以对UDP进行状态跟踪。 conntrack本身并不会对包进行过滤,而是...

    nf_conntrack_proto_udp.rar_out

    标题中的“nf_conntrack_proto_udp.rar_out”暗示了一个与网络连接跟踪(Netfilter Connection Tracking,简称NFCT)相关的主题,特别是涉及UDP(User Datagram Protocol)协议的子部分。这个名称可能对应于一个软件...

    tftp链接跟踪

    `ip_conntrack_helper_register`函数的作用是将该模块加入到以`helpers`为首的链表中: ```c int ip_conntrack_helper_register(struct ip_conntrack_helper *me) { BUG_ON(me-&gt;timeout == 0); WRITE_LOCK(&ip_...

    iptables不错脚本

    # 载入相关模块 PATH=/sbin:/bin:/usr/sbin:/usr/bin ...modprobe ip_conntrack_ftp &gt; /dev/null 2&gt;&1 modprobe ip_conntrack_irc &gt; /dev/null 2&gt;&1 modprobe ipt_MASQUERADE &gt; /dev/null 2&gt;&1

    Netfilter_读书笔记.pdf

    - `struct nf_hook_ops ip_conntrack_local_out_ops;` // 对应 LOCAL_OUT - `struct nf_hook_ops ip_conntrack_out_ops;` // 对应 POST_ROUTING - `struct nf_hook_ops ip_conntrack_local_in_ops;` // 对应 ...

    Linux-netfilter-conntrack机制初步分析

    它调用`ip_ct_get()`函数来查找或创建连接记录,并调用`ip_conntrack_reass()`函数来重新组装分片的数据包。这个过程对于确保正确地处理分片数据包至关重要。 ##### 4.2 ip_conntrack_in() 此函数处理进入系统的...

    connview.php - [ip_conntrack frontend]-开源

    ConnView是conntrack表查看器。 这是php脚本-ip_conntrack表的前端。 您可以选择过滤,连接排序。 脚本可识别conntrack表中的常见服务。您可以查看连接列表或每个IP的详细信息列表等。

    iptables的conntrack表满了导致访问网站很慢.docx

    首先,可以通过增大`ip_conntrack_max`参数来增加conntrack表的最大连接数。例如,在`/etc/sysctl.conf`文件中设置`net.ipv4.ip_conntrack_max = 1048576`,表示允许的最大连接数为1048576。需要注意的是,这个值...

    基于Kubernetes v1.24.0的集群搭建(二).doc

    本文主要介绍了基于 Kubernetes v1.24.0 的集群搭建的第二部分,涵盖了 K8S 的相关部署、配置 yum 源、br_netfilter 和 ip_conntrack 模块配置、配置内核转发及网桥过滤、安装 ipset 及 ipvs 等重要的知识点。...

    Linux修改TCP连接数.doc

    系统对 TCP 连接的跟踪限制是由 `net.ipv4.ip_conntrack_max` 内核参数决定的。我们可以通过修改 `/etc/sysctl.conf` 文件,添加以下行: ``` net.ipv4.ip_conntrack_max = 10240 ``` 这将将系统对 TCP 连接的跟踪...

    vsftp登录后不显示文件目录的问题怎么修改防火墙.doc.docx

    IPTABLES_MODULES=ip_conntrack_netbios_ns ip_conntrack_ftp service iptables restart 四、防火墙管理技巧 防火墙管理是非常重要的,以下是一些防火墙管理技巧: 1. 所有的防火墙文件规则必须更改。 2. 以最小的...

    Linux网络地址转换NAT源码分析.pdf

    在Netfilter框架中,NAT操作主要是通过ip_conntrack(连接跟踪)模块以及ip_nat(网络地址转换)模块来实现的。 Conntrack模块用于跟踪和管理网络连接的状态信息,是NAT得以实现的基础。它记录了每个连接的信息,...

    nat.rar_VXWORKS nat_nat

    Linux的NAT机制通常涉及IP连接跟踪(conntrack)、协议处理(proto)以及对TCP、UDP、ICMP等不同协议的支持。 根据提供的文件名,我们可以推测这些文件的功能和作用: 1. `nat.c`:这是主要的NAT功能实现文件,...

    Linux网络地址转换NAT源码分析

    `nat`结构包含`ip_nat_info`和`ip_conntrack_nat_help`两个参数。`ip_nat_info`是核心部分,用于存储如何进行地址转换的相关信息。其中,`initialized`字段标识连接是否已进行过NAT初始化,`num_manips`表示一个连接...

    linuxnat介绍

    另一个重要的结构体是 union ip_conntrack_nat_help,它是各协议 NAT 时需要特殊处理的结构描述。 Linux NAT 是一个复杂的网络地址转换技术,它需要使用 netfilter 框架、hook 机制和连接跟踪来实现。通过了解 ...

    LINUX2.4.x 连接跟踪和地址转换

    在这些路径上,连接跟踪和地址转换注册了多个关键函数,例如用于连接跟踪的`nf_conntrack_in`和`nf_conntrack_out`,以及用于地址转换的`nf_nat_snat`和`nf_nat_dnat`。这些函数在处理数据包的过程中,会创建或更新...

    linux系统报xfs_vm_releasepage警告问题的处理方法

    问题说明 最近的几台机器在同一天的...Mar 26 20:55:03 host1 kernel: Modules linked in: nf_conntrack_ipv4 nf_defrag_ipv4 xt_conntrack nf_conntrack iptable_filter ip_tables ebtable_filter ebtables ip6tab

    阿里云搭建IPv6隧道支持IPv6

    ip_conntrack 532815 ipt_MASQUERADE,iptable_nat,ip_nat,ip_conntrack_netbios_ns,xt_state nfnetlink 107132 ip_nat,ip_conntrack iptable_filter 71051 ip_tables 170292 iptable_nat,iptable_filter ip6t_...

    Linux实战型企业运维工程师试题测评 433页

    解决方法包括查看当前的ip_conntrack配置值和ip_conntrack_buffer的使用状态,并找出消耗连接跟踪资源最多的IP地址。 3. PHP-FPM进程占用高:在Linux系统中,如果NGINX配合PHP-FPM环境运行时PHP-FPM进程占用过高,...

Global site tag (gtag.js) - Google Analytics