Setup WireGuard VPN on Hetzner Cloud

Authors

Introduction

This guide provides a complete, copy-paste ready solution for setting up WireGuard VPN on a Hetzner Cloud server running Ubuntu 22.04 LTS or later.

Prerequisites

  • Create a Hetzner Cloud server with Shared vCPU running Ubuntu 22.04 LTS or later
    • For networking select both Public IPv4 and IPv6
    • Add SSH keys (usually contents of your ~/.ssh/id_rsa.pub)

Installation and Configuration

SSH into your Hetzner server ssh root@your_server_ipv4 and paste the following complete script. All keys and configurations will be automatically generated and properly set up.

#!/bin/bash

# Exit on any error
set -e

# Install required packages
echo "Installing required packages..."
sudo apt update
sudo apt install wireguard ufw qrencode -y

# Enable IP forwarding
echo "Configuring IP forwarding..."
echo "net.ipv4.ip_forward = 1" | sudo tee -a /etc/sysctl.conf
echo "net.ipv6.conf.all.forwarding = 1" | sudo tee -a /etc/sysctl.conf
sudo sysctl -p

# Create WireGuard directory if it doesn't exist
sudo mkdir -p /etc/wireguard
cd /etc/wireguard

# Generate server keys
echo "Generating server keys..."
wg genkey | sudo tee /etc/wireguard/server_private.key
sudo chmod 600 /etc/wireguard/server_private.key
sudo cat /etc/wireguard/server_private.key | wg pubkey | sudo tee /etc/wireguard/server_public.key

# Generate client keys
echo "Generating client keys..."
wg genkey | sudo tee /etc/wireguard/client_private.key
sudo cat /etc/wireguard/client_private.key | wg pubkey | sudo tee /etc/wireguard/client_public.key

# Get server public IP
SERVER_IP=$(ip  addr show dev eth0 | grep -oP '(?<=inet )([0-9.]+)' | head -1)
SERVER_PRIVATE_KEY=$(sudo cat /etc/wireguard/server_private.key)
CLIENT_PUBLIC_KEY=$(sudo cat /etc/wireguard/client_public.key)

# Create server configuration
echo "Creating server configuration..."
cat << EOF | sudo tee /etc/wireguard/wg0.conf
[Interface]
PrivateKey = ${SERVER_PRIVATE_KEY}
Address = 10.0.0.1/24
ListenPort = 51820
PostUp = ufw route allow in on wg0 out on eth0
PostUp = iptables -t nat -I POSTROUTING -o eth0 -j MASQUERADE
PostUp = ip6tables -t nat -I POSTROUTING -o eth0 -j MASQUERADE
PostDown = ufw route delete allow in on wg0 out on eth0
PostDown = iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
PostDown = ip6tables -t nat -D POSTROUTING -o eth0 -j MASQUERADE

[Peer]
PublicKey = ${CLIENT_PUBLIC_KEY}
AllowedIPs = 10.0.0.2/32
EOF

# Set correct permissions
sudo chmod 600 /etc/wireguard/wg0.conf

# Configure firewall
echo "Configuring firewall..."
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow 51820/udp
sudo ufw allow OpenSSH
echo "y" | sudo ufw enable

# Create client configuration
echo "Creating client configuration..."
SERVER_PUBLIC_KEY=$(sudo cat /etc/wireguard/server_public.key)
CLIENT_PRIVATE_KEY=$(sudo cat /etc/wireguard/client_private.key)

cat << EOF | sudo tee /etc/wireguard/client.conf
[Interface]
PrivateKey = ${CLIENT_PRIVATE_KEY}
Address = 10.0.0.2/32
DNS = 1.1.1.1, 1.0.0.1

[Peer]
PublicKey = ${SERVER_PUBLIC_KEY}
Endpoint = ${SERVER_IP}:51820
AllowedIPs = 0.0.0.0/0, ::/0
PersistentKeepalive = 25
EOF

# Start WireGuard
echo "Starting WireGuard..."
sudo systemctl enable wg-quick@wg0
sudo systemctl start wg-quick@wg0

# Create directory for client configs
mkdir -p ~/wireguard-client-configs
cp /etc/wireguard/client.conf ~/wireguard-client-configs/
chmod 700 ~/wireguard-client-configs

# Generate QR code
echo "Generating QR code..."
qrencode -t ansiutf8 < /etc/wireguard/client.conf > ~/wireguard-client-configs/client-qr.txt

# Print status information
echo "
========================================
WireGuard Installation Complete!
========================================

Server Information:
- Public IP: ${SERVER_IP}
- Port: 51820
- Interface: wg0

Client configuration has been saved to:
~/wireguard-client-configs/client.conf

QR code for mobile clients has been saved to:
~/wireguard-client-configs/client-qr.txt

To check WireGuard status:
sudo wg show

To view the QR code for mobile clients:
cat ~/wireguard-client-configs/client-qr.txt
"

# Show WireGuard status
echo "Current WireGuard status:"
sudo wg show

Using the VPN

For Desktop Clients

  1. Install WireGuard client for your operating system:

  2. Copy the contents of ~/wireguard-client-configs/client.conf to your client machine

  3. Import the configuration into your WireGuard client

  4. Enable the VPN connection

For Mobile Clients

  1. Install WireGuard app:

  2. Scan the QR code displayed in ~/wireguard-client-configs/client-qr.txt

  3. Enable the VPN connection

Adding Additional Clients

To add more clients, run these commands on the server:

#!/bin/bash

# Generate keys for the new client
CLIENT_NUM=2  # Change this number for each new client
sudo wg genkey | sudo tee "/etc/wireguard/client${CLIENT_NUM}_private.key"
sudo cat "/etc/wireguard/client${CLIENT_NUM}_private.key" | wg pubkey | sudo tee "/etc/wireguard/client${CLIENT_NUM}_public.key"

# Get the keys and server info
NEW_CLIENT_PRIVATE_KEY=$(sudo cat "/etc/wireguard/client${CLIENT_NUM}_private.key")
NEW_CLIENT_PUBLIC_KEY=$(sudo cat "/etc/wireguard/client${CLIENT_NUM}_public.key")
SERVER_PUBLIC_KEY=$(sudo cat /etc/wireguard/server_public.key)
SERVER_IP=$(ip addr show dev eth0 | grep -oP '(?<=inet )([0-9.]+)' | head -1)

# Add peer to server config
sudo tee -a /etc/wireguard/wg0.conf << EOF

[Peer]
PublicKey = ${NEW_CLIENT_PUBLIC_KEY}
AllowedIPs = 10.0.0.$((CLIENT_NUM + 1))/32
EOF

# Create client config
cat << EOF | sudo tee "/etc/wireguard/client${CLIENT_NUM}.conf"
[Interface]
PrivateKey = ${NEW_CLIENT_PRIVATE_KEY}
Address = 10.0.0.$((CLIENT_NUM + 1))/32
DNS = 1.1.1.1, 1.0.0.1

[Peer]
PublicKey = ${SERVER_PUBLIC_KEY}
Endpoint = ${SERVER_IP}:51820
AllowedIPs = 0.0.0.0/0, ::/0
PersistentKeepalive = 25
EOF

# Generate QR code for the new client
qrencode -t ansiutf8 < "/etc/wireguard/client${CLIENT_NUM}.conf" > "/etc/wireguard/client${CLIENT_NUM}-qr.txt"

# Restart WireGuard to apply changes
sudo systemctl restart wg-quick@wg0

echo "New client configuration created:"
echo "Config file: /etc/wireguard/client${CLIENT_NUM}.conf"
echo "QR code: /etc/wireguard/client${CLIENT_NUM}-qr.txt"

Troubleshooting

If you encounter issues, check:

  1. WireGuard service status:
sudo systemctl status wg-quick@wg0
  1. Logs:
sudo journalctl -xeu wg-quick@wg0
  1. Interface status:
sudo wg show
ip addr show wg0
  1. Firewall status:
sudo ufw status
  1. IP forwarding status:
sysctl net.ipv4.ip_forward
sysctl net.ipv6.conf.all.forwarding

All commands in this guide are ready to use without any modifications. The script automatically generates all necessary keys and configurations, and provides clear output about where to find the client configuration files.