OpenConnect binder samman två separata utbyten med ett enda kortlivat värde: webbinloggningen och VPN-tunneln. Det första utbytet är vanlig HTTPS: autentiseringsuppgifter, en SAML-rundtur eller en token går till gatewayen, och svaret bär en autentiseringskaka. Det andra utbytet visar upp den kakan för samma gateway som bevis på att webbfasen redan har skett, och först då reser sig tunneln.

Under inloggningen förhandlas ingenting om tunneln. Det är den delen som är värd att förstå, eftersom de flesta skriptfel antar att kakan är ett lösenord som ska lagras, eller en nyckel som skyddar trafiken, när den egentligen är en bärarbiljett för en bestämd gatewaysession.

Vad klienten och gatewayen utbyter, i ordning

Autentiseringsfasen ser ut som en vanlig skyddad webbplats. OpenConnect skickar användarens autentiseringsuppgifter, eller följer gatewayens omdirigering till en identitetsleverantör, och gatewayen svarar med ett dokument som bäddar in autentiseringskakan. I AnyConnect-protokollet reser det värdet i en kakheader på de följande begäranden, vanligtvis under ett namn som webvpn, och handboken behandlar det som den uppgift som bär sessionen vidare.

Den andra fasen är en CONNECT-begäran till gatewayens VPN-slutpunkt med kakan bifogad. Gatewayen kontrollerar den, tilldelar en adress, och klienten startar CSTP över TLS, med DTLS som en valfri snabbare dataväg när sessionen finns. Först vid denna punkt fastställs tunnelparametrar, rutter, DNS-inställningar och sessionens trafiknycklar. Kakan släppte in klienten genom dörren; den krypterade ingenting.

Den här ordningen förklarar varför openconnect --authenticate finns. Kör det, och det utför webbfasen, skriver ut ett litet block skalsvariabler som COOKIE, HOST, CONNECT_URL och FINGERPRINT, och avslutar sedan innan någon tunnel byggs. Ett omslagsskript kan därefter starta den riktiga anslutningen med de värdena, och det är precis den uppdelning som en huvudlös eller tvåcontainers driftsättning behöver.

Kakan är en sessionsbärare, inte en nyckel

Behandla värdet som du skulle behandla ett sessions-ID i en webbapplikation. Den som har det under dess livstid kan begära av gatewayen den tunnel som sessionen har rätt till, så hemlighållandet spelar roll. Men att kopiera det avslöjar inte trafik, eftersom tunnelns konfidentialitet kommer från TLS-handskakningen och de härledda nycklarna, inte från kaksträngen.

Det är inte heller ett permanent tillstånd. Gatewayen och identitetsleverantören bestämmer hur länge sessionen lever, och en webbläsare som fortfarande visar en inloggad sida säger ingenting om huruvida tunnelsessionen fortfarande är giltig. Att återansluta efter utgång innebär att upprepa webbfasen och producera en färsk kaka, och det är just poängen med reautentisering, inte en olägenhet som ska konstrueras bort.

Behandla inte en kaka som en universell ersättning för andra autentiseringsuppgifter. Ett SAML-påstående, ett webbläsarlösenord och en kaka som utfärdats av en annan tjänst är olika objekt med olika målgrupper, och att klistra in det ena i det andras fält misslyckas vanligtvis vid gatewayen eller, värre, lyckas mot den felaktiga förtroendegränsen.

Att lämna över kakan utan att lämna kopior

Den säkraste mekaniska överlämningen på Linux är standardinmatning. --cookie-on-stdin läser värdet från stdin, så kakan visas aldrig i processens argumentlista, där vilken lokal användare som helst kan läsa den med ps. En pipeline som autentiserar i en process och matar tunneln i en annan håller värdet i ett rör i stället för i en fil eller en miljövariabel.

Argument och miljövariabler är svagare av olika skäl. Ett argument syns i processtabellen under hela klientens livstid och hamnar ofta i skalhistoriken. En miljövariabel ärvs av barnprocesser, och en systemd-enhet som sätter den i enhetsfilen lagrar hemligheten i en läsbar konfiguration. Om en fil är nödvändig, begränsa den till tjänstekontot och ta bort den när sessionen slutar.

Håll också privilegiegränsen medveten. Processen som talar med identitetsleverantören och kanske öppnar en webbläsare bör köra som den användare som äger inloggningen. Processen som konfigurerar rutter, DNS och tunnelanordningen kan behöva mer privilegier. Att köra hela webbläsaren som root för att dess kaka ska vara tillgänglig för en root-ägd tunnel är det felaktiga utbytet, och moderna OpenConnect-uppsättningar kan lämna över värdet över den gränsen uttryckligen.

Loggning förtjänar samma misstänksamhet. Utförlig klientutdata, hjälpskript och gatewaydiagnostik kan alla upprepa begäransomaterial, och inte alla loggnivåer maskerar kakan. Fånga den minsta felpost du behöver, håll den utanför delade kanaler och kontrollera ett maskat prov innan du bifogar det till ett ärende.

Verifiering och utgång i den andra fasen

Den andra fasen måste fortfarande verifiera servern. Den FINGERPRINT som --authenticate skriver ut är en certifikatnål i formen pin-sha256:, och att lämna den till tunnelanropet med --servercert håller kontrollen förankrad i gatewayen som du autentiserade dig mot. Att stänga av certifikatkontrollen för att göra ett skript enklare tar bort det enda beviset på att kakan lämnas till den avsedda värden.

När gatewayen avvisar kakan är lösningen en ny autentiseringsrunda, inte en längre cache. Lagra kakan bara under anslutningens livstid, radera tillfälliga filer vid avslut och använd identitetsleverantörens eller gatewayens process för att ta bort sessionen när en session exponeras eller en enhet tappas bort. En cachad kaka är inte ett undantag från MFA.

Innan du automatiserar detta, verifiera fyra saker: tunneln körs under rätt konto, kakan kommer in via stdin, certifikatets fingeravtryck är nålat och sessionen kastas när tunneln stängs. Om något saknas har automatiseringen utökat förtroendet för kakan i stället för att återskapa det manuella flödet.

Relaterade artiklar