Last active
December 5, 2022 19:17
-
-
Save engelmarkus/25b98a20191f197573809c38f01f11fd to your computer and use it in GitHub Desktop.
Setting up a VPN with WireGuard on a vServer
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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