2020-03-19T22:38:43

Not speed but latency is what you need.

A little how-to configure Raspberry-Pi as NAT gateway/router for the real speed.

Alternative title could be "Not strength but dexterity is what you need.", but I'll be writing about network performance, not a physical performance.

Let's clarify the "why". Make a test, take a bigger file you have on your disk and start uploading it to any service on the internet ftp/dropbox/file-share/scp/... or simply run a speed test and at the same time run ping to some near-by server, like for example `ping meon.eu`. Here an example at my home with 30Mbit download and 3Mbit upload cable connection:

$ ping meon.eu
PING meon.eu (116.202.1.201) 56(84) bytes of data.
64 bytes from float1.meon.eu (116.202.1.201): icmp_seq=1 ttl=51 time=20.3 ms
64 bytes from float1.meon.eu (116.202.1.201): icmp_seq=2 ttl=51 time=20.2 ms
64 bytes from float1.meon.eu (116.202.1.201): icmp_seq=3 ttl=51 time=21.7 ms
64 bytes from float1.meon.eu (116.202.1.201): icmp_seq=4 ttl=51 time=22.3 ms
#### here is when the upload started:
64 bytes from float1.meon.eu (116.202.1.201): icmp_seq=5 ttl=51 time=597 ms
64 bytes from float1.meon.eu (116.202.1.201): icmp_seq=6 ttl=51 time=625 ms
64 bytes from float1.meon.eu (116.202.1.201): icmp_seq=7 ttl=51 time=667 ms
64 bytes from float1.meon.eu (116.202.1.201): icmp_seq=8 ttl=51 time=699 ms
64 bytes from float1.meon.eu (116.202.1.201): icmp_seq=9 ttl=51 time=573 ms
^C
--- meon.eu ping statistics ---
9 packets transmitted, 9 received, 0% packet loss, time 8071ms
rtt min/avg/max/mdev = 20.265/360.874/699.015/305.716 ms

If you are gamer, you know that 500ms is matter of (virtual) life and dead, if you are a (normal) internet user, you for sure know that feeling of "this internet is so slow today"... Uploads or long downloads happen all the time. There are couple of phones and tables and computers connected to LAN all the time and they decide when ever they feel like to do backups (uploads) or to fetch fresh updates (downloads), both adding to the overall latency. This means that each request for any internet resource during that time is delayed by those 500ms, resulting page load times being in seconds, resulting in "slow internet" at random times. Internet providers will tell you to buy faster connectivity, but unless you get a 100+Mbit line you can still run into the same problem of latency spikes. In case you are in remote areas and/or connected by "radio" like 3G/LTE, you can get much higher latency with bigger transfers → 1.5s and more.

Now here is how the same scenario looks like with configured Linux traffic shaping:

$ ping meon.eu
PING meon.eu (116.202.1.201) 56(84) bytes of data.
64 bytes from float1.meon.eu (116.202.1.201): icmp_seq=1 ttl=51 time=21.0 ms
64 bytes from float1.meon.eu (116.202.1.201): icmp_seq=2 ttl=51 time=28.6 ms
64 bytes from float1.meon.eu (116.202.1.201): icmp_seq=3 ttl=51 time=23.4 ms
64 bytes from float1.meon.eu (116.202.1.201): icmp_seq=4 ttl=51 time=23.0 ms
#### here is when the same upload started:
64 bytes from float1.meon.eu (116.202.1.201): icmp_seq=5 ttl=51 time=25.7 ms
64 bytes from float1.meon.eu (116.202.1.201): icmp_seq=6 ttl=51 time=25.4 ms
64 bytes from float1.meon.eu (116.202.1.201): icmp_seq=7 ttl=51 time=22.9 ms
64 bytes from float1.meon.eu (116.202.1.201): icmp_seq=8 ttl=51 time=22.5 ms
64 bytes from float1.meon.eu (116.202.1.201): icmp_seq=9 ttl=51 time=23.7 ms
^C
--- meon.eu ping statistics ---
9 packets transmitted, 9 received, 0% packet loss, time 8012ms
rtt min/avg/max/mdev = 21.071/24.085/28.662/2.096 ms

# stats over a 1h period with 3 people at home working on their computers (yes it's corona virus time):
--- meon.eu ping statistics ---
3568 packets transmitted, 3568 received, 0% packet loss, time 3572148ms
rtt min/avg/max/mdev = 18.272/21.901/87.630/3.898 ms

Short how-to

Traffic shaping configuration for two interfaces - "eth0.7" public interface, outbound traffic is upload so it's set to 2.5Mbit from maximum 3Mbit and "br0" (eth0.100 + wlan0) which is the local LAN interface, outbound traffic is download so it's set to 25Mbit from maximum 30Mbit:

root@uli:~# cat /etc/network/if-up.d/tc
#!/bin/bash

# public interface -> upload
if [ "$IFACE" = "eth0.7" ]; then
    /sbin/tc qdisc add dev $IFACE root handle 2: htb default 20
    /sbin/tc class add dev $IFACE parent 2: classid 2:2 htb rate 3mbit burst 15k
    /sbin/tc class add dev $IFACE parent 2:2 classid 2:20 htb rate 2500kbit burst 15k
    /sbin/tc qdisc add dev $IFACE parent 2:20 handle 20: sfq perturb 10
fi

# private interface -> download
if [ "$IFACE" = "br0" ]; then
    /sbin/tc qdisc add dev $IFACE root handle 1: htb default 10
    /sbin/tc class add dev $IFACE parent 1: classid 1:1 htb rate 30mbit burst 15k
    /sbin/tc class add dev $IFACE parent 1:1 classid 1:10 htb rate 25mbit burst 15k
    /sbin/tc qdisc add dev $IFACE parent 1:10 handle 10: sfq perturb 10
fi

Full how-to

Let's start with a trick how to turn Raspberry Pi into a router/gateway. RPi is equipped with just one physical network interface, but using VLANs it's possible to have two required for full NAT and routing gateway.

Below a picture of cable Model (in bridge mode) + PoE+ Smart Switch (TPE-TG44ES) + patch pannel with cables going to upstairs rooms and smart switch configuration. Cable modem is plugged to port 8, RPi plugged to port 4, the rest of the ports is for LAN devices:

Here all the configuration changes required to make to default Raspbian Buster Lite image:

  • load Raspberian image on SD → `dd if=2020-02-13-raspbian-buster-lite.img of=/dev/mmcblk0 status=progress`
  • boot that image with internet access, then login and as root execute:
  • `apt-get update && apt-get install etckeeper screen vim iproute2 isc-dhcp-server bridge-utils hostapd ifstat bmon && apt-get remove dhcpcd5 && passwd root && passwd pi`
  • then shutdown again and update/replace following files:
    $ tree rpi-as-wifi-gateway-router
    rpi-as-wifi-gateway-router
    ├── boot
    │   └── ssh
    ├── etc
    │   ├── cron.d
    │   │   └── reboot-daily
    │   ├── default
    │   │   ├── crda
    │   │   ├── hostapd
    │   │   └── isc-dhcp-server
    │   ├── dhcp
    │   │   └── dhcpd.conf
    │   ├── firewall
    │   ├── hostapd.conf
    │   ├── hostname
    │   ├── hosts
    │   ├── network
    │   │   ├── if-up.d
    │   │   │   ├── firewall
    │   │   │   └── tc
    │   │   └── interfaces
    │   ├── screenrc
    │   ├── ssh
    │   │   └── sshd_config
    │   └── timezone
    └── root
    
    9 directories, 15 files
  • files that can be used as they are:
    • boot/ssh → empty file to start sshd, is on second partition (!)
    • etc/cron.d/reboot-daily → will reboot your router every day at 04:04
    • etc/default/crda → to set you region (`iw reg get`)
    • etc/default/hostapd → to enable hostapd to start
    • etc/default/isc-dhcp-server → to enable dhcpd server to start and set interface to br0
    • etc/dhcp/dhcpd.conf → dhcpd server config with 192.168.42.100-250 leases pool, 8.8.8.8/.4.4 dns servers
    • etc/firewall → iptables firewall with nat, ssh and ping allowed from WAN
    • etc/network/interfaces → eth0.7 as WAN with dhcp, the rest of port as eth.100 + wlan0 in br0 bridge
    • etc/network/if-up.d/firewall → NAT & firewall rules
    • etc/screenrc → startup_message off && vbell off
    • etc/ssh/sshd_config → PasswordAuthentication no
  • files that needs to be edited:
    • etc/hostname → a place for your creativity
    • etc/hosts → write hostname there
    • root/.ssh/authorized_keys → add your ssh key here so that you can log-in (ssh password authentication is off)
    • etc/timezone → Europe/Vienna
    • etc/hostapd.conf → wlan0 in AP mode with ssid CHANGE_ME and passphrase CHANGE_ME
    • etc/network/if-up.d/tc → traffic shaping, you need to change 30mbit+25mbit and 3mbit+2500kbit based on your connection speed
  • here all those files as tarball. Just copy/overwrite those into the root system and edit/adjust the ones mentioned above.