Logga in i Cisco Secure Client från ett Linux-skal, utan gränssnittet
Ett here-dokument är inte ett inloggningsprotokoll. Fånga den verkliga ordningen på uppmaningarna, använd expect när den varierar och håll lösenordet borta från argv och historiken.
Föreställningen är att ett here-dokument med fyra rader är en fullständig icke-interaktiv inloggning, och den håller ända tills gatewayen erbjuder två grupper, skriver ut en banner eller ber om en token efter lösenordet. Då skriver samma skript lösenordet i en meny som väntade sig en siffra. Kommandorads klienten på Linux går att skripta, men bara om du ger den det den faktiskt väntar på, inte det handledningen antog.
Det fasta here-dokumentet är en myt
Ciscos Linux-klient installerar ett litet program på /opt/cisco/anyconnect/bin/vpn, och Secure Client 5 levererar det fortfarande. Så länge tjänsten vpnagentd kör läser flaggan -s svar från standardinmatningen i den ordning klienten begär dem. Den ordningen är inte fast mellan servrar.
En gruppmeny lägger till en rad. En inloggningsbanner lägger till en till. En tokenförfrågan efter lösenordet bryter sönder ett skript med fyra rader helt, eftersom den femte raden aldrig skulle vara token. Felet är tyst: klienten tar emot fel sträng, anslutningsförsöket avslutas och skriptet rapporterar inget användbart.
Kör klienten för hand en gång mot samma gateway och version och skriv ned uppmaningarna i den ordning de dyker upp. Den utskriften är den specifikation som ditt skript måste uppfylla.
Vad klienten väntar på
I det vanliga fallet med en grupp är ordningen användarnamn, lösenord och ibland en bannerbekräftelse. Den första raden i ett here-dokument blir bara ett menyindex när servern verkligen visar en meny, och det är därför samma skript fungerar på en plats och misslyckas på nästa.
/opt/cisco/anyconnect/bin/vpn -s connect vpn.example.net <<EOF
0
alice
$VPN_PASSWORD
y
EOF
Läs det som fyra svar på fyra möjliga frågor, inte som ett fast protokoll. Nollan är ett menyval, inte ett lösenord, och det avslutande y:et accepterar en banner som många gatewayer aldrig skickar.
Använd expect när ordningen inte går att förutse
När ordningen på uppmaningarna varierar, sluta räkna rader och vänta på uppmaningen i stället. Ett expect-skript startar kommandot connect, väntar på användarnamnsprompten, skickar, väntar på lösenordsprompten, skickar och väntar sedan på det anslutna tillståndet. Varje väntan har sin egen tidsgräns.
Behandla en tidsgräns som ett fel och avsluta. Ett skript som fortsätter skicka inmatning efter en oväntad uppmaning skriver gärna lösenordet i ett skal, en meny eller vad som helst annat som råkar läsa. Så blir ett inloggningsskript en incident.
Expect ger dig också en utskrift som du kan logga med hemligheten borttagen, och den är värd mer än utgångskoden när en gateway ändrar sina uppmaningar efter en uppgradering.
Hemligheten måste bo någonstans
Varje version av det här problemet har en svaghet: lösenordet måste finnas i en form som klienten kan läsa. Att skicka det som argument exponerar det i processtabellen. Att eka det genom ett rör sätter det ofta i skallhistoriken. Båda är läsbara för andra lokala användare på en delad hoppvärd.
install -m 600 /dev/null ~/.vpn-secret
umask 077; VPN_PASSWORD=$(cat ~/.vpn-secret) /opt/cisco/anyconnect/bin/vpn -s connect vpn.example.net
En fil med läget 600 som ägs av kontot är minimum, och den är fortfarande en hemlighet i klartext på disken. secret-tool lookup läser från Linux nyckelring, och på macOS gör security find-generic-password -w samma jobb. Där organisationen stöder certifikat- eller SAML-autentisering, föredra det, eftersom ett lagrat lösenord plus MFA fortfarande inte kan slutföra en inloggning utan en människa.
Bekräfta tunneln och ta sedan över frånkopplingen
Lita inte på frånvaron av feltext. Fråga klienten om dess tillstånd och kontrollera gränssnittet självständigt:
/opt/cisco/anyconnect/bin/vpn state
ip -brief address
Tillståndet ska läsa Connected, och ett tunnelgränssnitt ska ha en adress. Begär sedan en resurs som tunneln ska nå, eftersom ett anslutet tillstånd utan rutt är ett verkligt utfall och lätt att missa.
Koppla från med vpn disconnect och låt skriptet som startade tunneln ta över frånkopplingen. Ett misslyckat jobb som lämnar en session öppen förbrukar en licensplats och ser ut som ett autentiseringsproblem för nästa person som försöker.
Arbetsordning: bekräfta vpnagentd, fånga den verkliga ordningen på uppmaningarna, välj here-dokument eller expect, håll hemligheten borta från argv och historiken, verifiera tillstånd och en resurs och koppla sedan från i samma skript.