#!/bin/bash # ultimate.sh for duron # Based on Wonder Shaper v1.1a echo "/usr/sbin/ultimate.sh: " # Please read the README before filling out these values. # Set the following values to somewhat less than your actual download # and upload speed in kilobits. Also set the device that is to be shaped. # Run a speed test from netspeed.stanford.edu with no shaping enabled. # Multiply the reported rates in Kb/s by ~.95 and enter them here: # Example: DNLINK=4.76M*.95 = 4522 # UPLINK=444.26K*.95 = 422 # Run the stanford test again. Note: stanford uses high ports. # Tweak during heavy upload so that each affected class has a small backlog but # as few dropped packets as possible. Interactive must NEVER backlog! # If heavy downloads affect uploads, tweak IMQ so there is a small backlog but # as few dropped packets as possible. # Watch the logs for "some class has too small rate" even with quantum set. # Stanford is in class 30; egress rate 36% ceil 92%, ingress rate 57% ceil 92% # Download w/HTB is plenty (5.2x), don't tweak. # Upload w/UPLINK=470 -> range 416 - 420 = ~85% of uCEIL. Try for 90% - 91%.
dCEIL=9740 # Stanford max down with no shaping (best of 3 tests) DNLINK=9350 # (.95*dCEIL, rounded down) uCEIL=974 # Stanford max up (best of 3 tests). UPLINK=952 # Tweak. (was 470=.95*uCEIL, rounded up) # Percentages, egress: # sum(Ie + Ae + Be + Pe) _MUST_ = 100 Ie=7 # Interactive Ae=50 # Accelerated Be=36 # Bulk Pe=7 # Penalized # Percentages, ingress (IMQ): # sum(Ii + Ai + Bi) _MUST_ = 100 Ii=5 # Interactive Ai=38 # Accelerated Bi=57 # Bulk IFE=eth1 # Egress NIC; External Interface IMQ=imq0 # Egress NIC - shape incoming # Local IPs: ATJ=`cat /etc/firewall/Duron` # Remote IPs: #ADE="216.196.97.0/24" # adelphia.net CHS="" # chsoft.biz DMF="" # Diana's NGUY="74.209.0.80/28" # Newsguy #HBED1="62.146.66.160/27" # H+BEDV (antivirus) #HBED2="217.11.60.0/27" # H+BEDV (antivirus) #ISW1="207.178.128.0/24" # iswest #ISW2="216.166.71.0/24" # iswest #ISW3="216.196.105.0/24" # iswest (giganews) LHD1="" # L. H. Dottie LHD2="" # L. H. Dottie #NEWS="" # news.chsoft.biz NSAD="67.21.15.0/24" # Adelphia dns servers NSTW="66.75.164.0/24" # Time Warner dns servers #QUE1="63.231.95.0/24" # quest #QUE2="207.225.159.0/24" # quest SC=`cat /etc/firewall/SupportJ` # Note that ports 5500 and 5900 have priority #TERA="66.150.105.0/24" # teranews WALK="" # Walker Foods #YIC="" # yesican.chsoft.biz ###### EXPLANATION # See 'INGRESS' below for information about incoming packets. All of this # except for that refers to queueing outgoing packets. # # Most of what is sent goes out on a randomly selected high SOURCE port # ('sport') to a specific DESTINATION port ('dport'). For example, an http # request is sent with 'dport' = 80 and 'sport' = random. Therefore, 'sport' # specifications are rarely applicable. The port number is located in the # packet header and is specified thus: # "u32 match ip dport PORT# 0xffff" or "u32 match ip sport PORT# 0xffff" # # Since shaping means quequeing OUTGOING packets, your IP Address(es) are # SOURCEs ('src') and the remote machine's IP Address(es) are DESTINATIONs # ('dst') - so, as with 'sport', 'src' specifications are rarely applicable. # The IP Address is located in the packet header and is specified thus: # "u32 match ip src IP-ADDRESS" or "u32 match ip dst IP-ADDRESS" # # Read the HOWTO "All the filtering commands you will normally need" for # protocol information (TCP, UDP, ICMP, GRE, IPSEC). Also see the TOS and # ICMP sections below. ###### # Sometimes you may notice low priority OUTGOING traffic slowing down important # traffic. In that case, the following eLoPrio options may help you: ## * * * * Structure: ## {1} * * * * * IFE DEFINITIONS ## {2} * * * * * EGRESS on IFE (HERE --> INTERNET) ## {3} * * * * * IMQ INGRESS shaping on IFE (HERE <-- INTERNET) ###### {1} External Interface DEFINITIONS: # Ports: # eLoPrioSPORT ('sport') # Set this to source ports that should have low priority. If you have # an unimportant webserver on your traffic, set this to 80. # These go into class 40 # (some ports ) 20 21 22 23 25 53 80 113 119 873 # (and what they are:) FTPd FTPc SSH SMTP DNS HTTP IDENT NNTP Rsync # 9001 is tor Server, 9030 is tor Directory # Search 6881 for torrent special handling (1:40) # Matches FROM me:PORT eLoPrioSPORT="8 21 23 67 68 79 110 135 137 138 139 389 445 446 901 1026 1027 1028 1029 1234 5018" # eHiPrioSPORT ('sport') # These go into class 20. SSH and scp are interactive (class 10). # *** Make sure no eLoPrioSPORTs are duplicated here! *** # Matches (apparently) nothing. eHiPrioSPORT="113 119 123 443 563 873 5500 5900" # eLoPrioDPORT ('dport') # Set this to destination ports that should have low priority. # The following are from my TARPIT list: 79 135 137 138 139 445 901 # Matches DIR=FROM? remote:PORT # These go into class 40 eLoPrioDPORT="8 21 23 67 68 79 110 135 137 138 139 389 445 446 901 1026 1027 1028 1029 1234 5018" # eHiPrioDPORT ('dport') # *** Make sure no eLoPrioDPORTs are duplicated here! *** ssh is interactive. # Matches DIR=FROM? ?:PORT # These go into class 20 eHiPrioDPORT="113 119 123 443 563 873 5500 5900" # IPs / Netmasks: # Set this to hosts or netmasks in your network that should have low priority. # Low priority OUTGOING traffic. You can leave this blank if you want. # Matches TO REMOTE # These go into class 40 eLoPrioCIDR_Src="" #eLoPrioCIDR_Src="$ATJ" # See EXPLANATION above; these do not need to be here. # Matches (apparently) nothing. # These go into class 20 eHiPrioCIDR_Src="$CHS $LHD1 $NGUY $SC $WALK" # Set this to hosts or netmasks on the internet that should have low priority. # Matches FROM REMOTE # These go into class 40 eLoPrioCIDR_Dst="221.0.0.0/8" # high priority destination netmasks ('dst'): # Matches DIR? REMOTE:IP # These go into class 20 eHiPrioCIDR_Dst="$CHS $LHD1 $NGUY $SC $WALK" ###### End External Interface DEFINITIONS if [ "$1" = "status" ]; then echo "Sent on $IFE:" # tc -s filter show dev $IFE tc -d qdisc ls dev $IFE tc -s qdisc ls dev $IFE tc -s class ls dev $IFE echo "'rate #bit' means Bytes per Second" echo "Received on $IMQ:" # tc -s filter show dev $IMQ tc -d qdisc ls dev $IMQ tc -s qdisc ls dev $IMQ tc -s class ls dev $IMQ echo "'rate #bit' is meaningless. Measure by Backlog and Dropped." exit fi # Clean existing setup, hiding errors tc qdisc del dev $IFE root 2> /dev/null > /dev/null tc qdisc del dev $IFE ingress 2> /dev/null > /dev/null iptables -t mangle -D PREROUTING -i $IFE -j IMQ --todev 0 2>/dev/null > /dev/null tc qdisc del dev $IMQ root 2> /dev/null > /dev/null ip link set $IMQ down 2> /dev/null > /dev/null modprobe -r ipt_IMQ # iptables modprobe -r imq # device modprobe -r cls_u32 modprobe -r sch_esfq # requires modified tc modprobe -r sch_sfq modprobe -r sch_htb modprobe -r sch_ingress if [ "$1" = "stop" ]; then exit fi ###### {2} uplink (EGRESS) on IFE # This part shapes on the external interface: (HERE --> INTERNET) # Install root HTB, point default traffic to 1:30: tc qdisc add dev $IFE root handle 1: htb default 30 # Shape everything at $UPLINK speed - this prevents huge queues in your # DSL modem which destroy latency: tc class add dev $IFE parent 1: classid 1:1 htb rate ${uCEIL}kbit burst 32k cburst 20k # High prio (interactive) class 1:10: tc class add dev $IFE parent 1:1 classid 1:10 htb rate $[Ie*$UPLINK/100]kbit \ ceil ${uCEIL}kbit burst 32k cburst 20k quantum 1514 prio 1 # Accelerated class 1:20 - the HIPRIO stuff: tc class add dev $IFE parent 1:1 classid 1:20 htb rate $[Ae*$UPLINK/100]kbit \ ceil $[96*$uCEIL/100]kbit burst 16k cburst 10k quantum 1514 prio 2 # Bulk & default class 1:30 - gets a low priority: tc class add dev $IFE parent 1:1 classid 1:30 htb rate $[Be*$UPLINK/100]kbit \ ceil $[92*$UPLINK/100]kbit burst 8k cburst 5k quantum 1514 prio 3 # ceil $[Ae*$UPLINK/100]kbit burst 8k cburst 5k quantum 1514 prio 3 # Penalized class 1:40 - the LOPRIO stuff gets the lowest rate and priority: tc class add dev $IFE parent 1:1 classid 1:40 htb rate $[Pe*$UPLINK/100]kbit \ ceil $[80*$UPLINK/100]kbit burst 2k quantum 1514 prio 4 # ceil $[Be*$UPLINK/100]kbit burst 2k quantum 1514 prio 4 # Some get Stochastic Fairness: # LARTC mailing list indicates that interactive should not be included. Andy # Furniss suggests that bulk be the only thing subject to SF. I set a long # perturb for accelerated and exclude interactive. # Increased limit from 64 to reduce # of dropped packets 7Dec07 # 11Dec07: esfq limit must be less than or equal depth; depth max = 1024: #tc qdisc add dev $IFE parent 1:10 handle 10: esfq limit 64 depth 64 divisor 10 hash classic perturb 20 tc qdisc add dev $IFE parent 1:20 handle 20: esfq limit 256 depth 256 divisor 10 hash classic perturb 99 tc qdisc add dev $IFE parent 1:30 handle 30: esfq limit 1024 depth 1024 divisor 10 hash classic perturb 20 tc qdisc add dev $IFE parent 1:40 handle 40: esfq limit 32 depth 32 divisor 10 hash classic perturb 10 # ARP: tc filter add dev $IFE parent 1: protocol all prio 5 u32 \ match u16 0x0806 0xffff at -2 flowid 1:40 ###### Accelerate (interactive) the following: # To speed up downloads while an upload is going on, put ACK packets in # the interactive class 1:10: # IP header length 0x5 (32 bit words) # IP total length 0x34 (ACK + 12 bytes of TCP options) # TCP ACK set (bit 5, offset 33) # ("at nexthdr+33" = "at 13") ## Match ACK on all TCP packets with the ACK bit set: ## Caveat!: This can match packets up to 64K; don't do it. Match small. #tc filter add dev $IFE parent 1: protocol all prio 5 u32 \ # match ip protocol 6 0xff \ # match u8 0x10 0xff at nexthdr+13 \ # flowid 1:10 # Match TCP packets smaller than 128 bytes: # Because of the mask, can only match powers of 2 (32, 64, 128...) # 0xfff8 - 8 # 0xfff0 - 16 # 0xffe0 - 32 # 0xffc0 - 64 # 0xff80 - 128 # Remarked out ACK, normally 5th line: match u8 0x10 0xff at 33 \ # "match u8 0x05 0x0f at 0" makes sure the IP header is 20 bytes. tc filter add dev $IFE parent 1: protocol all prio 5 u32 \ match ip protocol 6 0xff \ match u8 0x05 0x0f at 0 \ match u16 0x0000 0xff80 at 2 \ flowid 1:10 # SSH and scp are interactive. tc filter add dev $IFE parent 1: protocol all prio 5 u32 \ match ip dport 22 0xffff flowid 1:10 tc filter add dev $IFE parent 1: protocol all prio 5 u32 \ match ip sport 22 0xffff flowid 1:10 # dns is interactive: tc filter add dev $IFE parent 1: protocol all prio 5 u32 \ match ip dport 53 0xffff flowid 1:10 tc filter add dev $IFE parent 1: protocol all prio 5 u32 \ match ip sport 53 0xffff flowid 1:10 ###### Some traffic is preferred, so in our class 1:20: for a in $eHiPrioDPORT; do tc filter add dev $IFE parent 1: protocol all prio 5 u32 \ match ip dport $a 0xffff flowid 1:20 done for a in $eHiPrioSPORT; do tc filter add dev $IFE parent 1: protocol all prio 5 u32 \ match ip sport $a 0xffff flowid 1:20 done for a in $eHiPrioCIDR_Src; do tc filter add dev $IFE parent 1: protocol all prio 5 u32 \ match ip src $a flowid 1:20 done for a in $eHiPrioCIDR_Dst; do tc filter add dev $IFE parent 1: protocol all prio 5 u32 \ match ip dst $a flowid 1:20 done ###### Give these short shrift: # Penalized traffic suffers a worse fate in our slowest class 1:40: # Special for torrents ports 6880-6887: # The mask determines the number of ports: ffff=1 fffe=2 fffc=4 fff8=8 fff0=16 tc filter add dev $IFE parent 1: protocol all prio 5 u32 \ match ip dport 6881 0xfff8 flowid 1:40 tc filter add dev $IFE parent 1: protocol all prio 5 u32 \ match ip sport 6881 0xfff8 flowid 1:40 for a in $eLoPrioDPORT; do tc filter add dev $IFE parent 1: protocol all prio 5 u32 \ match ip dport $a 0xffff flowid 1:40 done for a in $eLoPrioSPORT; do tc filter add dev $IFE parent 1: protocol all prio 5 u32 \ match ip sport $a 0xffff flowid 1:40 done for a in $eLoPrioCIDR_Src; do tc filter add dev $IFE parent 1: protocol all prio 5 u32 \ match ip src $a flowid 1:40 done for a in $eLoPrioCIDR_Dst; do tc filter add dev $IFE parent 1: protocol all prio 5 u32 \ match ip dst $a flowid 1:40 done if [ -f /etc/firewall/shitlist ]; then while read SLIST; do SLIST=$(echo "$SLIST" | awk '{print $1}') tc filter add dev $IFE parent 1: protocol all prio 5 u32 \ match ip dst $SLIST flowid 1:40 done <-- INTERNET) modprobe imq numdevs=1 # Since class 1:10 uses the default pfifo_fast, we need to give it txqueuelen # packets because pfifo_fast drops incoming packets when the queue fills up: ip link set $IMQ up txqueuelen 1024 mtu 1500 # Install root HTB, point default traffic to 1:30: tc qdisc add dev $IMQ root handle 1: htb default 30 # Shape everything at DNLINK speed: # Root class tc class add dev $IMQ parent 1: classid 1:1 htb rate ${dCEIL}kbit burst 32k \ cburst 20k quantum 1500 # High priority (interactive) class 1:10 tc class add dev $IMQ parent 1:1 classid 1:10 htb rate $[Ii*$DNLINK/100]kbit \ ceil ${dCEIL}kbit burst 32k cburst 20k quantum 1500 prio 1 # Accelerated class 1:20 tc class add dev $IMQ parent 1:1 classid 1:20 htb rate $[Ai*$DNLINK/100]kbit \ ceil $[96*$dCEIL/100]kbit burst 16k cburst 10k quantum 1500 prio 2 # Bulk & default class 1:30 tc class add dev $IMQ parent 1:1 classid 1:30 htb rate $[Bi*$DNLINK/100]kbit \ ceil $[92*$dCEIL/100]kbit burst 8k cburst 5k quantum 1500 prio 3 # Stochastic Fairness tc qdisc add dev $IMQ parent 1:20 handle 20: esfq limit 1024 depth 1024 divisor 10 hash dst perturb 99 tc qdisc add dev $IMQ parent 1:30 handle 30: esfq limit 768 depth 768 divisor 10 hash dst perturb 20 # Interactive ports: IMQint="22 53 5500 5900" # Accelerated ports: IMQacc="80 113 123 443 873 6502" for a in $IMQint; do tc filter add dev $IMQ parent 1: protocol all prio 5 u32 match \ ip dport $a 0xffff flowid 1:10 tc filter add dev $IMQ parent 1: protocol all prio 5 u32 match \ ip sport $a 0xffff flowid 1:10 done for a in $IMQacc; do tc filter add dev $IMQ parent 1: protocol all prio 5 u32 match \ ip dport $a 0xffff flowid 1:20 tc filter add dev $IMQ parent 1: protocol all prio 5 u32 match \ ip sport $a 0xffff flowid 1:20 done # Not needed because 1:30 is default: ## Match everything else: #tc filter add dev $IMQ parent 1: protocol all prio 5 u32 match u32 0 0 flowid 1:30 iptables -t mangle -I PREROUTING -i $IFE -j IMQ --todev 0 # Done ultimate.sh