FreeBSD ipfilter的严重问题

来源:岁月联盟 编辑:zhu 时间:2008-01-18
FreeBSD ipfilter的严重问题内容简介:【FreeBSD教程】 我为一客户做的防火墙(FreeBSD(p23) ipfilter 3.4.33pre2)天天都要死好几次,而且每次都是在没任何反应和输出信息的情况下死掉,弄得我好没面子。我一直没查出问题在哪。 这几天在Ipfilter的网   【FreeBSD教程】我为一客户做的防火墙(FreeBSD(p23) ipfilter 3.4.33pre2)天天都要死好几次,而且每次都是在没任何反应和输出信息的情况下死掉,弄得我好没面子。我一直没查出问题在哪。
  这几天在Ipfilter的网站上看到邮件列表里一个人碰到和我相同的情况,原文如下:
  Using FreeBSD 4.9-STABLE ipfilter 3.4.33pre2
  If I have ipf rules like:
  block return-icmp (port-unr) in log quick on xl0 proto udp from any to any port = 111
  attempts to connect to that port cause the sytem to freeze instantly, no crash dumps, no errors etc.
  The same happens using
  block return-icmp -as-dest ........

  I haven't seen anything like this in recent archives.
  What can I do to further debug this ?

  大家可以做个简单的测试:
  假设防火墙为A,工作站为B。
  在你的ipf.conf规则文件的最前面加上这样一条规则:
  block return-icmp-as-dest in quick on fxp0 proto udp from any to any port = 53

  其中fxp0是你要测试的接口,根据你自己的情况修改。
  然后在另外一台电脑B上把DNS设为要测试的这台防火墙A的IP地址,在 B上运行nslookup,随便查询几个域名,多查几次,你就会看到防火墙A在没任何信息输出的情况下立即冻结,死机。真可怕,百事百灵。即使你的ipf.conf没这个规则在非凡情况下也会出现这种现象,我试了3.4.33pre1-pre3都有这个毛病,据说3.4.32也是,3.4.31好象没这个毛病。有人公布了一个patch,我试了一下,有效。我附在后面,这个patch已得到ipfilter作者的认同,可以放心使用。
  

  Index: ip_fil.c
  =========================================
  RCS file: /home/cvs/firewall/firewall/usrlocal/ipfilter34/ipfilter3433/ip_fil.c,v
  retrieving revision 1.3
  diff -u -r1.3 ip_fil.c
  --- ip_fil.c 17 Dec 2003 12:33:56 -0000 1.3
   ip_fil.c 22 Dec 2003 11:23:28 -0000
  @@ - 1285,7 1285,7 @@
  frn.fin_ifp = fin->fin_ifp;
  frn.fin_v = fin->fin_v;
  frn.fin_out = fin- >fin_out;
  - frn.fin_mp = fin->fin_mp;
   frn.fin_mp = mp;

  ip = mtod(m, ip_t *);
  hlen = sizeof(*ip);
  @@ -1465,7 1465,13 @@
  #endif

  if (avail) {
   slen = oip->ip_len;
   oip->ip_len = htons(oip->ip_len);
   soff = oip- >ip_off;
   oip->ip_off = htons(oip->ip_off);
  bcopy((char *)oip, (char *)&icmp->icmp_ip, MIN (ohlen, avail));
   oip->ip_len = slen;
   oip->ip_off = soff;
  avail -= MIN(ohlen, avail);
  }

  @@ -1486,10 1492,6 @@
  } else
  #endif
  {
  - slen = oip->ip_len;
  - oip- >ip_len = htons(oip->ip_len);
  - soff = oip->ip_off;
  - oip->ip_off = htons(ip->ip_off);

  ip->ip_src.s_addr = dst4.s_addr;
  ip->ip_dst.s_addr = oip->ip_src.s_addr;
  @@ -1509,13 1511,7 @@
  fin->fin_hlen = hlen;
  err = send_ip(oip, fin, &m);
  fin->fin_hlen = shlen;
  - #ifdef USE_INET6
  - if (fin->fin_v == 4)
  -#endif
  - {
  - oip->ip_len = slen;
  - oip->ip_off = soff;
  - }
  
  return err;
  }

图片内容