How to setup and configure WireGuard on Debian / Ubuntu

Posted on

How to setup and configure WireGuard on Debian / Ubuntu

How to setup and configure WireGuard on Debian / Ubuntu

Introduction

WireGuard is a modern, fast, and secure VPN tunneling protocol that can be used to establish encrypted tunnels between machines to create private networks. It aims to be simpler, leaner, and more performant than older VPN protocols like IPsec and OpenVPN.

In this guide, we will walk through the full process of setting up WireGuard on Debian or Ubuntu Linux servers. This will allow you to create encrypted connections between servers, route traffic through VPN tunnels, and essentially create a virtual private network.

We will cover:

  • Installing WireGuard on Debian and Ubuntu
  • Generating public/private key pairs
  • Configuring the WireGuard interface and peers
  • Enabling IP forwarding
  • Integrating WireGuard with systemd for automatic startup
  • Setting permanent IP addressing
  • Configuring NAT for remote peers
  • Client configuration

By the end, you should have a fully functioning WireGuard setup on Debian or Ubuntu that can securely tunnel traffic between servers.

Prerequisites

Before we get started, there are a few prerequisites:

  • Two or more Debian or Ubuntu servers (or VMs)
  • Root access to each server
  • Basic understanding of networking concepts
  • Ability to edit configuration files with a text editor

The setup will be done on two or more machines that can communicate over a network. For testing purposes, you can use local VMs, servers, or cloud machines.

The instructions will work for setting up WireGuard between any endpoints – it does not have to be just Debian/Ubuntu servers. WireGuard clients are available for all major platforms.

Installing WireGuard

The first step is to install the WireGuard package on all the machines that will be part of the VPN tunnel.

On Debian

$ sudo apt update
$ sudo apt install wireguard

On Ubuntu

$ sudo apt update
$ sudo apt install wireguard

This will install the WireGuard module and userspace tools like wg and wg-quick.

Generating Keys and Configuration

Now we need to generate the public/private key pairs that will be used by WireGuard to establish the encrypted tunnels. Each machine participating in the VPN will need its own private key and a corresponding public key.

Generate the private key with:

$ wg genkey > privatekey

This will create a new private key and save it to privatekey.

Next, generate the public key:

$ wg pubkey < privatekey > publickey

Do this for each server that will be part of the VPN. Make sure to safely store the private key file on each machine. The public key can be freely shared.

Next we need to generate a configuration file that specifies the interface, peers/endpoints, and keys.

Create a file called wg0.conf:

$ sudo nano /etc/wireguard/wg0.conf

Add the following contents, replacing the PublicKey and PrivateKey with your own for each server:

[Interface]
Address = 10.0.0.1/24
ListenPort = 51820
PrivateKey = SERVER1_PRIVATE_KEY
[Peer]
PublicKey = SERVER2_PUBLIC_KEY
AllowedIPs = 10.0.0.2/32

So for two servers, you may have:

Server 1:

[Interface]
Address = 10.0.0.1/24
ListenPort = 51820
PrivateKey = SERVER1_PRIVATE_KEY
[Peer]
PublicKey = SERVER2_PUBLIC_KEY
AllowedIPs = 10.0.0.2/32

Server 2:

[Interface]
Address = 10.0.0.2/24
ListenPort = 51820
PrivateKey = SERVER2_PRIVATE_KEY
[Peer]
PublicKey = SERVER1_PUBLIC_KEY
AllowedIPs = 10.0.0.1/32

The Address and AllowedIPs configure the IP addresses used by the VPN tunnel interface. Make sure any IPs used don’t conflict with your existing network.

The ListenPort and PrivateKey are required in the [Interface] section. Then add a [Peer] section for each server you want to connect to, using its PublicKey.

You can add more peers by adding additional [Peer] sections. Make sure to also add the peer IP to AllowedIPs.

Save the config file and enable IP forwarding (explained below).

Creating Interfaces and Peers

With the configuration in place, we can now create the interface and establish the peer connections:

$ sudo wg-quick up wg0

This will set up the wg0 interface using the details from wg0.conf.

Run the same wg-quick command on each server to bring up their VPN interfaces. The peers will connect using the public keys and begin tunneling traffic.

You can inspect the status of the interface with:

$ sudo wg show

This will display details like the public key, listening port, and peers for the interface.

At this point your WireGuard VPN tunnel is active! Traffic will now flow between the peered servers encrypted over the tunnels.

However, for routing to work properly we need to enable IP forwarding on each server.

Routing Traffic Through the VPN Tunnel

With IP forwarding enabled, traffic can be sent between the WireGuard peers and routed through the encrypted VPN tunnel.

To enable forwarding on Debian/Ubuntu:

$ sudo sysctl -w net.ipv4.ip_forward=1

To make this persistent across reboots:

$ sudo nano /etc/sysctl.conf

Uncomment the line:

net.ipv4.ip_forward=1

Save the file and reboot or run sudo sysctl -p to load the new settings.

Now traffic can be routed between the VPN peers. However, the connection will drop as soon as you restart the server since the wg-quick configuration is not persistent.

To automatically bring up the VPN on boot we need to integrate WireGuard with systemd.

Systemd Integration and Start on Boot

To have WireGuard start on boot and persist across restarts, we need to configure a systemd service.

Create a new systemd service file:

$ sudo nano /etc/systemd/system/wg-quick@wg0.service

Paste in the following:

[Unit]
Description=WireGuard VPN tunnel for %i
After=network-online.target nss-lookup.target
Wants=network-online.target nss-lookup.target
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/bin/wg-quick up %i
ExecStop=/usr/bin/wg-quick down %i
[Install]
WantedBy=multi-user.target

This will start and stop the VPN tunnel using wg-quick.

Now enable the service:

$ sudo systemctl enable wg-quick@wg0

This will create a systemd service that runs wg-quick on boot.

Reboot your servers and WireGuard should come up automatically! Verify with wg show.

Permanent IP Addressing

By default, the WireGuard peers will use their latest public IP when making connections. If your servers have dynamic IPs, this can cause problems.

To assign permanent static IPs used just for the VPN connections, add a PersistentKeepalive option to the peer sections:

[Peer]
PublicKey = PEER_PUBLIC_KEY
AllowedIPs = 10.0.0.2/32
Endpoint = PEER_PUBLIC_IP:51820
PersistentKeepalive = 25

This will ping the peer every 25 seconds to keep the most recent IP address updated.

You can also explicitly set the endpoint IP like above if the public IP never changes.

NAT for Allowing Connections from Remote Peers

In most cases, you’ll want to allow connections to your VPN server from remote peers/clients over the internet.

This means opening and forwarding the WireGuard listening port (UDP 51820 by default).

If behind a NAT firewall, add these port forwarding rules:

# Forward port 51820 inbound to the WireGuard server
$ iptables -A INPUT -p udp --dport 51820 -j ACCEPT
$ iptables -A FORWARD -i eth0 -o wg0 -j ACCEPT
# Forward traffic from WireGuard server back out to internet
$ iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE

You’ll also need to configure port forwarding rules on your router to send inbound UDP 51820 traffic to your WireGuard server.

Now remote peers can connect to your server’s public IP on port 51820 over the internet.

Client Configuration

To connect clients like mobile devices, just install a WireGuard app and use the server’s public IP and public key in the client config.

Here’s an example mobile client config:

[Interface]
PrivateKey = CLIENT_PRIVATE_KEY
Address = 10.0.0.3
[Peer]
PublicKey = SERVER_PUBLIC_KEY
Endpoint = SERVER_PUBLIC_IP:51820
AllowedIPs = 0.0.0.0/0

This will route all client traffic through the VPN tunnel when connected.

And that covers the full setup of WireGuard on Debian and Ubuntu!

Summary

Your Debian or Ubuntu servers should now have encrypted WireGuard tunnels between them. Traffic will be routed through the tunnels, secured by modern cryptography.

WireGuard is fast, simple, and lean compared to alternatives like IPsec or OpenVPN. It makes an ideal VPN for connecting infrastructure securely across the internet.

There are many additional options for tuning and expanding your WireGuard setup as well – refer to the project docs for more details.

I hope this guide was helpful for getting WireGuard set up on your Debian or Ubuntu systems! Let me know if you have any other questions.

Alternative Solutions for Creating a VPN

While WireGuard offers a robust and relatively simple solution, alternative approaches exist for creating a VPN on Debian/Ubuntu systems. Here are two distinct methods, along with explanations and code examples:

1. Using OpenVPN

OpenVPN is a well-established and highly configurable VPN solution. While generally considered more complex to set up than WireGuard, it offers a wider range of features and configuration options, making it suitable for more complex network scenarios.

Explanation:

OpenVPN relies on SSL/TLS for encryption and authentication. It supports various authentication methods, including pre-shared keys, certificates, and usernames/passwords. OpenVPN can operate in two primary modes: routed (tun) and bridged (tap). Routed mode is generally preferred for its simplicity and performance.

Installation:

sudo apt update
sudo apt install openvpn easy-rsa

Configuration:

The configuration process for OpenVPN is more involved than WireGuard. It typically involves generating certificates for both the server and clients using Easy-RSA, and then configuring the OpenVPN server and client configuration files. A basic server configuration file (/etc/openvpn/server.conf) might look like this:

port 1194
proto udp
dev tun

ca /etc/openvpn/easy-rsa/pki/ca.crt
cert /etc/openvpn/easy-rsa/pki/issued/server.crt
key /etc/openvpn/easy-rsa/pki/private/server.key  # This file should be kept secret

dh /etc/openvpn/easy-rsa/pki/dh.pem

server 10.8.0.0 255.255.255.0

ifconfig-pool-persist ipp.txt

push "redirect-gateway def1 bypass-dhcp"
push "dhcp-option DNS 8.8.8.8"
push "dhcp-option DNS 8.8.4.4"

keepalive 10 120

cipher AES-256-CBC
auth SHA256

user nobody
group nogroup

persist-key
persist-tun

status openvpn-status.log
log-append  openvpn.log

verb 3

A corresponding client configuration file (client.conf) would look like this:

client
dev tun
proto udp
remote your_server_ip 1194
resolv-retry infinite
nobind
user nobody
group nogroup
persist-key
persist-tun

ca ca.crt
cert client.crt
key client.key

remote-cert-tls server
tls-version-min 1.2
cipher AES-256-CBC
auth SHA256

verb 3

Remember to replace your_server_ip with the actual public IP address of your OpenVPN server. Also, the ca.crt, client.crt, and client.key files need to be copied from the server to the client.

Enabling IP Forwarding and NAT (same as WireGuard):

The IP forwarding and NAT configuration is identical to the WireGuard setup.

Starting OpenVPN:

sudo systemctl start openvpn@server
sudo systemctl enable openvpn@server

Advantages of OpenVPN:

  • Wider range of configuration options.
  • Mature and well-documented.
  • Supports various authentication methods.

Disadvantages of OpenVPN:

  • More complex to configure than WireGuard.
  • Can be slower than WireGuard in some scenarios.

2. Using SSH Tunneling with Dynamic Port Forwarding

This method creates a secure tunnel through an SSH connection, and then allows applications on the client side to forward traffic through that tunnel. It’s particularly useful for securing individual applications rather than routing all traffic through a VPN.

Explanation:

SSH tunneling leverages the existing SSH protocol for encryption. Dynamic port forwarding allows the client to act as a SOCKS proxy, forwarding traffic to different destinations through the secure SSH tunnel.

Setup:

  1. SSH Server: Ensure you have an SSH server running on the destination machine. This is typically enabled by default on most Linux distributions.

  2. SSH Client: Use an SSH client (e.g., the ssh command in Linux/macOS or PuTTY in Windows) to create the dynamic port forwarding tunnel.

Command Example:

ssh -D 8080 user@your_server_ip

This command establishes an SSH connection to your_server_ip as user and sets up a dynamic port forward on local port 8080. All traffic sent to port 8080 on the client machine will be securely forwarded through the SSH tunnel to the server, and then routed to its final destination.

Configuration:

Once the tunnel is established, you need to configure your applications to use the SOCKS proxy. For example, in Firefox, you would go to Settings -> Network Settings -> Configure Proxy Access to the Internet. Select "Manual proxy configuration" and set the SOCKS Host to localhost and the Port to 8080.

Advantages of SSH Tunneling:

  • Simple to set up for basic use cases.
  • Uses the widely available SSH protocol.
  • Useful for securing individual applications.

Disadvantages of SSH Tunneling:

  • Not a full VPN solution – only secures traffic forwarded through the tunnel.
  • Performance can be limited by SSH overhead.
  • Requires manual configuration of each application.

These alternative methods provide different approaches to creating a VPN or secure tunnel on Debian/Ubuntu systems. The choice depends on your specific requirements and the level of complexity you are willing to manage. While WireGuard remains a strong choice for many, understanding these alternatives broadens your options for secure networking.

Leave a Reply

Your email address will not be published. Required fields are marked *