Beta
×

Welcome to the Slashdot Beta site -- learn more here. Use the link in the footer or click here to return to the Classic version of Slashdot.

Thank you!

Before you choose to head back to the Classic look of the site, we'd appreciate it if you share your thoughts on the Beta; your feedback is what drives our ongoing development.

Beta is different and we value you taking the time to try it out. Please take a look at the changes we've made in Beta and  learn more about it. Thanks for reading, and for making the site better!

Bidirectional Traffic Shaping Script

stmfreak (230369) writes | more than 6 years ago

Networking

#!/bin/bash
# Copyright gone. I had lots of help from the Internet,
# this wouldn't have been possible without lots of sources.
# Thanks. Give back what you learn.

#!/bin/bash
# Copyright gone. I had lots of help from the Internet,
# this wouldn't have been possible without lots of sources.
# Thanks. Give back what you learn.

# This script has been obscured, you'll want to enter your
# LAN ip subnets and favorite hosts in appropriate places or
# leave those filters commented out.
#
# To start:
# ./script
#
# To stop:
# ./script stop
#
# To monitor:
# ./script status
#

#### Bandwidth Limiting ####
# set link speeds to ~85% of your rated line speed in kbit/s

# INET*, we artificially limit to control costs over our 100Mbps pipe.
INETDWN=4000
INETUP=4000

# WAN* is the 100Mbps switch between hosts in the DMZ, before hitting
# our ISPs pipe.
WANUP=92000
WANDWN=92000

# LAN* is our private and trusted network.
LANUP=92000
LANDWN=92000

### these ratios allowed me to fiddle. I don't fiddle any more.
# The ratios basically say R10 gets 70% of the bandwidth, but
# because we're using an HTB, idle bandwidth will get shared
# among R20 and R30 at a ration of R20/R30. If R20 doesn't want
# the bandwidth either, then R30 gets it all, up to its ceiling.
# I'm still not sure how or if burst works. Have fun!

# set ratios for the queue's rate limits
R10=70
R20=25
R30=5
# set ratios for the queue's ceil limits
C10=100
C20=85
C30=75
# set ratios for the queue's burst limits
B10=100
B20=70
B30=40

# declare our interfaces
WAN=eth0
LAN=eth1

##### status? #####
# report status and exit
if [ "$1" = "status" ]
then
                echo "################## $WAN filters ###################"
                tc -s qdisc ls dev $WAN
                echo
                tc -s class ls dev $WAN
                echo "################## $LAN filters ###################"
                tc -s qdisc ls dev $LAN
                echo
                tc -s class ls dev $LAN
                exit
fi

##### stop #####
tc qdisc del dev $WAN root 2> /dev/null > /dev/null
tc qdisc del dev $WAN ingress 2> /dev/null > /dev/null
tc qdisc del dev $LAN root 2> /dev/null > /dev/null
tc qdisc del dev $LAN ingress 2> /dev/null > /dev/null

# and exit if we're stopping
if [ "$1" = "stop" ]
then
                exit
fi

##################################################################
################## start traffic shaping #########################
# note, these policies only control the rate that traffic goes out
# of each interface. Uploads, so to speak. Trying to control
# downloads is done by either an ingress policer or controlling
# the rate we forward traffic out/up the LAN interface or both
##################################################################

#### setup WAN traffic filters

# install root HTB, point default traffic to 1:30
tc qdisc add dev $WAN root handle 1: htb default 30

# establish rate limited class
tc class add dev $WAN parent 1: classid 1:1 htb \
      rate ${INETUP}kbit burst $[$INETUP*8]

# add local wan class
tc class add dev $WAN parent 1: classid 1:2 htb \
      rate ${WANUP}kbit burst $[$WANUP*8]

# setup classes with different prio levels
tc class add dev $WAN parent 1:1 classid 1:10 htb \
      rate $[$R10*$INETUP/100]kbit ceil $[$C10*$INETUP/100]kbit \
      burst $[$B10*$INETUP/100*8] prio 1
tc class add dev $WAN parent 1:1 classid 1:20 htb \
      rate $[$R20*$INETUP/100]kbit ceil $[$C20*$INETUP/100]kbit \
      burst $[$B20*$INETUP/100*8] prio 2
tc class add dev $WAN parent 1:1 classid 1:30 htb \
      rate $[$R30*$INETUP/100]kbit ceil $[$C30*$INETUP/100]kbit \
      burst $[$B30*$INETUP/100*8] prio 3

# all get stochastic fairness
tc qdisc add dev $WAN parent 1:10 handle 10: sfq perturb 10
tc qdisc add dev $WAN parent 1:20 handle 20: sfq perturb 10
tc qdisc add dev $WAN parent 1:30 handle 30: sfq perturb 10

# and filter traffic onto each
U32="tc filter add dev $WAN protocol ip parent 1: prio 1 u32"

# traffic to our local external subnet is backdoored
# $U32 match ip dst A.B.C.D/M flowid 1:2

# ICMP is unrestricted to measure line
$U32 match ip protocol 1 0xff flowid 1:10

# http takes the sorta slow path
$U32 match ip sport 80 0xffff flowid 1:20
$U32 match ip sport 443 0xffff flowid 1:20
$U32 match ip dport 80 0xffff flowid 1:20
$U32 match ip dport 443 0xffff flowid 1:20

# ftp-data takes the slow path
$U32 match ip sport 20 0xffff flowid 1:30
$U32 match ip dport 20 0xffff flowid 1:30

# TOS Minimum Delay (ssh, NOT scp)
$U32 match ip tos 0x10 0xff flowid 1:10
# we don't host VoIP anymore, but if we did it goes in 1:10
$U32 match ip tos 0xb8 0xff flowid 1:10
$U32 match ip tos 0x68 0xff flowid 1:10

# this tries to matches downloads and torrent packets
$U32 match ip tos 0x20 0xff flowid 1:30

# traffic to is important, goes into 1:20
# $U32 match ip dst A.B.C.D flowid 1:20

# DNS
$U32 match ip sport 53 0xffff flowid 1:20
$U32 match ip dport 53 0xffff flowid 1:20

# setup ingress policer to keep downloads in check
tc qdisc add dev $WAN handle ffff: ingress

# give packets from lots of headroom
#tc filter add dev $WAN parent ffff: protocol ip prio 1 u32 \
# match ip src A.B.C.D/32 police \
# rate ${WANDWN}kbit burst $[$WANDWN*8] \
# drop flowid :1

# give packets from local subnet some headroom
#tc filter add dev $WAN parent ffff: protocol ip prio 2 u32 \
# match ip src A.B.C.D/M police \
# rate ${WANDWN}kbit burst $[$WANDWN*8] \
# drop flowid :1

# everything else gets rate limited at 110% since we'd rather
# catch it in the LAN shaper than just drop on the floor here
tc filter add dev $WAN parent ffff: protocol ip prio 3 u32 \
      match ip src 0.0.0.0/0 police \
      rate $[11*$INETDWN/10]kbit burst $[$INETDWN*8] \
      drop flowid :1

# end WAN traffic shaping

#### Setup LAN traffic filters
# By rate limiting traffic going out the LAN interface, we do
# a much better job of shaping than merely dropping packets
# with the WAN ingress filter.
#
# This affects DOWNLOADS by employees!

# setup root HTB with default on 1:30
tc qdisc add dev $LAN root handle 1: htb default 30

# here we setup a class for DMZ->LAN traffic aka backdoor
tc class add dev $LAN parent 1: classid 1:1 htb \
      rate ${LANUP}kbit burst $[$LANUP*8] prio 1

# and here, we setup classes for WAN->LAN traffic
tc class add dev $LAN parent 1: classid 1:2 htb \
      rate ${INETDWN}kbit \
      burst $[$INETDWN*8] prio 1
tc class add dev $LAN parent 1:2 classid 1:10 htb \
      rate $[$R10*$INETDWN/100]kbit ceil $[$C10*$INETDWN/100]kbit \
      burst $[$B10*$INETDWN/100*8] prio 1
tc class add dev $LAN parent 1:2 classid 1:20 htb \
      rate $[$R20*$INETDWN/100]kbit ceil $[$C20*$INETDWN/100]kbit \
      burst $[$B20*$INETDWN/100*8] prio 2
tc class add dev $LAN parent 1:2 classid 1:30 htb \
      rate $[$R30*$INETDWN/100]kbit ceil $[$C30*$INETDWN/100]kbit \
      burst $[$B30*$INETDWN/100*8] prio 3

# all get stochastic fairness
tc qdisc add dev $LAN parent 1:10 handle 10: sfq perturb 10
tc qdisc add dev $LAN parent 1:20 handle 20: sfq perturb 10
tc qdisc add dev $LAN parent 1:30 handle 30: sfq perturb 10

# and filter traffic onto each
U32="tc filter add dev $LAN protocol ip parent 1: prio 1 u32"

# send local traffic to the bypass
$U32 match ip src 127.0.0.1 flowid 1:1
# $U32 match ip src 10.B.C.D/M flowid 1:1

# send traffic to the bypass
# $U32 match ip src A.B.C.D flowid 1:1

# backdoor downloads for my desktop (approved torrents)
# torrent traffic listens on , but establishes conns on many ports
# $U32 match ip dst 10.B.C.D flowid 1:1

# icmp gets high priority
$U32 match ip protocol 1 0xff flowid 1:10

# http takes the sorta slow path
$U32 match ip sport 80 0xffff flowid 1:20
$U32 match ip sport 443 0xffff flowid 1:20
$U32 match ip dport 80 0xffff flowid 1:20
$U32 match ip dport 443 0xffff flowid 1:20

# ftp-data takes the slow path
$U32 match ip sport 20 0xffff flowid 1:30
$U32 match ip dport 20 0xffff flowid 1:30

# ssh should go into important, try 1:10 if you get latency
#$U32 match ip sport 22 0xffff flowid 1:20
#$U32 match ip dport 22 0xffff flowid 1:20

# interactive tos flags, this catches ssh, but not scp
$U32 match ip tos 0x10 0xff flowid 1:10

# one of these three also gets youtube videos from port 80!
#$U32 match ip tos 0xb8 0xff flowid 1:10
#$U32 match ip tos 0x68 0xff flowid 1:10

# this matches downloads and torrent packets
$U32 match ip tos 0x20 0xff flowid 1:30

# end LAN traffic shaping

# notice, no ingress policer here, but you could add one
# if you're worried about massive uploads from your users
# swamping the WAN out bound filters.

cancel ×

comment

Slashdot Login

Need an Account?

Forgot your password?

Submission Text Formatting Tips

We support a small subset of HTML, namely these tags:

  • b
  • i
  • p
  • br
  • a
  • ol
  • ul
  • li
  • dl
  • dt
  • dd
  • em
  • strong
  • tt
  • blockquote
  • div
  • quote
  • ecode

"ecode" can be used for code snippets, for example:

<ecode>    while(1) { do_something(); } </ecode>