Traffic Control

Using iptables to rate-limit incoming connections

Using iptables to rate-limit incoming connections

The iptables firewall has several useful extension modules which can be used to in addition to the basic firewall functionality. One of the more interesting of these extensions is the "recent" module which allows you to match recent connections, and perform simple throttling on incoming connections.

We've previously described keeping SSH access secure by limiting which users can connect, or just firewalling access so that only a small list of trusted IP addresses can connect. In most cases this is sufficient to protect your system.

However there are times when you have to allow arbitary incoming connections, when you are travelling for example.

In these situations you can open up your system to allow incoming connections and be the target of a dictionary attack - literally a machine trying to connect and login over and over again using usernames and passwords from a dictionary.

These attempts will be logged in your /var/log/auth.log file like this:

sshd[x]: Illegal user admin from aa.bb.cc.dd
sshd[x]: Illegal user test from  aa.bb.cc.dd
sshd[x]: Illegal user guest from aa.bb.cc.dd

In this situation you can create a collection of firewalling rules which will deny access from remote clients who attempt to connect "too many" times.

If you have an existing firewall in place, using iptables, then adding the rules is very straightforward.

The way the recent module works is fairly straightforward, you basically add IP addresses to a list, which can then be used in the future to test connection attempts against. This allows you to limit the number of connections against either a number of seconds, or connection attempts. In our example we'll do both.

An example is probably the simplest way to illustrate how it works. The following two rules will limit incoming connections to port 22 to no more than 3 attemps in a minute - an more than that will be dropped:

iptables -I INPUT -p tcp --dport 22 -i eth0 -m state --state NEW -m recent \
--set
iptables -I INPUT -p tcp --dport 22 -i eth0 -m state --state NEW -m recent \
--update --seconds 60 --hitcount 4 -j DROP

The --state flag takes a comma seperated list of connection states as an argument, by using "--state NEW" as we did we make sure that only new connections are managed by the module.

The --set parameter in the first line will make sure that the IP address of the host which initiated the connection will be added to the "recent list", where it can be tested and used again in the future i.e. in our second rule.

The second rule is where the magic actually happens. The --update flag tests whether the IP address is in the list of recent connections, in our case each new connection on port 22 will be in the list because we used the --set flag to add it in the preceeding rule.

Once that's done the --seconds flag is used to make sure that the IP address is only going to match if the last connection was within the timeframe given. The --hitcount flag works in a similar way - matching only if the given count of connection attempts is greater than or equal to the number given.

Together the second line will DROP an incoming connection if:

  • The IP address which initiated the connection has previously been added to the list and
  • The IP address has sent a packet in the past 60 seconds and
  • The IP address has sent more than 4 packets in total.

You can adjust the numbers yourself to limit connections further, so the following example will drop incoming connections which make more than 2 connection attempts upon port 22 within ten minutes:

iptables -I INPUT -p tcp --dport 22 -i eth0 -m state --state NEW -m recent \
--set
iptables -I INPUT -p tcp --dport 22 -i eth0 -m state --state NEW -m recent \
--update --seconds 600 --hitcount 2 -j DROP

If you wish to test these rules you can script a number of connection attempts from an external host with the netcat package.

The following script attempts to connect to the IP address 192.168.1.1 5 times. The first couple of attempts you should see a welcome banner such as "SSH-2.0-OpenSSH_3.8.1p1 Debian-8.sarge.4" - after that the script will hang as it's packets are dropped and no response is sent:

#!/bin/bash
for i in `seq 1 5` ; do
echo 'exit' | nc 192.168.1.1 22 ;
done

There's a lot of documentation on the netfilter/iptables firewall, and it's available modules which you can find in the Netfilter Extension HOWTO.

This HOWTO contains documentation on many different modules, along with examples. A recommended read if you're interested in Linux firewalling.

If you wish to experiment with rules and testing it's worth remembering how to remove all active rules. The following commands will flush your iptables filewall, and remove all currently active rules:

iptables -F
iptables -X
Share/Save/Bookmark

limit method limits per packet

This new method is WAYYY better.


the old -m limit method limits per packet per port.. if you have someone flooding your ssh connetion, it'll actually disable the service all around, causing YOU not to be able to get on. not really the effect you wanted.

This new method, actually bases its rate limit on a per IP basis.

So if you are getting flooded from 1 ip specifically, only that 1 ip will be locked down.

Everyone else will be able to get on still. as long as they stay within the connection limit itself.


I'll be honest. *I* didnt figure this out. i found it on a url

http://www.debian-ad...rg/articles/187


It does work, as a few linux-noob'ers helped me test it successfully.
-----------

The way the recent module works is fairly straightforward, you basically add IP addresses to a list, which can then be used in the future to test connection attempts against. This allows you to limit the number of connections against either a number of seconds, or connection attempts. In our example we'll do both.

An example is probably the simplest way to illustrate how it works. The following two rules will limit incoming connections to port 22 to no more than 3 attemps in a minute - an more than that will be dropped:

iptables -I INPUT -p tcp --dport 22 -i eth0 -m state --state NEW -m recent \
--set

iptables -I INPUT -p tcp --dport 22 -i eth0 -m state --state NEW -m recent \
--update --seconds 60 --hitcount 4 -j DROP

The --state flag takes a comma seperated list of connection states as an argument, by using "--state NEW" as we did we make sure that only new connections are managed by the module.

The --set parameter in the first line will make sure that the IP address of the host which initiated the connection will be added to the "recent list", where it can be tested and used again in the future i.e. in our second rule.

The second rule is where the magic actually happens. The --update flag tests whether the IP address is in the list of recent connections, in our case each new connection on port 22 will be in the list because we used the --set flag to add it in the preceeding rule.

Once that's done the --seconds flag is used to make sure that the IP address is only going to match if the last connection was within the timeframe given. The --hitcount flag works in a similar way - matching only if the given count of connection attempts is greater than or equal to the number given.

Together the second line will DROP an incoming connection if:

* The IP address which initiated the connection has previously been added to the list and
* The IP address has sent a packet in the past 60 seconds and
* The IP address has sent more than 4 packets in total.

You can adjust the numbers yourself to limit connections further, so the following example will drop incoming connections which make more than 2 connection attempts upon port 22 within ten minutes:

iptables -I INPUT -p tcp --dport 22 -i eth0 -m state --state NEW -m recent \
--set

iptables -I INPUT -p tcp --dport 22 -i eth0 -m state --state NEW -m recent \
--update --seconds 600 --hitcount 2 -j DROP

If you wish to test these rules you can script a number of connection attempts from an external host with the netcat package.

The following script attempts to connect to the IP address 192.168.1.1 5 times. The first couple of attempts you should see a welcome banner such as "SSH-2.0-OpenSSH_3.8.1p1 Debian-8.sarge.4" - after that the script will hang as it's packets are dropped and no response is sent:

#!/bin/bash

for i in `seq 1 5` ; do
echo 'exit' | nc 192.168.1.1 22 ;
done

There's a lot of documentation on the netfilter/iptables firewall, and it's available modules which you can find in the Netfilter Extension HOWTO.

This HOWTO contains documentation on many different modules, along with examples. A recommended read if you're interested in Linux firewalling.

If you wish to experiment with rules and testing it's worth remembering how to remove all active rules. The following commands will flush your iptables filewall, and remove all currently active rules:

iptables -F
iptables -X

using iptables to block bit torrent

#!/bin/bash
# IP ranges
PUBLIC=196.*.*.144/29
DMZ=192.168.*.0/24
COLTECH=192.168.*.0/24
# Loopback address
LOOP=127.0.0.1
# Delete old iptables rules
# and temporarily block all traffic.
iptables -P OUTPUT DROP
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -F
iptables -X
# Set default policies
iptables -P OUTPUT ACCEPT
iptables -P INPUT DROP
iptables -P FORWARD DROP
# PROXY redirect
iptables -A INPUT -i eth0 -p tcp --dport 80 -j DROP
iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 8080
# Prevent external packets from using loopback addr
iptables -A INPUT -i eth0 -s $LOOP -j DROP
iptables -A FORWARD -i eth0 -s $LOOP -j DROP
iptables -A INPUT -i eth0 -d $LOOP -j DROP
iptables -A FORWARD -i eth0 -d $LOOP -j DROP
# Anything coming from the Internet should have a real Internet address
iptables -A FORWARD -i eth0 -s 192.168.0.0/16 -j DROP
iptables -A FORWARD -i eth0 -s 172.16.0.0/12 -j DROP
iptables -A FORWARD -i eth0 -s 10.0.0.0/8 -j DROP
iptables -A INPUT -i eth0 -s 192.168.0.0/16 -j DROP
iptables -A INPUT -i eth0 -s 172.16.0.0/12 -j DROP
iptables -A INPUT -i eth0 -s 10.0.0.0/8 -j DROP
############################################################################################
###############################   ACLs
##################################################
############################################################################################
## Global Accept
iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT
## coltech
############## full access ip adresses
iptables -A FORWARD -s 192.168.*.1 -j ACCEPT 	## coltechserver
iptables -A FORWARD -s 192.168.*.3 -j ACCEPT 	## coltserv
iptables -A FORWARD -s 192.168.*.100 -j ACCEPT 	## japie lpt
iptables -A FORWARD -s 192.168.*.101 -j ACCEPT 	## japie
iptables -A FORWARD -s 192.168.*.102 -j ACCEPT 	## almarie
iptables -A FORWARD -s 192.168.*.103 -j ACCEPT 	## almarie lpt
iptables -A FORWARD -s 192.168.*.129 -j ACCEPT 	## japie ipaq
iptables -A FORWARD -s 192.168.*.201 -j ACCEPT 	## greg virtual machine
iptables -A FORWARD -s 192.168.*.202 -j ACCEPT 	## greg virtual machine
iptables -A FORWARD -s 192.168.*.203 -j ACCEPT 	## greg lpt
iptables -A FORWARD -s 192.168.*.204 -j ACCEPT 	## bertie lpt
iptables -A FORWARD -s 192.168.*.205 -j ACCEPT 	## greg lpt
iptables -A FORWARD -s 192.168.*.206 -j ACCEPT 	## greg lpt
############## allowed ports for restrited access ipaddesses
iptables -A FORWARD -s COLTECH -p tcp --dport 21 -j ACCEPT
iptables -A FORWARD -s COLTECH -p tcp --dport 22 -j ACCEPT
iptables -A FORWARD -s COLTECH -p tcp --dport 25 -j ACCEPT
iptables -A FORWARD -s COLTECH -p tcp --dport 53 -j ACCEPT
iptables -A FORWARD -s COLTECH -p tcp --dport 110 -j ACCEPT
iptables -A FORWARD -s COLTECH -p tcp --dport 137 -j ACCEPT
iptables -A FORWARD -s COLTECH -p tcp --dport 139 -j ACCEPT
iptables -A FORWARD -s COLTECH -p tcp --dport 143 -j ACCEPT
iptables -A FORWARD -s COLTECH -p tcp --dport 443 -j ACCEPT
iptables -A FORWARD -s COLTECH -p tcp --dport 3389 -j ACCEPT
iptables -A FORWARD -s COLTECH -j DROP # coltech
# Block outgoing NetBios (if you have windows machines running
# on the DMZ subnet).  This will not affect any NetBios
# traffic that flows over the VPN tunnel, but it will stop
# local windows machines from broadcasting themselves to
# the internet.
iptables -A FORWARD -p tcp --sport 137:139 -o eth0 -j DROP
iptables -A FORWARD -p udp --sport 137:139 -o eth0 -j DROP
iptables -A OUTPUT -p tcp --sport 137:139 -o eth0 -j DROP
iptables -A OUTPUT -p udp --sport 137:139 -o eth0 -j DROP
# Check source address validity on packets
iptables -A FORWARD -s ! $DMZ -i eth1 -j DROP
iptables -A FORWARD -s ! $COLTECH -i eth2 -j DROP
# Allow local loopback
iptables -A INPUT -s $LOOP -j ACCEPT
iptables -A INPUT -d $LOOP -j ACCEPT
# Allow incoming pings (can be disabled)
#iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT
# Allow inbound services
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
iptables -A INPUT -p tcp --dport 1194 -j ACCEPT
# Allow packets from TUN/TAP devices.
iptables -A INPUT -i tun+ -j ACCEPT
iptables -A FORWARD -i tun+ -j ACCEPT
iptables -A INPUT -i tap+ -j ACCEPT
iptables -A FORWARD -i tap+ -j ACCEPT
# Allow packets from DMZ subnets
iptables -A INPUT -i eth1 -j ACCEPT
iptables -A FORWARD -i eth1 -j ACCEPT
iptables -A INPUT -i eth2 -j ACCEPT
iptables -A FORWARD -i eth2 -j ACCEPT
# Keep state of connections from local machine and DMZ subnets
iptables -A OUTPUT -m state --state NEW -o eth0 -j ACCEPT
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A FORWARD -m state --state NEW -o eth0 -j ACCEPT
iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A OUTPUT -m state --state NEW -o eth1 -j ACCEPT
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A FORWARD -m state --state NEW -o eth1 -j ACCEPT
iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A OUTPUT -m state --state NEW -o eth2 -j ACCEPT
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A FORWARD -m state --state NEW -o eth2 -j ACCEPT
iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT
# Masquerade local subnet(s)
iptables -t nat -A POSTROUTING -s $DMZ -o eth0 -j MASQUERADE
iptables -t nat -A POSTROUTING -s $COLTECH -o eth0 -j MASQUERADE
iptables -t nat -A POSTROUTING -s $COLTECH -o eth1 -j MASQUERADE
# Save iptables rules and restart iptables
iptables-save > /etc/sysconfig/iptables
service iptables restart

iptables and check script

################################################
##############################
iptables -F
#################################################
#### polityka DROP dla INPUT
iptables -P INPUT DROP
#################################################
#### polityka DROP dla OUTPUT
iptables -P OUTPUT DROP
###################################################
#### polityka ACCEPT dla FORWARD
iptables -P FORWARD ACCEPT
#### wlaczenie loopback
iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT
iptables -A FORWARD -o lo -j ACCEPT 
#####################################################################
####### WWW  & DNS ##################################################
iptables -A OUTPUT -p tcp  --syn -s $ip  --dport 80 -j ACCEPT -m state --state NEW
iptables -A OUTPUT -p udp  -s $ip  --dport 53 -j ACCEPT -m state --state NEW
#####################################################################
####### kadu ########################################################
iptables -A OUTPUT -p tcp -s 0/0 --dport 8074 -j ACCEPT -m state --state NEW
####################################################################
###### ssh -logowanie 1 na minute- #################################
#iptables -A INPUT -p tcp --dport 22 -m limit --limit 1/min 
#iptables -A INPUT -p tcp --dport 22 -m hashlimit --hashlimit 1/min --hashlimit-mode srcip --hashlimit-name ssh -m state --state NEW -j ACCEPT
iptables  -A  INPUT  -p  tcp   --dport  22  -m   connlimit --connlimit-above 1 -j REJECT
iptables -A OUTPUT -p tcp --dport 22 -j ACCEPT -m state --state NEW
####################################################################
##### auth #########################################################
iptables -A INPUT -p tcp --source-port 113 -j ACCEPT
#####################################################################
#### ftp  ###########################################################
#iptables -A INPUT -p tcp ! --syn --sport 20:21 -d $ip --dport 1024:65535 -j ACCEPT
iptables -A OUTPUT -p tcp -s $ip --sport 1024:65535 --dport 20:21 -j ACCEPT -m state --state NEW
######################################################################
#### Zabezpieczenie przed powodzia SYN (Syn-flood):###################
iptables -A INPUT -p tcp --syn -m limit --limit 1/s -j ACCEPT
######################################################################
#### Ping of death: ##################################################
iptables -A INPUT -p icmp --icmp-type echo-request -m limit --limit 1/s -j ACCEPT
#####################################################################
#### Wlaczenie przekazywania IP######################################
echo 1 > /proc/sys/net/ipv4/ip_forward
#####################################################################
#### Wlaczenie blokady komunikatow echo (ping) jesli : 0 --true  , 1 --false
echo 0 > /proc/sys/net/ipv4/icmp_echo_ignore_all
#####################################################################
#### Blokada przed atakami typu SYN FLOODING
echo 1 > /proc/sys/net/ipv4/tcp_syncookies
#####################################################################
# Weryfikacja adresu zrodlowego na poziomie kernela
# zeby zdalne hosty nie mogly sie podszyc pod moj komputer
#####################################################################
echo 1 > /proc/sys/net/ipv4/conf/default/rp_filter
################################################
#PING
iptables -A INPUT -p icmp -s 0/0 -d 0/0 -j DROP
####################################################################
####  https, skype, apache ######################################
iptables -A OUTPUT -p tcp -s $ip --sport 1024:65535 --dport 443 -j ACCEPT -m state --state NEW
#############################################################################
iptables -A OUTPUT  -p tcp -s $ip -d 0/0 --dport 1024:65535 -j ACCEPT -m state --state NEW
#############################################################################
#############################################################################
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A OUTPUT -p tcp -m state --state ESTABLISHED -j ACCEPT
iptables -A INPUT -m state --state INVALID -j DROP

script for P2P

Based in wshaper:
#!/bin/bash
# MLDonkey Wondershaper
# In kilobits
DOWNLINK=256
UPLINK=128
DEV=ppp0
QLEN=30 #Default 3
RQ=1    #Default 10
BURST=30 #Default 6
CLASS12="http/tcp/both pop3/tcp/dport pop3s/tcp/dport https/tcp/dport
8080/tcp/b
oth nntp/tcp/both"
case "$1" in
start)
IPTCMD="iptables -A WSHAPER -t mangle -p"
tc disc del dev $DEV root 2> /dev/null > /dev/null
tc disc del dev $DEV ingress 2> /dev/null > /dev/null
tc disc del dev imq0 root 2> /dev/null > /dev/null
iptables -t mangle -D POSTROUTING -o $DEV -j WSHAPER 2> /dev/null
\
> /dev/null
ip link set dev $DEV qlen $QLEN
tc qdisc add dev $DEV root handle 1: htb r2q $RQ default 13
tc class add dev $DEV parent 1: classid 1:1 htb rate
$[$UPLINK-2]kbit \
ceil $[$UPLINK-2]kbit burst ${BURST}k
tc class add dev $DEV parent 1:1 classid 1:10 htb rate \
$[(($UPLINK-2)*17)/100]kbit ceil $[$UPLINK-2]kbit prio 2
tc class add dev $DEV parent 1:1 classid 1:11 htb rate \
$[(($UPLINK-2)*40)/100]kbit ceil $[$UPLINK-2]kbit prio 0
tc class add dev $DEV parent 1:1 classid 1:12 htb rate \
$[(($UPLINK-2)*40)/100]kbit ceil $[$UPLINK-2]kbit prio 1
tc class add dev $DEV parent 1:1 classid 1:13 htb rate \
1kbit ceil $[$UPLINK-2]kbit prio 3
tc qdisc add dev $DEV parent 1:10 handle 10: sfq perturb 10
tc qdisc add dev $DEV parent 1:11 handle 11: sfq perturb 10
tc qdisc add dev $DEV parent 1:12 handle 12: sfq perturb 10
tc qdisc add dev $DEV parent 1:13 handle 13: sfq perturb 10
tc filter add dev $DEV parent 1:0 prio 0 protocol ip handle 10 \
fw flowid 1:10
tc filter add dev $DEV parent 1:0 prio 1 protocol ip handle 11 \
fw flowid 1:11
tc filter add dev $DEV parent 1:0 prio 2 protocol ip handle 12 \
fw flowid 1:12
tc filter add dev $DEV parent 1:0 prio 3 protocol ip handle 13 \
fw flowid 1:13
iptables -t mangle -N WSHAPER
iptables -t mangle -I POSTROUTING -o $DEV -j WSHAPER
# Class 10
$IPTCMD tcp -m length --length :64 -j MARK --set-mark 10   ## ACKs
# $IPTCMD tcp -p tcp --tcp-flags ACK -j MARK --set-mark 10
# Class 11
$IPTCMD tcp --dport ssh -j MARK --set-mark 11              ## SSH
$IPTCMD tcp --sport ssh -j MARK --set-mark 11
$IPTCMD icmp -j MARK --set-mark 11                         ## ICMP
$IPTCMD udp --dport domain -j MARK --set-mark 11           ## DNS
$IPTCMD all --source 192.168.0.2 -j MARK --set-mark 11     ##
linuxclient
$IPTCMD all --destination 192.168.0.2 -j MARK --set-mark 11
$IPTCMD all --source 192.168.0.3 -j MARK --set-mark 11     ##
linuxlaptop
$IPTCMD all --destination 192.168.0.3 -j MARK --set-mark 11
$IPTCMD all --source 192.168.0.4 -j MARK --set-mark 11     ##
compaqlaptop
$IPTCMD all --destination 192.168.0.4 -j MARK --set-mark 11
# Class 12
for PORTPROTODEST in $CLASS12 ; do
PORT=`echo $PORTPROTODEST | awk -F/ '{print $1}'`
PROTO=`echo $PORTPROTODEST | awk -F/ '{print $2}'`
DEST=`echo $PORTPROTODEST | awk -F/ '{print $3}'`
if [ "$PROTO" = "both" ]; then
if [ "$DEST" = "both" ]; then
$IPTCMD tcp --dport $PORT -j MARK --set-mark 12
$IPTCMD udp --sport $PORT -j MARK --set-mark 12
$IPTCMD tcp --sport $PORT -j MARK --set-mark 12
$IPTCMD udp --dport $PORT -j MARK --set-mark 12
else
$IPTCMD tcp --$DEST $PORT -j MARK --set-mark 12
$IPTCMD udp --$DEST $PORT -j MARK --set-mark 12
fi
else
if [ "$DEST" = "both" ]; then
$IPTCMD $PROTO --dport $PORT -j MARK --set-mark 12
$IPTCMD $PROTO --sport $PORT -j MARK --set-mark 12
else
$IPTCMD $PROTO --$DEST $PORT -j MARK --set-mark 12
fi
fi
done
# Class 13 default
$IPTCMD udp --sport 4660:4670 -j MARK --set-mark 13
$IPTCMD udp --dport 4660:4670 -j MARK --set-mark 13
$IPTCMD tcp --sport 4660:4670 -j MARK --set-mark 13
$IPTCMD tcp --dport 4660:4670 -j MARK --set-mark 13
$IPTCMD udp --dport 8948 -j MARK --set-mark 13
$IPTCMD tcp --dport 8948 -j MARK --set-mark 13
$IPTCMD udp --sport 8948 -j MARK --set-mark 13
$IPTCMD tcp --sport 8948 -j MARK --set-mark 13
tc qdisc add dev imq0 handle 1: root htb default 1
tc class add dev imq0 parent 1: classid 1:1 htb rate $[DOWNLINK-2]kbit
tc qdisc add dev imq0 parent 1:1 handle 10: htb default 5
tc class add dev imq0 parent 10: classid 10:1 htb \
rate $[((DOWNLINK-2)*10)/100]kbit ceil $[DOWNLINK-2]kbit burst 30k
prio 1
tc class add dev imq0 parent 10: classid 10:2 htb \
rate $[((DOWNLINK-2)*70)/100]kbit ceil $[DOWNLINK-2]kbit burst 30k
prio 2
tc class add dev imq0 parent 10: classid 10:5 htb \
rate $[((DOWNLINK-2)*20)/100]kbit ceil $[DOWNLINK-2]kbit prio 3
tc qdisc add dev imq0 parent 10:1 handle 21:0 pfifo
tc qdisc add dev imq0 parent 10:2 handle 22:0 sfq
tc qdisc add dev imq0 parent 10:5 handle 23:0 sfq
tc filter add dev imq0 protocol ip pref 1 parent 10: handle 1 fw classid
10:1
tc filter add dev imq0 protocol ip pref 2 parent 10: handle 2 fw classid
10:2
iptables -t mangle -A PREROUTING -i $DEV -j IMQ
iptables -t mangle -A PREROUTING -i $DEV -p tcp -m tos --tos
minimize-delay -m s
tate --state ESTABLISHED -j MARK --set-mark 1
iptables -t mangle -A PREROUTING -i $DEV -p tcp -m length --length :64
-j MARK -
-set-mark 1
iptables -t mangle -A PREROUTING -i $DEV -p tcp --dport 22  -m state
--state EST
ABLISHED -j MARK --set-mark 2
iptables -t mangle -A PREROUTING -i $DEV -p tcp --sport 80 --dport 1024:
-m stat
e --state ESTABLISHED -j MARK --set-mark 2
iptables -t mangle -A PREROUTING -i $DEV -p tcp --dport 80 --sport 1024:
-m stat
e --state ESTABLISHED -j MARK --set-mark 2
iptables -t mangle -A PREROUTING -i $DEV -p tcp --sport 443 --dport
1024: -m sta
te --state ESTABLISHED -j MARK --set-mark 2
iptables -t mangle -A PREROUTING -i $DEV -p tcp --sport pop3 -m state
--state ES
TABLISHED -j MARK --set-mark 2
iptables -t mangle -A PREROUTING -i $DEV -p udp --sport domain -j MARK
--set-mar
k 2
iptables -t mangle -A PREROUTING -i $DEV -p icmp -j MARK --set-mark 2
ip link set imq0 up
echo "wshaper started"
;;
stop)
iptables -t mangle -D POSTROUTING -o $DEV -j WSHAPER 2> /dev/null
\
> /dev/null
iptables -t mangle -D PREROUTING -i $DEV -j WSHAPER 2> /dev/null \
> /dev/null
iptables -t mangle -D PREROUTING -i $DEV -j IMQ 2> /dev/null \
> /dev/null
iptables -t mangle -F PREROUTING 2> /dev/null >/dev/null
iptables -t mangle -F WSHAPER 2> /dev/null > /dev/null
iptables -t mangle -X WSHAPER 2> /dev/null > /dev/null
tc qdisc del dev $DEV root 2> /dev/null > /dev/null
tc qdisc del dev $DEV ingress 2> /dev/null > /dev/null
tc qdisc del dev imq0 root 2> /dev/null > /dev/null
echo "wshaper stopped"
;;
restart)
$0 stop
$0 start
;;
status)
# print anything interesting
echo "[qdisc]"
tc -s qdisc show dev $DEV
echo "[class]"
tc -s class show dev $DEV
echo "[iptables]"
iptables -t mangle -L WSHAPER -xnv
echo "[imq]"
tc -s qdisc show dev imq0
tc -s class show dev imq0
exit
;;
*)
echo "Usage: $0 {start|stop|restart|status}"
;;
esac