Bescherm je thuisnetwerk met een zelfgebouwde VPN
Wanneer je op afstand een apparaat of server in je thuisnetwerk benadert, is dat niet zonder risico. Met een eigen VPN-server creëer je een versleutelde verbinding. Daarmee blijft je netwerk van buitenaf onzichtbaar, behalve voor geautoriseerde apparaten zoals je smartphone.
In dit artikel laten we zien hoe je zelf een VPN-server opzet met WireGuard:
- Installeer Docker Desktop op een Windows-pc
- Maak een docker-compose.yml-bestand aan
- Controleer of het WireGuard-dashboard lokaal bereikbaar is
- Maak een VPN-client aan en verbind je smartphone via de WireGuard-app met een QR-code
- Maak externe toegang mogelijk door je publieke IP-adres in te stellen in het yml-bestand
- Configureer poortdoorverwijzing op je router om externe VPN-verzoeken door te sturen
- Gebruik DuckDNS om je VPN bereikbaar te houden via een vast domein, zelfs bij een dynamisch IP-adres
- Laat een tweede container draaien om je DuckDNS-adres automatisch te updaten
Stel ook je thuisnetwerk goed in: Netwerken zonder gedoe: de ultieme gids voor (gevorderde) thuisgebruikers
Het kan handig zijn om bijvoorbeeld services op je thuiscomputer, of andere apparaten, zoals ip-camera’s en domotica op afstand te benaderen. Veel gebruikers maken dit mogelijk met een poortdoorverwijzing in de router. Deze gaat rechtstreeks naar een of andere interne service waardoor de poorten van deze services ook van buitenaf bereikbaar zijn. Dit is helaas niet de veiligste oplossing. Veel botnets en hackers scannen namelijk automatisch op open poorten om vervolgens gerichte aanvallen uit te voeren. Zo kan ook malware worden geïnstalleerd die zich vervolgens naar andere apparaten in je netwerk kan verspreiden.
Daarnaast is het verkeer met je thuisnetwerk vaak onversleuteld, zeker wanneer je geen https of TLS (Transport Layer Security) gebruikt. Maak je bijvoorbeeld verbinding via een openbaar wifi-netwerk, dan kunnen aanvallers makkelijk je gegevens onderscheppen en je netwerkverkeer manipuleren. Met een eigen VPN-server in je netwerk vermijd je deze risico’s grotendeels. We leggen uit hoe dit werkt, maar vooral hoe je dit installeert op een Windows-pc en je netwerk extern via deze server benadert. Je kunt dit eventueel ook realiseren op je Raspberry Pi, NAS of binnen Home Assistant.
Virtual Private Network
Een VPN-verbinding (Virtual Private Network) werkt door eerst een VPN-server op te zetten en te bepalen welke apparaten of clients toegang krijgen. Dit gebeurt via een cryptografisch sleutelpaar, bestaande uit een publieke en private sleutel, uniek voor elke client. Je kunt VPN-servers meestal ook zo configureren dat elke client aan een specifiek ip-adres wordt gekoppeld, waardoor alleen aanvragen met de juiste publieke sleutel vanaf dat ip-adres worden geaccepteerd. Niet-herkende sleutels krijgen doorgaans helemaal geen reactie (silent drop), wat wel zo veilig is. Alleen vertrouwde apparaten kunnen dus verbinding maken. Bovendien wordt ook het dataverkeer volledig versleuteld, zodat internetproviders en hackers dit niet kunnen lezen.
Als je via een VPN-server op je thuisnetwerk verbinding maakt met het internet, zien verder alleen websites en diensten het publieke ip-adres van je thuisnetwerk. Ze zien dus niet die van je mobiele apparaat. Dit kan handig zijn als je bijvoorbeeld online wilt bankieren vanuit het buitenland. Sommige banken blokkeren buitenlandse transacties of vragen om extra verificatie.
Er zijn enkele betrouwbare VPN-protocollen, zoals OpenVPN, IKEv2/IPsec en WireGuard. In dit artikel gaan we aan de slag met WireGuard. Die biedt niet alleen sterke encryptie en snelle verbindingen (via UDP), maar is via WireGuard Easy relatief eenvoudig te installeren op Linux en Windows (met Docker Compose).
Een veilige verbinding via een versleutelde VPN-tunnel.
Docker Desktop
We installeren de VPN-server op een Windows 11-pc. Dit gaat het eenvoudigst via Docker Desktop. Deze applicatie is beschikbaar voor Windows, macOS en Linux. Hiermee draai je een nagenoeg kant-en-klare WireGuard-server in een geïsoleerde omgeving, oftewel een container.
De installatie verloopt in enkele muisklikken: de eerste keer klik je op Accept en twee keer op Skip. Minimaliseer hierna het venster, maar laat de app draaien. Standaard wordt ook Docker Compose geïnstalleerd, dit is een opdrachtregeltool waarmee je vanuit één configuratiebestand (docker-compose.yml) ook meerdere containers tegelijk kunt starten en beheren. Dit maakt het opzetten van de WireGuard-server eenvoudiger. Je kunt vanaf de Opdrachtprompt met de opdrachten docker info (of docker run hello-world) en docker compose version checken of beide componenten beschikbaar zijn.
Docker Desktop heb je met enkele klikken geïnstalleerd.
Docker Compose
Docker is nu klaar om de WireGuard-container te installeren, starten en beheren. Gebruik hiervoor dit docker-compose.yml-bestand. Scrol op de pagina naar de link docker-compose.yml en druk op het knopje Copy raw file (rechtsboven). Open een teksteditor, zoals Notepad++ of Kladblok. Plak de inhoud met de toetscombinatie Ctrl+V in de editor. Sla dit bestand op als docker-compose.yml in een aparte, eventueel nog te creëren map, bijvoorbeeld C:\Users\<je_gebruikersnaam>\docker\wireguard.
Het nog onbewerkte yml-bestand hebben we lokaal opgeslagen.
Wachtwoord en taal
Wijzig het standaardwachtwoord zonder dit in leesbare vorm op te slaan. Gebruik het veld PASSWORD_HASH en voer hier een versleutelde wachtwoord-hash in.
Ga hiervoor naar de hash generator, vul het gewenste wachtwoord in bij Enter plain text to hash en klik op Generate. Kopieer de Hashed Output met Ctrl+C en plak deze met Ctrl+V achter PASSWORD_HASH= in het yml-bestand. Verwijder hier het commentaarteken # en vervang alle enkele $-tekens in de hash door dubbele $$-tekens. Voor bijvoorbeeld het wachtwoord 123ReshiftNL!!! zou dit opleveren: PASSWORD_HASH=$$2a$$04$$OXVNdAoCApXePuUr1IXNqe2JuDf.62hzkbINCSPGaf4QMOhQadP.i.
Als je het WireGuard-dashboard niet wilt beveiligen, kun je deze regel geheel verwijderen, maar dit is niet aan te raden. Verder kun je de dashboardinterface instellen op Nederlands door in het yml-bestand – LANG=en te vervangen door – LANG=nl.
Veiligheidshalve gebruik je een wachtwoordhash en dus niet het wachtwoord zelf.
Netwerkparameters
Een andere belangrijke parameter is nog WG_HOST. Deze kun je, als test, voorlopig instellen op het interne ip-adres van de pc met je WireGuard-server. Zorg er bij voorkeur voor dat dit een vast of gereserveerd ip-adres is. Je vindt dit adres door op de Opdrachtprompt het commando ipconfig uit te voeren, achter IPv4 Address bij je actieve netwerkverbinding, zoals Ethernet of Wi-Fi.
Je treft in het yml-bestand bijvoorbeeld ook WG_DEFAULT_DNS aan. Standaard wordt blijkbaar de CloudFlare DNS-server (1.1.1.1) gebruikt, maar als je wilt kun je dit hier wijzigen, bijvoorbeeld in WG_DEFAULT_DNS=8.8.8.8, 8.8.4.4 voor de Google DNS-servers (verwijder dan ook het commentaarteken #).
Noteer ook de poorten die door WireGuard worden gebruikt: 51820 (poort voor inkomende VPN-verbindingen) en 51821 (poort voor het lokale dashboard). Uit veiligheidsoverwegingen zou je eventueel de luisterpoort voor inkomende connecties kunnen aanpassen. Dat doe je bijvoorbeeld als volgt: - “55555:51820/udp”. De eerste, gewijzigde poort is namelijk de externe poort. De tweede poort is de interne poort die WireGuard zelf gebruikt en deze moet zo blijven. Er zijn nog heel wat andere instelbare parameters, maar deze kun je in principe ongewijzigd laten.
De meeste parameters in het yml-bestand kun je (gelukkig) ongemoeid laten.
Proefdraaien
Controleer of alle items die met – beginnen netjes onder elkaar staan uitgelijnd, want YAML blijkt gevoelig voor spaties en inspringingen. Bewaar vervolgens het gewijzigde yml-bestand via Bestand / Opslaan (als).
Hoewel er nog router- en clientinstellingen nodig zijn, kan het geen kwaad om alvast te testen of de WireGuard-container goed opstart en het dashboard bereikbaar is. Open de Opdrachtprompt en navigeer naar de WireGuard-map (C:\Users\<je_gebruikersnaam>\docker\wireguard in ons eerdere voorbeeld). Voer daar het commando docker compose up -d uit.
Als Docker meldt dat de Windows Firewall de verbinding blokkeert, klik dan op Toestaan. Kort daarna verschijnt de melding Container wg-easy Started. In Docker Desktop, bij het onderdeel Containers, zie je dat wg-easy actief is en via Show all ports worden de netwerkpoorten weergegeven zoals in het yml-bestand opgenomen. Hier kun je de container ook stoppen, opnieuw starten of desnoods verwijderen.
Test het WireGuard-dashboard door op de pc te surfen naar localhost:51821. Na het invoeren van het wachtwoord verschijnt de melding dat er nog geen clients zijn. Die moet je dus eerst nog aanmaken.
Je kunt op verschillende manieren controleren of de container goed is opgestart.
Client op je mobiel
Maak voor elk apparaat dat je met de VPN-server wilt verbinden een aparte login aan, zodat je altijd ziet welke apparaten een connectie hebben gemaakt. Klik op +Nieuwe client, geef een duidelijke naam in, zoals Mijn Android smartphone, en bevestig met Creëren. Je krijgt nu het ip-adres te zien dat WireGuard voor deze connectie reserveert. Zorg dat de schakelknop is ingeschakeld en klik op het QR-code-pictogram.
Ga nu naar je apparaat. Test dit eerst met een smartphone die verbonden is met hetzelfde netwerk als je WireGuard-server. Download en open de WireGuard-app via de appstore. Tik op de +-knop en kies Scan van QR-code. Bevestig met Tijdens gebruik van app en richt de camera op de QR-code op je pc. Geef de tunnel een naam, zoals MijnWireGuard, en bevestig met Maak nieuwe tunnel.
Zodra je de schakelknop bij deze verbinding inschakelt, wordt de VPN-connectie opgezet. Dit herken je vaak aan een sleutelicoontje in de statusbalk. Tik op de naam van de verbinding om details te bekijken zoals de Publieke sleutel, Adressen, ingestelde DNS-servers, het Eindpunt (poort en ip-adres waarop je WireGuard-server luistert) en de Transfer (ontvangen en verzonden data). Dit dataverkeer kun je trouwens ook realtime volgen in het WireGuard-dashboard bij de betreffende client.
Zowel op de server als op de client kun je de verbinding en transfers volgen.
Client op je pc
Als je apparaat geen QR-code ondersteunt, kun je een configuratiebestand gebruiken. Ga naar het WireGuard-dashboard en klik op het downloadicoontje naast de betreffende client om een conf-bestand te genereren.
Voor bijvoorbeeld een Windows-laptop installeer je met een paar muisklikken eerst de WireGuard-app. Start deze app en klik op Import tunnel(s) from file. Verwijs naar het gedownloade conf-bestand en bevestig met Activate. De VPN-connectie wordt meteen opgezet.
Je kunt een VPN-verbinding ook opzetten met het bijbehorende configuratiebestand.
Lukt de VPN-connectie niet, controleer dan op de pc met de WireGuard-server of de juiste poort in luistermodus staat. We gaan uit van de standaardpoort 51820. Open de Opdrachtprompt en voer het volgende commando uit: netstat -ano | findstr :51820.
Als het goed is, krijg je zoiets als UDP 0.0.0.0:51820 : te zien.
Toch niet? Voeg dan een regel toe in Windows Firewall om dit binnenkomende verkeer toe te staan. Druk op Windows-toets+R, voer firewall.cpl in en open Geavanceerde instellingen. Ga naar Regels voor binnenkomende verbindingen en klik op Nieuwe regel. Kies Poort, klik op Volgende, selecteer UDP en vul bij Specifieke lokale poorten 51820 in. Klik op Volgende, kies De verbinding toestaan, klik weer op Volgende, selecteer de drie items, klik opnieuw op Volgende en geef een naam in, zoals WireGuard UDP 51820. Rond af met Voltooien.
Indien nodig zet je de VPN-poort open met een extra firewallregel.
Externe toegang
De VPN-connectie werkt voorlopig helaas alleen binnen je eigen netwerk, wat niet zo nuttig is. Om je VPN-server ook extern bereikbaar te maken, gebruik je niet het interne ip-adres van de server, maar vul je in het yml-bestand achter WG_HOST= het publieke ip-adres van je router/netwerk in. Dit adres vind je door vanaf je netwerk naar www.whatismyip.org te surfen en bij My Public IPv4 te kijken. Dit resulteert bijvoorbeeld in WG_HOST=85.196.235.130.
Zet deze wijzigingen door door de WireGuard-container opnieuw te creëren, door vanuit de WireGuard-map de commando’s docker compose down en docker compose up -d uit te voeren.
Maak opnieuw de container aan om aanpassingen in het yml-bestand door te voeren.
Routerconfiguratie
Je kunt dit op zich al testen, maar verder dan je router kom je helaas niet. Je moet namelijk eerst een mechanisme instellen dat aanvragen voor WireGuard (op standaardpoort 51820) doorstuurt naar de computer waarop de VPN-server draait. Hoe je deze poortdoorverwijzing uitvoert, hangt af van je routermodel. Op deze site staan instructies voor talrijke modellen.
Meestal komt het hierop neer: Meld je aan bij je router via de browser. Het interne ip-adres van je router vind je door ipconfig in de Opdrachtprompt uit te voeren, en bij Default Gateway te kijken. Zoek in de routerconfiguratie een rubriek als Port Forwarding of eventueel Virtual Server en creëer een nieuwe regel. Stel zowel de externe als interne poort in op 51820 (UDP) en vul tevens het interne ip-adres van je WireGuard-server in. Bevestig je instellingen. Maak vervolgens een nieuwe client aan in je WireGuard-dashboard. Hiermee zou je nu ook extern verbinding moeten kunnen maken met de VPN-server.
Zo ziet de poortdoorverwijzingsregel eruit op onze eigen router (D-Link EaglePro AI).
We hebben de WireGuard-setup in dit artikel bewust in fasen opgezet: eerst intern via het interne ip-adres, daarna extern via het publieke ip-adres en tot slot via DDNS. Deze getrapte aanpak kan namelijk helpen bij het gericht opsporen van mogelijke problemen.
Vooral bij externe verbindingen kunnen weleens obstakels opduiken. Zo kan je router een firewall hebben die inkomende verbindingen blokkeert. Overweeg dan een firewallregel die verkeer op poort 51820 (UDP) toestaat.
Een ander mogelijk probleem is CGNAT (Carrier Grade Network Address Translation), dat door sommige internetproviders vooral bij glasvezelabonnementen wordt toegepast. Hierdoor krijg je een gedeeld publiek ip-adres (zo’n adres begint meestal met 100.) en lukt poortdoorverwijzing niet zomaar. In dat geval kun je een externe VPN-service met ingebouwde poortdoorverwijzing overwegen, zoals ZeroTier of Tailscale.
Ook kan je netwerk achter een dubbele router zitten: die van je internetprovider en een eigen router. In dit geval moet je eerst een extra poortdoorverwijzing instellen van de buitenste router (op UDP 51820) naar het interne ip-adres van de binnenste router.
Een actieve Tailscale-verbinding tussen pc en mobiel apparaat.
DDNS: registratie
We zijn er helaas wellicht nog niet helemaal. De kans is namelijk reëel dat je internetprovider je publieke ip-adres dynamisch toekent, waardoor dit adres zomaar kan wijzigen. In plaats van dit na elke wijziging telkens handmatig aan te moeten passen in het WireGuard yml-bestand, is het beter een DDNS-dienst (Dynamic DNS) te gebruiken.
Een handige, gratis optie is DuckDNS. Ga naar www.duckdns.org en maak een account aan, bijvoorbeeld via Sign in with Google. Kies een geschikt subdomein en bevestig met add domain, bijvoorbeeld http://mijn-wireguard.duckdns.org. Als alles goed gaat, verschijnt je publieke ip-adres automatisch bij current ip. Vul het desnoods handmatig in en bevestig dan met update ip. Noteer het token dat bovenaan wordt weergegeven, bijvoorbeeld c88e263d-3c31-4a72-a879-6aeb90660037.
Om te testen of je domein correct werkt, open je de Opdrachtprompt en geef je (in ons voorbeeld) het volgende commando:
nslookup mijn-wireguard.duckdns.org
Dit zou je publieke ip-adres moeten tonen. Vul nu deze domeinnaam (mijn-wireguard.duckdns.org) in het yml-bestand achter WG_HOST=, en maak de bestaande container opnieuw aan, zoals eerder uitgelegd.
Creëer het gewenste subdomein bij DuckDNS en controleer of dat operationeel is.
DDNS: auto-update
De DDNS-provider heeft het gekozen subdomein aan je huidige publieke ip-adres gekoppeld. Nu moet je ervoor zorgen dat deze koppeling behouden blijft, ook als het publieke ip-adres wijzigt. Dit kan door een op de achtergrond draaiende Docker-container een API (Application Programming Interface) van Duck DNS te laten aanroepen.
Open je teksteditor en voer de volgende code in:
services:
duckdns:
image: linuxserver/duckdns
container_name: duckdns
restart: unless-stopped
environment:
- TZ=Europe/Amsterdam
- SUBDOMAINS=<mijn_subdomein>
- TOKEN=<mijn_duckdns_token>
- LOG_FILE=false # Optioneel, zet op true voor logs
networks:
- default
Vervang uiteraard <mijn_subdomein> en <mijn_duckdns_token> door de juiste waarden. Bewaar dit bestand als docker-compose.yml in een aparte map, bijvoorbeeld C:\Users\<je_gebruikersnaam>\docker\duckdns. Voer vervolgens vanuit deze map het commando docker compose up -d uit en controleer in Docker Desktop of de container van Duck DNS draait.
Met een extra container houd je de Duck DNS-koppeling netjes up-to-date.
Zodra je met je VPN-server verbonden bent, kun je op afstand normaliter ook je WireGuard-dashboard openen door in je browser het interne ip-adres van de server gevolgd door :51821 in te voeren, zoals 192.168.0.164:51821. Daarnaast krijg je wellicht ook toegang tot gedeelde mappen op de pc waarop WireGuard draait, bijvoorbeeld via een mobiele bestandsbrowser als Cx File Explorer, mits je de juiste inloggegevens gebruikt. Ook zou je andere toestellen in je netwerk moeten kunnen pingen, tenzij een firewall dit blokkeert.
Wil je ook services op andere toestellen binnen je thuisnetwerk benaderen, zoals bestands- of fotodeling, dan zijn vaak extra configuraties nodig. Dit hangt af van de situatie en kan zich op verschillende niveaus afspelen:
- VPN-configuratie: zorg dat de VPN-client pakketten voor je LAN-subnet via de WireGuard-interface kan verzenden en ontvangen;
- Routering en NAT op Windows: schakel eventueel ip-forwarding in, voeg een statische route toe en configureer eventueel NAT;
- Docker-netwerk: koppel de WireGuard-container aan een (extra?) Docker bridge-netwerk dat toegang heeft tot je LAN;
- Firewall: stel indien nodig regels in die ervoor zorgen dat WireGuard en de betreffende services verkeer op de juiste poorten doorlaten.
We hebben helaas niet de ruimte om hier dieper op in te gaan.
Een van de configuraties: onze WireGuard-container hebben we aan ons LAN-netwerk gekoppeld.