科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网软件频道Linux操作系统中IP包过滤的具体实现 (2)

Linux操作系统中IP包过滤的具体实现 (2)

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

此时路由信息已包括在了skbuff数据结构的dst 项中,紧接着调用skb->dst->input(skb) 继续处理。

作者:赛迪网技术社区 来源:赛迪网技术社区 2007年10月21日

关键字: 过滤 IP 操作系统 Linux

  • 评论
  • 分享微博
  • 分享邮件

此时路由信息已包括在了skbuff数据结构的dst 项中,紧接着调用skb->dst->input(skb) 继续处理。对发往本地高层协议的包,则调用ip_local_deliver(),进行处理。对转往其他主机的包,则实际调用ip_forward()处理。值得注意的是,经伪装的包在回来时,其目的IP是防火墙的IP,经路由后,也送入ip_local_deliver( )处理,在ip_local_deliver( )内部先解伪装,然后再查一次路由,发往本地的直接送往高层,,否则依然调用ip_forward( )。

2、ip_forward( )用来处理发往其他主机的数据包,其函数流程为:

1)、因为ip_forward()接收的参数是一个skbuff,它首先利用skbuff的指针,把IP头找出: iph = skb->nh.iph

2)、因为ip_forward()由ip_rcv()调用,而在ip_rcv()中已查过了路由,此处只需利用skbuff的指针定位路由信息即可:

  struct rtable *rt; /* Route we use */ 
  rt = (struct rtable*)skb->dst;

3)、如果此IP包的生存时间(ttl)已到,则丢弃。

  if (iph->ttl <= 1) 
  goto too_many_hops;

4)、如果在选项中指定了严格的源路由功能(strict source routing) ,且此处无法达到,也丢弃:

  if (opt->is_strictroute && rt->rt_dst != rt->rt_gateway) 
  goto sr_failed;

5)、如果指定的伪装功能,且上层协议是ICMP,则在此处处理一部分,且跳过后面的包过滤处理

  #ifdef CONFIG_IP_MASQUERADE 
  if(!(IPCB(skb)->flags&IPSKB_MASQUERADED)) { 
  if (iph->protocol == IPPROTO_ICMP) { 
  
  ........ 
  
  fw_res = ip_fw_masq_icmp(&skb, maddr); 
  if (fw_res) 
  /* ICMP matched - skip firewall */ 
  goto skip_call_fw_firewall; 
  ........ 
  
  } 
  } 
  #endif

6)、如果上一步的前提不成立,则要经过一次包过滤。

  fw_res=call_fw_firewall(PF_INET, dev2, iph, NULL, &skb);

7)、在当前linux版本中,包过滤与伪装功能在许多地方是紧密联系在一起的,如采用同样的配置工具ipchains,同样的配置接口setsocketopt(),其中是否启动伪装的标志也在防火墙的chains中.

8)、因为伪装可能改变了skbuff的一些信息,此时要重新定位一下IP头及其选项:

  iph = skb->nh.iph; 
  opt = &(IPCB(skb)->opt);

9)、因为转发的数据总是要送出的,紧接着会调用call_out_firewall(),并把数据送出去.

3、在ip_local_deliver()中.

1).如果需要,首先重组IP包:

  if (sysctl_ip_always_defrag == 0 && 
  (iph->frag_off & htons(IP_MF|IP_OFFSET))) { 
  skb = ip_defrag(skb); 
  if (!skb) 
  return 0; 
  iph = skb->nh.iph;

2).然后调用ip_fw_demasquerade解开IP伪装。

  ret = ip_fw_demasquerade(&skb);

3)、再次调用路由查找,根据真正的IP来发送此包。

  ip_route_input(skb, iph->daddr, iph->saddr, iph->tos, skb->dev)

4)、根据路由发往上层或是转发(略)。

在对数据包进行处理的全部过程中,分别调用了以下三个函数:call_in_firewall(), call_fw_firewall()和 call_out_firewall()。察看这三个函数的具体实现发现,其核心过程都在于ip_fw_check() 这个函数,它完成了数据包与规则的实际匹配。

ip_fw_check()函数分析:防火墙的规则链由ip_chain数据结构描述,其中包含了指向链中第一条规则的指针和链的缺省策略。规则链中的每条规则由ip_fwkernel数据结构描述。ip_fw_check()所做的就是将每一个ip包与规则链中的每一条规则(实际就是ip_fw数据结构所描述的内容)按照链表的组织顺序一一比较,若匹配则并返回规则的行动项。

结束语

以上简单的介绍了linux下实现包过滤的基本方法,希望对大家起到抛砖引玉的作用。

    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章