User Tools

Site Tools


unix:gateway

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
unix:gateway [2013/10/13 12:32]
robm [IP Forwarding and NAT]
unix:gateway [2018/10/04 14:37] (current)
robm Update link to Knoppix
Line 293: Line 293:
 I used to use Ubuntu's stock ''wondershaper'' package, but now use my own adaptation of it that does *not* shape or police LAN traffic. This allows my gateway PC to double as a file server: internet traffic is shaped and policed to match my ADSL line speeds, while file-server (local) traffic runs at gigabit speeds. I used to use Ubuntu's stock ''wondershaper'' package, but now use my own adaptation of it that does *not* shape or police LAN traffic. This allows my gateway PC to double as a file server: internet traffic is shaped and policed to match my ADSL line speeds, while file-server (local) traffic runs at gigabit speeds.
  
-<code sh+See my ADSL project on GitHub: https://github.com/meermanr/adsl 
-#!/bin/sh+ 
 +<code bash wondershaper
 +#!/bin/bash -e
  
 # Adapted from http://lartc.org/wondershaper/ # Adapted from http://lartc.org/wondershaper/
  
 +DEV=$1
 DOWNLINK=$2 DOWNLINK=$2
 UPLINK=$3 UPLINK=$3
-DEV=$1+ 
 +# The following fudge factors allow you to express the usable % of your link.   
 +
 +# Experimentation has shown that ~75% of the author's ADSL downlink can be used  
 +# before upstream congestion starts to affect round-trip times. In other words,  
 +# by throttling our download speeds we can ensure that our ISP does not queue  
 +# any packs on our behalf, giving us full control over congestion. 
 +DOWNFACTOR='74/100' 
 +UPFACTOR='75/100'
  
 if [ "x$DEV" = "x" ] if [ "x$DEV" = "x" ]
 then then
-    echo "Usage: $0 (DEV) [ 'clear' | (DOWNLINK UPLINK) ]"+    echo "Usage: $0 (DEV) [ 'clear' | (DOWNLINK kbit/s) (UPLINK kbit/s) ]"
     exit 0     exit 0
 fi fi
Line 311: Line 322:
 if [ "x$DOWNLINK" = "x" ] if [ "x$DOWNLINK" = "x" ]
 then then
-    tc -s qdisc ls dev $DEV+    #echo "--------------------------------------------------------------------------------" 
 +    #iptables -nvL -t mangle 
 +    #echo "--------------------------------------------------------------------------------" 
 +    tc -s filter ls dev $DEV 
 +    echo "--------------------------------------------------------------------------------" 
 +    #tc -s qdisc ls dev $DEV 
 +    #echo "--------------------------------------------------------------------------------"
     tc -s class ls dev $DEV     tc -s class ls dev $DEV
     exit 0     exit 0
Line 319: Line 336:
 tc qdisc del dev $DEV root    2> /dev/null > /dev/null || true tc qdisc del dev $DEV root    2> /dev/null > /dev/null || true
 tc qdisc del dev $DEV ingress 2> /dev/null > /dev/null || true tc qdisc del dev $DEV ingress 2> /dev/null > /dev/null || true
 +
 +# Flush and delete all mangle rules
 +iptables -F 
 +iptables -X 
 +iptables -t mangle -F 
 +iptables -t mangle -X 
  
 if [ "x$DOWNLINK" = "xclear" ] if [ "x$DOWNLINK" = "xclear" ]
Line 326: Line 349:
 fi fi
  
-############################################################################### +trap "$0 $1 clear" ERR
-# UPLINK+
  
-Set root Queuing Discipline (qdisc) to Class Based Queuing (cbq) +Calculations 
-tc qdisc add dev $DEV root handle 1: cbq avpkt 1000 bandwidth 1000mbit +
 +# Target latency is < 50ms. This means max burst length should be limited to  
 +1/20th the queue's rate.
  
-# Traffic is either headed to the gateway (i.e. internet traffic) or not.   
-# Internet uplink is scarse, so aggresively shape it. LAN uplink is plentiful,  
-# do not restrict it. 
  
 +LOCALIP=$(ifconfig eth0 | sed -ne 's/^.*inet addr:\([0-9.]\+\).*/\1/p')
 +
 +# =============================================================================
 +# Queues and Classes
 # ============================================================================= # =============================================================================
-INTERNET GATEWAYShape to $UPLINK speed, this prevents huge queues in the  +1ROOT 
-DSL modem that cause massive latency +# |-- 1:ff LOCAL_TRAFFIC (to/from this host itself) 
-tc class add dev $DEV parent 1: classid 1:1 cbq rate ${UPLINK}kbit \ +| `-- ff: (sfq) 
-    allot 1500 prio 5 bounded isolated+# |-- 1:1 INTERNET->LAN (downlink) 
 +# | `-- 10(red) Drop traffic as link approaches congestion 
 +# `-- 1:2 LAN->INTERNET (uplink) 
 +#   |-- 1:21: High priority 
 +#   | `-- 21: (sfq) 
 +#   |-- 1:22: Medium priority 
 +#   | `-- 22: (sfq) 
 +#   `-- 1:23: Low priority 
 +#     `-- 23: (sfq) Low priority
  
-High priority internet traffic +ROOT 
-tc class add dev $DEV parent 1:1 classid 1:10 cbq rate ${UPLINK}kbit \ +tc qdisc add dev $DEV root handle 1: htb
-   allot 1600 prio 1 avpkt 1000 +
-# .. and its actual queue that holds the packets +
-tc qdisc add dev $DEV parent 1:10 handle 10: sfq perturb 10+
  
 +    # LOCAL TRAFFIC
 +    tc class add dev $DEV parent 1: classid 1:ff htb \
 +        rate 100mbit \
 +        burst $((100/20))mbit \
 +        cburst $((100/20))mbit \
 +        prio 1
  
-# Default priority internet traffic, bulk transfers. +        # .. and its actual queue that holds the packets 
-tc class add dev $DEV parent 1:1 classid 1:20 cbq rate $((9*$UPLINK/10))kbit \ + tc qdisc add dev $DEV parent 1:ff handle ff: sfq perturb 10
-   allot 1600 prio 2 avpkt 1000 +
-# .. and its actual queue that holds the packets +
-tc qdisc add dev $DEV parent 1:20 handle 20: sfq perturb 10+
  
-Low priority traffic. +    INTERNET->LAN (downlink) 
-tc class add dev $DEV parent 1:classid 1:30 cbq rate $((8*$UPLINK/10))kbit \ +    tc class add dev $DEV parent 1: classid 1:1 htb \ 
-   allot 1600 prio 2 avpkt 1000 +        rate $(($DOWNLINK*$DOWNFACTOR))kbit \ 
-# .. and its actual queue that holds the packets +        ceil $(($DOWNLINK*$DOWNFACTOR))kbit \ 
-tc qdisc add dev $DEV parent 1:30 handle 30: sfq perturb 10+        burst $(($DOWNLINK*$DOWNFACTOR/20))kbit \ 
 +        cburst $(($DOWNLINK*$DOWNFACTOR/20))kbit \ 
 +        prio 10
  
-============================================================================= +        .. and its actual queue that holds the packets 
-LAN +        Note: All values are in BYTES. It doesn't seem to accept "kbit" 
-tc class add dev $DEV parent 1: classid 1:40 cbq rate 1000mbit +        # 
-    allot 1500 prio 5 borrow sharing +        # The burst calculation needs to be increased by one so as to avoid an  
-tc qdisc add dev $DEV parent 1:40 handle 40: sfq perturb 10+        # internal assert in the qdisc (seems our target and their min  
 +        # acceptable burst are one and the same) 
 +        tc qdisc add dev $DEV parent 1:1 handle 10red 
 +            limit $(($DOWNLINK*$DOWNFACTOR*1000/8)) \ 
 +            avpkt 1500 \ 
 +            burst $((($DOWNLINK*1000/8/20/1500)+1)) \ 
 +            min   $(($DOWNLINK*1000/8/20)) \ 
 +            max   $(($DOWNLINK*$DOWNFACTOR*1000/8)) \ 
 +            ecn \ 
 +            probability 1
  
-============================================================================= +    LAN->INTERNET (uplink) 
-# Filters+    tc class add dev $DEV parent 1: classid 1:2 htb \ 
 +        rate $(($UPLINK*$UPFACTOR))kbit \ 
 +        ceil $(($UPLINK*$UPFACTOR))kbit \ 
 +        burst $(($UPLINK/20))kbit \ 
 +        cburst $(($UPLINK/20))kbit \ 
 +        prio 20
  
-LAN traffic ----------------------------------------------------------------- +        High priority 
-tc filter add dev $DEV parent 1:0 protocol ip prio u32 +        tc class add dev $DEV parent 1:2 classid 1:21 htb 
-    match ip dst 192.168.0.0/16 flowid 1:40 +            rate $(($UPLINK*$UPFACTOR*4/6))kbit \ 
-tc filter add dev $DEV parent 1:0 protocol ip prio 1 u32 +            ceil $(($UPLINK*$UPFACTOR))kbit 
-    match ip dst 10.0.0.0/8 flowid 1:40 +            prio 0
-tc filter add dev $DEV parent 1:0 protocol ip prio 1 u32 \ +
-    match ip dst 172.16.0.0/12 flowid 1:40+
  
-Internet traffic ------------------------------------------------------------+        Medium priority 
 +        tc class add dev $DEV parent 1:2 classid 1:22 htb \ 
 +            rate $(($UPLINK*$UPFACTOR*2/6))kbit \ 
 +            ceil $(($UPLINK*$UPFACTOR))kbit \ 
 +            prio 1
  
-TOS Minimum Delay (ssh, NOT scp) in 1:10: +        Low priority 
-tc filter add dev $DEV parent 1:0 protocol ip prio 10 u32 +        tc class add dev $DEV parent 1:2 classid 1:23 htb 
-      match ip tos 0x10 0xff  flowid 1:10+            rate $(($UPLINK*$UPFACTOR*1/6))kbit \ 
 +            prio 2
  
-ICMP (ip protocol 1) in the interactive class 1:10 so we  +        .. and their actual queues that hold the packets 
-# can do measurements & impress our friends+        for ID in 21 22 23 
-tc filter add dev $DEV parent 1:0 protocol ip prio 11 u32 +        do 
-        match ip protocol 0xff flowid 1:10+            tc qdisc add dev $DEV parent 1:$ID handle $ID: sfq 
 +            ## tc qdisc add dev $DEV parent 1:$ID handle $ID: red 
 +            ##     limit $(($UPLINK*$UPFACTOR*1000/8)) \ 
 +            ##     avpkt 1500 \ 
 +            ##     burst $((($UPLINK*1000/8/20/1500)+1)) \ 
 +            ##     min   $(($UPLINK*1000/8/20)) \ 
 +            ##     max   $(($UPLINK*$UPFACTOR*1000/8)) \ 
 +            ##     ecn \ 
 +            ##     probability 1 
 +        done
  
-# pablo.iranzo@uv.es provided a patch for the MLDonkey system 
-# The MLDonkey uses small UDP packets for source propogation 
-# which floods the wondershaper out. 
-tc filter add dev $DEV parent 1:0 protocol ip prio 10 u32 \ 
-   match ip protocol 17 0xff \ 
-   match ip sport 4666 0xffff \ 
-   flowid 1:30  
  
-prioritize small packets (<64 bytes)+============================================================================= 
 +# Filters 
 +# =============================================================================
  
-tc filter add dev $DEV parent 1: protocol ip prio 12 u32 \ +# ----------------------------------------------------------------------------- 
-   match ip protocol 6 0xff \ +# LOCAL TRAFFIC 
-   match u8 0x05 0x0f at 0 \ +# Mark traffic generated by this host itself (INPUT + OUTPUT, but not FORWARD) 
-   match u16 0x0000 0xffc0 at 2 \ +iptables -t mangle -A INPUT  -p all -i $DEV -j MARK --set-mark 0xff 
-   flowid 1:10+iptables -t mangle -A OUTPUT -p all -o $DEV -j MARK --set-mark 0xff
  
 +# ("fw" means the handle refers to a MARK, rather than a qdisc)
 +tc filter add dev $DEV parent 1: protocol ip prio 1 handle 0xff fw classid 1:ff
  
-#for a in $NOPRIOPORTDST +----------------------------------------------------------------------------- 
-#do +INTERNET->LAN (downlink)
-# tc filter add dev $DEV parent 1: protocol ip prio 14 u32 \ +
-#    match ip dport $a 0xffff flowid 1:30 +
-#done+
 # #
-#for a in $NOPRIOPORTSRC +Note: We assume that LAN->LAN traffic is *not* forwarded through this host,  
-#do +and so we need only check the destination of a given packet. We've already  
- tc filter add dev $DEV parent 1: protocol ip prio 15 u32 \ +taken care of this host's own traffic above. 
-#    match ip sport $a 0xffff flowid 1:30 + 
-#done+iptables -t mangle -N DOWNLINK 
 +iptables -t mangle -A DOWNLINK -p all -j MARK --set-mark 0x1 
 +tc filter add dev $DEV parent 1: protocol ip prio 2 handle 0x1 fw classid 1:1 
 + 
 +for SUBNET in 192.168.0.0/16 10.0.0.0/8 172.16.0.0/12  
 +do 
 +    iptables -t mangle -A PREROUTING -p all -i $DEV ! -s $SUBNET -d $SUBNET -j DOWNLINK 
 +done 
 + 
 + 
 +# ----------------------------------------------------------------------------- 
 +# LAN->INTERNET (uplink)
 # #
-#for a in $NOPRIOHOSTSRC +Note: Assumes that all downlink and private traffic have already been  
-#do +classified, so no source checks are performed. 
-# tc filter add dev $DEV parent 1: protocol ip prio 16 u32 \ + 
-#    match ip src $a flowid 1:30 +iptables -t mangle -N UPLINK 
-#done +iptables -t mangle -A UPLINK -p all -j MARK --set-mark 0x22     Default to medium priority 
-+#for CHAIN in PREROUTING INPUT FORWARD OUTPUT POSTROUTING DOWNLINK UPLINK
-#for in $NOPRIOHOSTDST+
 #do #do
- tc filter add dev $DEV parent 1: protocol ip prio 17 u32 \ +   iptables -t mangle -I $CHAIN -p tcp --sport 12345 -j MARK --set-mark 0/0 
-#    match ip dst $a flowid 1:30+#    iptables -t mangle -I $CHAIN -p tcp --dport 12345 -j MARK --set-mark 0/0
 #done #done
  
-# Internet traffic catch-all: bulk. +for SUBNET in 192.168.0.0/16 10.0.0.0/8 172.16.0.0/12  
-tc filter add dev $DEV parent 1: protocol ip prio 18 u32 \ +do 
-   match ip dst 0.0.0.0/flowid 1:20+    iptables -t mangle -A PREROUTING -p all -i $DEV -s $SUBNET ! -d $SUBNET -j UPLINK 
 +done
  
 +##
 +## HIGH PRIORITY ##
 +##
  
-############################################################################### +TOS Minimum Delay (ssh, NOT scp) 
-# DOWNLINK +tc filter add dev $DEV parent 1: protocol ip prio 20 u32 \ 
-+    match ip tos 0x10 0xff \ 
-# Limit downloads to slightly less than the maximum achievable speed. This  +    flowid 1:21
-# prevents a queues building up in the ISP (which is typically a huge FIFO),  +
-# and so reduces round-trip time; effectively reducing latency.+
  
-Ingress policer +ICMP (ip protocol 1) in the interactive class so we can do measurements &  
-(FYI: The term "shaping" only applied to egress traffic, "policing" is the  +impress our friends: 
-ingress equivalent)+tc filter add dev $DEV parent 1: protocol ip prio 20 u32 \ 
 +    match ip protocol 1 0xff \ 
 +    flowid 1:21
  
-tc qdisc add dev $DEV handle ffffingress+# Prioritize small packets (<64 bytes) 
 +tc filter add dev $DEV parent 1protocol ip prio 20 u32 \ 
 +    match ip protocol 6 0xff \ 
 +    match u8 0x05 0x0f at 0 \ 
 +    match u16 0x0000 0xffc0 at 2 \ 
 +    flowid 1:21
  
-LAN traffic is exempt from policing +Prioritise ACK packets (but only if they are small) 
-tc filter add dev $DEV parent ffff: protocol ip prio 40 u32 \ +# IP protocol 6, 
-    match ip src 192.168.0.0/16 \ +# IP header length 0x5(32 bit words), 
-    police pass \ +# IP Total length 0x34 (ACK + 12 bytes of TCP options) 
-    flowid :1 +# TCP ack set (bit 5, offset 33) 
-tc filter add dev $DEV parent ffff: protocol ip prio 40 u32 \ +tc filter add dev $DEV parent 1: protocol ip prio 20 u32 \ 
-    match ip src 10.0.0.0/+    match ip protocol 6 0xff 
-    police pass +    match u8 0x05 0x0f at 0 
-    flowid :1 +    match u16 0x0000 0xffc0 at 2 
-tc filter add dev $DEV parent ffff: protocol ip prio 40 u32 +    match u8 0x10 0xff at 33 
-    match ip src 172.16.0.0/12 \ +    flowid 1:21
-    police pass +
-    flowid :1+
  
-Internet traffic that arrives too fast should be discarded +Traffic headed to robmeerman.co.uk (typically SSH proxying to else where) 
-tc filter add dev $DEV parent ffff: protocol ip prio 50 u32 \ +tc filter add dev $DEV parent 1: protocol ip prio 20 u32 \ 
-    match ip src 0.0.0.0/0 \ +    match ip dst 85.119.82.218/32 
-    police rate ${DOWNLINK}kbit burst 10k drop +    flowid 1:21
-    flowid :+
-</code>+
  
 +# Traffic originating from the Xbox should be treated as urgent
 +tc filter add dev $DEV parent 1: protocol ip prio 20 u32 \
 +    match ip src 192.168.1.2/32 \
 +    flowid 1:21
 +
 +
 +##
 +## LOW PRIORITY ##
 +##
 +
 +# # WiiU, while it's downloading purchases
 +# tc filter add dev $DEV parent 1: protocol ip prio 30 u32 \
 +#     match ip src 192.168.1.5/32 \
 +#     flowid 1:23
 +
 +# TOS High Throughput
 +tc filter add dev $DEV parent 1: protocol ip prio 30 u32 \
 +    match ip tos 0x8 0xff \
 +    flowid 1:23
 +
 +# If no other filter has classified the packet, then use FW markers (set by 
 +# iptables -j MARK). All UPLINK packets are marked as 0x22 by default (see 
 +# iptables command earlier)
 +tc filter add dev $DEV parent 1: protocol ip prio 40 handle 0x21 fw classid 1:21 # High priority
 +tc filter add dev $DEV parent 1: protocol ip prio 40 handle 0x22 fw classid 1:22 # Medium priority
 +tc filter add dev $DEV parent 1: protocol ip prio 40 handle 0x23 fw classid 1:23 # Low priority
 +
 +
 +# Reset counters, so that packet counts are in sync (it takes time to add 
 +# rules, and during that time the first rule added may be hit, leading to 
 +# confusing packet counts: "But these rules should always apply to the same 
 +# packets! How can their hit count be different?"
 +iptables -t mangle -Z
 +</code>
 ==== Transparent Web Proxy ==== ==== Transparent Web Proxy ====
  
Line 485: Line 589:
  
 ==== My Solution ==== ==== My Solution ====
-I use WinXP on my laptop, and happened to have a copy of [[http://www.vmware.com/|VMware]]((A "PC Emulator", it creates a blank virtual PC for you to do what you like with.)) installed so I setup a new virtual machine with two NICs and inserted my trusty [[http://www.knoppix.org/|Knoppix Linux LiveCD]]((This is a bootable copy of Debian Linux, which is famous for having a complete toolset and great hardware auto-detection)). Once booted I used the [[http://www.tldp.org/HOWTO/IP-Masquerade-HOWTO/index.html|Linux IP Masquerade HOWTO]] to get things going.+I use WinXP on my laptop, and happened to have a copy of [[http://www.vmware.com/|VMware]]((A "PC Emulator", it creates a blank virtual PC for you to do what you like with.)) installed so I setup a new virtual machine with two NICs and inserted my trusty [[http://www.knopper.net/knoppix/index-en.html|Knoppix Linux LiveCD]]((This is a bootable copy of Debian Linux, which is famous for having a complete toolset and great hardware auto-detection)). Once booted I used the [[http://www.tldp.org/HOWTO/IP-Masquerade-HOWTO/index.html|Linux IP Masquerade HOWTO]] to get things going.
  
 Amazingly, this worked! I had 3 IPs on one NIC: 2 for the virtual machine running Knoppix, and 1 for Windows itself. Actually, IIRC, all 3 actually had seperate MAC addresses too. Amazingly, this worked! I had 3 IPs on one NIC: 2 for the virtual machine running Knoppix, and 1 for Windows itself. Actually, IIRC, all 3 actually had seperate MAC addresses too.
unix/gateway.1381667531.txt.gz · Last modified: 2013/10/13 12:32 by robm