Homelab VPN with Wireguard

updated: 2024-02-03

A VPN is a way to create a secure tunnel from a remote network onto your own network. When I am not at home I can still trust my DNS requests and access resources from my personal networks. There are different VPN softwares out there and today I will be setting up WireGuard.

wireguard
wireguard

Installing and configuring WireGuard with Docker

In order to run the WireGuard server, I will be using a docker container inside of a virtual machine. In order to keep this post concise, please check out my previous post on docker if you are not familiar with the technology. I also have a post on setting up virtual machines and yet another post on setting up a dedicated system to run virtual machines with proxmox.

Requirements

In order to proceed, you must have a suitable Linux System with docker installed. See above for posts that will help you meet these requirements.

The container image that will be used here is created by the LinuxServer.io team who keep up with regular security updates and publish images that are not affected by the rate limits of the public Docker Hub.

Wireguard template

In order to preserve the configuration of the WireGuard server that is running in a docker container, we can user a docker-compose template. Save the following as a docker-compose.yml file in a location that you will remember and that is not readable by any user.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
---
version: "2.1"
services:
  wireguard:
    image: ghcr.io/linuxserver/wireguard
    container_name: wireguard
    cap_add:
      - NET_ADMIN
      - SYS_MODULE
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=America/New_York
      - SERVERURL=wireguard.example.com #set this to your public hostname or IP
      - SERVERPORT=51820 #optional for running on a different port
      - PEERS=1 #optional for increasing # of allowed connected clients
      - PEERDNS=auto #optional "auto" will use Host's DNS
      - INTERNAL_SUBNET=10.13.13.0 #optional change wireguard client subnet
      - ALLOWEDIPS=0.0.0.0/0 #optional only allow certain client IPs to connect
    volumes:
      - /path/to/appdata/config:/config
      - /lib/modules:/lib/modules
    ports:
      - 51820:51820/udp
    sysctls:
      - net.ipv4.conf.all.src_valid_mark=1
    restart: unless-stopped

Once this template has been saved, the WireGuard server can be started with the following command:

1
docker compose up -d

Upgrading to new versions

Run these commands in the directory with the docker-compose.yml template:

1
2
docker compose pull
docker compose up -d

Port forwarding

Now in order to connect to your WireGuard server from the internet, you must open the associated port in your firewall and if on a consumer ISP, the best bet is to port forward the WireGuard port to your Internet gateway or router provided by your ISP.

In the example above, the server was configured to use port 51820/udp

Configuring a WireGuard client

Now that the WireGuard server is running, note the IP address and/or DNS hostname of the system. Wait a few minutes for the container to initialize and then run the following command to output the container logs:

1
docker compose logs wireguard

Within this output should be a QR code. We can use this to configure a client to connect to the server.

Connect iOS client

To connect an iOS client, download the official client from the Apple App store. Once the application is downloaded, press the + in the upper right to add a new server. In the following menu, select “Create from QR code”. If you lost the QR code, enter the following command in the container shell:

1
qrencode -t ansiutf8 < tunnel.conf

Line up your camera with the output of the docker-compose logs to scan the QR code generated by the wireguard container. Once the code has scanned, you can choose a name for the VPN connection. Now you should be able to toggle on and off the connection through the WireGuard app.

wireguard_ios
wireguard_ios

comments powered by Disqus