Raspberry Pi als vpn-server met OpenVPN

Met een vpn surf je op het internet zonder dat je provider meekijkt of omzeil je regioblokkades van bepaalde websites. Maar een vpn is ook handig om overal veilig toegang te krijgen tot jouw thuisnetwerk. Een Raspberry Pi als vpn-server inzetten is mogelijk te maken met OpenVPN. Zo werkt dat.

Op zich heb je geen vpn nodig om toegang te krijgen tot je thuisnetwerk. Met enkele portforwarding-regels in je router kom je ook wel binnen. Maar portforwarding is niet altijd de beste oplossing. Veel services zijn standaard geconfigureerd voor maximaal gebruiksgemak binnen je thuisnetwerk. Zet je die services open voor het hele internet, dan zijn ze zelden afdoende beveiligd.

Je moet je dus voor elke afzonderlijke service verdiepen in de verschillende beveiligingsmogelijkheden. Dat is best een tijdrovende klus. De kans bestaat dat je dan alsnog zaken over het hoofd ziet. Een vpn is wat dat betreft veel eenvoudiger. Er is één centraal toegangspunt tot je netwerk, namelijk de vpn-server. Als je die afdoende beveiligt, hoef je je over de rest van je netwerk minder zorgen te maken.

Met OpenVPN is een Raspberry Pi in te zetten als vpn-server. Voor je verder leest, kun je hier meer informatie vinden over OpenVPN.

OpenVPN op Raspberry Pi installeren

OpenVPN vereist geen erg krachtige hardware, dus kozen we voor een Raspberry Pi. Download Raspbian Jessie Lite, pak de download uit en schrijf die naar een sd-kaart met Win32DiskImager of dd. Koppel de boot-partitie van de sd-kaart even aan een Linux-systeem en plaats er een leeg bestand genaamd ssh. Boot je Pi vanaf de sd-kaart en controleer in je router welk ip-adres de Pi gekregen heeft. Log nu in via ssh met de gebruiker pi en het wachtwoord raspberry. Het handmatig opzetten van een ca-infrastructuur is behoorlijk complex. Gelukkig levert OpenVPN met easy-rsa een reeks scripts mee om die taak te vereenvoudigen. Installeer om te beginnen openvpn:

apt install openvpn

Gebruik daarna volgend commando om easy-rsa te integreren met OpenVPN:

make-cadir /etc/openvpn/ca

Open nu het bestand /etc/openvpn/ca/vars en vul daarin jouw persoonlijke gegevens in. De meeste opties spreken voor zich. Bij KEY_ORG vul je de naam van jouw organisatie in of gewoon je eigen naam. KEY_OU is de afdeling binnen jouw organisatie (Organisational Unit). Is dat niet van toepassing voor jou, vul dan bijvoorbeeld OpenVPN in. Vervolgens voer je een reeks commando’s uit om de nieuwe configuratie in te lezen, de dh-parameters te berekenen (benodigd voor het uitwisselen van encryptiesleutels tussen client en server) en zowel een ca-certificaat als een certificaat voor de vpn-server aan te maken (zie afbeelding). De tweede stap duurt makkelijk tien tot vijftien minuten op oudere Pi’s. De resulterende bestanden vind je terug in de submap keys.

Servers configureren

Met Raspbians OpenVPN-pakket kun je meerdere vpn’s configureren op dezelfde machine. Je definieert een nieuw vpn door een configuratiebestand aan te maken in /etc/openvpn, bijvoorbeeld home.conf. In de afbeelding zie je een minimaal configuratiebestand voor een OpenVPN-server: we doorlopen de belangrijkste parameters. Met de opties proto en port kies je respectievelijk het protocol en de poort voor OpenVPN. Wij houden de standaardinstellingen aan, maar vaak kiest men voor tcp en poort 443 om firewallrestricties te omzeilen. Bij local vul je het lan-ip-adres van je Pi in en bij server het gewenste netwerkadres voor jouw VPN.

Zorg dat dat niet overlapt met het netwerkadres van de lokale netwerken die jij gebruikt! De volgende vier parameters verwijzen naar de benodigde bestanden van onze ca en met de laatste vier schroeven we de beveiliging nog wat op. Werk je nog met OpenVPN-clients ouder dan versie 2.3.3, dan laat je tls-version-min weg. Het bestand ta.key moet je trouwens nog aanmaken met volgend commando:

openvpn --genkey --secret /etc/openvpn/ta.key

Het is ook een goed idee om de permissies van het configuratiebestand in te perken:

chmod 640 /etc/openvpn/home.conf

Beveiligen

Je kunt OpenVPN verder beveiligen door de service te starten in een zogenoemde chroot-jail onder een speciale gebruiker. OpenVPN heeft dan enkel beperkte toegang tot een klein deel van het bestandssysteem van jouw Pi. Je activeert die beveiliging met de vijf eerste opties in de afbeelding hiernaast. Vergeet ook niet om de gebruiker én de directory eerst aan te maken:

useradd -d /etc/openvpn/chroot -M -s /bin/false openvpn
mkdir -p /etc/openvpn/chroot/tmp

Vervolgens stellen we een directory in waar OpenVPN naar een configuratiebestand zoekt voor elke client die een verbinding wilt opzetten. Het pad naar die directory is relatief ten opzichte van de chroot-directory, dus maken we die daarin aan:

mkdir /etc/openvpn/chroot/clients

Zonder configuratiebestand in die directory laat OpenVPN geen verbinding toe (ccd-exclusive). Daarna schakelen we compressie in aan de kant van de server (comp-lzo) én de client (push comp-lzo). Topology subnet zorgt ervoor dat elke client een eigen ip-adres krijgt in hetzelfde subnet: 192.168.200.x in ons voorbeeld.

De optie client-to-client laat verschillende vpn-clients rechtstreeks met elkaar communiceren. Standaard zien ze immers enkel de vpn-server en niet de andere clients. Met de twee laatste regels schakel je iets meer logging in en schrijf je die weg in een apart bestand. Dat is vooral in het begin erg nuttig, als je vpn-verbinding niet meteen werkt.

Clients toevoegen

De OpenVPN-server is nu klaar: tijd om een eerste client toe te voegen. Om te beginnen maak je een private key en certificaat aan voor de client. In de afbeelding zie je een voorbeeld voor een client met hostname linuxmint. In dit geval beveiligen we de private key met een wachtwoordzin (--pass-optie). Verder in dit artikel komen we nog een voorbeeld tegen waarbij je die optie beter weglaat. Vervolgens maak je een configuratiebestand aan met daarin het voor de client gewenste ip-adres in het vpn-subnet. In het voorbeeld hiernaast is dat 192.168.200.2. Daarna zet je de permissies goed en start je de openvpn-service in de voorgrond:

openvpn --config /etc/openvpn/home.conf

Krijg je geen foutmeldingen te zien? Stop openvpn dan met Ctrl-C en open het bestand /etc/default/openvpn. Verwijder het #-teken voor de regel AUTOSTART="all" en voer dan volgende commando’s uit:

systemctl daemon-reload
systemctl start openvpn

OpenVPN draait nu als een daemon in de achtergrond en is klaar voor inkomende verbindingen. Je merkt ook dat er een extra netwerkinterface verschenen is met het vpn-adres van je server:

ip addr show tun0

Portforwarding

De volgende stap is om de OpenVPN-service op onze Pi beschikbaar te maken voor de buitenwereld. Daarvoor voeg je een portforwarding-regel toe op je router. De precieze procedure daarvoor is erg merk-gebonden, dus zoek zelf even uit hoe dit voor jouw router werkt. Het komt erop neer dat je een bepaalde poort op de externe interface van je router doorstuurt naar het interne ip-adres van de Pi en de poort die je in /etc/openvpn/home.conf gespecificeerd had.

Let ook op dat je hetzelfde protocol selecteert (tcp of udp) als in dat configuratiebestand. Je hoeft overigens extern niet dezelfde poort te gebruiken als intern. Sommige providers blokkeren namelijk bepaalde poorten. In dat geval ben je verplicht een andere poort te gebruiken. Zo is het bijvoorbeeld prima mogelijk om poort 8443 of 11194 op je router te forwarden naar 1194 op je Pi.

Linux-client instellen

We beginnen met een Linux Mint-machine om onze OpenVPN-server te testen. Kopieer alvast de bestanden ca.crt, ta.key, linuxmint.crt en linuxmint.key naar de client. De benodigde software is in Linux Mint standaard al geïnstalleerd. Gebruik je een andere Linux-distributie en is dat niet het geval? Installeer dan het pakket Network-manager-openvpn-gnome. Klik vervolgens op het netwerkpictogram in het systeemvak en ga naar Netwerverbindingen. Klik op Toevoegen, kies OpenVPN als verbindingstype en klik op Aanmaken. In het VPN-tabblad vul je volgende gegevens in:

- Gateway: het externe ip-adres van jouw router.

- Gebruikerscertificaat: linuxmint.crt

- CA-certificaat: ca.crt

- Privé-sleutel: linuxmint.key

- Wachtwoord van de privésleutel: de eerder ingestelde passphrase

Klik vervolgens op Geavanceerd, ga naar TLS-authenticatie en vul bij Overeenkomst met onderwerp de hostname in van je Pi zoals die in het servercertificaat staat (raspberrypi in ons voorbeeld). Selecteer de optie Verify peer (server) certificate usage signature. Vink tot slot de optie Extra TLS-authenticatie gebruiken aan. Selecteer het bestand ta.key en laat Sleutelrichting op Geen staan. Onder Beveiliging selecteer je dezelfde algoritmes als op de server: AES-256-CBC voor Vercijfering en SHA-256 voor HMAC-authenticatie. Onder Algemeen vink je volgende opties aan:

- LZO-datacompressie gebruiken.

- TCP-verbinding gebruiken (indien je voor tcp in plaats van udp gekozen had op de server).

- Aangepaste gateway-poort (indien je niet poort 1194 op je Pi gebruikt).

Klik tot slot op OK en Opslaan om de vpn-verbinding te bewaren. Sluit het configuratievenster voor netwerkverbindingen, klik opnieuw op netwerkpictogram in het systeemvak en selecteer de nieuwe vpn-verbinding om die te testen. Verschijnt er geen netwerkinterface tun0 met het gekozen ip-adres (192.168.200.2 in ons geval), zoek dan naar foutmeldingen in /var/log/syslog op de client en /var/log/openvpn.log op de server. Om zeker te zijn dat je verbinding correct werkt, installeer je bijvoorbeeld het pakket apache2 op je Pi.

Open na installatie het vpn-ip-adres van je Pi in een browser op de client: 192.168.200.1. Zie je een pagina zoals de afbeelding, dan werkt je vpn-verbinding correct. Maak daarna met pkitool een nieuw certificaat aan op de server en zet een configuratiebestand klaar in /etc/openvpn/chroot/clients voor een tweede client. Wij kozen voor de hostname windows10 en ip-adres 192.168.200.3.

Windows-client instellen

Wil je vanaf Windows met je vpn verbinden, download dan de Windows-installer. Na installatie krijg je een shortcut met de misleidende naam OpenVPN GUI. De naam GUI mag je met een korreltje zout nemen, want de interface bestaat uit een pictogram in het systeemvak met maar enkele opties. De eigenlijke vpn-verbinding configureer je via een tekstbestand met de benodigde parameters. In de afbeelding hiernaast zie je een voorbeeld dat correct samenwerkt met onze serverconfiguratie. Bewaar dit met de extensie .ovpn, klik rechts op het OpenVPN-pictogram in het systeemvak en kies Bestand importeren.

OpenVPN maakt nu een nieuwe map aan onder ~/OpenVPN/config. Kopieer de .key- en .crt-bestanden in die directory en kies daarna Verbinden uit het menu van de OpenVPN GUI. Vul het wachtwoord van de private key in, klik Toegang toestaan in het waarschuwingsvenster van de Windows Firewall en de verbinding wordt opgezet. De optie Status weergeven toont je eventuele foutmeldingen. Sluit je de OpenVPN GUI, dan vind je die meldingen in een logbestand onder ~/OpenVPN/log.

Services

Via de vpn-verbinding krijg je toegang tot alle services op jouw Raspberry Pi die niet aan één specifiek ip-adres gebonden zijn. Het lsof-commando uit de afbeelding toont je alle actieve services met bijbehorende ip-adressen en poortnummers. Merk op dat onze Pi intussen over drie ip-adressen beschikt: localhost of 127.0.0.1 (onbereikbaar voor andere machines), 192.168.1.7 (bereikbaar via het lan) en 192.168.200.1 (bereikbaar via het vpn).

In ons voorbeeld zijn ssh, dansguardian en minidlna via alle ip-adressen bereikbaar (*). Squid en Postfix (master) zijn enkel bereikbaar vanaf localhost en Samba enkel via het lan. Wil je bijvoorbeeld Samba ook benaderen via het vpn? Pas dan de opties interfaces en bind interfaces only in /etc/samba/smb.conf aan zodat die service ook op ip-adres 192.168.200.1 luistert. De meeste services hebben vergelijkbare opties.

Verbinden

Wil je toegang krijgen tot services op andere machines, dan moet je die nog verbinden met je vpn. Op een homeserver kun je het best een permanente verbinding opzetten met de vpn-server. Op een Linux-machine zonder de Network Manager-gui installeer je daarvoor het openvpn-pakket. Maak een certificaat en private key aan zonder wachtwoordzin door de --pass-optie weg te laten bij pkitool. Plaats die bestanden samen met ca.crt en ta.key in /etc/openvpn. Bewaar ook het configuratiebestand van onze Windows-client met .conf-extensie in die directory, uiteraard aangepast voor de correcte certificaten.

Vervolgens start je openvpn net zoals we dat bij onze server gedaan hadden in de paragraaf Clients toevoegen. Voor een Windows-machine gebruik je ook een private key zonder wachtwoord. Kopieer de map met de bestaande configuratiebestanden van ~/OpenVPN/config naar C:\Program Files\OpenVPN\config. In het ovpn-bestand moet je wel het volledig pad invullen naar de ca-, cert-, key- en tls-auth-bestanden. Plaats elk pad tussen dubbele aanhalingstekens en gebruik overal \\ in plaats van \. Open de Services Management Console (services.msc) en selecteer OpenVPNService. Kies Eigenschappen uit het contextmenu, wijzig het Opstarttype naar Automatisch en klik op Starten en OK.

Tunnels en proxy's

Wil je tenslotte snel toegang krijgen tot een bepaalde service in je lan die niet via een vpn-ip-adres bereikbaar is? Gebruik dan de portforwarding-functie van ssh om het netwerkverkeer in een ssh-verbinding te tunnelen. Vanaf een Linux-machine werkt dat als volgt. Stel dat je poort 8080 op de machine met ip-adres 192.168.1.8 wilt bereiken. Jouw vpn-client komt niet bij dat adres, maar de Pi wel. Met volgend commando forward je poort 8080 op jouw client via de vpn-server naar die machine:

ssh -L 8080:192.168.1.8:8080 192.168.200.1

Verbind je vervolgens met poort 8080 op jouw client, dan kom je via de Pi terecht op poort 8080 op de machine met ip-adres 192.168.1.8. Een vergelijkbaar trucje gebruik je om snel via jouw thuisverbinding te surfen:

ssh -D 1080 192.168.200.1

Daarmee zet ssh op poort 1080 een lokale socks-server op. Stel je vervolgens in je browser localhost:1080 in als socks-proxy, dan wordt al het netwerkverkeer via ssh getunneld naar je vpn-server. Dat is erg handig om te surfen vanuit een publiek netwerk dat je niet vertrouwt. Ook onbeveiligd http-verkeer is op die manier immers versleuteld tussen jouw pc en je vpn-server thuis. Zowel portforwarding als een socks-proxy kan je onder Windows configureren via Putty.

Deel dit artikel
Reageer op dit artikel
Wat vond je van dit artikel?

Aanbevolen voor jou

ID.nl logo

ID.nl, onderdeel van Reshift BV, is in 2022 gestart en uitgegroeid tot de meest toonaangevende en complete consumentensite van Nederland. Het doel van ID.nl is om de consument te helpen met alle technologie die hoort bij het dagelijks leven: van smart-health-meters tot e-bikes, van warmtepompen tot zonnepanelen - en alles daar tussenin!

Duidelijk, betrouwbaar en onafhankelijk: ID.nl maakt moeilijke dingen makkelijk.

Contact

ID.nl

Nijverheidsweg 18

2031 CP Haarlem

info@id.nl

Telefoon: 023-5430000