Autentificare în Cisco Secure Client dintr-un shell Linux, fără GUI
Un here-document nu este un protocol de autentificare. Înregistrează ordinea reală a prompturilor, folosește expect când aceasta variază și ține parola în afara argv și a istoricului.
Convingerea este că un here-document cu patru linii este o autentificare neinteractivă completă și rezistă exact până când gateway-ul oferă două grupuri, tipărește un banner sau cere un token după parolă. Atunci același script tastează parola într-un meniu care aștepta un număr. Clientul de linie de comandă din Linux poate fi scriptat, dar numai dacă îi dai ce așteaptă de fapt, nu ce a presupus tutorialul.
Here-documentul fix este un mit
Clientul Linux al Cisco instalează un program mic în /opt/cisco/anyconnect/bin/vpn, iar Secure Client 5 îl livrează în continuare. Cât timp serviciul vpnagentd rulează, opțiunea -s citește răspunsuri de la intrarea standard în ordinea în care clientul le cere. Acea ordine nu este fixă între servere.
Un meniu de grupuri adaugă o linie. Un banner de autentificare adaugă încă una. Cererea de token după parolă rupe complet un script de patru linii, pentru că a cincea linie nu ar fi fost niciodată tokenul. Eșecul este silențios: clientul primește un șir greșit, încercarea de conectare se termină, iar scriptul nu raportează nimic util.
Rulează clientul manual o dată împotriva aceluiași gateway și aceleiași versiuni și notează prompturile în ordinea în care apar. Acea transcriere este specificația pe care scriptul tău trebuie să o îndeplinească.
Ce așteaptă clientul
În cazul obișnuit cu un singur grup, secvența este nume de utilizator, parolă și uneori o confirmare de banner. Prima linie a unui here-document devine index de meniu doar când serverul chiar afișează un meniu, de aceea același script funcționează pe un site și eșuează pe următorul.
/opt/cisco/anyconnect/bin/vpn -s connect vpn.example.net <<EOF
0
alice
$VPN_PASSWORD
y
EOF
Citește asta ca patru răspunsuri la patru întrebări posibile, nu ca un protocol fix. Zero este o selecție de meniu, nu o parolă, iar y-ul final acceptă un banner pe care multe gateway-uri nu îl trimit niciodată.
Folosește expect când ordinea nu este previzibilă
Când ordinea prompturilor variază, oprește numărarea liniilor și așteaptă promptul în schimb. Un script expect pornește comanda connect, așteaptă promptul de nume de utilizator, trimite, așteaptă promptul de parolă, trimite și apoi așteaptă starea conectat. Fiecare așteptare are propriul timeout.
Tratează un timeout ca eșec și ieși. Un script care continuă să trimită date după un prompt neașteptat va tasta bucuros parola într-un shell, într-un meniu sau în orice altceva citește. Așa devine un script de autentificare un incident.
Expect îți dă și o transcriere pe care o poți înregistra cu secretul eliminat, iar asta valorează mai mult decât codul de ieșire când un gateway își schimbă prompturile după o actualizare.
Secretul trebuie să trăiască undeva
Fiecare versiune a acestei probleme are o singură slăbiciune: parola trebuie să existe într-o formă pe care clientul o poate citi. Trecerea ei ca argument o expune în tabela de procese. Afișarea ei printr-un pipe o pune adesea în istoricul shell-ului. Ambele sunt citibile de alți utilizatori locali de pe un host de salt partajat.
install -m 600 /dev/null ~/.vpn-secret
umask 077; VPN_PASSWORD=$(cat ~/.vpn-secret) /opt/cisco/anyconnect/bin/vpn -s connect vpn.example.net
Un fișier cu modul 600 deținut de cont este minimul, și rămâne un secret în text simplu pe disc. secret-tool lookup citește din inelul de chei Linux, iar pe macOS aceeași sarcină este făcută de security find-generic-password -w. Unde organizația acceptă autentificare prin certificat sau SAML, preferă-o, pentru că o parolă stocată plus MFA tot nu poate finaliza o autentificare fără un om.
Confirmă tunelul, apoi asumă-ți deconectarea
Nu te baza pe absența textului de eroare. Întreabă clientul despre starea lui și verifică interfața independent:
/opt/cisco/anyconnect/bin/vpn state
ip -brief address
Starea ar trebui să afișeze Connected, iar o interfață de tunel ar trebui să aibă o adresă. Apoi cere o resursă pe care tunelul ar trebui să o atingă, pentru că o stare conectată fără rută este un rezultat real și ușor de ratat.
Deconectează cu vpn disconnect și lasă scriptul care a pornit tunelul să preia deconectarea. O sarcină eșuată care lasă o sesiune deschisă consumă un loc de licență și arată ca o problemă de autentificare pentru următoarea persoană care încearcă.
Ordinea lucrului: confirmă vpnagentd, înregistrează ordinea reală a prompturilor, alege here-document sau expect, ține secretul în afara argv și a istoricului, verifică starea și o resursă, apoi deconectează în același script.