vpn-klienten som följer med Cisco AnyConnect beter sig som ett samtal: den skriver en prompt, väntar på en rad och skriver sedan nästa. Mata in det samtalet från en fil eller en pipe och samma binär körs utan övervakning. Tekniken är en omdirigering plus en ordnad lista med svar, och det är listan, inte omdirigeringen, som avgör om skriptet är pålitligt.

Två saker bryter det i praktiken. Ordningen på prompterna förskjuts när en gateway frågar något extra, och ett sparat lösenord gör ett enda skrivfel till en kontolåsning. Behandla sekvensen som versionshanterade data som du kan jämföra efter varje gatewayändring. Misslyckas högt i stället för att försöka igen, för en loop är precis hur ett felstavat lösenord blir ett låst konto.

En sekvens, i den ordning klienten frågar

Kör klienten interaktivt en gång och skriv ned varje prompt i den ordning den visas. Den transkriptionen blir svarfilen. När du omdirigerar filen till binären måste första raden vara själva anslutningskommandot, och därför börjar sekvensen med ett värdnamn i stället för ett användarnamn.

connect vpn.example.com
0
<username>
<password>
y
exit

Den bara 0 väljer den första anslutningsprofilen när gatewayen erbjuder en lista; använd det index som din gateway skriver ut. y accepterar en inloggningsbanner, så ta bort den raden om det inte finns någon banner och lägg in en där din gateway ställer en extra fråga. Det avslutande exit är det som låter klienten avsluta rent när det sista svaret har förbrukats.

/opt/cisco/anyconnect/bin/vpn -s < anyconnect.txt

Icke-interaktivt läge är inte valfritt här. Utan -s kan klienten ta över terminalen och ignorera omdirigerad inmatning; med den läses svaren från strömmen och processen återvänder. Där binären behöver förhöjda rättigheter, linda anropet i sudo -n så att skriptet misslyckas direkt i stället för att blockera på en lösenordsfråga.

Där svarfilen läcker

En fil med ett lösenord är en autentiseringsuppgift, så ge den rättigheterna för en sådan: läge 600, ägd av kontot som kör jobbet, och aldrig i en delad eller synkroniserad katalog. Skapa den med läget redan satt i stället för att rätta den efteråt, eftersom en fil är kortvarigt läsbar för alla mellan skrivningen och chmod.

install -m 600 /dev/null ~/.config/anyconnect.txt
chmod 700 ~/.config

Den andra halvan är argv. Ett lösenord som skickas som argument är synligt för varje lokal användare som listar processer, och det hamnar också i skalets historik. Läs det från en fildeskriptor eller en miljövariabel i stället, och sätt nyttolasten inom citattecken så att skalet inte kan expandera något inuti den.

printf '%s\n' 'connect vpn.example.com' '0' "$VPN_USER" "$VPN_PASS" 'y' 'exit' \
  | sudo -n /opt/cisco/anyconnect/bin/vpn -s

Se upp med citattecknen. Inuti dubbla citattecken kan ett lösenord som innehåller ! expanderas av ett interaktivt skal innan klienten ens ser det, och felet kommer som ett generellt event-not-found-fel som ser ut som ett protokollproblem.

Bevisa tunneln och stäng den sedan

Ett anslutet tillstånd bevisar bara att klienten tror sig ha en session. Välj en värd som bara svarar inifrån företagsnätet och testa den en gång innan du gör något annat. Ett fel där är ett routing- eller policyfel, och att köra inloggningen igen ändrar inte det.

/opt/cisco/anyconnect/bin/vpn state
curl -sS -o /dev/null -w '%{http_code}\n' --max-time 10 https://<internal-host>/
/opt/cisco/anyconnect/bin/vpn disconnect

Kontrollera tillståndsutdata före och efter frånkopplingen. En klient som lämnas med en gammal session kan neka nästa anslutning medan skriptet fortfarande rapporterar framgång, och det felläget är osynligt om du bara tittar på utgångskoder. Jämför de två avläsningarna i stället för att lita på den andra ensam. Alias i en skalprofil räcker för dagligt bruk, medan allt schemalagt förtjänar samma granskning av autentiseringsuppgifter och identitet som vilket annat oövervakat jobb som helst.

När en fast lista inte längre är säker

En svarfil kodar dagens promptordning. En ändrad banner, ett påtvingat lösenordsbyte eller en utmaning om andra faktorn gör den till en loop som kan låsa kontot, därför måste skriptet avsluta vid det första oväntade svaret i stället för att starta om.

Fånga det klienten skrev ut, returnera en status som inte är noll och låt anroparen avgöra. Där gatewayen kräver en andra faktor, är det ärliga svaret att en oövervakad inloggning inte är tillgänglig för den profilen, inte att sekvensen behöver en rad till.

Rotation hör till samma granskning. Om autentiseringsuppgiften lagras, bestäm vem som får läsa den, när den ändras och vad som tar bort den när värden byggs om. Ett skript som fungerar i ett år för att ingen har rört lösenordet är inte en design, utan en olycka som väntar på en rotationspolicy.

Profiler som inte är AnyConnect

Två äldre Cisco-stilar för autentiseringsuppgifter blandas ihop med denna. En vpnc-profil frågar efter ett IPSec ID, som egentligen är gruppnamnet, sedan en grupphemlighet, sedan dina egna uppgifter, och alla tre kommer från den som driver gatewayen. Äldre Cisco IPsec är ett annat protokoll än AnyConnect, så vpnc kan inte nå en tjänst som bara är AnyConnect; openconnect --protocol=anyconnect är den öppna klienten för det jobbet.

En .pcf-fil beskriver den äldre klientprofilen. Värden, gruppnamnet och grupplösenordet i den kan skrivas in igen för hand i en klient som talar Cisco IPsec, även om filen inte är en universell import och varje port eller tunnelläge som inte är standard oftast försvinner i överföringen.

Börja med det gatewayen faktiskt erbjuder och välj sedan den klient som talar det protokollet. Att kopiera en profil från en annan sajt är hur folk hamnar med att felsöka autentiseringsuppgifter som aldrig var problemet.

Relaterade artiklar