1 / 56

NETFILTER 分析

NETFILTER 分析. droplet@kernelchina.org 2006/2. 目录. introduction netfilter conntrack nat alg extension iptables match target programming netfilter. 防火墙是什么. 网络报文的选择,监控,过滤系统 部署在网络边界,关键路径上 网络报文的表示 策略的表示. 防火墙的类型. 包过滤 应用代理 状态检测. LINUX 防火墙的发展历史. linux2.0.x:ipfw linux2.2.x:ipchains

odele
Download Presentation

NETFILTER 分析

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. NETFILTER分析 droplet@kernelchina.org 2006/2 www.kernelchina.org

  2. 目录 • introduction • netfilter • conntrack • nat • alg extension • iptables • match • target • programming netfilter www.kernelchina.org

  3. 防火墙是什么 • 网络报文的选择,监控,过滤系统 • 部署在网络边界,关键路径上 • 网络报文的表示 • 策略的表示 www.kernelchina.org

  4. 防火墙的类型 • 包过滤 • 应用代理 • 状态检测 www.kernelchina.org

  5. LINUX防火墙的发展历史 • linux2.0.x:ipfw • linux2.2.x:ipchains • linux2.4.x:iptables • linux2.6.x:iptables www.kernelchina.org

  6. 检查点 nf_hooks[NPROTO][NF_MAX_HOOKS] nf_hook_ops • NPROTO = 32,支持协议族的数量 • NF_MAX_HOOKS = 8,支持检查点的数量 • 检查点上的nf_hook_ops结构,按priority的值,从小到大排列 www.kernelchina.org

  7. 检查点上的数据结构 struct nf_hook_ops { struct list_head list; nf_hookfn *hook; int pf; int hooknum; int priority; }; unsigned int nf_hookfn(unsigned int hooknum,struct sk_buff **skb,const struct net_device *in,const struct net_device *out, int (*okfn)(struct sk_buff *)); • list:链表结构;hook:检查点上调用的函数;pf:协议族;hooknum:检查点的编号;priority:此结构的优先级 • nf_register_hook:注册nf_hook_ops结构 • nf_unregister_hook:卸载nf_hoop_ops结构 www.kernelchina.org

  8. 检查点的定义 #define NF_HOOK(pf, hook, skb, indev, outdev, okfn) \ (list_empty(&nf_hooks[(pf)][(hook)])\ ? (okfn)(skb)\ : nf_hook_slow((pf), (hook), (skb), (indev), (outdev), (okfn))) • NF_HOOK:定义检查点 • (okfn)(skb):如果检查点上没有钩子函数,直接调用这个函数;如果有钩子函数,则先遍历检查点上的钩子函数,并根据钩子函数的返回值来确定下一步的动作;如果钩子函数完全遍历,同样需要调用这个函数 • nf_hook_slow:遍历检查点上的nf_hook_ops结构,并调用nf_hookfn www.kernelchina.org

  9. 检查点的调用流程 NF_HOOK nf_hook_slow nf_hookfn (okfn) 返回值 NF_DROP: 禁止包通过 NF_ACCEPT: 允许包通过 NF_STOLEN: 包被本机缓存 NF_QUEUE: 把包发送到用户空间 NF_REPEAT: 重复上一次遍历过程 www.kernelchina.org

  10. 检查点在PF_INET中的位置 链路层 NF_IP_PRE_ROUTING NF_IP_POST_ROUTING ROUTE 网络层 NF_IP_FORWARD ROUTE NF_IP_LOCAL_IN NF_IP_LOCAL_OUT 传输层 www.kernelchina.org

  11. NF_IP_PRE_ROUTING www.kernelchina.org

  12. NF_IP_LOCAL_IN www.kernelchina.org

  13. NF_IP_FORWARD www.kernelchina.org

  14. NF_IP_LOCAL_OUT www.kernelchina.org

  15. NF_IP_POST_ROUTING www.kernelchina.org

  16. conntrack的检查点 链路层 NF_IP_PRE_ROUTING NF_IP_POST_ROUTING ROUTE 网络层 NF_IP_FORWARD ROUTE NF_IP_LOCAL_IN NF_IP_LOCAL_OUT 传输层 www.kernelchina.org

  17. ip_conntrack_in • 每个包与一个状态结构关联,如果关联已存在,就不需要重复检查 • 在连接跟踪前要先把分片包组装成完整的包 • 如果是icmp协议的包,需要特殊处理 • 查找是否有与此包相关的状态结构,如果有,则根据包的信息进行状态转换,如果没有,则创建新的状态结构 • 不同协议对此协议包的特殊处理 • 此状态结构是否有相关的helper,如果有,就执行相应的helper函数 • if ((*pskb)->nfct) • return NF_ACCEPT; • *pskb = ip_ct_gather_frags(*pskb); • icmp_error_track(*pskb, &ctinfo, hooknum) • if (!(ct = resolve_normal_ct(*pskb, proto,&set_reply,hooknum,&ctinfo))) • ret = proto->packet(ct, (*pskb)->nh.iph, (*pskb)->len, ctinfo); • ret = ct->helper->help((*pskb)->nh.iph, (*pskb)->len, ct, ctinfo); www.kernelchina.org

  18. ip_confirm • 如果是已确认过的包就不需要再次确认 • 从skbuff的信息中找到与之相关的状态结构 • 只有ORIGINAL方向的包可以创建状态结构,REPLY方向的包只需匹配状态结构 • 计算ORIGINAL方向和REPLY方向的哈希值 • 如果此状态结构不在哈希表中,就把它加入哈希表 • 设置状态结构的已确认标记 • !is_confirmed((struct ip_conntrack *)skb->nfct->master) • ct = __ip_conntrack_get(nfct, &ctinfo); • if (CTINFO2DIR(ctinfo) != IP_CT_DIR_ORIGINAL) • return NF_ACCEPT; • 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]); • set_bit(IPS_CONFIRMED_BIT, &ct->status); www.kernelchina.org

  19. ip_conntrack状态结构 sk_buff ip_conntrack sk_buff ...... ...... ...... tuplehash[O] ...... ...... tuplehash[R] ...... ORIGINAL方向的包 ...... REPLY方向的包 struct ip_conntrack_tuple { src.ip src.u //不同协议,这个值不同 dst.ip dst.u //不同协议,这个值不同 dst. protonum } www.kernelchina.org

  20. ip_conntrack与sk_buff的关系 ip_conntrack sk_buff ct_general ...... ...... nfct nf_ct_info ...... ...... • 每个sk_buff都将与一个ip_conntrack关联,所以从sk_buff中可以得到与之关联的ip_conntrack • 每个sk_buff都将与ip_conntrack的一个状态关联,所以从sk_buff可以得到相应ip_conntrack的状态 www.kernelchina.org

  21. ip_conntrack与全局表的关系 ip_conntrack与全局表的关系 ip_conntrack_hash ip_conntrack ...... tuplehash[O] bysource (for nat) tuplehash[R] bysource byipsproto ...... byipsproto (for nat) www.kernelchina.org

  22. ip_conntrack状态转换[1] ORIGINAL IP_CT_NEW IP_CT_RELATED REPLY IP_CT_ESTABLISHED + IP_CT_IS_REPLY ORIGINAL IP_CT_ESTABLISHED nf_ct_info 0 1 2 3 4 www.kernelchina.org

  23. ip_conntrack状态转换[2] 任意有效状态 REPLY icmp error IP_CT_RELATED ORIGINAL icmp error IP_CT_RELATED + IP_CT_IS_REPLY nf_ct_info 0 1 2 3 4 www.kernelchina.org

  24. ip_conntrack与tcp协议 struct ip_conntrack_protocol_tcp { tcp_pkt_to_tuple //从tcp包中得到tuple tcp_invert_tuple //从tcp包中得到反向的tuple tcp_packet //tcp协议私有状态处理 tcp_new //创建tcp协议的状态结构时调用 tcp_exp_matches_pkt //这个包是否符合expect的要求 ...... } struct ip_ct_tcp 状态结构中与tcp协议相关的私有状态 www.kernelchina.org

  25. ip_conntrack与udp协议 struct ip_conntrack_protocol_udp { udp_pkt_to_tuple //从udp包中得到tuple udp_invert_tuple //从udp包中得到反向的tuple udp_packet //udp协议对状态结构的特殊处理 udp_new //创建udp协议的状态结构时调用 ....... } www.kernelchina.org

  26. ip_conntrack与icmp协议 struct ip_conntrack_protocol_icmp { icmp_pkt_to_tuple //从icmp包中得到tuple icmp_invert_tuple //从icmp包中得到反向的tuple icmp_packet //icmp协议对状态结构的特殊处理 icmp_new //创建icmp协议的状态结构时调用 ...... } struct ip_ct_icmp 状态结构中,与icmp协议相关的私有信息 www.kernelchina.org

  27. nat的检查点 链路层 NF_IP_PRE_ROUTING NF_IP_POST_ROUTING ROUTE 网络层 NF_IP_FORWARD ROUTE NF_IP_LOCAL_IN NF_IP_LOCAL_OUT 传输层 www.kernelchina.org

  28. nat与ip_conntrack struct ip_nat_info_manip direction 包的方向 hooknum 检查点编号 maniptype 转换类型 manip 替换地址和端口(或id) ip_conntrack:ip_nat_info ...... initialized num_manips bysource bysource byipsproto ...... byipsproto www.kernelchina.org

  29. ip_nat_fn • 首先找到与包关联的状态结构 • 如果这个状态结构是从expect创建出来的,就调用它的父连接的nat helper的expect函数来创建本连接的地址转换结构 • 如果状态结构的状态是IP_CT_RELATED、IP_CT_RELATED+IP_CT_IS_REPLY、IP_CT_NEW,就查找地址转换规则来创建本连接的地址转换结构 • 根据状态结构中的地址转换结构对包进行地址和端口的修改 • ct = ip_conntrack_get(*pskb, &ctinfo); • ret = call_expect(master_ct(ct), pskb, hooknum, ct, info); • ret = ip_nat_rule_find(pskb, hooknum, in, out, ct, info); • do_bindings(ct, ctinfo, info, hooknum, pskb); www.kernelchina.org

  30. ip_nat_setup_info • 找到一个唯一的ip地址和端口,生成一个新的tuple • 修改ip_conntrack中REPLY方向的tuple • 如果是源转换,生成ORIGINAL方向和REPLY方向的地址转换结构 • 如果是目的转换,生成ORIGINAL方向和REPLY方向的地址转换结构 • 把ip_conntrack放入nat的哈希表 • get_unique_tuple • ip_conntrack_alter_reply • ip_ct_tuple_src_equal • ip_ct_tuple_dst_equal • place_in_hashes www.kernelchina.org

  31. do_bindings • 根据ip_conntrack中的地址转换结构修改包的地址和端口,并重新计算校验和 • 如果这个ip_conntrack有nat helper,则调用它的help函数 • manip_pkt((*pskb)->nh.iph->protocol, • (*pskb)->nh.iph, (*pskb)->len,&info->manips[i].manip, info->manips[i].maniptype, &(*pskb)->nfcache); • ret = helper->help(ct, exp, info, ctinfo, • hooknum, pskb); www.kernelchina.org

  32. nat与tcp协议 struct ip_nat_protocol_tcp { tcp_manip_pkt //修改包的tcp端口 tcp_in_range //包的tcp端口是否在指定的范围之内 tcp_unique_tuple //找到一个唯一的tuple ....... } www.kernelchina.org

  33. nat与udp协议 struct ip_nat_protocol_udp { udp_manip_pkt //修改udp包的端口 udp_in_range //udp包的端口是否在指定的范围之内 udp_unique_tuple //找到一个唯一的tuple ....... } www.kernelchina.org

  34. nat与icmp协议 struct ip_nat_protocol_icmp { icmp_manip_pkt //修改icmp包的id icmp_in_range //icmp的id是否在指定的范围之内 icmp_unique_tuple //找到一个唯一的tuple ....... } www.kernelchina.org

  35. ip_conntrack与ALG的关系 ip_conntrack_helper ip_conntrack ...... helper conntrack中与ALG相关的参数 help nat.info.helper nat.help nat中与ALG相关的参数 ...... ip_nat_helper www.kernelchina.org

  36. ALG调用流程 ip_conntrack_expect->expectfn ip_conntrack->helper->help ip_conntrack->helper->help ip_conntrack.nat->helper->help ip_conntrack.nat->helper->expect 控制连接流程 ip_conntrack.nat->helper->help 数据连接流程 www.kernelchina.org

  37. ip_conntrack与expect的关系 ip_conntrack_expect_list parent ip_conntrack 如果找到与ip_conntrack 关联的ip_conntrack_exp ect,就把它从全局链表中 删掉 ...... sibling_list ip_conntrack_expect master ....... ...... list expected_list expectant parent ip_conntrack的所有子连接都可以通过sibling_list找到 sibling ...... ...... sibling_list master ....... child ip_conntrack www.kernelchina.org

  38. iptables • 一个包选择、监控、过滤系统 • table,chain,rule • 系统预定义了三个table:filter,nat,mangle • 用户空间的数据结构和内核空间的数据结构不同 • 一个可扩展的架构 www.kernelchina.org

  39. ipt_table struct ipt_table { struct list_head list; char name[IPT_TABLE_MAXNAMELEN]; struct ipt_replace *table; //表初始化时的数据 unsigned int valid_hooks; //表监听的检查点 rwlock_t lock; struct ipt_table_info *private; //表的数据最后存储在这里 struct module *me; }; www.kernelchina.org

  40. target_offset next_offset hook_entry[] matchs underflow[] target target_offset next_offset matchs target ipt_entry ipt_entry ipt_table_info www.kernelchina.org

  41. 规则匹配策略 • 不能从一个预定义的chain跳转到另一个预定义的chain,只能从预定义的chain跳转用户定义的chain,或者用户定义的chain之间相互跳转 • 不同检查点上的chain不能相互跳转 • 预定义的chain有默认的包处理方式,如果chain上的规则都没有匹配,就使用默认的处理方式 • 如果用户定义的chain上的规则都没有匹配,则返回指向这个chain的规则所在的chain的下一条规则 www.kernelchina.org

  42. filter表 链路层 NF_IP_PRE_ROUTING NF_IP_POST_ROUTING ROUTE 网络层 NF_IP_FORWARD ROUTE NF_IP_LOCAL_IN NF_IP_LOCAL_OUT 传输层 www.kernelchina.org

  43. nat表 链路层 NF_IP_PRE_ROUTING NF_IP_POST_ROUTING ROUTE 网络层 NF_IP_FORWARD ROUTE NF_IP_LOCAL_IN NF_IP_LOCAL_OUT 传输层 www.kernelchina.org

  44. mangle表 链路层 NF_IP_PRE_ROUTING NF_IP_POST_ROUTING ROUTE 网络层 NF_IP_FORWARD ROUTE NF_IP_LOCAL_IN NF_IP_LOCAL_OUT 传输层 www.kernelchina.org

  45. hook的顺序 NF_IP_PRE_ROUTING NF_IP_POST_ROUTING mangle[-150] conntrack[-200] mangle[-150] nat[snat][100] nat[dnat][-100] conntrack[max] NF_IP_FORWARD NF_IP_LOCAL_IN NF_IP_LOCAL_OUT mangle[-150] mangle[-150] conntrack[-200] filter[0] filter[0] mangle[-150] nat[100] nat[dnat][-100] conntrack[max-1] filter[0] www.kernelchina.org

  46. ipt_match struct ipt_match { ...... match //匹配skbuff checkentry //检查参数是否合法 destroy //模块释放时调用 }; www.kernelchina.org

  47. ipt_entry_match iptables_match 用户空间 内核空间 ipt_ip ipt_entry_match ipt_match ipt_entry_target www.kernelchina.org

  48. ipt_target struct ipt_target { ...... target //对包做出修改或判断 checkentry //检查参数是否合法 destroy //模块释放时调用 }; www.kernelchina.org

  49. ipt_entry_target iptables_target 用户空间 内核空间 ipt_ip ipt_entry_match ipt_entry_target ipt_target www.kernelchina.org

  50. 增加一个table • 在内核中增加一个表,注意表所监听的检查点 • 这个表可以使用哪些match和target,这个表的用途是什么 www.kernelchina.org

More Related