Skip to content

Blog

Setup WireGuard

Setup DNS records

Login to your DNS provider and set A/AAAA DNS records properly. Otherwise, Let's Encrypt (HTTP-01 challenge) and VPN clients will have trouble connecting to the server. In this example, we will use the host vpn.example.com.

Set server routing

This is crucial for routing traffic:

echo -e "# IP Forwarding\\nnet.ipv4.ip_forward = 1\\nnet.ipv6.conf.all.forwarding = 1\\n" >> /etc/sysctl.conf
sysctl -w net.ipv4.ip_forward=1
sysctl -w net.ipv6.conf.all.forwarding=1

Install WireGuard with UI

Tested on Debian 12

  1. Install Docker by following this guide
  2. Create a docker-compose.yml file for the VPN stack

    For WGUI_PASSWORD use a complex password to secure web access.

    For SESSION_SECRET use a 64 alphanumeric string to secure web sessions.

    For WGUI_SERVER_INTERFACE_ADDRESSES change it if you have same subnet in clients' networks.

    For WGUI_DNS change it if you need specific DNS servers to use.

    ---
    services:
    caddy:
        image: 'caddy:latest'
        container_name: 'caddy'
        volumes:
            - '/etc/caddy/Caddyfile:/etc/caddy/Caddyfile:ro'
            - 'caddy-data:/data'
            - 'caddy-config:/config'
        network_mode: 'host'
        restart: 'unless-stopped'
    
    wgui:
        image: 'ngoduykhanh/wireguard-ui:latest'
        container_name: 'wgui'
        cap_add:
            - 'NET_ADMIN'
        environment:
            BIND_ADDRESS: '127.0.0.1:8080'
            SESSION_SECRET: '!Replace_Me_Pl3ase!'
            SESSION_MAX_DURATION: 365
            WGUI_SERVER_INTERFACE_ADDRESSES: '10.10.10.0/24'
            WGUI_SERVER_LISTEN_PORT: 51820
            WGUI_DEFAULT_CLIENT_ALLOWED_IPS: '0.0.0.0/0,::/0'
            WGUI_DEFAULT_CLIENT_EXTRA_ALLOWED_IPS: ''
            WGUI_DEFAULT_CLIENT_USE_SERVER_DNS: true
            WGUI_DEFAULT_CLIENT_ENABLE_AFTER_CREATION: true
            WGUI_USERNAME: 'admin'
            WGUI_PASSWORD: '!Replace_Me_Pl3ase!'
            WGUI_MANAGE_START: true
            WGUI_MANAGE_RESTART: true
            WGUI_DNS: '1.1.1.1,1.0.0.1'
            WGUI_MTU: 1280
            WGUI_PERSISTENT_KEEPALIVE: 25
            WGUI_FIREWALL_MARK: '0xca6c'
        volumes:
            - 'wgui-data:/app/db'
            - '/etc/wireguard:/etc/wireguard'
        network_mode: 'host'
        restart: 'unless-stopped'
    
    volumes:
        caddy-data:
        caddy-config:
        wgui-data:
    
  3. Prepare Caddy files and directories to serve WireGuard-UI via HTTPS:

    mkdir /etc/caddy
    {
        echo "vpn.example.com {"
        echo "  reverse_proxy 127.0.0.1:8080"
        echo "}"
    } > /etc/caddy/Caddyfile
    
  4. Bring the VPN stack up docker compose up -d

  5. Navigate to https://vpn.example.com

Secure server's firewall

Use our Firewall to allow only required ports for the server:

My Dashboard -> WireGuard Service -> Firewall -> Restore Rules -> Upload the below rules file in JSON format snc-wireguard-fwrules.json

[{"proto":"tcp","enable":1,"dport":"80","comment":"HTTP","action":"ACCEPT","iface":"net0","type":"in","pos":0,"sport":null,"macro":null,"source":null,"dest":null},{"proto":"udp","enable":1,"dport":"443","comment":"HTTPS QUIC","action":"ACCEPT","iface":"net0","type":"in","pos":1,"sport":null,"macro":null,"source":null,"dest":null},{"proto":"tcp","enable":1,"dport":"443","comment":"HTTPS","action":"ACCEPT","iface":"net0","type":"in","pos":2,"sport":null,"macro":null,"source":null,"dest":null},{"proto":"tcp","enable":1,"dport":"22","comment":"SSH","action":"ACCEPT","iface":"net0","type":"in","pos":3,"sport":null,"macro":null,"source":null,"dest":null},{"proto":"udp","enable":1,"dport":"51820","comment":"WireGuard","action":"ACCEPT","iface":"net0","type":"in","pos":4,"sport":null,"macro":null,"source":null,"dest":null}]

Now drop everything else except the traffic needed for WireGuard and HTTP/HTTPS:

My Dashboard -> WireGuard Service -> Firewall Options -> Edit -> Input Policy -> DROP -> Save Changes

Set server PostUp and PostDown scripts

In WireGuard-UI, navigate to Wireguard Server to configure scripts:

eth0 is the internet facing network interface (change it, if needed)

Post Up Script:

iptables -A FORWARD -i wg0 -j ACCEPT ; iptables -w -t nat -A POSTROUTING -o eth0 -j MASQUERADE ; ip6tables -w -t nat -A POSTROUTING -o eth0 -j MASQUERADE

Post Down Script:

iptables -D FORWARD -i wg0 -j ACCEPT ; iptables -w -t nat -D POSTROUTING -o eth0 -j MASQUERADE ; ip6tables -w -t nat -D POSTROUTING -o eth0 -j MASQUERADE

Finally, click Save and then start creating new Wireguard Clients.

How To Install Docker on Debian Linux

Debian version supported: 12 (bookworm), 11 (bullseye), 10 (buster).

Docker Engine depends on containerd and runc. Docker Engine bundles these dependencies as one bundle: containerd.io. If you have installed the containerd or runc previously, uninstall them to avoid conflicts with the versions bundled with Docker Engine.

for pkg in docker.io docker-doc docker-compose podman-docker containerd runc; do sudo apt-get remove $pkg; done

After that install Docker Engine using the following commands:

# Add Docker's official GPG key:
sudo apt-get update
sudo apt-get install ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/debian/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc

# Add the repository to Apt sources:
echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/debian \
  $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update

# Install Docker engine:
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

Now you should be ready to go!

Hello world

This is the initial blog post. Expect more!