This shows you the differences between two versions of the page.
Both sides previous revision Previous revision Next revision | Previous revision | ||
unix:gateway [2010/05/16 20:32] robm +DNS caching / redirecting of WAN domains |
unix:gateway [2018/10/04 14:37] (current) robm Update link to Knoppix |
||
---|---|---|---|
Line 21: | Line 21: | ||
node [shape=record] | node [shape=record] | ||
modem [label=" | modem [label=" | ||
- | gateway [label=" | + | gateway [label=" |
switch [label=" | switch [label=" | ||
} | } | ||
Line 31: | Line 31: | ||
modem: | modem: | ||
lan -> switch | lan -> switch | ||
- | switch -> gateway:lan:w | + | switch -> gateway:eth0:w |
- | 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 63: | Line 62: | ||
subgraph cluster_gateway_pc | subgraph cluster_gateway_pc | ||
{ | { | ||
- | gateway_pc [shape=record, | + | gateway_pc [shape=record, |
label=" | label=" | ||
} | } | ||
Line 73: | Line 72: | ||
{ | { | ||
edge [arrowhead=none] | edge [arrowhead=none] | ||
- | internet -> gateway_modem: | + | internet -> gateway_modem: |
- | gateway_modem: | + | gateway_modem: |
- | gateway_pc:lan -> lan [label=" | + | gateway_pc:eth0 -> lan [label=" |
- | gateway_modem: | + | gateway_modem: |
} | } | ||
Line 86: | Line 85: | ||
- PC broadcasts via DHCP for an IP address | - PC broadcasts via DHCP for an IP address | ||
- Modem (LAN, 192.168.1.1) responds with an IP address + static settings | - Modem (LAN, 192.168.1.1) responds with an IP address + static settings | ||
- | * Gateway IP = Gateway (eth1, 192.168.1.2) | + | * Gateway IP = Gateway (eth0, 192.168.1.2) |
- | * Primary DNS = Gateway (eth1, 192.168.1.2) | + | * Primary DNS = Gateway (eth0, 192.168.1.2) |
* Secondary DNS = Modem (LAN, 192.168.1.1) | * Secondary DNS = Modem (LAN, 192.168.1.1) | ||
- User of PC starts to browse example.com | - User of PC starts to browse example.com | ||
- PC queries Gateway (eth1) for IP of example.com (1.2.3.4) | - PC queries Gateway (eth1) for IP of example.com (1.2.3.4) | ||
* If Gateway' | * If Gateway' | ||
- | - PC connects to example.com (1.2.3.4) via Gateway (eth1, 192.168.1.2) | + | - PC connects to example.com (1.2.3.4) via Gateway (eth0, 192.168.1.2) |
- Gateway applies traffic shaping | - Gateway applies traffic shaping | ||
- | - Gateway | + | - Gateway forwards the shaped traffic to Modem (LAN) |
- Modem (WAN) forwards connection to ISP | - Modem (WAN) forwards connection to ISP | ||
- ISP do their thing | - ISP do their thing | ||
- ISP sends response to Modem (WAN) | - ISP sends response to Modem (WAN) | ||
- | - Modem (LAN) forwards response to Gateway | + | - Modem (LAN) forwards response to Gateway |
- | - Gateway | + | - Gateway applies traffic shaping and forwards response to PC |
===== Configuration ===== | ===== Configuration ===== | ||
Line 164: | Line 163: | ||
Kernel IP routing table | Kernel IP routing table | ||
Destination | Destination | ||
- | 192.168.1.1 | + | 192.168.1.0 |
- | 192.168.1.0 | + | |
0.0.0.0 | 0.0.0.0 | ||
</ | </ | ||
Important features: | Important features: | ||
- | | + | * All LAN traffic goes via '' |
- | | + | |
* The rest (internet traffic) should be forwarded through 192.168.1.1 (Modem LAN) | * The rest (internet traffic) should be forwarded through 192.168.1.1 (Modem LAN) | ||
Line 181: | Line 178: | ||
</ | </ | ||
- | {{:unix: | + | Configuration files to edit: |
+ | |||
+ | ''/ | ||
+ | < | ||
+ | option rfc3442-classless-static-routes code 121 = array of unsigned integer 8; | ||
+ | |||
+ | send host-name "< | ||
+ | send dhcp-requested-address 192.168.1.2; | ||
+ | supersede domain-name "local robmeerman.co.uk"; | ||
+ | supersede routers 192.168.1.1; | ||
+ | prepend domain-name-servers 127.0.0.1; | ||
+ | |||
+ | request subnet-mask, | ||
+ | domain-name, | ||
+ | netbios-name-servers, | ||
+ | rfc3442-classless-static-routes, | ||
+ | </ | ||
- | {{: | ||
==== IP Forwarding and NAT ==== | ==== IP Forwarding and NAT ==== | ||
Line 191: | Line 203: | ||
<code sh> | <code sh> | ||
- | # Unnessary? | ||
- | #iptables –flush | ||
- | #iptables –table nat –flush | ||
- | #iptables –delete-chain | ||
- | #iptables –table nat –delete-chain | ||
- | # | ||
- | ##Setup IP forwarding and masquerating.. | ||
- | #iptables –table nat –append POSTROUTING –out-interface eth0 -j MASQUERADE | ||
- | #iptables –append FORWARD –in-interface eth0 -j ACCEPT | ||
- | |||
echo 1 > / | echo 1 > / | ||
</ | </ | ||
Line 212: | Line 214: | ||
</ | </ | ||
+ | === Disabling ICMP Host Redirection === | ||
+ | |||
+ | As you probably noticed from the physical topology diagram, there is only one network interface on the gateway PC, and so you may find that the gateway PC informs all of its clients that they can talk to the modem directly: | ||
+ | |||
+ | < | ||
+ | PING google.com (173.194.37.104) 56(84) bytes of data. | ||
+ | From skuld.local (192.168.1.2): | ||
+ | 64 bytes from lhr14s02-in-f104.1e100.net (173.194.37.104): | ||
+ | </ | ||
+ | |||
+ | This can be disabled on-the-fly via: | ||
+ | |||
+ | < | ||
+ | echo 0 | sudo tee / | ||
+ | echo 0 | sudo tee / | ||
+ | </ | ||
+ | |||
+ | **Update 2013-10:** This guide used to update ''/ | ||
+ | |||
+ | Or permanently by adding the following to ''/ | ||
+ | |||
+ | < | ||
+ | net/ | ||
+ | net/ | ||
+ | net/ | ||
+ | net/ | ||
+ | </ | ||
+ | |||
+ | See http:// | ||
==== DNS Service ==== | ==== DNS Service ==== | ||
< | < | ||
Line 224: | Line 255: | ||
</ | </ | ||
* '' | * '' | ||
- | - Alias '' | + | - Alias '' |
* '' | * '' | ||
* < | * < | ||
Line 259: | Line 290: | ||
sudo wondershaper eth0 $((3712*1000)) $((448*1000)) | sudo wondershaper eth0 $((3712*1000)) $((448*1000)) | ||
</ | </ | ||
+ | |||
+ | I used to use Ubuntu' | ||
+ | |||
+ | See my ADSL project on GitHub: https:// | ||
+ | |||
+ | <code bash wondershaper> | ||
+ | #!/bin/bash -e | ||
+ | |||
+ | # Adapted from http:// | ||
+ | |||
+ | DEV=$1 | ||
+ | DOWNLINK=$2 | ||
+ | UPLINK=$3 | ||
+ | |||
+ | # 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 [ " | ||
+ | then | ||
+ | echo " | ||
+ | exit 0 | ||
+ | fi | ||
+ | |||
+ | # Display status when DOWNLINK/ | ||
+ | if [ " | ||
+ | then | ||
+ | #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 | ||
+ | exit 0 | ||
+ | fi | ||
+ | |||
+ | # Clear both IN and OUT | ||
+ | tc qdisc del dev $DEV root 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 [ " | ||
+ | then | ||
+ | echo " | ||
+ | exit 0 | ||
+ | fi | ||
+ | |||
+ | trap "$0 $1 clear" ERR | ||
+ | |||
+ | # Calculations | ||
+ | # | ||
+ | # Target latency is < 50ms. This means max burst length should be limited to | ||
+ | # 1/20th the queue' | ||
+ | |||
+ | |||
+ | LOCALIP=$(ifconfig eth0 | sed -ne ' | ||
+ | |||
+ | # ============================================================================= | ||
+ | # Queues and Classes | ||
+ | # ============================================================================= | ||
+ | # 1: ROOT | ||
+ | # |-- 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 | ||
+ | |||
+ | # ROOT | ||
+ | tc qdisc add dev $DEV root handle 1: htb | ||
+ | |||
+ | # LOCAL TRAFFIC | ||
+ | tc class add dev $DEV parent 1: classid 1:ff htb \ | ||
+ | rate 100mbit \ | ||
+ | burst $((100/ | ||
+ | cburst $((100/ | ||
+ | prio 1 | ||
+ | |||
+ | # .. and its actual queue that holds the packets | ||
+ | tc qdisc add dev $DEV parent 1:ff handle ff: sfq perturb 10 | ||
+ | |||
+ | # INTERNET-> | ||
+ | tc class add dev $DEV parent 1: classid 1:1 htb \ | ||
+ | rate $(($DOWNLINK*$DOWNFACTOR))kbit \ | ||
+ | ceil $(($DOWNLINK*$DOWNFACTOR))kbit \ | ||
+ | burst $(($DOWNLINK*$DOWNFACTOR/ | ||
+ | cburst $(($DOWNLINK*$DOWNFACTOR/ | ||
+ | prio 10 | ||
+ | |||
+ | # .. and its actual queue that holds the packets | ||
+ | # Note: All values are in BYTES. It doesn' | ||
+ | # | ||
+ | # The burst calculation needs to be increased by one so as to avoid an | ||
+ | # 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 10: red \ | ||
+ | limit $(($DOWNLINK*$DOWNFACTOR*1000/ | ||
+ | avpkt 1500 \ | ||
+ | burst $((($DOWNLINK*1000/ | ||
+ | min | ||
+ | max | ||
+ | ecn \ | ||
+ | probability 1 | ||
+ | |||
+ | # LAN-> | ||
+ | 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 | ||
+ | |||
+ | # High priority | ||
+ | tc class add dev $DEV parent 1:2 classid 1:21 htb \ | ||
+ | rate $(($UPLINK*$UPFACTOR*4/ | ||
+ | ceil $(($UPLINK*$UPFACTOR))kbit \ | ||
+ | prio 0 | ||
+ | |||
+ | # Medium priority | ||
+ | tc class add dev $DEV parent 1:2 classid 1:22 htb \ | ||
+ | rate $(($UPLINK*$UPFACTOR*2/ | ||
+ | ceil $(($UPLINK*$UPFACTOR))kbit \ | ||
+ | prio 1 | ||
+ | |||
+ | # Low priority | ||
+ | tc class add dev $DEV parent 1:2 classid 1:23 htb \ | ||
+ | rate $(($UPLINK*$UPFACTOR*1/ | ||
+ | prio 2 | ||
+ | |||
+ | # .. and their actual queues that hold the packets | ||
+ | for ID in 21 22 23 | ||
+ | do | ||
+ | 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/ | ||
+ | ## avpkt 1500 \ | ||
+ | ## burst $((($UPLINK*1000/ | ||
+ | ## | ||
+ | ## | ||
+ | ## ecn \ | ||
+ | ## | ||
+ | done | ||
+ | |||
+ | |||
+ | # ============================================================================= | ||
+ | # Filters | ||
+ | # ============================================================================= | ||
+ | |||
+ | # ----------------------------------------------------------------------------- | ||
+ | # LOCAL TRAFFIC | ||
+ | # Mark traffic generated by this host itself (INPUT + OUTPUT, but not FORWARD) | ||
+ | iptables -t mangle -A INPUT -p all -i $DEV -j MARK --set-mark 0xff | ||
+ | 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 | ||
+ | |||
+ | # ----------------------------------------------------------------------------- | ||
+ | # INTERNET-> | ||
+ | # | ||
+ | # Note: We assume that LAN->LAN traffic is *not* forwarded through this host, | ||
+ | # and so we need only check the destination of a given packet. We've already | ||
+ | # taken care of this host's own traffic above. | ||
+ | |||
+ | 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 | ||
+ | iptables -t mangle -A PREROUTING -p all -i $DEV ! -s $SUBNET -d $SUBNET -j DOWNLINK | ||
+ | done | ||
+ | |||
+ | |||
+ | # ----------------------------------------------------------------------------- | ||
+ | # LAN-> | ||
+ | # | ||
+ | # 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 | ||
+ | # iptables -t mangle -I $CHAIN -p tcp --sport 12345 -j MARK --set-mark 0/0 | ||
+ | # iptables -t mangle -I $CHAIN -p tcp --dport 12345 -j MARK --set-mark 0/0 | ||
+ | #done | ||
+ | |||
+ | for SUBNET in 192.168.0.0/ | ||
+ | do | ||
+ | iptables -t mangle -A PREROUTING -p all -i $DEV -s $SUBNET ! -d $SUBNET -j UPLINK | ||
+ | done | ||
+ | |||
+ | ## | ||
+ | ## HIGH PRIORITY ## | ||
+ | ## | ||
+ | |||
+ | # TOS Minimum Delay (ssh, NOT scp) | ||
+ | tc filter add dev $DEV parent 1: protocol ip prio 20 u32 \ | ||
+ | match ip tos 0x10 0xff \ | ||
+ | flowid 1:21 | ||
+ | |||
+ | # ICMP (ip protocol 1) in the interactive class so we can do measurements & | ||
+ | # impress our friends: | ||
+ | tc filter add dev $DEV parent 1: protocol ip prio 20 u32 \ | ||
+ | match ip protocol 1 0xff \ | ||
+ | flowid 1:21 | ||
+ | |||
+ | # Prioritize small packets (<64 bytes) | ||
+ | tc filter add dev $DEV parent 1: protocol ip prio 20 u32 \ | ||
+ | match ip protocol 6 0xff \ | ||
+ | match u8 0x05 0x0f at 0 \ | ||
+ | match u16 0x0000 0xffc0 at 2 \ | ||
+ | flowid 1:21 | ||
+ | |||
+ | # Prioritise ACK packets (but only if they are small) | ||
+ | # IP protocol 6, | ||
+ | # 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 1: protocol ip prio 20 u32 \ | ||
+ | match ip protocol 6 0xff \ | ||
+ | match u8 0x05 0x0f at 0 \ | ||
+ | match u16 0x0000 0xffc0 at 2 \ | ||
+ | match u8 0x10 0xff at 33 \ | ||
+ | flowid 1:21 | ||
+ | |||
+ | # Traffic headed to robmeerman.co.uk (typically SSH proxying to else where) | ||
+ | tc filter add dev $DEV parent 1: protocol ip prio 20 u32 \ | ||
+ | match ip dst 85.119.82.218/ | ||
+ | flowid 1:21 | ||
+ | |||
+ | # 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 ==== | ||
+ | |||
+ | < | ||
+ | |||
+ | Then edit ''/ | ||
+ | - the '' | ||
+ | - the '' | ||
+ | |||
+ | Restart Squid ('' | ||
+ | |||
+ | < | ||
===== The 1 NIC problem ===== | ===== The 1 NIC problem ===== | ||
Line 264: | 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. |