- 论坛徽章:
- 0
|
关于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 用sysctl net.inet.ipf取得,你也可以用sysctl设置其值
- #单位为秒,实际的超时值是=变量值/2
- #比如udptimeout=240/2=120秒=2分钟
- net.inet.ipf.fr_tcpidletimeout: 864000
- net.inet.ipf.fr_tcpclosewait: 480
- net.inet.ipf.fr_tcplastack: 480
- net.inet.ipf.fr_tcptimeout: 480
- net.inet.ipf.fr_tcpclosed: 120
- net.inet.ipf.fr_tcphalfclosed: 14400
- net.inet.ipf.fr_udptimeout: 240
- net.inet.ipf.fr_udpacktimeout: 24
- net.inet.ipf.fr_icmptimeout: 120
- net.inet.ipf.fr_icmpacktimeout: 12
- net.inet.ipf.fr_ipfrttl: 120
复制代码
========
udp数据报:
如何测试呢?首先设定一个防火墙规则包含keepstate,然后我再发一个udp数据报.再检查keep state的state表的状态就行了.因为发送多个数据报的话会state表看起来太杂,所以我写了一个用于测试目的建立一个防火墙规则并写一个仅发送一个udp数据报的程式
- #用于测试目的的防火墙
- pass out quick all keep state
- pass in quick all
复制代码
- //仅发送一个udp数据报的程式
- //用法: ./a.out <源端口>; <目的端口>;
- int main(argc,argv)
- int argc;
- char **argv;
- {
- char *msg="test";
- struct sockaddr_in sa;
- struct sockaddr_in sa2;
- int sk;
- sa.sin_len=sa2.sin_len=sizeof(struct sockaddr_in);
- sa.sin_port=htons(atoi(argv[1]));
- sa2.sin_port=htons(atoi(argv[2]));
- sa.sin_family=sa2.sin_family=AF_INET;
- inet_pton(AF_INET,"127.0.0.1",&sa.sin_addr);
- inet_pton(AF_INET,"127.0.0.1",&sa2.sin_addr);
- if((sk=socket(AF_INET,SOCK_DGRAM,0))<0)
- err(1,"socket");
- bind(sk,(struct sockaddr*)&sa,sizeof(sa));
- if(sendto(sk,msg,4,0,(struct sockaddr*)&sa2,sizeof(struct sockaddr_in))<0)
- err(1,"sendto");
- else
- printf("send ok.\n");
- exit(0);
- }
复制代码
一个用于测试state表ttl值以及实际消费的时间的sh
- #!/bin/sh
- #清空state表
- ipf -FS
- #发送一个udp数据报
- ./a.out 7777 9999
- sleep 1
- #取state表中ttl值
- ttl=`ipfstat -sl|grep ttl|awk '{print $5}'`
- echo "ipfilter's ttl: $ttl"
- ts=1
- while [ true ];do
- ttl=`ipfstat -sl|grep ttl|awk '{print $5}'`
- if [ -z "$ttl" ];then break;fi
- echo -n "."
- ts=$(($ts + 1))
- sleep 1
- done
- #打印实际消费的时间
- echo "time use: $ts"
复制代码
好,准备工作完成,开始测试吧.
- bsd# ./test.sh
- send ok.
- ipfilter's ttl: 239
- ...................................................................................................................time use: 118
- 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表),我这儿是
- bsd# ipfstat -sl
- 127.0.0.1 ->; 127.0.0.1 ttl 863990 pass 0x5006 pr 6 state 4/4
- pkts 10 bytes 664 1116 ->; 21 8eec72c3:8135dd2f 57344<<0:57344<<0
- pass out quick keep state IPv4
- pkt_flags & 2(b2) = b, pkt_options & ffffffff = 0
- pkt_security & ffff = 0, pkt_auth & ffff = 0
- 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,即可模拟一次连接建立到完成的情况.试试吧.
- bsd# echo | ftp 127.0.0.1; ipfstat -sl
- Name (127.0.0.1:lyx): This FTP server is anonymous only.
- ftp: Login failed.
- 127.0.0.1 ->; 127.0.0.1 ttl 480 pass 0x5006 pr 6 state 10/8
- pkts 28 bytes 1828 1118 ->; 21 a44fc9d5:8bb8e429 57344<<0:57344<<0
- pass out quick keep state IPv4
- pkt_flags & 2(b2) = b, pkt_options & ffffffff = 0
- pkt_security & ffff = 0, pkt_auth & ffff = 0
- interfaces: in lo0,lo0 out lo0,lo0
- bsd#
复制代码
也就是说即使一次tcp会话结束了。ipfilter也不会马上把这项记录从state表中删除,还会保持240秒。
小结:
好了,也不少了,看到这儿你还没牺牲的话那我太感动了。这么多变量一时也模拟证明不完。表1中的各个变量大多见名知意,其余的就留给你自己去验正吧.通过这篇短文你应该能够了解ipfilter的keep state的时间限制值了吧,用sysctl设置相应的变量即可控制ipfilter的state表了.网络的情况比这儿模拟的要复杂多。朋友你自己慢慢测试推敲吧. |
|