Kunnen clients op twee OpenVPN-servers elkaar bereiken?
Twee OpenVPN-servers maken twee clientpools, niet één netwerk. Routeer ertussen met aparte subnetten, wederzijdse routes en een expliciete vertrouwensgrens.
Een tweede OpenVPN-server opzetten geeft je een tweede plek waar clients kunnen verbinden, en niets meer. Hij zet die clients niet op het netwerk van de eerste server, en de optie client-to-client verandert alleen doorsturen binnen één serverproces. De twee pools worden één netwerk wanneer je er bewust tussen routeert, met een eigenaar per richting. Alles hieronder gaat uit van TUN-modus in userspace waarbij dat interne doorsturen uit staat, zodat de kernel de beslissing neemt.
De mythe: één accountlijst, één netwerk
Authenticatie en bereikbaarheid worden verward omdat beide in de serverconfiguratie zitten. Een gebruiker die op een van beide gateways kan inloggen, ziet er van buiten uit als een gebruiker op één systeem met twee deuren. Binnen deelt elke server adressen uit zijn eigen pool uit en installeert alleen routes voor de clients die hij beëindigt. Dus een client op gateway A die een pakket naar een client op gateway B stuurt, vraagt om een bestemming waar zijn eigen server nog nooit van heeft gehoord. Het pakket gaat naar de standaardroute van A, verlaat de tunnel en komt aan bij een firewall die nooit is gevraagd het toe te staan.
Een tweede server toevoegen voegt dus geen redundantie, discovery of een gedeeld broadcastdomein toe. Het voegt een gerouteerd netwerk toe dat een plan nodig heeft, en het plan begint bij adressering.
Geef elke gateway een eigen pool en transitadres
Twee bereiken die niets anders mogen overlappen, plus een kleine transitlink tussen de hosts, is het hele adresplan. Houd de transit op een privésegment dat je beheert, en schrijf de nummers op voordat een van beide servers een lease uitgeeft.
| Gateway | Client pool | Transit address |
|---|---|---|
| gateway-a | 10.64.10.0/24 | 172.28.44.1/30 |
| gateway-b | 10.64.20.0/24 | 172.28.44.2/30 |
Weerst de verleiding om beide servers dezelfde pool te geven zodat profielen identiek blijven. Een kernelroute kan niet zeggen welke van twee hosts op dit moment een willekeurig adres binnen een gedeeld bereik bezit, dus de routetabel zou naar één gateway wijzen en de client kan aan de andere hangen. Interfacenamen zijn lokale conventies, geen gedeelde toestand. Beide hosts hier noemen het tunnelapparaat tun0 en de transitlink transit0, wat prima is omdat geen enkel pakket die namen draagt.
Installeer de route aan beide kanten
Elke gateway heeft een route naar de pool van de ander via het transitadres nodig, en doorsturen moet aan staan wil een van beide als hop fungeren. Controleer eerst de huidige tabel, voeg dan de entry toe en maak hem persistent via de netwerkbeheerder van de host in plaats van een herverbindingshook.
sysctl net.ipv4.ip_forward
ip route add 10.64.20.0/24 via 172.28.44.2 dev transit0
ip route get 10.64.20.37
Spiegel dat op de andere host met de pools omgewisseld. Dezelfde route steeds opnieuw toevoegen vanuit een ongerelateerd script is hoe een host meerdere kopieën en een mysterieuze wijziging krijgt de volgende keer dat iemand de tabel leest. Als de transitlink zelf een tunnel is, wijst de route naar de topologie van die tunnel en moet de hop een herverbinding overleven. Een transitadres dat dertig seconden verdwijnt, neemt het pad tussen de pools mee, wat een ontwerpeigenschap is die je beter kunt benoemen dan ontdekken.
Push de clientroute zonder eigenaarschap te veinzen
Clients hebben een route naar de externe pool nodig, anders stuurt hun eigen besturingssysteem het pakket naar de standaardgateway en ziet de tunnel het nooit. De serverconfiguratie is de natuurlijke plek om die af te leveren.
push "route 10.64.20.0 255.255.255.0"
Zet de spiegelregel in de configuratie van de andere server, verbind daarna een testclient opnieuw en lees zijn tabel. Een client die gepushte routes negeert, heeft zijn eigen goedgekeurde configuratie nodig, en een route die nooit aankomt is geen toegangsbeheer. Geef een client geen iroute voor de hele pool van de andere gateway. Die richtlijn bestaat voor een subnet achter één verbonden client, en hem gebruiken om een ontbrekende route tussen gateways te verdoezelen levert een server op die denkt dat hij adressen bezit die hij niet kan bereiken.
Bewijs één verzoek en weiger een ander
Kies een echte bewerking, bijvoorbeeld HTTPS van een client op 10.64.10.21 naar een dienst op 10.64.20.37, en sta precies dat toe op beide hosts. Elke firewall laat het verzoek aan zijn inkomende kant toe en het gevolgde antwoord aan de retourkant; het eigen dienstbeleid van de bestemming moet het nog steeds accepteren.
iptables -A FORWARD -i tun0 -o transit0 -s 10.64.10.21 -d 10.64.20.37 -p tcp --dport 443 -j ACCEPT
iptables -A FORWARD -i transit0 -o tun0 -d 10.64.10.21 -s 10.64.20.37 -p tcp --sport 443 -m conntrack --ctstate ESTABLISHED -j ACCEPT
Met wederzijdse routes is source-NAT onnodig en hier actief schadelijk: de bron vertalen verbergt welke client het verzoek deed en ondermijnt bron-gebaseerd beleid aan de bestemmingskant. Controleer dat een bestaande masquerade-regel voor internetuitgang dit pad niet ook vangt. Test dan de weigering. Een dienst die lokaal bij pool B moet blijven, moet onbereikbaar blijven vanaf pool A, en clientparen op dezelfde gateway moeten ook worden getest, omdat het doorstuurbeleid dat je net hebt gewijzigd ook voor hen geldt.
Nog een correctie op het mentale model: de transitlink vervoert ontsleutelde binnenpakketten, dus het is een vertrouwensgrens en geen particuliere garantie. Als hij een netwerk doorkruist dat je niet beheert, bescherm die hop dan met een goedgekeurde versleutelde tunnel en routeer via de echte topologie. End-to-end TLS authenticeert de toepassing nog steeds zelf, en daarom moet de interne dienst het blijven gebruiken.