2009年4月14日星期二

iptables 限速Shell无需TC(限制NAT机器上Internet速度)


比如说我现在限制192.168.10.166-到192.168.10.220这个网段的IP上网速度为30Kbs左右,实现的脚本如下

#!/bin/bash

for ((i = 166; i < 220; i++))
do
/sbin/iptables -A FORWARD -s 192.168.10.$i -m limit --limit 20/s -j ACCEPT
iptables -A FORWARD -s 192.168.10.$i DROP
done

执行此脚本即可

iptables中有个limit模块,遗憾的是他只能限制packet,而不是Bytes
不过…… 先来看一段资料




[root@platinum root]# ifconfig

eth0 Link encap:Ethernet HWaddr 00:0A:EB:07:22:82

UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1

RX packets:443747 errors:0 dropped:0 overruns:0 frame:0

TX packets:417700 errors:0 dropped:0 overruns:0 carrier:0

collisions:0 txqueuelen:1000

RX bytes:218731248 (208.5 Mb) TX bytes:65766454 (62.7 Mb)

Interrupt:9 Base address:0xac00



eth1 Link encap:Ethernet HWaddr 00:E0:4C:39:6D:96

inet addr:172.25.39.254 Bcast:172.25.39.255 Mask:255.255.255.0

UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1

RX packets:691411 errors:0 dropped:0 overruns:0 frame:0

TX packets:960662 errors:0 dropped:0 overruns:0 carrier:0

collisions:0 txqueuelen:1000

RX bytes:82794610 (78.9 Mb) TX bytes:976909968 (931.6 Mb)

Interrupt:11 Base address:0xc800



lo Link encap:Local Loopback

inet addr:127.0.0.1 Mask:255.0.0.0

UP LOOPBACK RUNNING MTU:16436 Metric:1

RX packets:1106 errors:0 dropped:0 overruns:0 frame:0

TX packets:1106 errors:0 dropped:0 overruns:0 carrier:0

collisions:0 txqueuelen:0

RX bytes:314982 (307.5 Kb) TX bytes:314982 (307.5 Kb)



ppp0 Link encap:Point-to-Point Protocol

inet addr:221.219.204.209 P-t-P:61.149.164.1 Mask:255.255.255.255

UP POINTOPOINT RUNNING NOARP MULTICAST MTU:1492 Metric:1

RX packets:438850 errors:0 dropped:0 overruns:0 frame:0

TX packets:412803 errors:0 dropped:0 overruns:0 carrier:0

collisions:0 txqueuelen:3

RX bytes:208763034 (199.0 Mb) TX bytes:56389653 (53.7 Mb)



ppp37 Link encap:Point-to-Point Protocol

inet addr:10.39.1.254 P-t-P:10.39.1.1 Mask:255.255.255.255

UP POINTOPOINT RUNNING NOARP MULTICAST MTU:1480 Metric:1

RX packets:14728 errors:0 dropped:0 overruns:0 frame:0

TX packets:12451 errors:0 dropped:0 overruns:0 carrier:0

collisions:0 txqueuelen:3

RX bytes:1327878 (1.2 Mb) TX bytes:2772440 (2.6 Mb)



[root@platinum root]#


eth0是我的WAN网卡
eth1是我的LAN网卡
ppp0是通过PPPoE方式拨叫网通线路
ppp37是我自己的PPPoE SERVER,给其他用户接入使用,用户使用的是WINXP系统

从上面的资料可以看到MTU这个东西,eth0和eth1都是1500,ppp0是1492,ppp37是1480(如果客户端是WIN2000则也是1492)

什么是MTU?
MTU是Maximum Transmission Unit的缩写。意思是网络上传送的最大数据包,单位是字节。如果本机的MTU比网关的 MTU大,大的数据包就会被拆开来传送,这样会产生很多数据包碎片,增加丢包率,降低网络速度。把本机的MTU设成比网关的MTU小或相同,就可以减少丢 包。不同的接入方式,MTU值是不一样的,下面是常用的几种接入方式默认的MTU值:
EtherNet (以太网)1500
PPPoE(ADSL) 1492
Dial-up(modem) 576

由此可以看出,一个标准以太网Frame是1500 Bytes,那么我们知道了这一点,可以利用iptables来进行带宽限制

iptables中有个limit模块,遗憾的是他只能限制packet,而不是bytes
但是我们现在已经知道了一个标准Ethernet Frame是1500 Bytes,这样就好做了

下面给大家演示一个限制upload速率的实例(已经通过测试)




# Limit Platinum

iptables -A FORWARD -s 10.39.1.1 -m limit --limit 20/s -j ACCEPT

iptables -A FORWARD -s 10.39.1.1 -j DROP


当然,用这种方法可以比tc更灵活,可以基于IP、PORT去进行控制,也可以针对INPUT/OUTPUT/FORWARD进行限制

这样唯一不好的是,不一定每个packet都是1500 Bytes,这样的限制只是一个大概,并非精确,一般速度均有所偏差


没有评论:

发表评论