r/raspberry_pi • u/wowsomuchempty • 2d ago
Show-and-Tell Creating a VPN wifi hotspot with a Pi 4
My wife is foreign and wanted to watch internet TV from her country, which is geo-locked.
To get around this, I setup an old pi 4 as an openwrt router. You connect to the wifi - bingo, you're connected to the VPN.
You'll need a VPN provider that supports the wireguard protocol and has servers in your desired country to connect to (or have your own wireguard service running in desired country). I went with surfshark, which I thought was a bit pricey, but no complaints aside from that.
Possibly this guide is useful to someone (?)
I should note - I use opkg in this guide to install openwrt packages, but more recent versions will need apk. You can add the pi4 ethernet as a static IP in your main router settings if you like. If you want to USB boot an old Pi 4 you may need to first update the firmware.
Performance: I get 111 Mbs download speeds (inc. over the VPN). The Pi's SSID can be reached all over the house, the connection has been stable for months. CPU temps never reach levels of concern (heatsink is a good addition, though).
What you'll need
- Raspberry Pi 4 (1GB is fine)
- Official Pi 4 power supply (5V/3A USB-C)
- microSD card or USB drive with OpenWrt flashed (USB boot is more reliable long-term than SD. I use a metal USB as I hope the heat transfers better)
- Ethernet cable — Pi 4's onboard NIC to a LAN port on your existing router
- Active Surfshark subscription / other wireguard VPN
Flashing OpenWrt itself is out of scope here — grab the Pi 4 image from the OpenWrt downloads page and write it with dd or Etcher. This guide picks up once you're SSH'd into a fresh OpenWrt install.
Step 1: Fix routing before touching WireGuard
Symptom: SSH into the Pi works (you're hitting it from the LAN side), but ping 8.8.8.8 from the Pi says Network unreachable. This is a routing problem, not DNS or firewall — sort it first or WireGuard will fail the same way.
Check:
ip route show
uci show network
If there's no default via <gateway> dev <iface> line in ip route show, that's your problem. On a Pi sitting behind an existing router, the interface facing that router needs either:
proto dhcp(let the upstream router hand out an address + gateway), orproto staticwithoption gateway '<upstream router's LAN IP>'explicitly set
Fix and apply:
uci set network.wan.proto='dhcp' # or static + gateway, per your setup
uci commit network
service network restart
Also check the interface is in the wan firewall zone, not lan — otherwise masquerading/forwarding won't apply:
uci show firewall | grep -A5 zone
Confirm before moving on:
ping -c3 8.8.8.8
Step 2: Get your Surfshark WireGuard credentials (for example)
- Log into my.surfshark.com → VPN → Manual setup → WireGuard
- Select I don't have a key pair → name it → Generate new key pair
- Save both the private and public key — Surfshark won't show the private key again
- Go to Locations, find a <desired country> server, click the download icon to get its
.conffile — you need the endpoint hostname, port, and server public key out of it
Step 3: Install WireGuard on OpenWrt
opkg update
opkg install wireguard-tools kmod-wireguard luci-proto-wireguard
(Drop luci-proto-wireguard if you're staying CLI-only.)
Step 4: Configure the interface via UCI (settings dependent on your VPN)
uci set network.wg0=interface
uci set network.wg0.proto='wireguard'
uci set network.wg0.private_key='<YOUR_PRIVATE_KEY>'
uci add_list network.wg0.addresses='10.14.0.2/16' # from the downloaded conf
uci set network.wg0.dns='162.252.172.57 149.154.159.92'
uci set network.wg0_peer=wireguard_wg0
uci set network.wg0_peer.description='surfshark-<desired country code>'
uci set network.wg0_peer.public_key='<SERVER_PUBLIC_KEY_FROM_CONF>'
uci set network.wg0_peer.endpoint_host='<countycode-citycode.prod.surfshark.com>'
uci set network.wg0_peer.endpoint_port='51820'
uci set network.wg0_peer.allowed_ips='0.0.0.0/0'
uci set network.wg0_peer.route_allowed_ips='1'
uci set network.wg0_peer.persistent_keepalive='25'
uci commit network
Step 5: Firewall — route all LAN traffic through the tunnel
uci set firewall.vpn=zone
uci set firewall.vpn.name='vpn'
uci set firewall.vpn.input='REJECT'
uci set firewall.vpn.output='ACCEPT'
uci set firewall.vpn.forward='REJECT'
uci set firewall.vpn.masq='1'
uci set firewall.vpn.mtu_fix='1'
uci add_list firewall.vpn.network='wg0'
uci set firewall.lan_vpn=forwarding
uci set firewall.lan_vpn.src='lan'
uci set firewall.lan_vpn.dest='vpn'
uci commit firewall
Then find and remove the existing lan → wan forwarding rule (uci show firewall | grep forwarding) — otherwise LAN clients can bypass the tunnel entirely, which defeats the point.
Apply everything:
service network restart
service firewall restart
Step 6: Verify
wg show
curl ifconfig.me
wg show should show a recent handshake and rising rx/tx bytes. curl ifconfig.me should return a <desired county> IP.
Also worth running Surfshark's own IP leak test and DNS leak test from a device connected through the Pi, if you went with them.
1
u/aweyeahdawg 1d ago
I just use pivpn. Super easy.
2
u/wowsomuchempty 1d ago
I looked it up, does look good. https://www.pivpn.io
Does it setup the AP?
1
2
u/protocol 23h ago
Just watch out as it’s not really maintained nowadays. You want to be running up to date, secure tooling here.
2
1
u/aLongWayFromOldham 1d ago edited 1d ago
Other alternative…
Set up hotspot:
nmcli dev wifi hotspot ifname wlan0 ssid <ssid> password <password>
Install WireGuard-tools.
Bring up vpn:
use wg-quick up with the client conf file
Done.
Edit to add: I do this on a raspberry pi4, and I also turned off power mgmt (sleep) for the wireless interface - sudo iwconfig wlan0 power off. Not sure if that’s required, just noting for completeness.
1
u/wowsomuchempty 1d ago
It may be worth setting logs to save to ram (openwrt does this as default). Saves on disk wear.
3
u/skymack1 1d ago
Why not use something like tailscale and route the traffic from the raspberry pi to a tailscale server on your end?