This will use a RaspberryPi as a VPN gateway for your whole network using an wired ethernet on eth0 and a wireless USB dongle or internal wifi (depending of signal strength and your location)
We want the Pi to always be reachable at 192.168.1.54 on your LAN (eth0).
Edit netplan config:
sudo vi /etc/netplan/50-cloud-init.yamlExample config:
network:
renderer: networkd
ethernets:
eth0:
dhcp4: false
dhcp6: false
addresses:
- 192.168.1.54/24
nameservers:
addresses: [1.1.1.1,1.0.0.1]
routes:
- to: 0.0.0.0/0
via: 192.168.1.254
wlx24050faaad43:
dhcp4: false
dhcp6: false
addresses: [192.168.55.1/24]
optional: trueApply:
sudo netplan applyCheck:
ip a show eth0
ping 192.168.1.254Disable IPv6
sudo vi /boot/firmware/cmdline.txt
append to end
ipv6.disable=1sudo apt update && sudo apt upgrade -y
sudo apt install wireguard openresolv net-tools hostapd dnsmasq inetutils-traceroute -ywireguard→ VPNhostapd→ WiFi AP servicednsmasq→ DHCP for clients
- Log into ProtonVPN Dashboard
- Go to Downloads → WireGuard Config
- Generate a config (choose server, protocol, port).
- Save it as
/etc/wireguard/wg0.conf.
Move the Proton config:
sudo mv ~/Downloads/proton-XXXX.conf /etc/wireguard/wg0.conf
sudo chmod 600 /etc/wireguard/wg0.conf
[Interface]
# Key for NJ-VPN
# Bouncing = 18
# NetShield = 1
# Moderate NAT = off
# NAT-PMP (Port Forwarding) = off
# VPN Accelerator = on
PrivateKey = xxxxxxxxx
Address = 10.2.0.2/32
DNS = 10.2.0.1
[Peer]
# US-NJ#68
PublicKey = xxxxxx
#AllowedIPs = 0.0.0.0/0, ::/0
AllowedIPs = 0.0.0.0/0
Endpoint = 163.5.171.29:51820Bring interface up:
sudo wg-quick up wg0
curl ipinfo.ioEnable on boot:
sudo systemctl enable wg-quick@wg0Check status:
sudo wg show
curl ifconfig.io→ Should now show ProtonVPN exit IP.
sudo vi /etc/sysctl.conf
sudo sysctl -p
net.ipv4.ip_forward=1
net.ipv6.conf.all.disable_ipv6 = 1
net.ipv6.conf.default.disable_ipv6 = 1
net.ipv6.conf.lo.disable_ipv6 = 1Check adapter name:
iw dev(We’ll assume it’s wlan1.)
sudo vi /etc/hostapd/hostapd.confExample:
interface=wlx24050faaad43
driver=nl80211
ssid=VPN-Gateway
hw_mode=g
channel=6
wmm_enabled=0
auth_algs=1
ignore_broadcast_ssid=0
wpa=2
wpa_passphrase=StrongWiFiPassword123
wpa_key_mgmt=WPA-PSK
rsn_pairwise=CCMPTell systemd where config is:
sudo vi /etc/default/hostapdSet:
DAEMON_CONF="/etc/hostapd/hostapd.conf"Enable & start:
sudo systemctl unmask hostapd
sudo systemctl enable hostapd
sudo systemctl start hostapdBackup default config:
sudo mv /etc/dnsmasq.conf /etc/dnsmasq.conf.backupCreate new one:
sudo vi /etc/dnsmasq.confExample:
port=0
interface=wlx24050faaad43
dhcp-range=192.168.55.10,192.168.55.50,255.255.255.0,24h
dhcp-option=6,10.2.0.1
sudo systemctl restart dnsmasq
sudo systemctl status dnsmasqGive it a gateway address for the subnet:
sudo ip addr flush dev wlx24050faaad43
sudo ip addr add 192.168.55.1/24 dev wlx24050faaad43
sudo ip link set wlx24050faaad43 upEnable packet forwarding:
sudo vi /etc/sysctl.confUncomment or add:
net.ipv4.ip_forward=1
net.ipv6.conf.all.forwarding=1Apply:
sudo sysctl -pFor now (no kill switch yet), add a simple NAT rule so clients route via ProtonVPN:
sudo iptables -t nat -A POSTROUTING -o proton -j MASQUERADEPersist with:
sudo apt install iptables-persistent -y
sudo netfilter-persistent save- Connect a laptop/phone to SSID
PiVPN-Gateway - It should get IP in
192.168.55.x - Run:
curl ifconfig.io
sudo tcpdump -i wlx24050faaad43 -n
cat /var/lib/misc/dnsmasq.leasesIt should show ProtonVPN exit IP, not your home IP.
At this point you’ll have:
- Pi on
192.168.1.54(LAN) - WireGuard tunnel active to ProtonVPN
- wlan1 broadcasting SSID
- Clients connected via SSID are tunneled through ProtonVPN
Here’s a minimal, safe “kill switch”: Wi-Fi clients only work when the WireGuard interface wg0 is up; if it goes down, they have no internet, and you can still SSH from your LAN.
Replace
wlx24050faaad43with your Wi-Fi IF name (yours) and keepeth0/protonas is.
# forwarding
sudo sysctl -w net.ipv4.ip_forward=1
# NAT to VPN (idempotent)
sudo iptables -t nat -C POSTROUTING -o wg0 -j MASQUERADE 2>/dev/null || \
sudo iptables -t nat -A POSTROUTING -o wg0 -j MASQUERADEsudo iptables -C INPUT -i eth0 -p tcp --dport 22 -s 192.168.1.0/24 -j ACCEPT 2>/dev/null || \
sudo iptables -A INPUT -i eth0 -p tcp --dport 22 -s 192.168.1.0/24 -j ACCEPTThese two ACCEPTs let Wi-Fi ↔ VPN; the two DROP rules block any Wi-Fi ↔ eth0 path (so no leak if VPN dies).
We insert so they sit at the top and take effect regardless of other rules.
# Allow Wi-Fi -> VPN (new + established)
sudo iptables -I FORWARD 1 -i wlx24050faaad43 -o wg0 -m conntrack --ctstate NEW,ESTABLISHED,RELATED -j ACCEPT
# Allow VPN -> Wi-Fi (return traffic)
sudo iptables -I FORWARD 1 -i wg0 -o wlx24050faaad43 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
# Block any Wi-Fi -> eth0 leak (and reverse)
sudo iptables -I FORWARD 1 -i wlx24050faaad43 -o eth0 -j DROP
sudo iptables -I FORWARD 1 -i eth0 -o wlx24050faaad43 -j DROPThat’s it. No default DROP policies, so you won’t lock yourself out. Behavior now:
- VPN up ➜ clients work (NAT via
proton). - VPN down ➜ clients can’t reach internet (blocked from
eth0). - SSH from 192.168.1.x ➜ still works.
sudo iptables -S FORWARD
sudo iptables -t nat -S
wg showThen test:
- iPhone online
sudo wg-quick down wg0→ iPhone loses internet ❌, SSH still finesudo wg-quick up wg0→ iPhone back online
sudo apt -y install iptables-persistent
sudo netfilter-persistent saveIf you ever want to remove just these four FORWARD rules:
sudo iptables -D FORWARD -i wlx24050faaad43 -o eth0 -j DROP
sudo iptables -D FORWARD -i eth0 -o wlx24050faaad43 -j DROP
sudo iptables -D FORWARD -i wg0 -o wlx24050faaad43 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
sudo iptables -D FORWARD -i wlx24050faaad43 -o wg0 -m conntrack --ctstate NEW,ESTABLISHED,RELATED -j ACCEPT.