This shows you the differences between two versions of the page.
Both sides previous revision Previous revision Next revision | Previous revision | ||
unix:gateway [2013/10/13 11:53] robm [IP Forwarding and NAT] |
unix:gateway [2018/10/04 14:37] (current) robm Update link to Knoppix |
||
---|---|---|---|
Line 32: | Line 32: | ||
lan -> switch | lan -> switch | ||
switch -> gateway: | switch -> gateway: | ||
- | gateway: | ||
} | } | ||
Line 40: | Line 39: | ||
^ Device ^ Notes ^ | ^ Device ^ Notes ^ | ||
| modem | ADSL modem with 1x phone line socket and 1x ethernet socket. Tends to get clogged for some reason (high latency, but connection stays up) | | | modem | ADSL modem with 1x phone line socket and 1x ethernet socket. Tends to get clogged for some reason (high latency, but connection stays up) | | ||
- | | gateway | Fast desktop PC with two network | + | | gateway | Linux host with *one* network |
| LAN | 4 or so PCs, Wii, Xbox, couple of Nintendo DS consoles, etc | | | LAN | 4 or so PCs, Wii, Xbox, couple of Nintendo DS consoles, etc | | ||
Line 234: | Line 233: | ||
**Update 2013-10:** This guide used to update ''/ | **Update 2013-10:** This guide used to update ''/ | ||
- | Or permanently by adding the following to ''/ | + | Or permanently by adding the following to ''/ |
< | < | ||
net/ | net/ | ||
net/ | net/ | ||
+ | net/ | ||
+ | net/ | ||
</ | </ | ||
Line 291: | Line 293: | ||
I used to use Ubuntu' | I used to use Ubuntu' | ||
- | < | + | See my ADSL project on GitHub: https:// |
- | #!/bin/sh | + | |
+ | < | ||
+ | #!/bin/bash -e | ||
# Adapted from http:// | # Adapted from http:// | ||
+ | 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' | ||
+ | # 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=' | ||
+ | UPFACTOR=' | ||
if [ " | if [ " | ||
then | then | ||
- | echo " | + | echo " |
exit 0 | exit 0 | ||
fi | fi | ||
Line 309: | Line 322: | ||
if [ " | if [ " | ||
then | then | ||
- | tc -s qdisc ls dev $DEV | + | |
+ | #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 317: | 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 [ " | if [ " | ||
Line 324: | Line 349: | ||
fi | fi | ||
- | ############################################################################### | + | trap "$0 $1 clear" ERR |
- | # UPLINK | + | |
- | # Set root Queuing Discipline (qdisc) | + | # Calculations |
- | tc qdisc add dev $DEV root handle | + | # |
+ | # Target latency is < 50ms. This means max burst length should be limited | ||
+ | # 1/20th the queue' | ||
- | # Traffic is either headed to the gateway | + | |
- | # Internet uplink is scarse, so aggresively shape it. LAN uplink is plentiful, | + | LOCALIP=$(ifconfig eth0 | sed -ne 's/^.*inet addr:\([0-9.]\+\).*/ |
- | # do not restrict it. | + | |
# ============================================================================= | # ============================================================================= | ||
- | # INTERNET GATEWAY: Shape to $UPLINK speed, | + | # Queues and Classes |
- | # DSL modem that cause massive latency | + | # ============================================================================= |
- | tc class add dev $DEV parent | + | # 1: ROOT |
- | allot 1500 prio 5 bounded isolated | + | # |-- 1:ff LOCAL_TRAFFIC (to/from this host itself) |
+ | # | `-- ff: (sfq) | ||
+ | # |-- 1:1 INTERNET-> | ||
+ | # | `-- 10: (red) Drop traffic as link approaches congestion | ||
+ | # `-- 1:2 LAN-> | ||
+ | # |-- 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 |
- | allot 1600 prio 1 avpkt 1000 | + | |
- | # .. and its actual queue that holds the packets | + | |
- | tc qdisc add dev $DEV parent | + | |
+ | # LOCAL TRAFFIC | ||
+ | tc class add dev $DEV parent 1: classid 1:ff htb \ | ||
+ | rate 100mbit \ | ||
+ | burst $((100/ | ||
+ | cburst $((100/ | ||
+ | prio 1 | ||
- | # Default priority internet traffic, bulk transfers. | + | |
- | tc class add dev $DEV parent 1:1 classid 1:20 cbq rate $((9*$UPLINK/ | + | tc qdisc add dev $DEV parent 1:ff handle |
- | allot 1600 prio 2 avpkt 1000 | + | |
- | # .. and its actual queue that holds the packets | + | |
- | tc qdisc add dev $DEV parent 1:20 handle | + | |
- | # Low priority traffic. | + | |
- | tc class add dev $DEV parent 1: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 | + | |
- | # .. and its actual queue that holds the packets | + | ceil $(($DOWNLINK*$DOWNFACTOR))kbit \ |
- | tc qdisc add dev $DEV parent 1:30 handle 30: sfq perturb | + | burst $(($DOWNLINK*$DOWNFACTOR/ |
+ | | ||
+ | prio 10 | ||
- | # ============================================================================= | + | |
- | # LAN | + | # Note: All values are in BYTES. It doesn' |
- | tc class add dev $DEV parent 1: classid | + | # |
- | | + | # The burst calculation needs to be increased by one so as to avoid an |
- | tc qdisc add dev $DEV parent | + | # internal assert in the qdisc (seems our target and their min |
+ | # acceptable burst are one and the same) | ||
+ | | ||
+ | limit $(($DOWNLINK*$DOWNFACTOR*1000/ | ||
+ | avpkt 1500 \ | ||
+ | | ||
+ | min | ||
+ | max | ||
+ | ecn \ | ||
+ | probability | ||
- | # ============================================================================= | + | |
- | # Filters | + | tc class add dev $DEV parent 1: classid 1:2 htb \ |
+ | rate $(($UPLINK*$UPFACTOR))kbit \ | ||
+ | ceil $(($UPLINK*$UPFACTOR))kbit \ | ||
+ | burst $(($UPLINK/ | ||
+ | cburst $(($UPLINK/ | ||
+ | prio 20 | ||
- | # LAN traffic ----------------------------------------------------------------- | + | |
- | tc filter | + | tc class add dev $DEV parent 1:2 classid |
- | 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 \ | + | |
- | 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 ------------------------------------------------------------ | + | |
+ | tc class add dev $DEV parent 1:2 classid 1:22 htb \ | ||
+ | rate $(($UPLINK*$UPFACTOR*2/ | ||
+ | ceil $(($UPLINK*$UPFACTOR))kbit \ | ||
+ | prio 1 | ||
- | # TOS Minimum Delay (ssh, NOT scp) in 1:10: | + | |
- | tc filter | + | tc class add dev $DEV parent 1:2 classid 1:23 htb \ |
- | match ip tos 0x10 0xff flowid | + | rate $(($UPLINK*$UPFACTOR*1/6))kbit \ |
+ | prio 2 | ||
- | # ICMP (ip protocol 1) in the interactive class 1:10 so we | + | |
- | # can do measurements & impress our friends: | + | for ID in 21 22 23 |
- | tc filter | + | |
- | match ip protocol | + | tc qdisc add dev $DEV parent 1:$ID handle $ID: sfq |
+ | ## | ||
+ | ## | ||
+ | ## avpkt 1500 \ | ||
+ | ## burst $((($UPLINK*1000/ | ||
+ | ## | ||
+ | ## | ||
+ | ## ecn \ | ||
+ | ## | ||
+ | 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 \ | ||
- | | ||
- | # 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 |
- | | + | iptables -t mangle -A OUTPUT -p all -o $DEV -j MARK --set-mark 0xff |
+ | # (" | ||
+ | tc filter add dev $DEV parent 1: protocol ip prio 1 handle 0xff fw classid 1:ff | ||
- | #for a in $NOPRIOPORTDST | + | # ----------------------------------------------------------------------------- |
- | #do | + | # INTERNET-> |
- | # 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/ | ||
+ | do | ||
+ | | ||
+ | done | ||
+ | |||
+ | |||
+ | # ----------------------------------------------------------------------------- | ||
+ | # LAN-> | ||
# | # | ||
- | #for a in $NOPRIOHOSTSRC | + | # Note: Assumes that all downlink and private traffic have already been |
+ | # classified, so no source checks are performed. | ||
+ | |||
+ | iptables -t mangle -N UPLINK | ||
+ | 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 | ||
#do | #do | ||
- | # tc filter add dev $DEV parent 1: protocol ip prio 16 u32 \ | + | # |
- | # match ip src $a flowid 1:30 | + | # |
- | #done | + | |
- | # | + | |
- | #for a in $NOPRIOHOSTDST | + | |
- | #do | + | |
- | # tc filter add dev $DEV parent 1: protocol ip prio 17 u32 \ | + | |
- | # match ip dst $a flowid 1:30 | + | |
#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/ | + | 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 | + | |
- | # 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 " | + | # 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 ffff: ingress | + | # Prioritize small packets (<64 bytes) |
+ | tc filter | ||
+ | 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 protocol |
- | match ip src 192.168.0.0/ | + | # IP header length 0x5(32 bit words), |
- | | + | # IP Total length 0x34 (ACK + 12 bytes of TCP options) |
- | | + | # TCP ack set (bit 5, offset 33) |
- | tc filter add dev $DEV parent | + | tc filter add dev $DEV parent |
- | match ip src 10.0.0.0/ | + | match ip protocol 6 0xff \ |
- | | + | |
- | | + | |
- | 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/ | + | flowid |
- | 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 | + | tc filter add dev $DEV parent |
- | match ip src 0.0.0.0/0 \ | + | match ip dst 85.119.82.218/32 \ |
- | police rate ${DOWNLINK}kbit burst 10k drop \ | + | flowid |
- | flowid :1 | + | |
- | </ | + | |
+ | # 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/ | ||
+ | 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/ | ||
+ | # | ||
+ | |||
+ | # 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 | ||
+ | </ | ||
==== Transparent Web Proxy ==== | ==== Transparent Web Proxy ==== | ||
Line 483: | Line 589: | ||
==== My Solution ==== | ==== My Solution ==== | ||
- | I use WinXP on my laptop, and happened to have a copy of [[http:// | + | I use WinXP on my laptop, and happened to have a copy of [[http:// |
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. |