Wireguard - Android Road Warrior
Motivation
There are a lot of blog posts and wiki pages about how to set up Wireguard, but I still had to do a bunch of trial and error to come up with a configuration that worked for me. I have two goals:
- Secure all traffic from my Android phone for privacy / when on unsecured WiFi.
- Full access to my home network resources when away from home.
Caveats:
- This does client key generation on the server, which is fine for this simple use case, but not a cryptographic best practice.
- This sets up only a single client. If you need multiple clients, you'll have to get fancier.
- As part of meeting my goals, ALL phone traffic goes through the VPN. That may not be your desired configuration.
Preparation
You will need:
- The public IP address of your router (or a DNS record that points to it)
- An open port on your router forwarded to wherever you run Wireguard
- The IP address of the DNS server your phone should use when connected to your home network (maybe your router, maybe not)
- Two addresses in a private subnet not used elsewhere on your home network
Implementation
I hosted all of this in a VM running Ubuntu 18.04.1.
At the end of this process, a QR Code is displayed to be scanned by the Wireguard Android app.
This script is run as root sudo bash -x simple-wireguard.sh
:
#!/bin/bash -x
################ CHANGE THESE ##################
# Your Home IP or DNS record
WG_ADDRESS=wireguard.your.domain
# UDP port forwarded to this machine
WG_PORT=12345
# DNS entries for the client to use when on VPN
WG_DNS=192.168.1.1,8.8.8.8
# Unused private IPs for this connection
WG_SERVER_INT=172.16.17.1
WG_CLIENT_INT=172.16.17.2
################################################
add-apt-repository -y ppa:wireguard/wireguard
apt-get -y update
apt-get -y install wireguard qrencode
# Enable Packet Forwarding
echo net.ipv4.ip_forward=1 > /etc/sysctl.d/wireguard.conf
sysctl -p /etc/sysctl.d/wireguard.conf
# Generate Keys and Configurations
cd /etc/wireguard
wg genkey | tee server.private | wg pubkey > server.public
wg genkey | tee client.private | wg pubkey > client.public
# Server Configuration sets up NAT
cat >wg0.conf <<EOF
[Interface]
Address = ${WG_SERVER_INT}
SaveConfig = false
PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -A FORWARD -o %i -j ACCEPT; iptables -t nat -A POSTROUTING -o net0 -j MASQUERADE
PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -D FORWARD -o %i -j ACCEPT; iptables -t nat -D POSTROUTING -o net0 -j MASQUERADE
ListenPort = ${WG_PORT}
PrivateKey = $(cat server.private)
[Peer]
PublicKey = $(cat client.public)
AllowedIPs = ${WG_CLIENT_INT}
EOF
cat >client.conf <<EOF
[Interface]
Address = ${WG_CLIENT_INT}
PrivateKey = $(cat client.private)
DNS = ${WG_DNS}
[Peer]
PublicKey = $(cat server.public)
Endpoint = ${WG_ADDRESS}:${WG_PORT}
AllowedIPs = 0.0.0.0/0
PersistentKeepalive = 10
EOF
# Turn on and enable for boot
systemctl start wg-quick@wg0
systemctl enable wg-quick@wg0
# Show the QR Code
qrencode -t ansiutf8 < client.conf
Better Tools
I wanted something simple and comprehensible that I built myself, but there are tools out there that build fancier configurations that are recommended by smart people in this space:
Another option that is built atop wireguard-go
is Tailscale. Their service is proprietary, though many of their client implementations are open-source.
References
- https://www.wireguard.com/quickstart/
- https://www.stavros.io/posts/how-to-configure-wireguard/
- https://wiki.debian.org/Wireguard
- https://www.ckn.io/blog/2017/11/14/wireguard-vpn-typical-setup/
- https://emanuelduss.ch/2018/09/wireguard-vpn-road-warrior-setup/
- https://github.com/michaeljs1990/docs/blob/master/software/wireguard.md
Below are a couple of gists I worked on when helping someone else trying to use the code above: