WireGuard en Tailscale VPN op een Linux VPS

16 min leestijd·Matthieu·securitydebianubuntulinuxheadscalevpntailscalewireguard|

Stel WireGuard helemaal zelf in of implementeer Tailscale voor beheerde VPN-toegang op Ubuntu 24.04 en Debian 12, met DNS-lekpreventie, PreSharedKey-verharding en een neutrale vergelijking inclusief Headscale.

Deze handleiding behandelt twee benaderingen voor VPN-toegang tot een Linux VPS: WireGuard (handmatig, volledige controle) en Tailscale (beheerd, kant-en-klaar). Beide gebruiken het WireGuard-protocol. Het verschil zit in wie de sleutels, routing en coördinatie beheert.

Kies het onderdeel dat bij je situatie past, of lees alle drie de delen om een weloverwogen keuze te maken.

Vereisten:

  • Een VPS met Ubuntu 24.04 of Debian 12 (werkt op een Virtua Cloud VPS)
  • SSH-toegang met een niet-root gebruiker met sudo-rechten
  • Een geconfigureerde en actieve firewall
  • Een lokale machine (Linux, macOS of Windows) als VPN-client

Waarom zou je via VPN verbinden met je Linux VPS?

Elke service die op een publiek IP-adres beschikbaar is, is een doelwit. SSH brute-force bots vinden nieuwe servers binnen enkele minuten. Databasepoorten, beheerpanelen en API-endpoints worden continu gescand. Een VPN houdt beheerinterfaces volledig buiten het publieke internet.

Het principe is eenvoudig: bind gevoelige services aan het VPN-interfaceadres in plaats van aan 0.0.0.0. Alleen apparaten met geldige VPN-sleutels kunnen ze bereiken. Het publieke internet ziet nooit dat deze poorten bestaan.

Veelvoorkomende toepassingen:

  • Beheertoegang zonder publieke SSH. Bind sshd aan het WireGuard-IP. Geen poort 22 meer blootgesteld aan de wereld. Fail2ban wordt optioneel als er niets te bruteforcen valt.
  • Tunnel naar privé AI-inferentie-API's. Draai je Ollama of een privé LLM-endpoint op je VPS? Zet het achter de VPN. Geen API-gateway nodig, geen tokenauthenticatie voor interne toegang.
  • Multi-cloud mesh-netwerk. Verbind VPS-nodes van verschillende providers (Virtua, Hetzner, OVH) in een privénetwerk. Services communiceren via versleutelde tunnels zonder publieke endpoints.
  • Versleuteling van verkeer op onbetrouwbare netwerken. Routeer al het verkeer via de VPS wanneer je werkt vanuit cafés of hotel-WiFi. Je ISP en de lokale netwerkbeheerder zien alleen versleutelde WireGuard-pakketten.

Het dreigingsmodel telt. Als je alleen vanaf een vast kantoor-IP toegang hebt tot je VPS, kunnen firewallregels volstaan. Maar als je vanaf meerdere locaties werkt, meerdere apparaten gebruikt of een team beheert met verschillende toegangsniveaus, is een VPN de schonere oplossing.

Hoe stel je WireGuard in op Ubuntu 24.04 of Debian 12?

WireGuard is een VPN-protocol dat sinds versie 5.6 in de Linux-kernel is ingebouwd. Het gebruikt Curve25519 voor sleuteluitwisseling, ChaCha20 voor versleuteling en bestaat uit ongeveer 4.000 regels code (vergeleken met meer dan 100.000 voor OpenVPN). Installeer het met apt, genereer sleutelparen, schrijf een configuratiebestand en start de tunnel. Het hele proces duurt minder dan 10 minuten.

Installeer WireGuard op de server:

sudo apt update && sudo apt install wireguard wireguard-tools -y

Het pakket wireguard levert de kernelmodule. Het pakket wireguard-tools levert de userspace-hulpprogramma's wg en wg-quick.

Hoe genereer je WireGuard-sleutels en configureer je de server?

WireGuard gebruikt asymmetrische sleutelparen (één per peer) plus een optionele preshared key voor post-kwantumverdediging. Genereer een serversleutelpaar, een clientsleutelpaar en een gedeelde preshared key. De preshared key voegt een laag symmetrische versleuteling toe bovenop de Curve25519-uitwisseling van WireGuard. Als een toekomstige kwantumcomputer de asymmetrische sleuteluitwisseling breekt, beschermt de symmetrische preshared key de tunnel nog steeds.

Genereer op de server de sleutels met een restrictief umask zodat bestanden met 600-rechten worden aangemaakt:

umask 077
wg genkey | sudo tee /etc/wireguard/server_private.key | wg pubkey | sudo tee /etc/wireguard/server_public.key
wg genpsk | sudo tee /etc/wireguard/psk.key
ls -la /etc/wireguard/
-rw------- 1 root root   45 Mar 19 10:01 psk.key
-rw------- 1 root root   45 Mar 19 10:01 server_private.key
-rw------- 1 root root   45 Mar 19 10:01 server_public.key

Alle drie bestanden hebben rechten 600 (alleen lezen/schrijven voor de eigenaar). De privésleutel en preshared key mogen nooit de server verlaten.

Genereer op je lokale machine (de client) een eigen sleutelpaar:

umask 077
wg genkey | tee client_private.key | wg pubkey > client_public.key

Je hebt de publieke sleutel van de client nodig op de server, en de publieke sleutel van de server op de client. De preshared key gaat naar beide kanten. Verstuur nooit privésleutels.

IP-forwarding inschakelen

De server moet verkeer routeren voor VPN-clients. Schakel IPv4- en IPv6-forwarding in:

echo 'net.ipv4.ip_forward = 1' | sudo tee /etc/sysctl.d/99-wireguard.conf
echo 'net.ipv6.conf.all.forwarding = 1' | sudo tee -a /etc/sysctl.d/99-wireguard.conf
sudo sysctl -p /etc/sysctl.d/99-wireguard.conf
net.ipv4.ip_forward = 1
net.ipv6.conf.all.forwarding = 1

Een bestand in /etc/sysctl.d/ gebruiken heeft de voorkeur boven het direct bewerken van /etc/sysctl.conf. Het overleeft pakketupdates en maakt duidelijk welke instellingen bij welke service horen.

Serverconfiguratie

Identificeer de publieke netwerkinterface van je server:

ip route show default
default via 203.0.113.1 dev eth0 proto static metric 100

In dit voorbeeld is de interface eth0. De jouwe kan ens3, ens18 of iets anders zijn. Gebruik wat er na dev staat.

Maak de serverconfiguratie aan:

sudo nano /etc/wireguard/wg0.conf
[Interface]
Address = 10.66.66.1/24, fd42:42:42::1/64
ListenPort = 51820
PrivateKey = <inhoud van /etc/wireguard/server_private.key>
PostUp = nft add table ip wireguard; nft add chain ip wireguard forward { type filter hook forward priority 0 \; policy accept \; }; nft add rule ip wireguard forward iifname "wg0" accept; nft add table ip nat; nft add chain ip nat postrouting { type nat hook postrouting priority 100 \; }; nft add rule ip nat postrouting oifname "eth0" masquerade
PostDown = nft delete table ip wireguard; nft delete table ip nat

[Peer]
PublicKey = <inhoud van client_public.key>
PresharedKey = <inhoud van /etc/wireguard/psk.key>
AllowedIPs = 10.66.66.2/32, fd42:42:42::2/128

Vervang eth0 in de PostUp/PostDown-regels door je werkelijke interfacenaam.

Wat elke sectie doet:

  • Address: het VPN-IP dat aan deze server is toegewezen. /24 en /64 bepalen de grootte van het VPN-subnet.
  • ListenPort: de UDP-poort waarop WireGuard luistert. 51820 is de conventie.
  • PostUp/PostDown: nftables-regels die NAT-masquerading inschakelen. Wanneer een VPN-client verkeer naar internet stuurt, herschrijft de server het bron-IP naar zijn eigen publieke IP. Dit maakt full-tunnel VPN mogelijk.
  • AllowedIPs in de [Peer]-sectie: welke VPN-IP's deze client mag gebruiken. /32 betekent precies één IP. Dit voorkomt dat clients andere VPN-adressen vervalsen.

Als je ufw gebruikt in plaats van nftables direct, vervang PostUp/PostDown door:

PostUp = ufw route allow in on wg0 out on eth0; iptables -t nat -I POSTROUTING -o eth0 -j MASQUERADE
PostDown = ufw route delete allow in on wg0 out on eth0; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE

Vergrendel het configuratiebestand. Het bevat je privésleutel:

sudo chmod 600 /etc/wireguard/wg0.conf

Firewall openen en tunnel starten

Sta de WireGuard UDP-poort toe in de firewall:

sudo ufw allow 51820/udp

Of direct met nftables:

sudo nft add rule inet filter input udp dport 51820 accept

Start de tunnel. De enable-aanwijzing maakt hem persistent na herstarts. De --now-vlag start hem direct:

sudo systemctl enable --now wg-quick@wg0
sudo systemctl status wg-quick@wg0
● wg-quick@wg0.service - WireGuard via wg-quick(8) for wg0
     Loaded: loaded (/usr/lib/systemd/system/wg-quick@.service; enabled; preset: enabled)
     Active: active (exited) since ...

De status toont active (exited) omdat wg-quick de interface instelt en dan stopt. De kernelmodule beheert de tunnel vanaf dat moment. Controleer de actieve tunnel:

sudo wg show
interface: wg0
  public key: aB3dEfGhIjKlMnOpQrStUvWxYz1234567890abc=
  private key: (hidden)
  listening port: 51820

peer: xY9zAbCdEfGhIjKlMnOpQrStUvWxYz1234567890=
  preshared key: (hidden)
  allowed ips: 10.66.66.2/32, fd42:42:42::2/128

De output (hidden) betekent dat WireGuard gevoelig sleutelmateriaal beschermt. Als je latest handshake ziet voor een peer, heeft die peer succesvol verbinding gemaakt.

Clientconfiguratie

Maak op je lokale machine de WireGuard-configuratie aan:

sudo nano /etc/wireguard/wg0.conf
[Interface]
Address = 10.66.66.2/24, fd42:42:42::2/64
PrivateKey = <inhoud van client_private.key>
DNS = 10.66.66.1

[Peer]
PublicKey = <inhoud van server_public.key>
PresharedKey = <inhoud van psk.key>
AllowedIPs = 0.0.0.0/0, ::/0
Endpoint = YOUR_SERVER_PUBLIC_IP:51820
PersistentKeepalive = 25

Uitleg van de belangrijke instellingen:

  • AllowedIPs = 0.0.0.0/0, ::/0 routeert al het verkeer via de VPN (full tunnel). Voor split tunneling waarbij alleen VPN-subnetverkeer door de tunnel gaat, gebruik je AllowedIPs = 10.66.66.0/24, fd42:42:42::/64.
  • Endpoint is het publieke IP en de poort van de server. De client heeft dit nodig om de verbinding te starten. De server heeft het endpoint van de client niet nodig omdat het dit leert uit inkomende pakketten.
  • PersistentKeepalive = 25 stuurt elke 25 seconden een keepalive-pakket. Dit houdt NAT-mappings actief zodat de server de client kan bereiken. Zonder dit valt de verbinding weg na NAT-timeout (doorgaans 30-120 seconden inactiviteit).
  • DNS = 10.66.66.1 stuurt DNS-queries naar het VPN-adres van de server. Dit voorkomt DNS-lekken (uitgelegd in de volgende sectie).

Op macOS en Windows gebruik je de WireGuard-app. Importeer het configuratiebestand of plak het erin.

Verbind vanaf de client:

sudo wg-quick up wg0
ping 10.66.66.1
PING 10.66.66.1 (10.66.66.1) 56(84) bytes of data.
64 bytes from 10.66.66.1: icmp_seq=1 ttl=64 time=4.23 ms
64 bytes from 10.66.66.1: icmp_seq=2 ttl=64 time=3.98 ms

Bevestig vanaf je lokale machine dat je publieke IP is veranderd (bij full tunnel):

curl -s https://ifconfig.me

Dit moet het publieke IP van de VPS teruggeven, niet je thuis-IP.

Meer clients toevoegen

Genereer voor elke extra client een nieuw sleutelpaar en een nieuwe preshared key (één PSK per peer-paar). Voeg een [Peer]-blok toe aan de wg0.conf van de server:

[Peer]
PublicKey = <nieuwe publieke client-sleutel>
PresharedKey = <nieuwe preshared key>
AllowedIPs = 10.66.66.3/32, fd42:42:42::3/128

Verhoog het IP-adres voor elke client. Herlaad na het bewerken zonder bestaande verbindingen te verbreken:

sudo wg syncconf wg0 <(sudo wg-quick strip wg0)

Dit past de nieuwe peer-configuratie toe zonder de interface te herstarten. Bestaande verbindingen blijven actief.

MTU-afstemming

WireGuard voegt 60 bytes overhead per pakket toe (28 bytes voor de buitenste IPv4- en UDP-headers, 32 bytes voor de WireGuard-header). Als je VPS een standaard MTU van 1500 bytes heeft, stel de WireGuard MTU dan in op 1420 in de [Interface]-sectie:

MTU = 1420

Stel dit in op zowel server als client. Niet-overeenkomende MTU's veroorzaken pakketfragmentatie en doorvoerdalingen die moeilijk te diagnosticeren zijn. Als je WireGuard draait over een verbinding met al verlaagde MTU (PPPoE, VXLAN), trek dit er dan van af.

Hoe voorkom je DNS-lekken met WireGuard?

DNS-lekken treden op wanneer je systeem DNS-queries buiten de VPN-tunnel om stuurt, waardoor de domeinen die je bezoekt worden blootgesteld aan je ISP of lokaal netwerk. Dit maakt het privacyvoordeel van VPN-routing teniet. De oplossing: draai een lokale DNS-resolver op de VPN-server en wijs de DNS van de client er doorheen via de tunnel.

Installeer Unbound op de server:

sudo apt install unbound -y

Maak een configuratiebestand zodat Unbound luistert op de WireGuard-interface:

sudo nano /etc/unbound/unbound.conf.d/wireguard.conf
server:
    interface: 10.66.66.1
    interface: fd42:42:42::1
    interface: 127.0.0.1
    access-control: 10.66.66.0/24 allow
    access-control: fd42:42:42::/64 allow
    access-control: 127.0.0.0/8 allow
    do-ip6: yes
    hide-identity: yes
    hide-version: yes
    harden-glue: yes
    harden-dnssec-stripped: yes
    use-caps-for-id: yes
    prefetch: yes

De hide-identity- en hide-version-richtlijnen voorkomen dat Unbound zijn softwareversie prijsgeeft in DNS-antwoorden. Versie-openbaarmaking helpt aanvallers bij het richten op bekende kwetsbaarheden. De harden-*-opties dwingen DNSSEC-validatie af en voorkomen cache poisoning. De optie use-caps-for-id voegt 0x20-codering toe aan DNS-queries, een lichtgewicht verdediging tegen vervalste antwoorden.

Op Ubuntu 24.04 luistert systemd-resolved standaard op poort 53 en botst met Unbound. Schakel het uit:

sudo systemctl disable --now systemd-resolved
sudo rm /etc/resolv.conf
echo "nameserver 127.0.0.1" | sudo tee /etc/resolv.conf

Start Unbound:

sudo systemctl enable --now unbound
sudo systemctl status unbound
 unbound.service - Unbound DNS server
     Loaded: loaded (/usr/lib/systemd/system/unbound.service; enabled; preset: enabled)
     Active: active (running) since ...

Test of Unbound oplost vanaf de WireGuard-interface:

dig @10.66.66.1 example.com +short

Je zou een of meer IP-adressen terug moeten krijgen. De exacte IP's hangen af van de huidige DNS-records van het domein.

De clientconfiguratie stelt al DNS = 10.66.66.1 in. Wanneer de WireGuard-tunnel actief is, gaan alle DNS-queries via de versleutelde tunnel naar Unbound. Geen queries lekken naar je ISP.

Ter bevestiging aan de clientzijde, verbind met de VPN en controleer:

resolvectl status wg0

De DNS-server moet alleen 10.66.66.1 tonen. Je kunt ook dnsleaktest.com gebruiken.

Test Vóór VPN Na VPN (met Unbound)
Getoonde DNS-server ISP-resolver (bijv. 192.168.1.1) 10.66.66.1 (VPS Unbound)
IP gezien door testsite Thuis-/kantoor-IP Publiek VPS-IP
DNS-queries zichtbaar voor ISP Ja Nee

Voor meer over DNS-beveiliging waaronder DNSSEC en DNS-over-HTTPS, zie.

Kill switch: wat gebeurt er als de tunnel wegvalt?

Als de WireGuard-tunnel wegvalt, stroomt verkeer onversleuteld via je standaardroute. Je echte IP en DNS-queries worden blootgesteld. Een kill switch voorkomt dit door al het niet-VPN-verkeer op firewallniveau te blokkeren.

Op de client voeg je nftables-regels toe die alleen verkeer toestaan via de WireGuard-interface en de versleutelde verbinding naar het server-endpoint:

sudo nft add table inet killswitch
sudo nft add chain inet killswitch output { type filter hook output priority 0 \; policy drop \; }
sudo nft add rule inet killswitch output oifname "wg0" accept
sudo nft add rule inet killswitch output ip daddr YOUR_SERVER_PUBLIC_IP udp dport 51820 accept
sudo nft add rule inet killswitch output oifname "lo" accept

Hiermee wordt al het uitgaand verkeer geblokkeerd als wg0 wegvalt. Geen DNS-lekken, geen plaintext-pakketten. Het enige toegestane verkeer is de versleutelde WireGuard-handshake naar de server.

Verwijder de kill switch om normaal routeren te herstellen:

sudo nft delete table inet killswitch

Voor een persistente kill switch die automatisch activeert, sla deze regels op in een bestand en laad ze met een systemd-service die vóór wg-quick@wg0 start.

Hoe installeer je Tailscale op een Linux VPS?

Tailscale is een mesh-VPN-service gebouwd op WireGuard. Het regelt sleuteldistributie, NAT-traversal en peer-discovery via een coördinatieserver. Je installeert de client, authenticeert met je identity provider en je apparaten kunnen elkaar bereiken. Geen handmatige sleuteluitwisseling, geen port forwarding, geen firewallregels openen.

De afweging: Tailscale's coördinatieserver is een service van derden. Het ziet metadata van je apparaten (IP's, hostnamen, welke apparaten online zijn) maar nooit je verkeer, dat peer-to-peer via WireGuard stroomt.

Hoe installeer je Tailscale op Ubuntu 24.04 of Debian 12?

Voeg de officiële Tailscale-repository toe en installeer het pakket. Dit vermijdt curl | sh en laat je updates verifiëren via apt.

Voor Ubuntu 24.04 (Noble):

sudo mkdir -p --mode=0755 /usr/share/keyrings
curl -fsSL https://pkgs.tailscale.com/stable/ubuntu/noble.noarmor.gpg | sudo tee /usr/share/keyrings/tailscale-archive-keyring.gpg >/dev/null
curl -fsSL https://pkgs.tailscale.com/stable/ubuntu/noble.tailscale-keyring.list | sudo tee /etc/apt/sources.list.d/tailscale.list
sudo apt-get update && sudo apt-get install tailscale -y

Voor Debian 12 (Bookworm):

sudo mkdir -p --mode=0755 /usr/share/keyrings
curl -fsSL https://pkgs.tailscale.com/stable/debian/bookworm.noarmor.gpg | sudo tee /usr/share/keyrings/tailscale-archive-keyring.gpg >/dev/null
curl -fsSL https://pkgs.tailscale.com/stable/debian/bookworm.tailscale-keyring.list | sudo tee /etc/apt/sources.list.d/tailscale.list
sudo apt-get update && sudo apt-get install tailscale -y

Start Tailscale en authenticeer:

sudo tailscale up

Dit toont een authenticatie-URL. Open deze in je browser en log in met je identity provider (Google, Microsoft, GitHub, etc.). Na authenticatie treedt de VPS toe tot je tailnet.

sudo systemctl status tailscaled
 tailscaled.service - Tailscale node agent
     Loaded: loaded (/usr/lib/systemd/system/tailscaled.service; enabled; preset: enabled)
     Active: active (running) since ...

Controleer het toegewezen Tailscale-IP:

tailscale ip -4
100.64.0.1

Elk apparaat in je tailnet krijgt een stabiel 100.x.x.x-adres (CGNAT-bereik). Dit IP blijft behouden na herstarts en herverbindingen. Gebruik het om je VPS te bereiken vanaf elk ander apparaat in hetzelfde tailnet.

Controleer de connectiviteit met je andere apparaten:

tailscale status
100.64.0.1    vps-frankfurt    youruser@  linux   -
100.64.0.2    laptop           youruser@  macOS   active; direct 203.0.113.50:41641

De aanduiding direct betekent dat verkeer peer-to-peer via WireGuard stroomt. Als er relay staat, gaat verkeer via een DERP-relayserver, wat latentie toevoegt. DERP-relaying treedt op wanneer beide peers achter restrictieve NATs zitten die directe verbindingen verhinderen.

Sleutelvervaldatum uitschakelen voor servers

Tailscale-sleutels verlopen standaard na 180 dagen. Bij verlopen gaat het apparaat offline tot iemand het opnieuw authenticeert. Voor een VPS die verbonden moet blijven heb je twee opties.

Optie 1: vervaldatum uitschakelen in de admin-console. Ga naar de Machines-pagina, zoek je VPS, klik op het menu en selecteer "Disable key expiry".

Optie 2 (aanbevolen): een getagde auth-key gebruiken. Getagde apparaten hebben de vervaldatum automatisch uitgeschakeld. Genereer een herbruikbare, getagde auth-key in de admin-console onder Settings > Keys en join met:

sudo tailscale up --auth-key=tskey-auth-XXXXX --advertise-tags=tag:server

Tags werken ook met ACL's (hieronder behandeld), wat ze de betere keuze maakt voor serverinfrastructuur.

Hoe configureer je een Tailscale exit node op je VPS?

Een exit node routeert al het internetverkeer van je apparaten via de VPS. Je uitgaand verkeer lijkt afkomstig van het IP-adres van de VPS. Dit werkt als een traditionele VPN: alles versleutelen, uitkomen op de locatie van de VPS.

Schakel IP-forwarding in op de VPS:

echo 'net.ipv4.ip_forward = 1' | sudo tee /etc/sysctl.d/99-tailscale.conf
echo 'net.ipv6.conf.all.forwarding = 1' | sudo tee -a /etc/sysctl.d/99-tailscale.conf
sudo sysctl -p /etc/sysctl.d/99-tailscale.conf

Adverteer de VPS als exit node:

sudo tailscale set --advertise-exit-node

Keur de exit node goed in de admin-console. Zoek de VPS, klik op het menu, ga naar "Edit route settings" en schakel "Use as exit node" in.

Vanaf je clientapparaat, begin de exit node te gebruiken:

sudo tailscale set --exit-node=<vps-tailscale-ip>

Om lokale LAN-toegang te behouden (printers, NAS, andere lokale apparaten) terwijl internetverkeer via de exit node loopt:

sudo tailscale set --exit-node=<vps-tailscale-ip> --exit-node-allow-lan-access=true

Om te stoppen met routeren via de exit node:

sudo tailscale set --exit-node=

Bevestig dat de exit node werkt door je publieke IP te controleren vanaf de client:

curl -s https://ifconfig.me

Dit moet het publieke IP van de VPS teruggeven.

Subnetroutering

Subnetroutering stelt een privénetwerk achter de VPS beschikbaar voor je tailnet. Dit is nuttig wanneer je VPS een privé databasesubnet of interne services kan bereiken die zelf geen Tailscale draaien.

sudo tailscale set --advertise-routes=192.168.1.0/24

Keur de route goed in de admin-console op dezelfde manier als exit nodes. Na goedkeuring kunnen alle tailnet-apparaten 192.168.1.0/24 bereiken via de VPS als gateway, zonder Tailscale op elke host in dat subnet te installeren.

Je kunt meerdere routes adverteren door ze met komma's te scheiden:

sudo tailscale set --advertise-routes=192.168.1.0/24,10.0.0.0/16

Voor zwaar belaste subnetrouters met veel gelijktijdige flows raadt Tailscale kernel-modus (alleen Linux) aan boven userspace-modus. Op Linux is kernel-modus de standaard. Controleer met:

tailscale debug prefs | grep RouteAll

Hoe stel je Tailscale-ACL's in voor VPS-toegang?

Standaard kunnen alle apparaten in een tailnet elkaar op alle poorten bereiken. Voor productie beperk je dit met ACL's in het tailnet-beleidsbestand.

Een minimaal beleid dat VPS-toegang beperkt tot een admin-groep:

{
  "groups": {
    "group:admins": ["alice@example.com", "bob@example.com"]
  },
  "tagOwners": {
    "tag:server": ["group:admins"]
  },
  "acls": [
    {
      "action": "accept",
      "src": ["group:admins"],
      "dst": ["tag:server:*"]
    }
  ]
}

Dit betekent: alleen leden van group:admins kunnen apparaten met de tag tag:server bereiken. Alle andere verbindingen worden standaard geweigerd. Bewerk dit in de admin-console onder Access Controls.

Tag de VPS bij het toetreden tot het tailnet:

sudo tailscale up --advertise-tags=tag:server

Een gedetailleerder beleid kan per poort beperken:

{
  "groups": {
    "group:admins": ["alice@example.com"],
    "group:developers": ["bob@example.com", "charlie@example.com"]
  },
  "tagOwners": {
    "tag:server": ["group:admins"]
  },
  "acls": [
    {
      "action": "accept",
      "src": ["group:admins"],
      "dst": ["tag:server:*"]
    },
    {
      "action": "accept",
      "src": ["group:developers"],
      "dst": ["tag:server:22,80,443"]
    }
  ]
}

Ontwikkelaars krijgen SSH- (22) en webtoegang (80, 443). Admins hebben volledige toegang. Niemand anders kan de server bereiken. Tailscale handhaaft deze regels op clientniveau, zodat verkeer wordt geblokkeerd voordat het de server bereikt.

MagicDNS

Tailscale bevat MagicDNS, dat elk apparaat een hostnaam geeft die binnen het tailnet kan worden opgelost. In plaats van 100.64.0.1 te onthouden, SSH je naar vps-frankfurt. Schakel het in via de admin-console onder DNS-instellingen. Geen Unbound of handmatige DNS-configuratie nodig.

Wat is Headscale en wanneer moet je het gebruiken?

Headscale is een open-source, zelf-gehoste implementatie van de Tailscale-coördinatieserver. Het gebruikt standaard Tailscale-clients maar draait het control plane op je eigen infrastructuur. Geen apparaatlimieten, geen telemetrie, geen afhankelijkheid van Tailscale's SaaS. Compatibel met alle officiële Tailscale-clients (Linux, macOS, Windows, iOS, Android).

De architectuur:

┌─────────────┐       ┌──────────────────┐       ┌─────────────┐
│  Client A    │──────▶│   Headscale      │◀──────│  Client B    │
│  (tailscale) │       │ (jouw server)    │       │  (tailscale) │
└──────┬───────┘       └──────────────────┘       └──────┬───────┘
       │                                                  │
       └────────────── WireGuard-tunnel ──────────────────┘
                     (direct, peer-to-peer)

Headscale beheert de sleuteluitwisseling, apparaatregistratie en ACL-handhaving. Het daadwerkelijke VPN-verkeer stroomt direct tussen peers via WireGuard. Headscale ziet nooit je dataverkeer, alleen coördinatiemetadata.

Wat Headscale vandaag ondersteunt: apparaatregistratie (CLI en OIDC), ACL's, subnetrouters, exit nodes, MagicDNS, pre-auth-sleutels en tagging. Het dekt de kern van Tailscale's functionaliteiten.

Wat het niet ondersteunt: Tailscale Funnel, Serve, netwerkflow-logs en sommige bètafuncties. De beheerinterface is alleen CLI. Door de community gebouwde web-UI's bestaan (headscale-ui) maar dekken niet elke functionaliteit.

Wanneer Headscale zinvol is:

  • Regelgeving verbiedt coördinatieservers van derden. Voor Tailscale's SaaS kunnen AVG-verwerkersovereenkomsten nodig zijn. Headscale elimineert die afhankelijkheid.
  • Je hebt meer apparaten nodig dan het gratis Tailscale-abonnement toestaat.
  • Je wilt volledige auditcontrole over apparaatregistratie en sleutelbeheer.
  • Je bouwt infrastructuur waarbij afhankelijkheid van een externe SaaS een single point of failure is.

Wanneer niet:

  • Je hebt Tailscale's wereldwijde DERP-relaynetwerk nodig voor betrouwbare NAT-traversal. Headscale kan DERP gebruiken, maar je moet je eigen relays draaien of accepteren dat je de publieke relays van Tailscale gebruikt.
  • Je wilt een gepolijste beheerinterface. Headscale is CLI-first.
  • Je hebt een klein team en geen zin om nóg een service te onderhouden.

Een volledige Headscale-installatietutorial is gepland voor een toekomstig artikel. Zie voorlopig de Headscale-documentatie.

WireGuard vs Tailscale vs Headscale: welke past bij jouw situatie?

Gebruik WireGuard als je volledige controle, minimale latentie, air-gapped netwerken of wettelijke vereisten nodig hebt die coördinatieservers van derden verbieden. Gebruik Tailscale als je meerdere apparaten beheert, NAT-traversal zonder port forwarding nodig hebt of ACL's wilt zonder handmatige configuratie. Voor teams die Tailscale-functies willen met zelf-gehost beheer, overweeg Headscale.

Dimensie WireGuard Tailscale Headscale
Installatietijd 10-15 min per peer 2 min per apparaat 30-60 min (server + clients)
Sleutelbeheer Handmatig (zelf genereren, distribueren, roteren) Automatisch (coördinatieserver) Automatisch (jouw coördinatieserver)
NAT-traversal Geen. Vereist port forwarding of publiek IP aan minstens één kant Ingebouwd (DERP-relays + STUN) Gedeeltelijk (eigen DERP of publieke relays)
Peer-discovery Handmatige config per peer Automatisch mesh Automatisch mesh
ACL's Firewallregels (nftables/iptables) Beleidsbestand in admin-console Beleidsbestand op jouw server
Max apparaten Onbeperkt Gratis abonnement heeft limieten (zie prijspagina) Onbeperkt
Multi-cloud mesh Config op elke node, N*(N-1)/2 peer-entries Join tailnet, mesh vormt automatisch Zoals Tailscale, zelf-gehost beheer
Afhankelijkheid derden Geen Tailscale Inc. (alleen coördinatie) Geen
AVG / compliance Volledige controle, geen verwerker van derden Tailscale verwerkt apparaatmetadata Volledige controle
DNS Handmatig (Unbound, etc.) MagicDNS (automatisch, hostnamen per apparaat) MagicDNS (met configuratie)
Latentie Minimaal (WireGuard op kernelniveau) Minimaal bij direct; +20-50 ms bij DERP-relay Zoals Tailscale
Team-onboarding Config-bestanden en sleutels handmatig delen Uitnodigingslink, SSO-login Registratie via CLI of OIDC
Post-kwantumverdediging PreSharedKey (handmatige setup) Niet door gebruiker configureerbaar Niet door gebruiker configureerbaar

Beslissingshulp

Solo-ontwikkelaar, één VPS: WireGuard. Het eenvoudigste pad. Nul afhankelijkheden. Laagst mogelijke latentie. Je genereert twee sleutels en schrijft twee configuratiebestanden.

Team van 3-15 personen, meerdere apparaten: Tailscale. De coördinatieserver bespaart uren sleutelbeheer. ACL's zijn netter dan nftables-regels per peer onderhouden. NAT-traversal werkt zonder netwerkwijzigingen.

Gereguleerde omgeving of verplichting tot self-hosting: Headscale als je de Tailscale-ervaring wilt zonder afhankelijkheid van derden. Puur WireGuard als je nul bewegende delen wilt en je team configuraties kan beheren.

Multi-cloud mesh (5+ nodes bij verschillende providers): Tailscale of Headscale. Met WireGuard vereisen 10 nodes in totaal 45 peer-entries. Bij 20 nodes zijn dat er 190. De configuratiebeheerlast groeit kwadratisch.

Toegang tot AI-inferentie-endpoint: Als je een tunnel maakt naar een GPU-VPS vanaf je laptop, werken beide. Tailscale is sneller op te zetten. WireGuard voegt geen meetbare overhead toe voor latentiegevoelige inferentie-aanroepen. Voor multi-GPU-setups bij verschillende providers is Tailscale's mesh de afweging waard.

Probleemoplossing

WireGuard-tunnel actief maar geen verkeer:

Controleer IP-forwarding:

sysctl net.ipv4.ip_forward

Moet net.ipv4.ip_forward = 1 teruggeven. Controleer of de masquerade-regels geladen zijn:

sudo nft list ruleset | grep masquerade

Als leeg, zijn de PostUp-regels niet uitgevoerd. Herstart met sudo systemctl restart wg-quick@wg0 en controleer journalctl -u wg-quick@wg0 op fouten.

WireGuard-handshake wordt nooit voltooid:

sudo wg show

Als latest handshake nooit verschijnt voor een peer, is UDP-poort 51820 ergens geblokkeerd. Bevestig dat de server luistert:

sudo ss -ulnp | grep 51820
UNCONN 0      0        0.0.0.0:51820      0.0.0.0:*

WireGuard gebruikt de kernelmodule direct, dus ss toont mogelijk geen procesnaam voor de socket.

Test dan vanaf de clientkant. Als je client achter een bedrijfsfirewall zit, kan UDP 51820 geblokkeerd zijn. Sommige netwerken staan alleen TCP 443 toe.

Tailscale toont "offline" in de admin-console:

sudo systemctl status tailscaled

Als het draait maar offline is, authenticeer opnieuw:

sudo tailscale up --force-reauth

Als tailscaled niet draait, controleer op poortconflicten met andere VPN-software.

DNS lekt nog steeds na Unbound-setup:

Controleer of Unbound luistert op het WireGuard-IP:

ss -ulnp | grep :53

Zoek 10.66.66.1:53 in de output. Als Unbound alleen bindt aan 127.0.0.1, controleer de interface:-regels in /etc/unbound/unbound.conf.d/wireguard.conf.

Op Ubuntu, controleer ook of systemd-resolved daadwerkelijk gestopt is:

sudo systemctl is-active systemd-resolved

Als het active teruggeeft, concurreert het met Unbound om poort 53.

Service-logs:

journalctl -u wg-quick@wg0 -f
journalctl -u tailscaled -f
journalctl -u unbound -f

Copyright 2026 Virtua.Cloud. Alle rechten voorbehouden. Deze inhoud is een origineel werk van het Virtua.Cloud-team. Reproductie, herpublicatie of herdistributie zonder schriftelijke toestemming is verboden.

Klaar om het zelf te proberen?

Deploy uw eigen server in seconden. Linux, Windows of FreeBSD.

Bekijk VPS-aanbod