免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2505 | 回复: 5
打印 上一主题 下一主题

IPfilter keep state的时效性 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2003-07-06 21:16 |只看该作者 |倒序浏览
关于IPfilter keep state的时间限制.
作者:夜未眠
Come From: ChongQing Gearbox co.,ltd

乱写一通,高手见笑了,如有错误之处请指正.
os:FreeBSD 4.8 STABLE
Ipfilter version:  v3.4.31
关于ipfilter的资料不是很多,而且讲得很浅。
当我看到keep state一节时,那本how-to就只说了keep state有时间限制。到底这个时间限制是多少以及何处去找这个时间限制值却没有说明。所以就有了此文


这里要用到的ipfilter 的命令
加载防火墙规则
# ipf -E
# ipf -Fa -f /etc/ipf.rules
清空state表
# ipf -FS
显示state表状态
# ipfstat -sl


一目了然:
        有经验的高手,看这个列表就行了,不用往下看了:

  1. #表 1 用sysctl net.inet.ipf取得,你也可以用sysctl设置其值
  2. #单位为秒,实际的超时值是=变量值/2
  3. #比如udptimeout=240/2=120秒=2分钟

  4. net.inet.ipf.fr_tcpidletimeout: 864000
  5. net.inet.ipf.fr_tcpclosewait: 480
  6. net.inet.ipf.fr_tcplastack: 480
  7. net.inet.ipf.fr_tcptimeout: 480
  8. net.inet.ipf.fr_tcpclosed: 120
  9. net.inet.ipf.fr_tcphalfclosed: 14400
  10. net.inet.ipf.fr_udptimeout: 240
  11. net.inet.ipf.fr_udpacktimeout: 24
  12. net.inet.ipf.fr_icmptimeout: 120
  13. net.inet.ipf.fr_icmpacktimeout: 12
  14. net.inet.ipf.fr_ipfrttl: 120
复制代码


========
udp数据报:
       如何测试呢?首先设定一个防火墙规则包含keepstate,然后我再发一个udp数据报.再检查keep state的state表的状态就行了.因为发送多个数据报的话会state表看起来太杂,所以我写了一个用于测试目的建立一个防火墙规则并写一个仅发送一个udp数据报的程式

  1. #用于测试目的的防火墙
  2. pass out quick all keep state
  3. pass in quick all
复制代码


  1. //仅发送一个udp数据报的程式
  2. //用法: ./a.out <源端口>;  <目的端口>;
  3. int main(argc,argv)
  4.         int argc;
  5.         char **argv;
  6. {
  7.         char *msg="test";
  8.         struct sockaddr_in sa;
  9.         struct sockaddr_in sa2;
  10.         int sk;
  11.         sa.sin_len=sa2.sin_len=sizeof(struct sockaddr_in);
  12.         sa.sin_port=htons(atoi(argv[1]));
  13.         sa2.sin_port=htons(atoi(argv[2]));
  14.         sa.sin_family=sa2.sin_family=AF_INET;
  15.         inet_pton(AF_INET,"127.0.0.1",&sa.sin_addr);
  16.         inet_pton(AF_INET,"127.0.0.1",&sa2.sin_addr);
  17.         if((sk=socket(AF_INET,SOCK_DGRAM,0))<0)
  18.                 err(1,"socket");
  19.         bind(sk,(struct sockaddr*)&sa,sizeof(sa));
  20.         if(sendto(sk,msg,4,0,(struct sockaddr*)&sa2,sizeof(struct sockaddr_in))<0)
  21.                 err(1,"sendto");
  22.         else
  23.                 printf("send ok.\n");
  24.         exit(0);
  25. }
复制代码


一个用于测试state表ttl值以及实际消费的时间的sh

  1. #!/bin/sh

  2. #清空state表
  3. ipf -FS
  4. #发送一个udp数据报
  5. ./a.out  7777 9999
  6. sleep 1
  7. #取state表中ttl值
  8. ttl=`ipfstat -sl|grep ttl|awk '{print $5}'`
  9. echo "ipfilter's ttl: $ttl"
  10. ts=1
  11. while [ true ];do
  12.         ttl=`ipfstat -sl|grep ttl|awk '{print $5}'`
  13.         if [ -z "$ttl" ];then break;fi
  14.         echo -n "."
  15.         ts=$(($ts + 1))
  16.         sleep 1
  17. done
  18. #打印实际消费的时间
  19. echo "time use: $ts"
复制代码


好,准备工作完成,开始测试吧.


  1. bsd# ./test.sh
  2. send ok.
  3. ipfilter's ttl: 239
  4. ...................................................................................................................time use: 118
  5. bsd#
复制代码


看到输出值了吗? state表中的ttl值是239秒,实际上经过的时间是118秒,实际上这个就是net.inet.ipf.fr_udptimeout变量的值240,也就是说.外出的udp数据报被ipfilter记入state表最多存在239(实际上是120秒,也就是2分钟),但如果这个udp有一个响应数据报呢?情况又是怎么样呢?比如上面的我从7777号端口向9999号端口发送了一个数据报,在120秒之内从9999号端口到7777号端口的数据报会影响state表吗?答案是会的.ipfilter会将state表中的对应项设为net.inet.ipf.fr_udpacktimeout: 24,也就是12秒. 测试方法就是执行一次./a.out 7777 9999之后在120秒内执行一次./a.out 9999 7777再查看state表中的ttl值,具体步骤这里就不详述了。

========
tcp数据报:
               tcp数据报比较复杂,这里只分析少数,其余的就指望朋友举一反三了.

              1.一个连接:
                               我在一个终端登录127.0.0.1的ftp服务器模拟一次tcp会话, ftp 127.0.0.1(在输入用户名处就可以切换终端检查state表),我这儿是

  1. bsd# ipfstat -sl
  2. 127.0.0.1 ->; 127.0.0.1 ttl 863990 pass 0x5006 pr 6 state 4/4
  3.         pkts 10 bytes 664       1116 ->; 21 8eec72c3:8135dd2f 57344<<0:57344<<0
  4.         pass out quick keep state       IPv4
  5.         pkt_flags & 2(b2) = b,          pkt_options & ffffffff = 0
  6.         pkt_security & ffff = 0, pkt_auth & ffff = 0
  7.         interfaces: in lo0,lo0 out lo0,lo0
复制代码

ipfilter state中对这次会话给的ttl值是863990,实际上就是表1 中的net.inet.ipf.fr_tcpidletimeout: 864000,折合大约有四天时间,差点儿我想只是我打字有点慢 ,也就是说超过这个时间这个记录项就会从state表中删除。四天时间应该足够了吧.

             2. 连接完成
                          执行命令 echo | ftp 127.0.0.1,即可模拟一次连接建立到完成的情况.试试吧.

  1. bsd# echo | ftp 127.0.0.1; ipfstat -sl
  2. Name (127.0.0.1:lyx): This FTP server is anonymous only.
  3. ftp: Login failed.
  4. 127.0.0.1 ->; 127.0.0.1 ttl 480 pass 0x5006 pr 6 state 10/8
  5.         pkts 28 bytes 1828      1118 ->; 21 a44fc9d5:8bb8e429 57344<<0:57344<<0
  6.         pass out quick keep state       IPv4
  7.         pkt_flags & 2(b2) = b,          pkt_options & ffffffff = 0
  8.         pkt_security & ffff = 0, pkt_auth & ffff = 0
  9.         interfaces: in lo0,lo0 out lo0,lo0
  10. bsd#
复制代码

也就是说即使一次tcp会话结束了。ipfilter也不会马上把这项记录从state表中删除,还会保持240秒。

小结:
        好了,也不少了,看到这儿你还没牺牲的话那我太感动了。这么多变量一时也模拟证明不完。表1中的各个变量大多见名知意,其余的就留给你自己去验正吧.通过这篇短文你应该能够了解ipfilter的keep state的时间限制值了吧,用sysctl设置相应的变量即可控制ipfilter的state表了.网络的情况比这儿模拟的要复杂多。朋友你自己慢慢测试推敲吧.

论坛徽章:
0
2 [报告]
发表于 2003-07-07 19:25 |只看该作者

IPfilter keep state的时效性

nr, 我前几天还为这个和红袖添香差点吵架来着.

论坛徽章:
0
3 [报告]
发表于 2003-07-09 09:43 |只看该作者

IPfilter keep state的时效性

顶。建议加精华

论坛徽章:
0
4 [报告]
发表于 2003-07-09 10:20 |只看该作者

IPfilter keep state的时效性

显示state表状态还可以用:
#ipfstat -t
这样就已像top那样的形式输出,直观形象:

-t     Show  the  state table in a way similar to they way
              top(1) shows  the  process  table.  States  can  be
              sorted  using  a        number        of  different  ways. This
              options requires ncurses(3) and needs  to  be  com-
              piled  in. It may not be available on all operating
              systems. See below, for  more  information  on  the
              keys that can be used while ipfstat is in top mode.

论坛徽章:
0
5 [报告]
发表于 2003-07-09 10:23 |只看该作者

IPfilter keep state的时效性

IPFilter TCP ACK/Bad Checksum Packet Denial Of Service Vulnerability
http://security.zz.ha.cn/ipfilterq.html

论坛徽章:
0
6 [报告]
发表于 2003-07-09 23:49 |只看该作者

IPfilter keep state的时效性

只想取瞬间state表的ttl值,所以用-sl.
另外有一个朋友问udp数据报在state表中时间这么短,oicq在很长时间不发任何消息,为什么仍能收到防火墙外的消息? 我想oicq为一个实时通讯软件,而且基于udp这种不可靠协议,客户端与服务端之间必然会有一种保活机制.比如客户端可能会发送数据报给服务器证自己仍在线.也许就是这些数据报更新了state表。所以oicq在闲置较长时间后仍能收到消息.由于oicq没有源码,这只是我个人猜测。不一定是正确的。有条件的朋友可以测试一下  
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP