We hebben steeds meer apparaten en servers in huis, die allerlei taken vervullen en die we kunnen bedienen zolang we met hetzelfde netwerk verbonden zijn. We vinden het tenslotte niet zo’n goed idee als Jan en alleman op onze homeserver door onze vakantiefoto’s kan struinen of onze lampen aan- en uit kan zetten. Om deze servers, die we op afstand willen onderhouden, toch bereikbaar te maken van buitenaf kunnen we een SSH daemon installeren en een poortje openen aan de buitenkant. De server moet dan wel een statisch IP-adres in de private range aan de binnenkant hebben. Om het veiliger te maken kunnen we een VPN-oplossing installeren en ons zo toegang verschaffen tot het lokale netwerk thuis. Maar het kan ook een stuk simpeler met ZeroTier.
Auteur: Martin van Es
ZeroTier is een open source Software Defined Network dat op basis van huis-tuin-en-keuken IP-verbindingen een beveiligde laag en peer-to-peer netwerk verzorgt. Bovenaan de ontwerpcriteria stonden gebruiksgemak, veiligheid en decentralisatie. Dat die drie niet hand in hand gaan, is te lezen in het manifest dat Adam Ierymenko op 1 augustus 2014 publiceerde toen hij voor het eerst over ZeroTier aan het nadenken was (zie referenties [1]).
In 2014 schrijft Adam Ierymenko een blog over een idee dat hij ZeroTier noemt, waarin hij beschrijft waar een gebruiksvriendelijk en veilig peer-to-peer VPN volgens hem aan moet voldoen. Zijn conclusie is dat gebruiksvriendelijkheid en volledige decentralisatie elkaar uitsluiten. Een belangrijke (technische) reden hiervoor is dat een peer-to-peer netwerk, waarin peers zich achter NAT-verbindingen verschuilen, het moeilijk maakt elkaar te vinden zonder een hulpje van buitenaf. Deze hulp vormt het zogenaamde centrale punt en de achilleshiel van het verlangen volledig decentraal en onafhankelijk te zijn.
Uiteindelijk kiest Adam voor een compromis, waarin een aantal domme en blinde centrale servers de peer-to-peer connecties tot stand helpen brengen, zonder dat deze inzage hebben in de communicatie of deze kunnen manipuleren. Deze zogenaamde Root servers zijn te vergelijken met de DNS root servers en helpen bij het opzetten van de peer-to-peer connecties. Dit werkt net zoals de DNS root servers je doorverwijzen naar de verantwoordelijke DNS-server voor het domein waar je naar op zoek bent. Alleen als er écht geen rechtstreekse verbinding mogelijk is, blijven de Root servers betrokken bij de communicatie, waarbij ze volledig blind zijn voor de inhoud van de pakketten. De ZeroTier client zal eerst proberen via UDP over poort 9993 een verbinding naar buiten op te zetten. Als dat vanwege firewall regels niet lukt, valt de client terug op TCP via 443. Deze poort is ook wel bekend van het alomtegenwoordige https-transport kanaal. Het moet gek lopen als ook dat niet lukt.
Zoals veel peer-to-peer protocollen is ook ZeroTier afhankelijk van NAT hole punching om een rechtstreekse verbinding tussen twee peers tot stand te brengen. NAT is de technologie, geboren uit noodzaak door een schaarste aan beschikbare IPv4 adressen, die ervoor zorgt dat je thuis gebruik kunt maken van meerdere lokale adressen en aan de buitenkant maar één publiek IP-adres nodig hebt. Om uit- en ingaand verkeer netjes op elkaar af te stemmen, houdt je router een tabel bij waarin staat welk apparaat aan de binnenkant een verbinding heeft met een server aan de buitenkant. Hierdoor kan terugkomend verkeer keurig op dezelfde computer afgeleverd worden. Hole punching is de techniek waarbij twee peers een opening in de NAT-tabel naar een centrale server maken en deze server de twee peers vervolgens onderling met elkaar verbindt door de geopende NAT translaties aan hen door te geven. Hierdoor kunnen ze rechtstreeks met elkaar communiceren zonder tussenkomst van de centrale server.
ZeroTier opereert 12 geografisch gescheiden Root servers, die samen de “Planeet Aarde” virtuele switch verzorgen. Het staat echter iedereen vrij om zelf Root servers te maken en deze als “manen” om Planeet Aarde te laten draaien. Deze persoonlijke servers zullen bij juiste configuratie van de clients als eerste gecontacteerd worden voor peer look-up verzoeken en alleen in uiterste nood de ZeroTier Root servers raadplegen. Als alle potentiële peers binnen een afgesloten netwerk segment vallen, is het dus mogelijk met eigen Root servers een lokaal ZeroTier netwerk op te bouwen, zonder ook maar één keer contact te hoeven maken met de ZeroTier Root servers. Een geruststellende gedachte voor de paranoïde lezers onder ons.
ZeroTier kent twee netwerk identifiers om de virtuele ZeroTier switch te gebruiken: het ZeroTier netwerkadres van een node in het netwerk en de netwerk identifier. Deze identifiers zijn het best te vergelijken met respectievelijk een poortje op een reusachtige switch en het daarop geconfigureerde VLAN. VLAN is een technologie die er op een switch voor zorgt dat sommige poorten van die switch wel en andere niet met elkaar verbonden zijn. Het node adres van een controller plus een netwerk ID vormen samen een unieke netwerk identifier:
Netwerk ID: 8056c2e21c123456 | | | Netwerknummer op controller | ZeroTier adres van de controller
ZeroTier heeft ervoor gekozen geen volwaardige statefull firewall op netwerkniveau te implementeren. In plaats daarvan zijn er slimme netwerk rules, capabilities en tags. Het gaat te ver om hier in dit artikel uitgebreid op in te gaan, maar het is belangrijk te weten dat generieke netwerk (beperkende) rules overwonnen kunnen worden door node specifieke capabilities en tags. Hiermee is op een fijnmazig niveau toegang te regelen in een netwerk dat bevolkt wordt door duizenden systemen zonder dat dit tot een explosie van rules leidt. Zie ook [2] in de referenties.
Zoals gezegd was één van de ontwerpcriteria gebruiksgemak. Een normale gebruiker hoeft zich dus geen zorgen te maken over bovenstaande theorie, maar het maakt het wel iets makkelijker om het netwerk op te starten en mogelijke problemen op te sporen.
ZeroTier is tot 100 apparaten gratis te gebruiken op hun infrastructuur. Wil en kun je zelf een controller onderhouden, dan is gebruik onbeperkt. Er is, de paranoïde gedachten daargelaten, dus geen enkele reden om met een paar apparaten te experimenteren met de ZeroTier controller. Daarvoor ga je eerst naar [3] (zie referenties) en maak je, al dan niet op basis van je bestaande Google account, een ZeroTier account aan. Gemak dient de mens.
Eenmaal ingelogd navigeer je naar de Networks tab en creëer je je eerste ZeroTier netwerk. ZeroTier zal dit netwerk een random naam en nieuwe netwerk identifier toekennen op basis van het ZeroTier node adres waarop het netwerk voor je gedefinieerd is. Door op het netwerk te klikken, kun je de eigenschappen van dit netwerk, zoals de naam en de private IP DHCP range, bewerken. Dit interface stelt je ook in staat om members toe te voegen en te autoriseren. Voordat je members toe kunt voegen, moet je eerst de ZeroTier client op één van je pc’s of servers geïnstalleerd hebben.
Hoewel alle ZeroTier code open source is, is het netwerk controller web-interface van [3] (zie referenties) dat niet. Als je zelf een controller wilt onderhouden, zal je aan de slag moeten met de (goed gedocumenteerde) API of zelf een interface moeten installeren op basis van bijvoorbeeld [4] (zie referenties).
Zoals gezegd was gebruiksgemak één van de belangrijkste randvoorwaarden in het ontwerp van ZeroTier. De makers hebben dan ook een oneliner, die de client voor je installeert en configureert gemaakt. Deze oneliner voert een bash script uit dat voor je uitzoekt of je een rpm- of deb-gebaseerde distributie draait, de ZeroTier repository toevoegt, de sleutels ophaalt, vertrouwt en de client installeert, als root:
curl -s https://install.zerotier.com/ | sudo bash
Als dit echt iets teveel van het goede voor je is, kun je bij [5] (zie referenties) lezen hoe je al deze acties handmatig één voor één uitvoert en controleert.
Tijdens de installatie genereert de client een network ID, die naderhand met het volgende commando op te vragen is:
zerotier-cli info 200 info 41f44***** 1.2.12 ONLINE
We kunnen nu twee routes bewandelen voor het toevoegen van deze node aan ons kersverse ZeroTier netwerk. Door middel van uitnodiging in het ZeroTier controller web interface of met een join request aan de commandline. Omdat ik toch al aan de commandline bezig ben, kies ik hiervoor. Zoek in het web interface eerst het netwerk ID van je nieuwe netwerk en laat je node een join verzoek sturen:
zerotier-cli join d3ecf5726d47f116 200 join OK
Alleen join requests sturen is uiteraard niet voldoende, want we willen een virtual private network. Ons join request zal dus eerst geautoriseerd moeten worden op de controller, voordat de node op het netwerk mag. Het controller interface zal automatisch het nieuwe join request tonen als ongeautoriseerde member. Onder het kopje Auth? in de tabel met members zit een checkbox voor elke aangemelde member. Zodra deze aangevinkt wordt, is een member lid en kan het met alle andere apparaten op het netwerk communiceren alsof ze in huis op dezelfde switch aangesloten waren. Aan de commandline kunnen we nu controleren met welke netwerken deze node verbonden is:
zerotier-cli listnetworks 200 listnetworks <nwid> <name> <mac> <status> <type> <dev> <ZT assigned ips> 200 listnetworks d3ecf5726d47f116 jovial_davies 16:b0:b3:21:b8:3a OK PRIVATE ztuga3fa33 fcbe:ab04:6441:f44c:cacf:0000:0000:0001/40,172.29.167.189/16
In het resultaat vinden we respectievelijk het netwerk ID waarop ik aangemeld was, de naam die ZeroTier voor dat netwerk verzonnen had (jovial_davies), het (virtuele) mac adres van het ZeroTier interface dat de client aangemaakt heeft, de naam van de interface op mijn laptop (ztuga3fa33, waarin het zt voorvoegsel het interface herkenbaar maakt als ZeroTier interface) en tenslotte de private IPv6 en IPv4 adressen, die door de controller uitgedeeld zijn.
Op een vergelijkbare manier voeg je bijvoorbeeld ook een mobiele telefoon toe aan je ZeroTier netwerk. Let op dat de ZeroTier Android client standaard geen gebruik maakt van GSM data. Om dat toch aan te zetten kun je in de settings Use Cellular Data aanvinken.
Op een goede dag reden we in de auto van visite terug naar huis. Recente experimenten met HomeAssistant zorgen er nu voor dat onze verwarming op een laag pitje staat, zodra niemand thuis is. Terloops vroeg ik of het misschien een goed idee zou zijn de verwarming alvast aan te zetten, zodat het comfortabel is als we thuiskomen. Heel toevallig was de ZeroTier client geïnstalleerd op mijn telefoon en was deze al eerder opgenomen in het ZeroTier thuisnetwerk. Het was niet lastig uit te leggen hoe mijn telefoon aangemeld moest worden op het ZeroTier netwerk, waarna de HomeAssistant short-cut op mijn desktop de mogelijkheid bood ons huis voor te bereiden op onze komst. Natuurlijk was dit ook mogelijk geweest met allerlei proprietaire cloud oplossingen of een ordinaire VPN. De kracht zat ‘m echter in het gemak van deze zelf geknutselde oplossing en de moeiteloze setup van ZeroTier. De toon is gezet!
[1] http://adamierymenko.com/decentralization.html
[2] https://zerotier.com/manual.shtml
[3] https://my.zerotier.com/login