有时候我们需要模拟网络丢包,可以用一台Linux 作为网络通信的一方或网关, 在Linux上用 iptables 创建防火墙规则, 阻止某些包,而规则的有效时间是一个随机值,到了预期时间,把规则删除。 如此循环。 用脚本语言很容易实现。
#! /bin/sh
#
# drop some packets to simulate network traffic jam
# Yuwen Dai, January 15 2013
#
function clean_up
{
# restore iptable rules
iptables -D OUTPUT -d 172.25.52.31 -p tcp --tcp-flags SYN,ACK,FIN,RST ACK -j DROP
exit
}
function get_random
{
local R=$((${RANDOM}*${1}/32767))
R=$((R+1))
echo ${R}
}
# user can use `ctrl-c' to exit the loop
trap clean_up SIGHUP SIGINT SIGTERM
# default interval time is 5 seconds
if [ $# -lt 1 ];then
INTERVAL=5
else
INTERVAL=${1}
fi
#
# loop
#
while [ 0 ];do
# Get a random number: [1, INTERVAL]
R=$(get_random ${INTERVAL})
# Drop TCP ACK segments
iptables -A OUTPUT -d 172.25.52.31 -p tcp --tcp-flags SYN,ACK,FIN,RST ACK -j DROP
#iptables -A FORWARD -s 172.25.52.37 -j DROP
# let the rule take effect for sometime
sleep ${R}
# delete the rule
iptables -D OUTPUT -d 172.25.52.31 -p tcp --tcp-flags SYN,ACK,FIN,RST ACK -j DROP
# No rule for sometime
R=$(get_random ${INTERVAL})
sleep ${R}
done
运行的时候,指定一个时间参数,单位为秒,表示防火墙规则会在这个范围内生效。 具体是这样的: 产生一个随机数,让规则生效这么长时间,然后删除该规则,再随机休眠若干时间,然后循环。 关于iptables规则, 要根据自己的需要进行设置。 我这里仅仅是把本机发往 172.25.52.31 的TCP ACK 给丢了。这里的规则在脚本里重复了好几次,不太好看。 暂时还没有想到好的办法。