OpenVPN achter stunnel: stuur de wrapper door, niet poort 1194
Twee luisteraars, drie poorten. Controleer waar de doorsturing landt, waar de wrapper bindt, waar hij verbindt, wat een lokale test oversloeg en beide identiteiten.
Zet een TLS-wrapper voor OpenVPN en de uitrol krijgt een tweede luisteraar, waarvan er maar één ooit naar het internet zou moeten kijken. Als de tunnel vanaf dezelfde machine werkt en van buitenaf faalt, is de doorsturing meestal op de verkeerde van de twee gericht. Wat moet kloppen is een keten: de openbare regel bereikt de wrapper, en de eigen backendverbinding van de wrapper bereikt de echte VPN-socket. Vier sprongen dragen die keten, en elk daarvan kan het onderzoek vroegtijdig beëindigen.
Twee sockets, twee eigenaren, één ervan openbaar
De wrapper beëindigt TLS voor de buitenste verbinding en geeft de ontsleutelde bytestroom door aan een gewone OpenVPN TCP-luisteraar. Dat zijn afzonderlijke sockets met afzonderlijke configuratiebestanden, dus het bewerken van de ene laat de andere ongemoeid en nog steeds ogenschijnlijk gezond. Het betekent ook dat de twee uit elkaar kunnen lopen wanneer de ene zonder de andere wordt gewijzigd.
Vanaf de machine zelf werken bewijst daarom heel weinig over het openbare pad. Een directe verbinding naar de native poort slaat de wrapper over, een verbinding naar de wrapper op zijn LAN-adres slaat de vertaling over, en alleen de volledige opzet aan de clientkant oefent wat een buitenstaander doet. Namen moeten ook zorgvuldig worden gelezen, want localhost betekent de host die precies die component draait, en niet de host waarop je toevallig typt. Houd dat onderscheid in je notities, want een test die is vastgelegd zonder de sprong die hij dekte, nodigt uit tot een vergelijking tussen twee verschillende dingen.
Waar de doorsturing werkelijk landt
De keten is als vier sprongen makkelijker vast te houden dan als drie poortnummers, omdat hetzelfde nummer aan elk uiteinde iets anders kan betekenen. Lees de tabel rij voor rij: elke rij is één socket die een verbinding moet aannemen en dan de volgende moet openen. Als een rij op de verkeerde partner is gericht, is het symptoom in de laatste kolom wat de gebruiker meldt.
| Hop | Listens on | Must reach | Symptom when it points elsewhere |
|---|---|---|---|
| Client machine | A local plaintext port | The wrapper's public TLS address | Plain text offered to a TLS endpoint |
| Router forward | Public TCP 443 | The wrapper host on its translated port | Wrapper records no connection at all |
| Wrapper, server mode | Its accepted port, 8443 here | The native VPN socket on loopback | Handshake completes, then silence |
| Native VPN listener | Loopback TCP port | Its peer, over TCP only | A UDP socket behind a byte-stream relay |
Een regel die op de native VPN-poort is gericht in plaats van op de wrapper, slaat de TLS-beëindiging volledig over, en dat is de meest voorkomende vorm van deze fout: de client opent een handshake met een luisteraar die OpenVPN-framing verwacht, zodat de verbinding kan openen en dan vastloopt. Controleer de vertaalde poort tegen het configuratiebestand van de wrapper en niet tegen het geheugen, want de volgende persoon die dat bestand bewerkt, heeft misschien een ander nummer gekozen. De twee opdrachten hieronder tonen beide kanten van die vraag tegelijk.
grep -nE '^[[:space:]]*(accept|connect)' /etc/stunnel/stunnel.conf
ss -lntp | grep -E ':443|:8443|:1194'
Het bindadres dat je weigert
Een accept-regel die aan 127.0.0.1 is gebonden, antwoordt alleen de host zelf, dus een doorsturing die op het LAN-adres aankomt, kan niet verbinden en de client ziet een weigering die klinkt als een pakketfilterprobleem. Kijk naar de socket voordat je de firewall aanraakt, want de socket is het goedkopere antwoord. Verbind de wrapper met de interface waarop de doorsturing is gericht, of houd hem op loopback en zorg dat de doorsturing loopback bereikt via iets dat echt werkt. Dat zijn twee ontwerpen, en elk heeft zijn eigen regel nodig.
Ze door elkaar halen is hoe een werkende wrapper van buitenaf onbereikbaar wordt terwijl elk bestand er correct uitziet. De controle hieronder is één opdracht, en hij beantwoordt een vraag die een doorlichting van de firewallregels niet kan. Als de uitvoer een loopback-adres toont terwijl de doorsturing op het LAN-adres is gericht, hoort de correctie in de accept-regel en niet in het pakketfilter.
ss -lntp '( sport = :8443 )'
Wat de lokale test werkelijk bewees
Een succes dat is vastgelegd zonder de sprong die het dekte, is geen bewijs over de andere sprongen. Noteer welk adres de test gebruikte en welk proces antwoordde. Herhaal het daarna van buiten het netwerk in plaats van vanaf een telefoon op dezelfde Wi-Fi, want haarspeldgedrag verschilt tussen routers en een verbinding die de LAN nooit verliet, kan een client tevredenstellen zonder dat de doorsturing er überhaupt aan te pas komt. Alleen die tweede poging oefent het pad dat een buitenstaander neemt.
Als de poging mislukt, volg dan één enkele verbinding door beide logboeken: de geaccepteerde en verbonden regels van de wrapper, daarna het sessielog van de VPN-daemon zelf. De eerste grens die niets vastlegt, is waar de volgende wijziging hoort. Zodra OpenVPN peer-opties vergelijkt, beoordeel je die berichten volgens de regels van die implementatie. Een waarschuwing over link-mtu-inconsistentie is niet automatisch fataal, link-mtu op 1500 vastzetten bewijst niet dat fragmentatie is gestopt, en cipher-onderhandeling hoort bij de interne OpenVPN-configuratie en niet bij de doorsturing van de router.
nc -vz 127.0.0.1 1194
journalctl -u stunnel -n 50 --no-pager
Die probes dekken de backend-socket en het wrapper-logboek, wat een geweigerde backend scheidt van een geweigerde handshake. Voer ze uit terwijl één poging gaande is en niet daarna. Tijdstempels van één poging maken de vergelijking betrouwbaar.
Twee identiteiten, twee faalorders
Het buitenste certificaat hoort bij de wrapper en de binnenste identiteit bij OpenVPN, en ze kunnen van verschillende autoriteiten komen. Een van de twee controles uitschakelen om een pad gezond te laten lijken, ruilt echte bescherming voor een cosmetisch resultaat. Behoud beide verificaties en debug ze in volgorde, want de volgorde van de berichten benoemt de laag: een certificaatprobleem van de wrapper verschijnt voordat er een VPN-optie wordt onderhandeld, terwijl een fout in de binnenste identiteit pas verschijnt als de stroom is opgezet.
De stunnel-handleiding definieert accept, connect en de clientmodus nauwkeurig, en die secties beantwoorden de socketvraag sneller dan gissen. Als je nog steeds niet kunt zeggen welke laag antwoordde, lees dan het certificaat dat de openbare poort presenteert met de opdracht hieronder. Een wrapper-certificaat in de uitvoer betekent dat de doorsturing de wrapper bereikte, en stilte of een protocolfout betekent dat niet. Dat ene onderscheid bespaart meer tijd dan elke andere controle hier.
openssl s_client -connect vpn.example:443 -servername vpn.example </dev/null 2>/dev/null | openssl x509 -noout -subject -issuer