Friday, 27 November 2020

Connecting with my parents

I have installed a Raspberry Pi Zero at my parents' house in the summer to connect our LAN networks better. One particular use case is streaming at my parents' house via my broadband access. For this reason, I have dynamic DNS and PiVPN with WireGuard on the Raspberry Pi 1 at our house. This enables the use case for hosts that can install a WireGuard client. For hosts that can not install WireGuard client like Chromecast, the need emerges to build a small island at my parents' house with complete DHCP/WiFi infrastructure connected to the Internet via my broadband access. I used a small USB WiFi stick plugged into the USB hub with Ethernet that is connected to the Raspberry Pi Zero at my parents' house. Using this USB WiFi stick as an access point with hostapd and running dnsmasq for DHCP, I could build the basic infrastructure.

pi@pi0:~ $ sudo apt install hostapd
pi@pi0:~ $ sudo systemctl unmask hostapd
pi@pi0:~ $ sudo systemctl enable hostapd
pi@pi0:~ $ sudo nano /etc/hostapd/hostapd.conf
country_code=HU
interface=wlan0
ssid=ralink
hw_mode=g
channel=1
macaddr_acl=0
auth_algs=1
ignore_broadcast_ssid=0
wpa=2
wpa_passphrase=*****************
wpa_key_mgmt=WPA-PSK
wpa_pairwise=TKIP
rsn_pairwise=CCMP
pi@pi0:~ $ sudo rfkill unblock wlan
pi@pi0:~ $ sudo nano /etc/dhcpcd.conf
interface wlan0
static ip_address=192.168.3.1/24
nohook wpa_supplicant
pi@pi0:~ $ sudo apt install dnsmasq
pi@pi0:~ $ sudo nano /etc/dnsmasq.conf
interface=wlan0
dhcp-range=192.168.3.2,192.168.3.20,255.255.255.0,24h
dhcp-option=6,8.8.8.8

As PiVPN on both sides were using conflicting IP addresses and WireGuard client can only be installed on Raspberry Pi OS based on Debian Buster with the hassle of backporting it from Debian Bullseye, I installed ZeroTier. For some reason, ZeroTier 1.6.1 does not install flawlessly on Raspberry Pi Zero so I had to make them from the git repository.

UPDATE

ZeroTier 1.6.2-2 now installs flawlessly on both Raspberry Pi Zero.

UPDATE 2

It turned out that Raspberry Pi 1 700 MHz CPU could not cope hairpin streaming with ZeroTier. Please note that hairpin streaming with WireGuard might be a working option even on Raspberry Pi 1 but it seems to be a hassle to backport WireGuard client from Debian Bullseye. Fortunately, I had an unused Raspberry Pi Zero W lying around as the only aerial position that provides good enough signal to its DVB-T hat is from my daughters' window upstairs and she refused to keep the window slightly open all day long for permanent installation. So instead of trying to move the setup over to WireGuard on Raspberry Pi 1 that has a lot of other duties anyway in my home, I gave this Raspberry Pi Zero W a try. It turned out that 1 GHz CPU clock speed is just enough for hairpin streaming with zerotier.

The resulting and relevant IP configuration with ASCII diagram is as follows:

pi@pi0w:~ $ ip a
wlan0: inet 192.168.1.10/24
zt5u4vfg76: inet 192.168.193.236/24

pi@pi0:~ $ ip a
eth0: inet 192.168.8.151/24
zt5u4vfg76: inet 192.168.193.79/24
wlan0: 192.168.3.1/24

wlan0 zt5u4vfg76 zt5u4vfg76 eth0
  |  ----------------------  |
  | |                      | |
 ------                   -----
| pi0w |                 | pi0 |
 ------                   -----
                           |
                           |/|
                             |
                          wlan0

The trickiest part of the routing is to direct the traffic from the small island DHCP/WiFi infrastructure into the ZeroTier link instead of the default route. I use a source-based rule with a separate routing table for this as follows, starting with enabling routing on both sides:

pi@pi0w:~ $ sudo nano /etc/sysctl.d/routed-ap.conf
net.ipv4.ip_forward=1

pi@pi0:~ $ sudo nano /etc/sysctl.d/routed-ap.conf
net.ipv4.ip_forward=1

pi@pi0:~ $ sudo nano /lib/dhcpcd/dhcpcd-hooks/40-route
/sbin/ip rule add from 192.168.3.0/24 table 1
/sbin/ip route add 192.168.3.0/24 via 192.168.3.1 table 1 
/sbin/ip route add default via 192.168.193.236 table 1

On my side of the ZeroTier link, I used NAT as follows:

pi@pi0w:~ $ sudo iptables -t nat -I POSTROUTING -j MASQUERADE
pi@pi0w:~ $ sudo iptables-save -f /etc/iptables.rules
pi@pi0w:~ $ sudo nano /etc/rc.local
iptables-restore /etc/iptables.rules

For static route for reverse traffic I used advanced manage route function on zero tier as follows:




To make this configuration persistent, I saved iptables rules and added ip commands to dhcpcd hooks.
The connection can be tested with tcpdump as follows:

pi@pi0w:~ $ sudo tcpdump -i zt5u4vfg76 net 192.168.3.0/24

UPDATE after 4 years

jordana@pi4g:~ $ sudo nano /etc/rc.local
#!/bin/bash
iptables-restore /etc/iptables.rules
jordana@pi4g:~ $ sudo chmod +x /etc/rc.local
jordana@pi4g:~ $ sudo reboot
jordana@pi4g:~ $ journalctl -b | grep rc.local
Dec 23 09:23:29 pi4g systemd[1]: Starting rc-local.service - /etc/rc.local Compatibility...
Dec 23 09:23:29 pi4g systemd[1]: Started rc-local.service - /etc/rc.local Compatibility.