Skip to content

Instantly share code, notes, and snippets.

@engelmarkus
Last active December 5, 2022 19:17
Show Gist options
  • Save engelmarkus/25b98a20191f197573809c38f01f11fd to your computer and use it in GitHub Desktop.
Save engelmarkus/25b98a20191f197573809c38f01f11fd to your computer and use it in GitHub Desktop.
Setting up a VPN with WireGuard on a vServer
Setting up a VPN with WireGuard
Prerequisites
A linux server with
- ip forwarding enabled:
~> sysctl net/ipv4/ip_forward
net.ipv4.ip_forward = 1
- the "tun" kernel module loaded:
~> lsmod | grep tun
tun 4242 -2
WireGuard suggests using their kernel module on linux systems, however, if you're running a vserver, you probably
cannot load your own kernel modules. Their userspace version "wireguard-go" which also serves as the backend for
the Android app can be used instead.
On my vserver which is running a modified version of Ubuntu 18.04, the tun controlling device isn't created
automatically, even though the kernel module is loaded. So I made systemd create it on boot:
~> cat /etc/tmpfiles.d/tun.conf
c! /dev/net/tun 0666 - - - 10:200
Get the sources for the wg program and compile it:
~> git clone --depth=1 https://github.com/WireGuard/WireGuard.git
~> cd WireGuard/src/tools
~> make
~> make install
Get the sources of wireguard-go and compile it:
~> git clone --depth=1 https://github.com/WireGuard/wireguard-go.git
~> cd wireguard-go
~> make wireguard-go
~> make install
Create a key pair for the server:
~> wg genkey | tee server-priv | wg pubkey > server-pub
Create a key pair and a preshared key for your first client:
~> wg genkey | tee client1-priv | wg pubkey > client1-pub
~> wg genpsk > client1-psk
Create a config file for the server:
~> cat /etc/wireguard/wg0.conf
[Interface]
PrivateKey = <insert server-priv>
ListenPort = 51820
# client1
[Peer]
PublicKey = <insert client1-pub>
PresharedKey = <insert client1-psk>
AllowedIPs = 10.0.0.2/32
PersistentKeepalive = 25
# client2
# ...
I wrote a little systemd service for setting up the vpn (adjust the paths if necessary):
~> cat /etc/systemd/system/wireguard@.service
[Unit]
Description=Provide wireguard interface and set up VPN
Requires=network.target
After=network.target
[Service]
Type=simple
Environment=WG_I_PREFER_BUGGY_USERSPACE_TO_POLISHED_KMOD=1
ExecStart=/usr/local/bin/wireguard-go -f %i
ExecStartPost=/bin/sleep 3
ExecStartPost=/sbin/ip address add dev %i 10.0.0.1
ExecStartPost=/usr/local/bin/wg setconf %i /etc/wireguard/%i.conf
ExecStartPost=/sbin/ip link set up dev %i
ExecStartPost=/sbin/ip route add 10.0.0.0/24 via 10.0.0.1
ExecStop=/sbin/ip link del dev %i
ExecStopPost=/sbin/ip route del 10.0.0.0/24
TimeoutStopSec=3
Restart=always
[Install]
WantedBy=multi-user.target
Enable and start the service:
~> systemctl enable wireguard@wg0
~> systemctl start wireguard@wg0
Create a config file for the first (Android-)client (you should add a custom DNS address or Android will
use the one it received via DHCP; if this was a local address, DNS requests won't go through the tunnel!):
~> cat client1.conf
# client1
[Interface]
PrivateKey = <insert client1-priv>
ListenPort = 51820
Address = 10.0.0.2/32
DNS = <insert a trusted dns server ip>
[Peer]
PublicKey = <insert server-pub>
PresharedKey = <insert client1-psk>
AllowedIPs = 0.0.0.0/0
Endpoint = <insert server ip>:51820
PersistentKeepalive = 25
Turn it into a qr code for easier set up:
~> qrencode -r client1.conf -o client1.conf.png
Open the WireGuard Android app and scan the qr code. Give the connection a name and enable it. You'll notice that
all internet access is blocked now, as the required firewall rules on the server are still missing:
~> iptables -A FORWARD -i wg0 -j ACCEPT
~> iptables -t nat -A POSTROUTING -o venet0 -j MASQUERADE
In the second rule, replace "venet0" with the name of your server's network interface.
You can put this command before the two in order to enable some logging of forwarded packets.
~> iptables -A FORWARD -i wg0 -j LOG --log-prefix FORWARD:
Now internet access on the Android system should be possible, while redirecting all traffic through the WireGuard tunnel.
For additional clients, generate a new keypair and a new preshared key, insert its data into the server config file and
create a new config file for the client. Make sure you adjust the ip address the client should use in both the server and the client config, i. e. "10.0.0.3/32".
In order to use the kernel module, create the wg0 interface with "ip" and remove the wireguard-go call
in the systemd service file:
"ip link add dev wg0 type wireguard"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment