Running a VPN server on a phone may sound like a developer‑only trick, but with WireGuard’s lightweight user‑space implementation you can turn almost any Android device into a functional VPN endpoint—without rooting or flashing. This tutorial walks you through every step, from installing Termux to generating keys, configuring wireguard-go, and exposing the tunnel to other devices on your LAN or over the internet.
WireGuard is praised for three core qualities that make it ideal for a phone‑based server:
.conf file defines the entire tunnel.Because WireGuard runs in user space via wireguard-go, you don’t need kernel modules or root privileges. Termux provides a Linux‑like environment where you can compile and run the necessary binaries.
Make sure the phone stays plugged into power while you test the server. A VPN tunnel can drain the battery quickly if the device is idle but still routing traffic.
VPNService APIs for user‑space VPNs.pkg update && pkg upgrade -y
pkg install wireguard-tools wireguard-go iproute2 iptables-nft -y
If iptables-nft is unavailable on your device, install iptables instead; the commands are identical for our use case.
nano or vim for editing configuration files:
pkg install nano -y
These packages give you the wg command (for managing interfaces), wg-quick (a helper script), and wireguard-go (the user‑space kernel implementation).
mkdir -p ~/wireguard/server
cd ~/wireguard/server
Keeping everything under ~/wireguard makes backups easy – you can copy the whole folder to a PC or cloud storage whenever you need to migrate the server.
WireGuard uses a pair of Curve25519 keys per peer. The server needs its own key pair, and each client will need a separate key.
wg genkey | tee server_private.key | wg pubkey > server_public.key
chmod 600 server_private.key server_public.key
cat server_public.key
Repeat the same process on the client device (or generate keys on the phone and copy them). For simplicity, we’ll generate a single client key pair on the same Android device and later copy the public key to the server configuration.
wg genkey | tee client_private.key | wg pubkey > client_public.key
chmod 600 client_private.key client_public.key
wg0.conf)WireGuard’s configuration is straightforward. The file lives in the same directory you created earlier.
nano (or your preferred editor):
nano wg0.conf
[Interface]
PrivateKey = SERVER_PRIVATE_KEY
Address = 10.0.0.1/24
ListenPort = 51820
# Optional: keep the interface alive when idle
PersistentKeepalive = 25
# Client peer definition
[Peer]
PublicKey = CLIENT_PUBLIC_KEY
AllowedIPs = 10.0.0.2/32
Replace SERVER_PRIVATE_KEY with the contents of server_private.key and CLIENT_PUBLIC_KEY with the contents of client_public.key. The Address line defines the VPN subnet – 10.0.0.0/24 works well for a small home setup.
Ctrl+X, then Y).At this point the server knows its own private key, where to listen, and which client is allowed to connect.
For devices on the client side to reach the internet through the Android phone, the phone must forward packets from the VPN interface (wg0) to its external network interface (usually wlan0 for Wi‑Fi). Android disables IP forwarding by default, but Termux can enable it for the duration of the session.
sysctl -w net.ipv4.ip_forward=1
If sysctl reports “permission denied”, you can write directly to the proc file:
echo 1 > /proc/sys/net/ipv4/ip_forward
iptables -t nat -A POSTROUTING -o wlan0 -j MASQUERADE
If your device uses a different interface name (e.g., eth0 for a USB‑ethernet adapter), replace wlan0 accordingly.
echo "iptables -t nat -A POSTROUTING -o wlan0 -j MASQUERADE" > ~/wireguard/start-nat.sh
chmod +x ~/wireguard/start-nat.sh
Note: Android’s built‑in firewall may interfere with custom iptables rules on some OEM skins. If you encounter “Operation not permitted”, try using iptables-nft instead, or install the iptables package that matches the kernel’s netfilter backend.
~/wireguard/start-nat.sh
wg-quick:
wg-quick up wg0
The command reads wg0.conf from the current directory. If you prefer an absolute path, use:
wg-quick up ~/wireguard/server/wg0.conf
wg show
You should see the interface name, the public keys, and a line like transfer: 0 B received, 0 B sent.
At this stage the server is listening on UDP port 51820. Android’s built‑in firewall usually allows outbound UDP, but inbound traffic to a non‑system app may be blocked. WireGuard’s user‑space implementation works around this by opening a socket that the Android VPNService forwards to the app, so no extra firewall rule is needed.
The client can be any device that supports WireGuard – another Android phone, a Windows PC, Linux, or macOS. Below we show the minimal configuration for a second Android device using the same Termux approach.
server_public.key file via a secure channel (e.g., encrypted email or QR code).wg0.conf:
[Interface]
PrivateKey = CLIENT_PRIVATE_KEY
Address = 10.0.0.2/24
[Peer]
PublicKey = SERVER_PUBLIC_KEY
Endpoint = SERVER_WIFI_IP:51820
AllowedIPs = 0.0.0.0/0, ::/0
PersistentKeepalive = 25
Replace CLIENT_PRIVATE_KEY with the contents of client_private.key, SERVER_PUBLIC_KEY with the server’s public key, and SERVER_WIFI_IP with the phone’s Wi‑Fi address (e.g., 192.168.1.45). The AllowedIPs line routes all traffic through the VPN.
wg-quick up wg0
ping -c 4 10.0.0.1
Successful replies mean the VPN tunnel is established. To verify internet routing, try:
curl https://ifconfig.me
The returned IP should match the server’s external IP, not the client’s original one.
Manually running the NAT script and wg-quick up each time is fine for occasional use, but you can create a tiny wrapper that launches everything with a single command.
start-wg.sh in the server directory:
cat > start-wg.sh <<'EOF'
#!/data/data/com.termux/files/usr/bin/bash
# Enable forwarding
sysctl -w net.ipv4.ip_forward=1
# Apply NAT rule
iptables -t nat -A POSTROUTING -o wlan0 -j MASQUERADE
# Bring up WireGuard
wg-quick up wg0
EOF
chmod +x start-wg.sh
~/wireguard/server/start-wg.sh
For a more permanent solution, you can add the script to Termux’s boot package, which runs commands after the device boots (requires the termux-boot add‑on from F‑Droid).
Endpoint in the client config uses the current Wi‑Fi address of the server. Android may change the IP after a router reboot.ListenPort to 51821 or another high port, and update the client’s Endpoint accordingly.iptables -t nat -L -n -v and look for a MASQUERADE entry targeting wlan0.cat /proc/sys/net/ipv4/ip_forward should output 1.ping, try adding a rule to accept forwarded traffic:
iptables -A FORWARD -i wg0 -j ACCEPT
iptables -A FORWARD -o wg0 -j ACCEPT
ListenPort in wg0.conf and restart.VPNService API may require the app to be marked as a VPN. Install the WireGuard app from the Play Store (it uses the same kernel module) and grant it VPN permission, then return to Termux. The permission persists for user‑space binaries.~/wireguard folder survives Termux updates, but a full app data clear will delete it. Back up *_private.key files to encrypted cloud storage.AllowedIPs line to split traffic (e.g., only route private subnets through the VPN).top if you suspect performance issues.With the steps above you now have a fully functional WireGuard VPN server running on an Android phone, completely without root. The same workflow scales to multiple clients – just add additional [Peer] sections to wg0.conf and generate a key pair for each device. Because everything lives in user space, you can stop the server at any time by running wg-quick down wg0, and your phone returns to its normal state instantly.
This approach is especially handy for:
Remember to keep your keys safe, monitor battery usage, and adjust firewall rules if you switch ROMs or Android versions. Happy tunneling!









