====== VPN via Raspberry Pi 4 ======
* Use a Raspberry Pi 4 (B) as WiFi access point
* Home network (and internet connection) attached via Ethernet cable
* Pi will run ExpressVPN
===== Disassociate WiFi =====
In order to use the WiFi chipset as an access point, we need default Raspberry Pi desktop environment (etc) from using it as a client.
One-off:
sudo wpa_cli terminate
Forever: Disabling the service permanently is tricky, as lots of events can cause it to be started. A better solution is to exclude ''wlan0'' from being managed by it, by adding ''nohook wpa_supplicant'' to ''/etc/network/interfaces.d/wlan0'' (created in the next section).
===== Configure WiFi settings =====
Create ''/etc/network/interfaces.d/wlan0'' and populate it with:
auto wlan0
iface wlan0 inet static
address 172.16.0.1/24
nohook wpa_supplicant # Conflicts with hostapd (WPA is for clients, not access points)
Note the IP address has to be in the same range as ''--dhcp-range'' in the following section on ''dnsmasq''.
sudo ifdown --verbose wlan0 # Take interface offline, so when we bring it back it uses our conf
sudo ifup --verbose wlan0
Check it has the IP you chose by running ''ip -br addr show wlan0'', e.g.:
root@raspberrypi4:~# ip -br addr show wlan0
wlan0 UP 172.16.0.1/24 169.254.114.246/16 fe80::3592:65db:94e0:c992/64
===== DHCP & DNS Services =====
Disable the default ''systemd-resolved'' service which runs on localhost, as it takes control of ''/etc/resolv.conf'', which in turn prevents the DHCP + DNS server we're about to install from noticing when expressvpn changes the DNS server.
It's important that ''dnsmasq'' notices when ''/etc/resolv.conf'' changes, or DNS lookups will fail entirely due to ExpressVPN adding firewall rules to drop all DNS queries that don't go via ExpressVPN.
sudo systemctl disable --now systemd-resolved
sudo apt update \
&& sudo apt install dnsmasq
Then test this in the foreground so you can see debug messages, etc
sudo systemctl stop dnsmasq \
&& sudo dnsmasq \
--no-daemon \
--dhcp-range=172.16.0.10,172.16.0.20,1h \
--except-interface=eth0 \
--dhcp-authoritative \
--log-queries \
--clear-on-reload
Later on, we'll want to move these settings into ''/etc/dnsmasq.conf''
===== WiFi Access Point =====
sudo apt update \
&& sudo apt install hostapd \
&& sudo vim /etc/default/hostapd
... and set ''DAEMON_CONF'' to point at a file we'll make in a moment:
DAEMON_CONF="/etc/hostapd/hostapd.conf"
Now create: ''/etc/hostapd/hostapd.conf''
sudo vim /etc/hostapd/hostapd.conf
Note that the country code has to be set to US for this to work. Something to do with regulatory issues about shipping "open" devices or something. Shrug.
(Taken from https://github.com/raspberrypi/linux/issues/2619#issuecomment-410703338 )
ctrl_interface=/var/run/hostapd
ctrl_interface_group=0
auth_algs=1
beacon_int=100
ssid=raspi-webgui
wpa_passphrase=ChangeMe
country_code=US
interface=wlan0
driver=nl80211
wpa=2
wpa_key_mgmt=WPA-PSK
wpa_pairwise=TKIP
rsn_pairwise=CCMP
macaddr_acl=0
logger_syslog=0
logger_syslog_level=4
logger_stdout=-1
logger_stdout_level=0
hw_mode=a
wmm_enabled=1
# N
ieee80211n=1
require_ht=1
ht_capab=[MAX-AMSDU-3839][HT40+][SHORT-GI-20][SHORT-GI-40][DSSS_CCK-40]
# AC
ieee80211ac=1
require_vht=1
ieee80211d=0
ieee80211h=0
vht_capab=[MAX-AMSDU-3839][SHORT-GI-80]
vht_oper_chwidth=1
channel=36
vht_oper_centr_freq_seg0_idx=42
ignore_broadcast_ssid=0
Test using the following command (so its all runs in the foreground and prints stuff you can read in case it doesn't work):
sudo systemctl stop hostapd # Stop the background service, if it was running
sudo hostapd -dd /etc/hostapd/hostapd.conf
Then try to connect from another device (e.g. mobile phone). The WiFi network should be visible, and when you connect you should get an IP address, but probably an error about no internet connection. That's next.
===== Network Address Translation =====
Enable Network Address Translation (NAT) on any traffic that leaves us via ExpressVPN's ''tun0'' interface.
Note that the interface doesn't exist until you run ''expressvpn connect'', but you can add the rule to ''iptables'' without issue.
iptables -t nat -A POSTROUTING -o tun0 -j MASQUERADE
Note that is this is the **only** MASQUERADE rule (check with ''iptables -t nat -nvL'') then devices using this access point will experience 100% packet loss when ExpressVPN is not connected. I consider this a feature, but if you don't you can add another rule for ''eth0'':
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE