当前位置首页 > 计算机 > linux/Unix
搜柄,搜必应! 快速导航 | 使用教程  [会员中心]

linux路由协议网络协议栈

文档格式:DOCX| 13 页|大小 597.35KB|积分 20|2023-04-08 发布|文档ID:198424535
第1页
下载文档到电脑,查找使用更方便 还剩页未读,继续阅读>>
1 / 13
此文档下载收益归作者所有 下载文档
  • 版权提示
  • 文本预览
  • 常见问题
  • 迈普学习总结经过在公司里学习了几个月,把大体的工作总结于下:在参与1800-20 3G路由的开发中,我参与了 l2tp, gre,静态路由,ipsec,日志关键信息提取的编写并同时参与了ipsec-tools源码,linux kernel 网络协议栈源码,l2tpd源码分析并且同时了解了 vrrp,rip等协议L2TP模块:L2tp代码流程:大体过程应该是这样的,中间也许有错,主要是记不大清楚了Pppd向内核注册过程如下图:L用户数据发送过程如下所示=应用程序 pppd■2, TFPP协议模块ttyGSM模组2. pppd的控制协议数据发送过程=pppd --Pap/chap/eap (et c)--> /dev/ppp --> PFF协议模块 --> tty --> GSM模组拓扑图:做lac的路由器通过拨号到lns,通过上面的连接认证后,lns会给lac分配一个私有ip地址,该Ip地址可以和2通信 通过这个过程后,久可以让内网1的pc访问内网2的pcGre模块:模型:开始的时候,内网1和内网2是不能相互到达的,因为中间有许多中间网络当建立好GRE隧道后,内网1就可以和内网2通信了实现:GRE脚本主要通过iproute2这个工具实现。

    使用的主要脚本命令:Ip route add $name mode gre remote $remoteip local $localip ttl 255Ip route set $name upIp route add net $net/$mask dev $name脚本流程:脚本从lua保存的配置文件中获取到上面的变量值,然后通过以上指令,将变量值设置到相应的隧道中 责任:主要担任gre模块的测试(与linux)DDNS模块:原理:DDNS又叫动态域名解析实用环境是在用户动态获取IP地址的情况下因为传统的DNS只能与固定IP地址绑定,一旦IP地址发生 变化,相应的域名将不能解析到变换后的IP地址上然后DDNS改变了这一点它以动态域名绑定的方式来完成这一点什么叫动态域名呢?就 是指在用户的IP地址发生改变时,相应的DDNS客户端会把自己现在的变化后的IP地址传给DDNS服务器,告诉它自己的IP地址已经发生变化, 需要服务器将以前绑定域名的IP换成现在变化后的IP地址如果内部在加上端口映射,那么久可以实现路由器内部的主机间接与DNS绑定,即其 他人通过域名就能访问的内网的某台计算上的服务器。

    责任:DDNS的测试静态路由模块:原理:举个例子,当一个路由器刚接入到一个网络中时,在这个陌生的环境中,它根本不知道去某个地址该怎么走,静态路由就相当于一个指 路人,它告诉路由器某个IP地址该怎么走配置的时候,只需要告诉路由器到达某个网络需要从哪张网卡和相应网卡出去的网关地址就可以了 这样凡是到那个网络的IP数据包,路由器都会将它从相应网卡转发出去(ttl-1)它并不关心数据包能否真正的到达实现:具体命令:route add net $net mask $netmask gw $gateway dev $device责任:静态路由的脚本的基本框架Ipsec模块:原理:在内核2.6版本中已经存在ipsec模块,该模块的主要作用是让数据包经过加密/认证从安全的隧道中到达指定的目标地址它的有几种 数据包格式,一种是esp,一种是ah,另一种是esp+ah他们的报文格式如下:Ah是一种用于认证报文,它主要是给数据包提供认证,防重放;ESP是一种用于加密报文,当然它也有认证的功能,并且也具有抗重放的机 制它是一种更优越于AH的报文结构另外,esp+ah则是一种集esp和ah于一身的格式,当然它的安全性就更不可否认了。

    整个模块分为两大类:第一类,kernel ipsec的实现,第二类上层应用程序ike即为ipsec模块协商认证算法和加密算法的协议下面谈谈ike协 议Ike协议分为两个阶段,第一阶段协商对对方的身份进行认证,并且为第二阶段的协商提供一条安全可靠的通道第一个阶段又分为3种模式, 我们常用的有两种模式,一个是主模式,一个是积极模式第二阶段主要对IPSEC的安全性能进行协商,产生真正可以用来加密数据流的密钥主模式(IKE SA阶段):以上过程中包含验证信息,我就没特别指出了具体参见如下:发送cockie包,用来标识唯一的一个IPSEC会话IKE 阶段一(主模式):发送消息 1 initiator====>responsor isakmp header sa payload proposal payload transform payload定义一组策略: 加密方法:DES 认证身份方法:预共享密钥 认证散列:MD5存活时间:86400秒Diffie-Hellman group: 1IKE阶段二(主模式):发送消息2 同上IKE阶段三(主模式):发送消息3 通过DH算法产生共享密钥KE (Key Exchang) Payload nonce(暂时)Payload DH算法:A: P(较大的质数)G PriA (随机产生) PubA=G"PriA mod P 交换PubA和PubB Z=PubB"PriA mod Pinitiator<====responsorinitiator====>responsorB: P(较大的质数)GPriB (随机产生) PubB=G"PriB mod PZ=PubA PriB mod PZ就是共享密钥,两个自我产生的Z应相同,它是用来产生3个SKEYID的素材。

    IKE阶段四(主模式):发送消息4 initiator<====responsor同上主模式第3、4条消息其实就是DH算法中需要交换的几个参数,然后路由器再通过DH算法计算出的公共密钥计算出以下3个参数(这是在 发送第5、6个消息前完成的):SKEYID_d:留在在第二阶段用,用来计算后续的IKE密钥资源;SKEYID_a :散列预共享密钥,提供IKE数据完整性和认证;SKEYID_e:用来加密下一阶段的message, data, preshared key,包括第二阶段initiator====>responsorIKE阶段五(主模式):发送消息5 Identity Payload:用于身份标识 Hash Payload:用来认证 以上2个负载都用SKEYID_e加密initiator<====responsorIKE阶段六(主模式):发送消息6 同上至此IKE协商第一阶段完成消息5、6是用来验证对等体身份的主要会发送6个报文,由于最后一组报文发送的是身份,此时身份已经加密,因此,只能采用地址进行认证,但其安全性高于积极模式缺点 是耗时比积极模式长积极模式:主要发送3个报文,安全性没有主模式好,由于其ID不加密,因此可用于移动客户端模式。

    即不用地址作为ID优点:速度快,缺点安全性 不高第二阶段快速模式(IPSec SA阶段):以上过程中包含验证信息(最开始如果支持PFS算法,那么还要协商DH算法),我就没特别指出了具体参见如下:首先判断是否启用了 PFS (完美转发安全),若启用了则重新进行DH算法产生密钥,若没有启用则是用第一阶段的密钥IPSec 阶段一(快速模式):发送消息 1 initiator====>responsor同样定义一组策略,继续用SKEYID_e加密:Encapsulation— ESPIntegrity checking— SHA-HMACDH group— 2Mode— TunnelIPSec 阶段二(快速模式):发送消息 2 initiator<====responsor同上,主要是对消息1策略的一个确认在发送消息3前,用SKEYID_d,DH共享密钥,SPI等产生真正用来加密数据的密钥IPSec阶段三(快速模式):发送消息3 initiator====>responsor用来核实 responsor 的 liveness至此,整个IPSec协商的两个过程已经完成,两端可以进行安全的数据传输。

    实现:ike协议我们主要是通过利用开源软件ipsec-tools来实现的责任:负责ipsec的代码BUG解决(BUG数量多,就不列出了),ipsec的证书申请脚本编写(研究了 openssl)Ipsec-tools 流程:eay_init();//opensll 初始化initlcconf();//本地配置文件初始化initrmconf();//远端配置文件初始化oakley_dhinit();//dh 算法初始化compute_vendorids();//dpdparse(ac, av);//传进来的参数分析ploginit();//本地日志初始化pfkey_init()//内核接口 af_key初始化,主要是向内核注册isakmp_cfg_init(ISAKMP_CFG_INIT_COLD))//isakmp 配置初始化cfparse();//配置文件分析,别且赋值给相应结构体session();//主 要会话下面是session函数里面的实现:sched_init();//调度初始化init_signal();//信 号初始化admin_init()//和 setkey, racoonctl 的连接口初始化initmyaddr();//初始化本地地址isakmp_init()//isakmp 初始化initfds();//初始化 select 的套接字natt_keepalive_init ();//初始化nat协商的相关内容for (i = 0; i <= NSIG; i++)//信号的相应保存变量初始化sigreq[i] = 0;check_sigreq();//检测是否收到有信号error = select(nfds, &rfds, (fd_set *)0, (fd_set *)0, timeout);//多 路监听admin_handler();//监听到setkey和racoonctl的fd触发,调用该函数处理isakmp_handler(p->sock);//监听到ike连接信息和ike协商信息处理函数pfkey_handler();//监听的内核af_key发上来的信息处理函数(包含发起ike协商等) isakmp_handler(p->sock);函数里最重要的函数是 isakmp_main()isakmp_handler(p->sock);()这个函数里面除了数据包有效性检查外,ph1_main()第一阶段函数,quick_main()第二阶段处理函数,这两个函数最重要。

    这两个函数内分别用了一个重要的结构体:如下ph1exchange[][]整个racoon就靠这个结构体来进行协商可以说是贯穿整个racoon)static int (*ph1exchange[][2][PHASE1ST_MAX])__P((struct phlhandle *, vchar_t *)) = (/* error */( {}, {}, },/* Identity Protection exchange */{{ nostatel, ident_i1send, nostatel, ident_i2recv, ident_i2send,ident_i3recv, ident_i3send, ident_i4recv, ident_i4send, nostatel, },{ nostatel, ident_r1recv, ident_r1send, ident_r2recv, ident_r2send, ident_r3recv, ident_r3send, nostatel, nostatel, nostatel, },},/* Aggressive exchange */{{ nostatel, agg_ilsend, nostatel, agg_i2recv, agg_i2send, nostatel, nostatel, nostatel, nostatel, nostatel, },{ nostatel, agg_rlrecv, agg_rlsend, agg_r2recv, agg_r2send, nostatel, nostatel, nostatel, nostatel, nostatel, },},/* Base exchange */{{ nostatel, base_ilsend, nostatel, base_i2recv, base_i2send,base_i3recv, base_i3send, nostatel, nostatel, nostatel, },{ nostatel, base_rlrecv, base_rlsend, base_r2recv, base_r2send, nostatel, nostatel, nostatel, nostatel, nostatel, },},};可以看的到上面有第一阶段有三个模式的发送和接受函数(main , Aggressive, base);其中有每一个模式下的交互消息一个函数。

    同时也有验证函数如果熟悉几种模式的发包流程, 相信通过函数定义的名字就可以轻松知道函数是干嘛用的了注意存在状态判断函数,发送 和接收函数,每个阶段都不同)以上函数会在phl_main()调用,在pfkey_handler()调用的则是 协商发起方static int (*ph2exchange[][2][PHASE2ST_MAX])__P((struct ph2handle *, vchar_t *)) = {/* error */{ {}, {}, },/* Quick mode for IKE */{{ nostate2, nostate2, quick_ilprep, nostate2, quick_ilsend,quick_i2recv, quick_i2send, quick_i3recv, nostate2, nostate2, },{ nostate2, quick_rlrecv, quick_rlprep, nostate2, quick_r2send,quick_r3recv, quick_r3prep, quick_r3send, nostate2, nostate2, }},};可以看到上面的第二阶段即快速模式下的发送和接受函数,这些函数就是ike第二阶段协商使用的。

    其中有二阶段的每个包的发送和接受,状态函数具体是怎么实现的请参看相应的源代码以上的 ph2handle 会在,quick_main()中调用日志分析各个处理方法和流程参考代码就可以了这就是大概流程,其中可能会涉及到openssl编码问题(第一 阶段的算法为二阶段的传递信息编码)编写选出特定信息的脚本通过awk的传参和让AWK进行处理Linux kernel网络协议栈流程:图 1, tcp/ip 协议栈 AF_INET 运行结构图(包含 IPSEC, netfilter,af_key)Ne#?//维护链表:netfilter定义了一个二维的链表头数组struct list_head nf_hooks[NPROTO][NF_MAX_HOOKS]来表示所有协议族的各个挂接点,NPROTO值为 32,可表示linux所支持所有32个协议族(include/linux/socket.h文件中定义),也就是使用socket(2)函数的第一个参数的值,如互联网的TCP/IP协议 族PF_INET(2)每个协议族有NF_MAX_HOOKS(8)个挂接点,但实际只用了如上所述的5个,数组中每个元素表示一个协议族在一个挂接点的 处理链表头。

    图2,netfilter维护的链表结构图例如:在IPv4(PF_INET协议族)下,各挂接点定义在:NF_IP_PRE_ROUTING中,在IP栈成功接收sk_buff包后处理,挂接点在在net/ipv4/ip_input.c 的函数int ip_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt) 中使用:return NF_HOOK(PF_INET, NF_IP_PRE_ROUTING, skb, dev, NULL,ip_rcv_finish);挂接点的操作由结构struct nf_hook_ops定义:include/linux/netfilter.hstruct nf_hook_ops{struct list_head list;//链表头,用于将此结构接入操作链表/* User fills in from here down. */nf_hookfn *hook;//钩子函数int pf; //协议族int hooknum;//挂接点如:PREROUTING/* Hooks are ordered in ascending priority. */int priority;//优先级 };优先级列表:NF_IP_PRI_FIRST = INT_MIN,NF_IP_PRI_CONNTRACK = -200,NF_IP_PRI_MANGLE = -150,NF_IP_PRI_NAT_DST = -100,NF_IP_PRI_FILTER = 0,NF_IP_PRI_NAT_SRC = 100,NF_IP_PRI_LAST = INT_MAXfnet模块挂接(详细运转关系,由于时间原因,就不在叙述)af^ey模块挂接(详细运转关系,由于时间原因,就不在叙述)内核中PF_KEY实现要完成的功能是实现维护内核的安全联盟(SA)和安全策略(SP)数据库,以及和用户空间的接口。

    详细过程略xfrm_state 表:xfrm状态用来描述SA在内核中的具体实现 struct xfrm_state{/* Note: bydst is re-used during gc *///每个状态结构挂接到三个HASH链表中struct hlist_node bydst; // 按目的地址 HASHstruct hlist_node bysrc; // 按源地址 HASHstruct hlist_node byspi; // 按 SPI 值 HASHatomic_t refcnt; //所有使用计数spinlock_t lock; // 状态锁struct xfrm_id id; // IDstruct xfrm_selector sel; // 状态选择子u32 genid;/* Key manger bits */struct {u8 state;u8 dying;u32 seq;} km;/* Parameters of this state. */struct {u32 reqid;u8 mode;u8 replay_window;u8 aalgo, ealgo, calgo;u8 flags;u16 family;xfrm_address_t saddr;int header_len;int trailer_len;} props;struct xfrm_lifetime_cfg lft; // 生存时间/* Data for transformer */struct xfrm_algo *aalg; // hash 算法struct xfrm_algo *ealg; // 加密算法struct xfrm_algo *calg; // 压缩算法/* Data for encapsulator */struct xfrm_encap_tmpl *encap; // NAT-T 封装信息、/* Data for care-of address */xfrm_address_t *coaddr;/* IPComp needs an IPIP tunnel for handling uncompressed packets */ struct xfrm_state *tunnel;/* If a tunnel, number of users + 1 */ atomic_t tunnel_users;/* State for replay detection */struct xfrm_replay_state replay;/* Replay detection state at the time we sent the last notification */ struct xfrm_replay_state preplay;/* internal flag that only holds state for delayed aevent at the* moment*/u32 xflags;/* Replay detection notification settings */u32 replay_maxage;u32 replay_maxdiff;/* Replay detection notification timer */ struct timer_list rtimer;/* Statistics */struct xfrm_stats stats;struct xfrm_lifetime_cur curlft;struct timer_list timer;/* Last used time */ u64 lastused;/* Reference to data common to all the instances of this* transformer. */struct xfrm_type *type;struct xfrm_mode *mode;/* Security context */ struct xfrm_sec_ctx *security;/* Private data of this transformer, format is opaque,* interpreted by xfrm_type methods. */ void *data;};xfrm_policy 表安全策略表struct xfrm_policy{struct xfrm_policy *next; // 下一个策略struct hlist_node bydst; // 按目的地址 HASH 的链表struct hlist_node byidx; // 按索引号 HASH 的链表/* This lock only affects elements except for entry. */ rwlock_t lock;atomic_t refcnt;struct timer_list timer;u8 type;u32 priority;u32 index;struct xfrm_selector selector;struct xfrm_lifetime_cfg lft;struct xfrm_lifetime_cur curlft;struct dst_entry *bundles;__u16 family;__u8 action;__u8 flags;__u8 dead;__u8 xfrm_nr;struct xfrm_sec_ctx *security;struct xfrm_tmpl xfrm_vec[XFRM_MAX_DEPTH];};esp模块挂接(向安全路由注册,向传输层操作链注册)ah模块挂接(方法雷陇,尸,略)linux kernel重要结构体s如cf sk_buf (由于时间关系咎略):managle表挂接(主要向昵成加尸中注册相关的处理函数,是上层iptables与netfilter的接口,实现 流程,略)filter表挂接(主要defter中注册相关的处理函数,是上层ptables与netfilter的接口,实现流 程,略)nat表挂接(主要向netfilter中注册相关的处理函数,是上层iptables与netfilter的接口,实现流程, 略)raw表挂接(主要向netfilter中注册相关的处理函数是上层iptables与netfilter的接口,实现流程, 略)其他正在研究中的暂略。

    点击阅读更多内容
    卖家[上传人]:dlmus1
    资质:实名认证