My notes on how to set up WireGuard
Find a file
2023-11-19 16:44:58 -06:00
README.md Update README.md 2023-11-19 16:44:58 -06:00

Ground-up configuration of WireGuard as a secure VPN

WireGuard can be a huge pain to set up- here's some notes on how to get it perfect the first time for two GNU/Linux devices, a server and client. This will cover setting up the server and adding one peer to it; to add multiple peers, simply repeat the process, skipping Step 2.

Step 1: Install WireGuard

Check the WireGuard installation page for specific installation instructions for your GNU/Linux distribution of choice.

Step 2: Initial Server Configuration

To initially set up a server, first you must create a public and private key for the server. To do that, run the following:

wg genkey | tee privatekey | wg pubkey > publickey

This will create publickey and privatekey in your working directory. Have these two strings of random data readily accessable for later. You may want to change their permissions to be read only for the root user: sudo chmod 400 p*key

The next step is to create the configuration file /etc/wireguard/wg0.conf. Note that wg0 can be any name. If you name it something other than wg0, change every instance of wg0 in the rest of the steps to the new name.

Add the following to /etc/wireguard/wg0.conf, filling in anything {in brackets} below:

[Interface]
Address = 192.168.2.1/32 # Any free address
PostUp   = iptables -A FORWARD -i %i -j ACCEPT; iptables -A FORWARD -o %i -j ACCEPT; iptables -t nat -A POSTROUTING -o {Network connection to be shared (ex. eth0)} -j MASQUERADE
PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -D FORWARD -o %i -j ACCEPT; iptables -t nat -D POSTROUTING -o {Network connection to be shared (ex. eth0)} -j MASQUERADE
ListenPort = 51280 # Any free port
PrivateKey = {Server's private key}

Save this file for now and close it. You may want to change this file's permissions to be read-write for the root user: sudo chmod 600 /etc/wireguard/wg0.conf

At this point, you likely will need to forward ports on your router to make the port you chose in the configuration file publically accessable. Consult your router's documentation for more information. You will need to know the public-facing port later.

The server will also need to change a configuration file for packet forwarding to work. Open /etc/sysctl.conf and uncomment the line net.ipv4.ip_forward=1, or do it with sed: sudo sed -i 's/#net.ipv4.ip_forward=1/net.ipv4.ip_forward=1/' /etc/sysctl.conf. After this is set, reload the configuration with sudo sysctl -p

Step 3: Initial Client Configuration

To initially set up a client, first you must create a public and private key for the client. To do that, run the following:

wg genkey | tee privatekey | wg pubkey > publickey

This will create publickey and privatekey in your working directory. Have these two strings of random data readily accessable for later. You may want to change their permissions to be read only for the root user: sudo chmod 400 p*key

The next step is to create the configuration file /etc/wireguard/wg0.conf. Note that wg0 can be any name. If you name it something other than wg0, change every instance of wg0 in the rest of the steps.

Add the following to /etc/wireguard/wg0.conf, filling in anything {in brackets} below:

[Interface]
Address = 0.0.0.0/0 # We will be changing this in a few minutes
ListenPort = 21841 # Any free port
PrivateKey = {Client's private key}
# Optional: Set a specific DNS server. This will prevent any networks from choosing an untrusted DNS server to use for your requests
# Uncomment the following line and change the IP address to your DNS server of choice
#DNS = 1.1.1.1

Save this file for now and close it. You may want to change this file's permissions to be read-write for the root user: sudo chmod 600 /etc/wireguard/wg0.conf

Step 4: Pair the client and server

For this step, each device should have easy access to the public key of the other (or you can type them by hand if you're a masochist). To start, we will edit the server's /etc/wireguard/wg0.conf by adding the following to the bottom:

[Peer]
PublicKey = {Client's public key}
AllowedIPs = 192.168.2.2/32 # Choose a free address on your server. Record this address.

If wg0 is already running, stop it by running sudo wg-quick down wg0. Bring the connection up by running sudo wg-quick up wg0.

Next, open the client's /etc/wireguard/wg0.conf. Change the Address under [Interface] to be exactly the address you chose in the server's [Peer] section above. Then, add the following to the bottom:

[Peer]
PublicKey = {Server's public key}
Endpoint = {Server's IP address or URL}:{Public-facing port}
AllowedIPs = 0.0.0.0/0
# If the client is behind a NAT firewall, uncomment the following line
#PersistentKeepalive = 25

If wg0 is already running, stop it by running sudo wg-quick down wg0. Bring the connection up by running sudo wg-quick up wg0.


Congratulations, your network traffic should now be encrypted between your device and your server. Note that any traffic coming out of the server is unencrypted.

You will likely want to set WireGuard to start on server startup. For systemd-based systems, run the following:

sudo systemctl enable wg-quick@wg0.service

Troubleshooting

If the client connection gets routed through the server, but there is no access to the remote LAN, then what's likely happening is that there is another rule on the client system that is interfereing with the 0.0.0.0/0 declaration. To get around this, add another entry to the AllowedIPs in the client's configuration. For example, if the remote LAN uses the 192.168.1.0/24 address space, then the following would allow access to that LAN:

AllowedIPs = 192.168.1.0/24, 0.0.0.0/0