VPN Wi-Fi Hotspot with Raspberry Pi
TL;DR: I explain here how to setup a home Wi-Fi network, which routes all traffic through a VPN, using a Raspberry Pi.
No one wants to get tracked or sniffed while browsing. Even those, who "have nothing to hide".
One of the ways to hide your traffic is to use a VPN. But connecting and disconnecting to it can be annoying. So, I want to setup a home Wi-Fi network, and, when connected to it, to browse automatically through the VPN.
There are already many VPN providers out there, the goal of this post is not to compare them. We just need one, which supports OpenVPN.
Setup
Any Raspberry Pi OS will do. I recommend using the Lite version.
Some of the values are based on a home network 192.168.0.0/24
OpenVPN
Add to /etc/network/interfaces:
auto lo iface lo inet loopback auto eth0 allow-hotplug eth0 iface eth0 inet dhcp up route add -net 192.168.0.0 netmask 255.255.255.0 gw 192.168.0.1 metric 300
Add this to /etc/resolvconf.conf to disable DNS Leaks:
name_servers=1.1.1.1 name_servers_append=1.0.0.1 name_server_blacklist=192.168.0.1
Restart:
$ sudo reboot now
Make sure it works:
$ ping google.com
Install OpenVPN:
$ sudo apt-get install openvpn -y
Copy the .ovpn you get from your VPN provider to the Raspberry Pi and then copy it to the OpenVPN configuration:
$ sudo cp /path_to_ovpn/my_config.ovpn /etc/openvpn/ex.conf
Add your credentials in /etc/openvpn/login (each on a separate line):
<USERNAME> <PASSWORD>
and secure them:
$ chmod 600 /etc/openvpn/login
You are now ready to test the VPN:
$ sudo openvpn --config /etc/openvpn/ex.conf
(Ctrl-C to stop)
Enable the OpenVPN service to connect to the VPN on startup and restart:
$ sudo systemctl enable openvpn@ex
$ sudo reboot now
Check your IP address (to make sure you are connected):
$ curl icanhazip.com
Kill Switch
In case the VPN connection is dropped, you might want to block any access to
the Internet with your real IP address. This can be achieved with a "kill switch" - it
won't allow any Internet traffic outside of the VPN.
Allow loopback device (localhost):
$ sudo iptables -A INPUT -i lo -j ACCEPT $ sudo iptables -A OUTPUT -o lo -j ACCEPT
Allow all local traffic:
$ sudo iptables -A INPUT -s 192.168.0.0/24 -j ACCEPT $ sudo iptables -A OUTPUT -d 192.168.0.0/24 -j ACCEPT
Allow VPN establishment. Only 2 ports will be open - 1 for DNS and 1 for VPN:
$ sudo iptables -A OUTPUT -p udp --dport 53 -j ACCEPT $ sudo iptables -A INPUT -p udp --sport 53 -j ACCEPT $ sudo iptables -A OUTPUT -p udp --dport 1194 -j ACCEPT $ sudo iptables -A INPUT -p udp --sport 1194 -j ACCEPT
Accept all TUN connections (tun = VPN tunnel)
$ sudo iptables -A OUTPUT -o tun+ -j ACCEPT $ sudo iptables -A INPUT -i tun+ -j ACCEPT
Set default policies to drop all communication unless specifically allowed:
$ sudo iptables -P INPUT DROP $ sudo iptables -P OUTPUT DROP $ sudo iptables -P FORWARD DROP
Persist the iptables configuration after rebooting:
$ sudo apt-get install iptables-persistent -y && sudo netfilter-persistent save && sudo systemctl enable netfilter-persistent && sudo reboot now
(You will be asked to confirm this. Choose Yes for both IP4 and IP6.)
Test the kill switch - the ping should not work while the OpenVPN service is stopped:
$ sudo service openvpn stop $ ping google.com $ sudo service openvpn start $ ping google.com
Hot Spot
This basically turns your Raspberry Pi into a WiFi router. Install hostapd:
$ sudo apt install hostapd $ sudo systemctl unmask hostapd $ sudo systemctl enable hostapd
Install dnsmasq (for a dhcp server)
$ sudo apt install dnsmasq
Configure the wlan interface in /etc/network/interfaces. The Wi-Fi network will be 192.168.4.0/24.
auto wlan0 allow-hotplug wlan0 iface wlan0 inet static address 192.168.4.1 netmask 255.255.255.0
Enable IPv4 routing in /etc/sysctl.d/routed-ap.conf:
# https://www.raspberrypi.org/documentation/configuration/wireless/access-point-routed.md # Enable IPv4 routing net.ipv4.ip_forward=1
Allow forwarding in iptables:
$ sudo iptables -P FORWARD ACCEPT $ sudo iptables -A OUTPUT -p udp --dport 67 -j ACCEPT $ sudo iptables -A INPUT -p udp --sport 67 -j ACCEPT $ sudo iptables -A OUTPUT -p udp --dport 68 -j ACCEPT $ sudo iptables -A INPUT -p udp --sport 68 -j ACCEPT $ sudo iptables -t nat -A POSTROUTING -o tun0 -j MASQUERADE $ sudo netfilter-persistent save
Configure the DHCP server in /etc/dnsmasq.conf:
interface=wlan0 # Listening interface dhcp-range=192.168.4.2,192.168.4.20,255.255.255.0,24h # Pool of IP addresses served via DHCP domain=wlan # Local wireless DNS domain address=/gw.wlan/192.168.4.1 # Alias for this router
Unblock the WLAN if it is blocked:
$ sudo rfkill unblock wlan
Configure the new WiFi network in /etc/hostapd/hostapd.conf:
country_code=DE interface=wlan0 ssid=<NameOfNetwork> hw_mode=g channel=7 macaddr_acl=0 auth_algs=1 ignore_broadcast_ssid=0 wpa=2 wpa_passphrase=<Password> wpa_key_mgmt=WPA-PSK wpa_pairwise=TKIP rsn_pairwise=CCMP
And set the config in /etc/default/hostapd:
DAEMON_CONF="/etc/hostapd/hostapd.conf"
Final reboot:
$ sudo systemctl reboot
At this point you should have a new WiFi network. Connect with you device(s) and check you IP address.