Een VPN-client scripten: kies de laag vóór het wachtwoord
Leveranciers-CLI, rasdial, een app-intentie of UI-automatisering falen elk anders. Kies de laag, houd het geheim buiten argv en wacht op status, niet op exitcodes.
Scripts starten VPN-clients op de laag die de auteur koos, en die laag is zelden degene die de taak nodig had. De opdrachtregel van de leverancier, de inbeller van het besturingssysteem en een mobiele app-intentie keren allemaal op een ander punt in het leven van de verbinding terug. Ze gaan ook anders om met het geheim, en dat verschil bepaalt of het wachtwoord zichtbaar is voor elke gebruiker op de machine. Kies de laag voordat je de eerste regel van het script schrijft.
Laag 1: de opdrachtregel van de leverancier
De meeste desktopclients leveren een opdrachtregel die een profielnaam en, maar al te vaak, een wachtwoord aanvaardt. De oude client van Cisco accepteerde een connect-werkwoord met gebruikers- en wachtwoordargumenten; macOS stelt de ingebouwde dienst beschikbaar via networksetup; NetworkManager antwoordt op nmcli. Deze aanroepen keren terug wanneer de opdracht klaar is, wat niet hetzelfde moment is als waarop de tunnel bruikbaar wordt. Lees de eigen documentatie van de leverancier voor de versie die je uitrolt, want deze interfaces veranderen en sommige verdwijnen volledig.
nmcli connection up "Work VPN"
networksetup -connectpppoeservice "Work VPN"
Het voordeel is dat de leverancier zijn eigen profielopslag kent, dus de aanroep gebruikt dezelfde configuratie als de GUI. Het nadeel is dat elke leverancier zijn eigen werkwoorden bedenkt, en een script voor de ene client gaat niet over naar een andere. Zie deze laag als het kortste pad wanneer de client vastligt en de versie is vastgezet.
Laag 2: de eigen dienst van het besturingssysteem
Op Windows maakt de inbeller deel uit van het besturingssysteem, en hij werkt tegen een telefoonboekvermelding in plaats van de profielopslag van de leverancier. Dat maakt hem draagbaarder over clients heen en makkelijker te scripten vanaf een serviceaccount. Het betekent ook dat de verbinding op de ene plek kan bestaan en niet op de andere, wat mensen verwart die in de verkeerde lijst kijken.
rasdial "Work VPN" user pass
Get-VpnConnection -Name "Work VPN" | Select-Object ConnectionStatus
Gebruik het PowerShell-oppervlak wanneer je de vermelding moet aanmaken of verwijderen in plaats van te bellen. De WMI- en cmdlet-lagen stellen dezelfde objecten onder verschillende namen bloot, en verwijderen is een aparte bewerking van verbreken. Een script dat alleen belt, laat na een migratie verouderde vermeldingen achter. Controleer naar welke opslag je automatisering schrijft voordat je belooft dat er wordt opgeruimd.
Remove-VpnConnection -Name "Old VPN" -Force
Get-VpnConnection
Op macOS is het equivalent de lijst met netwerkdiensten, waar een bestaande dienst op naam wordt verbonden in plaats van ter plekke aangemaakt.
Inloggegevens lekken op elke laag, dus kies het kanaal
Alles wat je op de opdrachtregel doorgeeft, verschijnt in de procestabel voor elke lokale gebruiker, en het overleeft meestal ook in de shellgeschiedenis. Het ondersteunde alternatief van OpenVPN is om het geheim uit een bestand te lezen met --askpass, en het bestand zelf heeft rechten nodig die passen bij het vertrouwen dat je erin stelt. Een benoemde pijp voorkomt dat het geheim naar schijf wordt geschreven, maar laat elk proces dat hem kan openen daar schrijven. Bewaar het geheim op Windows in de referentiebeheerder, of in een bestand dat alleen het serviceaccount kan lezen, en nooit als letterlijke tekst in een batchbestand.
openvpn --config /etc/openvpn/work.conf --askpass /etc/openvpn/work.secret --auth-nocache --daemon
ls -l /etc/openvpn/work.secret
Dezelfde regel geldt voor tokens en eenmalige codes: als de automatisering ze nodig heeft, heeft de automatisering een kanaal nodig dat geen opdrachtregelargument is. Wissel het geheim wanneer je het mechanisme verandert, want de oude waarde heeft ergens in een log gestaan. Een script dat werkt en lekt, is geen werkend script.
Wacht op status en houd dan toezicht met één eigenaar
Elk van deze aanroepen keert terug voordat de tunnel klaar is, dus poll de status die de client blootlegt of test een bestemming erbinnen met een time-out. Bestanden kopiëren of een databaseverbinding openen direct na de verbindingsaanroep is een race, en het faalt met tussenpozen op een manier die op een netwerkstoring lijkt.
ip link show tun0
nmcli -t -f GENERAL.STATE connection show "Work VPN"
curl -sS --max-time 5 https://app.internal.example/health -o /dev/null
Verbreken heeft hetzelfde probleem in omgekeerde richting: het proces kan eindigen voordat de routes weg zijn. Gebruik de hooks van de client waar die bestaan, zoals de up- en down-scripts van OpenVPN of de ExecStartPost van een systemd-unit, want die draaien op het punt dat je echt belangrijk vindt. Hooks draaien met de rechten van wat ze ook heeft aangeroepen, dus een hook die netwerken herstart heeft een expliciete regel nodig in plaats van een aanname. Houd precies één eigenaar voor de levensduur van de verbinding.
Wanneer twee toezichthouders hetzelfde profiel starten en stoppen, is het resultaat een herverbindingslus die leest als een storing van de provider. Het runbook eindigt wanneer de laag gedocumenteerd is, het geheim een kanaal heeft dat geen argv is, de wachtvoorwaarde een statuscontrole met een time-out is, en één proces de levenscyclus bezit.