O OpenConnect une duas trocas separadas com um único valor de vida curta: o login web e o túnel VPN. A primeira troca é HTTPS comum: as credenciais, uma ida e volta SAML ou um token vão para o gateway, e a resposta carrega um cookie de autenticação. A segunda troca apresenta esse cookie ao mesmo gateway como prova de que a fase web já aconteceu, e só então o túnel sobe.

Durante o login nada sobre o túnel é negociado. Essa é a parte que vale entender, porque a maioria dos erros de script assume que o cookie é uma senha a ser guardada, ou uma chave que protege o tráfego, quando na verdade é um bilhete ao portador para uma sessão específica do gateway.

O que o cliente e o gateway trocam, em ordem

A fase de autenticação parece um site protegido comum. O OpenConnect envia as credenciais do usuário, ou segue o redirecionamento do gateway para um provedor de identidade, e o gateway responde com um documento que embute o cookie de autenticação. No protocolo AnyConnect esse valor viaja num cabeçalho de cookie nas requisições seguintes, normalmente com um nome como webvpn, e o manual o trata como a credencial que leva a sessão adiante.

A segunda fase é uma requisição CONNECT ao endpoint VPN do gateway com esse cookie anexado. O gateway o verifica, atribui um endereço, e o cliente inicia CSTP sobre TLS, com DTLS como caminho de dados opcional mais rápido assim que a sessão existe. Só nesse ponto são estabelecidos os parâmetros do túnel, as rotas, as configurações de DNS e as chaves de tráfego da sessão. O cookie fez o cliente passar pela porta; não criptografou nada.

Essa sequência explica por que existe o openconnect --authenticate. Execute-o e ele faz a fase web, imprime um pequeno bloco de variáveis de shell como COOKIE, HOST, CONNECT_URL e FINGERPRINT, e então sai antes de qualquer túnel ser construído. Um script de envolvimento pode então iniciar a conexão real com esses valores, e é exatamente a divisão que uma implantação sem tela ou em dois contêineres precisa.

O cookie é um portador de sessão, não uma chave

Trate o valor como trataria um identificador de sessão numa aplicação web. Quem o tiver durante a sua vida pode pedir ao gateway o túnel a que essa sessão tem direito, então o sigilo importa. Mas copiá-lo não revela tráfego, porque a confidencialidade do túnel vem do aperto de mão TLS e das chaves derivadas, não da string do cookie.

Também não é uma concessão permanente. O gateway e o provedor de identidade decidem quanto tempo a sessão vive, e um navegador que ainda mostra uma página logada não diz nada sobre se a sessão do túnel continua válida. Reconectar após o vencimento significa repetir a fase web e produzir um cookie novo, e esse é o sentido da reautenticação, não um incômodo a ser contornado com engenharia.

Não trate um cookie como substituto universal de outras credenciais. Uma asserção SAML, uma senha de navegador e um cookie emitido por outro serviço são objetos diferentes com públicos diferentes, e colar um no campo do outro normalmente falha no gateway ou, pior, tem sucesso contra o limite de confiança errado.

Entregar o cookie sem deixar cópias

A entrega mecânica mais segura no Linux é a entrada padrão. --cookie-on-stdin lê o valor do stdin, então o cookie nunca aparece na lista de argumentos do processo, onde qualquer usuário local pode lê-lo com ps. Um pipeline que autentica num processo e alimenta o túnel em outro mantém o valor num pipe em vez de num arquivo ou variável de ambiente.

Argumentos e variáveis de ambiente são mais fracos por motivos diferentes. Um argumento é visível na tabela de processos durante toda a vida do cliente e muitas vezes acaba no histórico do shell. Uma variável de ambiente é herdada por processos filhos, e uma unidade systemd que a define no arquivo da unidade guarda o segredo numa configuração legível. Se um arquivo for necessário, restrinja-o à conta de serviço e apague-o quando a sessão terminar.

Mantenha também o limite de privilégios deliberado. O processo que fala com o provedor de identidade e talvez abra um navegador deve rodar como o usuário dono daquele login. O processo que configura rotas, DNS e o dispositivo do túnel pode precisar de mais privilégios. Rodar o navegador inteiro como root para que seu cookie esteja disponível a um túnel de propriedade do root é a troca errada, e as configurações modernas do OpenConnect podem passar o valor por esse limite de forma explícita.

O registro em log merece a mesma desconfiança. A saída detalhada do cliente, os scripts auxiliares e o diagnóstico do gateway podem repetir material da requisição, e nem todo nível de log redige o cookie. Capture o menor registro de erro de que precisa, mantenha-o fora de canais compartilhados e revise uma amostra redigida antes de anexá-la a um ticket.

Verificação e vencimento na segunda fase

A segunda fase ainda precisa verificar o servidor. O FINGERPRINT que o --authenticate imprime é uma fixação de certificado na forma pin-sha256:, e passá-lo à chamada do túnel com --servercert mantém a checagem ancorada no gateway contra o qual você se autenticou. Desligar a checagem de certificados para simplificar um script remove a única prova de que o cookie está sendo entregue ao host pretendido.

Quando o gateway rejeita o cookie, a solução é uma nova rodada de autenticação, não um cache mais longo. Guarde o cookie só durante a vida da conexão, apague os arquivos temporários ao sair e use o processo de remoção de sessão do provedor de identidade ou do gateway quando uma sessão for exposta ou um dispositivo for perdido. Um cookie em cache não é isenção de MFA.

Antes de automatizar isso, verifique quatro coisas: o túnel roda com a conta correta, o cookie chega pelo stdin, a impressão digital do certificado está fixada e a sessão é descartada quando o túnel fecha. Se faltar alguma, a automação ampliou a confiança no cookie em vez de reproduzir o fluxo manual.

Artigos relacionados