Laat één OpenVPN-client via SSH bij een andere komen zonder de pool te openen
Houd client-to-client uit, laat de kernel één stroom doorsturen en laat de rest van de pool dicht. Twee regels op de server plus één op de bestemming.
Eén client moet de SSH-dienst van een andere client bereiken, en de rest van de pool moet zo geïsoleerd blijven als nu. De verleidelijke schakelaar is client-to-client, die peer-toegang voor iedereen tegelijk aanzet en de beslissing aan OpenVPN geeft in plaats van aan de kernel. Een smaller antwoord houdt die schakelaar uit en laat de routing en firewall van de server zelf precies één stroom dragen.
Het mechanisme telt meer dan de tekst van de regel, omdat de twee benaderingen het pakket op verschillende plaatsen zetten. Weten welke je hebt gekozen verklaart zowel de regel die niets lijkt te doen als de peer die zonder haar verbindt.
Waar client-to-client het pakket verplaatst
Met client-to-client aan stuurt de server een peer-pakket intern door in plaats van het weer via het tunnelapparaat naar buiten te sturen, zodat het pakket nooit op het doorstuurpad van de kernel komt. Dat is handig en het betekent ook dat je firewall de stroom nooit ziet die hij zou moeten bewaken. Laat de optie uit en de server routeert het pakket weer naar buiten via dezelfde interface, wat het voor netfilter zet. Dezelfde interface erin, dezelfde eruit, en de FORWARD-keten heeft de stem.
De ruil is expliciet: je wint een beleidspunt en je neemt het routeer- en doorstuurwerk over dat de sluipweg voor je deed. Dat werk is klein voor één stroom en groeit met elke uitzondering die je toevoegt. Tel de uitzonderingen nu, want in de regelset leeft het peerbeleid werkelijk.
Het pad dat een peer-pakket werkelijk aflegt
Neem een Linux Community OpenVPN 2.6-dienst aan, userspace-TUN-verwerking in plaats van DCO, subnette-topologie, tun0 en een pool van 10.44.0.0/24 met client A op 10.44.0.21 en client B op 10.44.0.37. Bij subnette-topologie dekken het adres en de netmasker die A kreeg de pool al, dus A stuurt het pakket naar het tunnelapparaat zonder extra gepushte route. Controleer de effectieve route op A in plaats van er een aan te nemen.
Op de server komt het pakket aan geadresseerd aan B, wat geen lokaal adres is, dus het wordt doorgestuurd. IPv4-doorgifte moet aan staan wil dat überhaupt gebeuren, en de routeopzoeking moet het pakket weer door tun0 naar buiten sturen. De firewall ziet dus een doorgestuurde stroom met dezelfde interface aan beide kanten, en dat is het detail dat de meeste regelsets missen. Hier is geen bronvertaling nodig, en het is juist het intact houden van A's adres waardoor B zijn eigen bronregel kan toepassen.
Twee regels op de server, in deze volgorde
Drie regels dragen de hele toestemming: doorsturen, de paaruitzondering en een standaard drop voor het tunnelpaar. De acceptregel noemt het paar en de dienst, zodat de toestemming een groeiende pool overleeft. Zet hem vóór elke algemene weigering van tunnel-naar-tunnelverkeer, want de eerste overeenkomst wint:
sysctl -w net.ipv4.ip_forward=1
iptables -A FORWARD -i tun0 -o tun0 -s 10.44.0.21 -d 10.44.0.37 -p tcp --dport 22 -j ACCEPT
iptables -A FORWARD -i tun0 -o tun0 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
iptables -A FORWARD -i tun0 -o tun0 -j DROPDie opdrachten zijn illustratief en horen bij welk mechanisme je host ook gebruikt om regels te bewaren; een invoeging tijdens runtime verdwijnt bij de volgende start. De stateful regel is wat B's antwoorden en de TCP-handdruk laat terugkeren zonder een tweede, gespiegelde accept.
Controleer daarna de tellers in plaats van de regellijst, want een regel die nooit overeenkomt ziet er identiek uit aan een die werkt. Als de tellers op nul blijven, neemt het pakket niet het pad dat je denkt.
Wat B nog moet toestaan
B draait de SSH-dienst, dus B beslist of er iets op het tunneladres luistert en of zijn eigen host-firewall de bron accepteert. Een netwerktoestemming op de server is geen toestemming voor enig account op B, en verificatie van de hostsleutel en gebruikersauthenticatie gelden nog steeds zoals van elke andere plek.
Test eerst het positieve geval: een nieuwe SSH-verbinding van A naar B's tunneladres, geaccepteerd met de verwachte hostsleutel. Test daarna een andere peer of een andere poort en bevestig dat die wordt geweigerd, want een toestemming die stil alles toelaat is niet te onderscheiden van een die werkt tot het erop aankomt. Beide helften van die test zijn nodig, en de tweede is degene die mensen overslaan.
Noteer de toegewezen adressen, de effectieve routes op beide clients en de exacte regels op de server en op B. Een geslaagde ping naar de gateway of een open poort op de server bewijst hier niets van, want beide kunnen waar zijn terwijl doorsturen tussen peers nog geblokkeerd is. Schrijf die nummers op terwijl de tunnel omhoog staat, want het adres dat een client na opnieuw verbinden krijgt kan een ander zijn.