- 论坛徽章:
- 0
|
最近为了测试某应用服务受网络影响的程度,在内部搭建了一个模拟丢包和延迟的环境。好久没接触freebsd了,freebsd下的ipfw是第一次用,在网上边看资料边做,基本上实现模拟丢包和延迟的网络状况。弄完后,写下这个文档初稿,希望以后对其它人也有所帮助,有问题的地方,还请大家多指教。
一. 工作原理
主要模拟客户端的网络环境,仿真局域网内丢包、延迟两种状况。
1台server用做网关 (linux 或 Freebsd),要求双网卡,1块出外网,1块接内网
1台或多台普通PC机,装有应用程序客户端,和网关那台server的内网在同一个网段.
网络拓扑图如下:(不知道怎么插图,我画了一个拓扑图的)
Eth0:219.235.200.88
Eth1:192.168.9.253
二. 实现方法
1 方法1 FreeBSD6.1 + ipfilter + ipnat + ipfw
1.1 概述
要在freebsd 下模拟丢包及延迟环境, 主要是利用ipfw的dummynet模块来实现。需要安装IPFW。
由于此机器还要用作网关,代理内网客户端出外网,需要安装ipfilter和ipnat 来实现NAT功能。(ipfw本身无法实现NAT功能,此点不同于linux下的 iptables )
IPFIREWALL (IPFW): FreeBSD下防火墙应用软件
IPFILTER(IPF): 提供了内核模式的防火墙和 NAT 机制
IPNAT : IPF 作为 FreeBSD 基本安装的一部分, 以一个独立的内核模块的形式提供
1.2 环境配置
【系统安装】 首先安装好Freebsd 6.1 基本系统
【环境配置】 具体如下
1.# sysinstall
执行此命令进入BSD的系统软件安装界面,安装操作系统的源码SRC和PORTS两Configure====>Distributions====>选ports和SRC选项里的libexec、sbin、sys这三项
2.编译内核源码,生成新的FREEBSD内核
#cd /usr/src/sys/i386/conf
#cp GENERIC kernel-ipfw kernel-ipfw为我们要编译的新内核,可自行随意命名
# vi kernel-ipfw
ident kernel-ipfw #修改此选项中的名字为你的新内核文件名
options IPFIREWALL #将 IPFW 作为内核的一部分来启用
options IPFIREWALL_VERBOSE #将启用记录通过 IPFW 的匹配了含 'log' 关键字规则的每一个包的功能
options IPFIREWALL_VERBOSE_LIMIT=10 #限制通过记录的包的个数
options IPFIREWALL_DEFAULT_TO_ACCEPT
#默认地允许所有的包通过防火墙,这项一定要加上,如果内核选项中没有加入 IPFIREWALL_DEFAULT_TO_ACCEPT,或将您的防火墙设置配置为允许所有的进入包, 则所有发到本机或发出的包都会被阻止
options IPFIREWALL_FORWARD #启用转发功能
options DUMMYNET #加载dummynet模块,模拟丢包和延迟的
options IPFILTER #用于启用 “IPFILTER” 防火墙的支持
options IPFILTER_LOG #用于启用 IPF 的日志支持
options IPDIVERT #这一选项启用 NAT 功能
…………
改完后保存退出
# cd ../compile/kernel-ipfw
# make cleandepend
# make
# make depend
# make
# make install
也可以将以上命令写成一行用 &&隔开
如 #make cleandepend && make depend &&make &&make install
#reboot 编译完内核后没问题重启机器
3.开始设置ipfilter 、ipnat 、 ipfw 来配置此机器为网关
确认内核编译重启机器时请注意检查是否成功启动新内核,都没问题后,开始进行如下其它配置。
需要配置三个文件
/etc/rc.conf
/etc/ipf.rules
/etc/ ipnat.rules
1》vi /etc/ipf.rules 此文件需要自己创建,默认是没有的,文件内容如下
pass in all 允许任何包从网卡进
pass out all 允许任何包从网卡出
由于只是暂时用于测试,实现环境为主,没有设置复杂的安全策略,如果用于其它用途时请根据具体环境需求加上相关安全策略。
2》vi /etc/rc.conf 文件具体内容如下
# -- sysinstall generated deltas -- # Tue Jan 23 20:09:43 2007
# Created: Tue Jan 23 20:09:43 2007
# Enable network daemons for user convenience.
# Please make all changes to this file, not to /etc/defaults/rc.conf.
# This file now contains just the overrides from /etc/defaults/rc.conf.
usbd_enable="YES"
pccard_ifconfig="NO" # Specialized pccard ethernet configuration (or NO).
pfsync_ifconfig="" # Additional options to ifconfig( for pfsync
ifconfig_lo0="inet 127.0.0.1" # default loopback device configuration.
#ifconfig_lo0_alias0="inet 127.0.0.254 netmask 0xffffffff" # Sample alias entry.
ifconfig_bge0="inet 219.235.200.88 netmask 255.255.255.240"
ifconfig_bge1="inet 192.168.9.253 netmask 255.255.255.0"
#ifconfig_ed0_ipx="ipx 0x00010010" # Sample IPX address family entry.
#ifconfig_fxp0_name="net0" # Change interface name from fxp0 to net0.
#gifconfig_gif0="10.1.1.1 10.1.2.1" # Examples typically for a router.
#gifconfig_gif1="10.1.1.2 10.1.2.2" # Examples typically for a router.
#ipv6_ifconfig_ed0="fec0:0:0:5::1 prefixlen 64" # Sample manual assign entry
#ipv6_ifconfig_ed0_alias0="fec0:0:0:5::2 prefixlen 64" # Sample alias entry.
sshd_enable="YES" # Enable sshd
sshd_program="/usr/sbin/sshd" # path to sshd, if you want a different one.
sshd_flags="" # Additional flags for sshd.
#ipv4_addrs_fxp0="192.168.0.1/24 192.168.1.1-5/28" # example IPv4 address entry.
defaultrouter="219.235.200.1" # Set to default gateway (or NO).
gateway_enable="YES" # Set to YES if this host will be a gateway. (用于不同网络接口进行包转发)
ipxgateway_enable="NO" # Set to YES to enable IPX routing.
forward_sourceroute="NO" # do source routing (only if gateway_enable is set to "YES"
ipv6_defaultrouter="NO" # Set to IPv6 default gateway (or NO).
ipv6_gateway_enable="NO" # Set to YES if this host will be a gateway.
#Add config by me 下面这些是我自己添加的
firewall_enable="YES"
ipfilter_enable="YES" #启动ipf防火墙
ipf -Fa -f /etc/ipf.rules #将被加载的规则定义,这是一个文本文件
ipnat_enable="YES" #启动ipnat功能
ipnat_program="/sbin/ipnat -FC -f"
ipnat_rules="/etc/ipnat.rules" #用于ipnat 的规则定义文件
ipmon_enable="YES" #启动IP监视日志
ipmon_flags="-Ds" #D=作为服务程序启动,s 使用syslog记录
# -- sysinstall generated deltas -- # Tue Jan 23 16:00:46 2007
firewall_type="OPEN" # Firewall type (see /etc/rc.firewall)
3》# vi /etc/ipnat.rules 启用nat功能,此文件需要自行创建
# more ipnat.rules
map bge0 192.168.9.0/24 -> 219.235.200.88 portmap tcp/udp auto
map bge0 192.168.9.0/24 -> 219.235.200.88
注:只设置这两条规则即可满足要求,beg0是指外网网卡设备号, 192.168.9.0/24 指内网网段, 219.235.200.88为此机器的外网IP;在网卡bge0上,把192.168.9.0/24 的所有IP地址和219.235.200.88进行单项映射 。
Ipnat.rules 文件修改保存后,需要重新加载NAT规则则,可使用如下命令执行:
# ipnat -CF -f /etc/ipnat.rules
# ipnat –l 可以用此命令查看当前映射关系
1.3 命令基本用法
1.3.1 IPF
# ipf –Fa –f /etc/ipf.rules
-Fa 表示清除所有的内部规则表
-f 用于指定要被读取的规则定义文件
通过运行上面的 IPF 命令,可以将正在运行的防火墙刷新为使用全新的规则集, 而不需要重新启动系统。这对于测试新的规则来说就很方便, 因为您可以任意执行上面的命令。
# ipfw show 列出当前规则及状态
# ipfw list 按顺序列出所有的规则
# ipfw delete 规则号 删除一条规则
# ipfw add 添加一条规则,具体请参照文档格式
1.3.2 IPNAT
# ipnat -CF -f /etc/ipnat.rules 要重新加载 NAT 规则
# ipnat –l 列出当前的 NAT 表的映射关系
# ipnat –s 查看当前系统上 NAT 的统计信息
1.4 测试丢包和延迟
1.4.1 设置丢包
这个规则5%的几率随机丢掉引入的包: ipfw add prob 0.05 deny ip from any to any in
# ipfw show 查看当前初始的规则
00100 15518 1790088 allow ip from any to any via lo0
00200 0 0 deny ip from any to 127.0.0.0/8
00300 0 0 deny ip from 127.0.0.0/8 to any
65000 2947230 563323009 allow ip from any to any
65535 10089 889327 allow ip from any to any
#
# ipfw add 60000 prob 0.05 deny ip from any to any in 添加一条规则号为60000,随机丢掉5%引入的包
60000 prob 0.050000 deny ip from any to any in 执行完指令后会出现如下提示
#
# ipfw show 查看规则设置是否成功
00100 15518 1790088 allow ip from any to any via lo0
00200 0 0 deny ip from any to 127.0.0.0/8
00300 0 0 deny ip from 127.0.0.0/8 to any
60000 1 92 prob 0.050000 deny ip from any to any in 已经成功
65000 2947379 563336043 allow ip from any to any
65535 10089 889327 allow ip from any to any
#
# ipfw delete 60000
当要设置新的丢包率时,先删除或者disable掉原有,也可以创建一条规则号小于60000的;因为ipfw的防火墙规则是按规则号从小到大执行;这一点不同于linux 下的ipatables, 一定要注意规则顺序问题
# ipfw show 成功删除
00100 15518 1790088 allow ip from any to any via lo0
00200 0 0 deny ip from any to 127.0.0.0/8
00300 0 0 deny ip from 127.0.0.0/8 to any
65000 2947470 563343976 allow ip from any to any
65535 10089 889327 allow ip from any to any
1.4.2 设置延时
通过dummynet pipes管道来设置,使用管道来设置会方便,规则可以用多次。
示例如下:
ipfw add pipe 1 ip from any to any out
ipfw add pipe 2 ip from any to any in
ipfw pipe 1 config delay 250ms
ipfw pipe 2 config delay 250ms
# ipfw show 查看初始的规则
00100 15614 1800040 allow ip from any to any via lo0
00200 0 0 deny ip from any to 127.0.0.0/8
00300 0 0 deny ip from 127.0.0.0/8 to any
65000 2948038 563415068 allow ip from any to any
65535 10089 889327 allow ip from any to any
#
# ipfw add 63000 pipe 1 ip from any to any in 添加一个管道为1,管道号数值可以自行定义
63000 pipe 1 ip from any to any in
# ipfw show 查看规则定义是否成功
00100 15614 1800040 allow ip from any to any via lo0
00200 0 0 deny ip from any to 127.0.0.0/8
00300 0 0 deny ip from 127.0.0.0/8 to any
63000 28 2529 pipe 1 ip from any to any in 可以看到已经成功了
65000 2948259 563435575 allow ip from any to any
65535 10089 889327 allow ip from any to any
# ipfw pipe 1 config delay 30ms 设置延迟为30ms ,注意这里的pipe管理数值和上面规则的数值是一致的
# ipfw pipe 1 config delay 50ms 如果增加延迟,重新设置这个就好了,这行代表当前引入50ms延迟
注意: 规则号要小于默认的63000,不然延迟不会生效。
注:看说明丢包设置也可以通过pipe来进行设置,但在测试过程中发现有问题,当设置管道后,主机就连接不上的情况。故我在设置丢包率时一直采用一次性修改的方式来测试的。
1.4.3 设置丢包和延时同时存在
方法参照上面丢包和延时的设置。
要特别注意一点:
在用ipfw设置规则时,丢包的规则号要小于延时的规则号,不然会发现不能生效。
2 方法2 RedHat Linux 9.0 + NistNet
这种方法,在家里的笔记本和dell1650上测试过,还可以。 在公司的其它像fedora5,as3系统环境下内核重编时一直有问题, 这里就不再写详细的文档了,只是告诉大家还有一个备选的方案。
2.1 概述
工作原理: Redhat 9.0 + NistNet + iptables(nat) 此机器应用iptables 做成网关。
Nistnet是一款基于Linux系统能够动态实时仿真IP网络环境的开源工具,它可实现端到端网络中那些关键性能,例如延迟、抖动、丢包等多种复杂的网络环境的模拟,为那些对于网络环境较为敏感的应用提供了便利的测试方法。
NistNet是做为Linux内核的一个可动态加载的模块来实现的。
三. Other
FreeBSD 方法很多参照 FreeBSD HandBook 中
http://cnsnap.cn.freebsd.org/doc/zh_CN.GB2312/books/handbook/
Nistnet更多内容请参考官网 http://www-x.antd.nist.gov/nistnet/
[ 本帖最后由 cmhuaer 于 2007-1-29 15:54 编辑 ] |
|