Dal lato del client sembra una disconnessione casuale dopo un’ora di sessione attiva. L’icona nella tray scompare, il tunnel si ricostruisce e il log mostra un errore di autenticazione invece di un errore di rete. In realtà la sessione ha rinegoziato e il secondo handshake ha richiesto credenziali di cui il client non aveva più una copia valida. Un codice monouso che ha funzionato al login non può funzionare di nuovo, quindi il rekey fallisce esattamente come previsto.

La soluzione è decidere cosa deve presentare il secondo handshake, non allungare il timer dei tentativi.

Ripercorri lo scambio dal punto di vista del client

Al login il client invia nome utente, password e un codice del dispositivo token, e il server accetta la combinazione. La sessione poi procede finché scatta un trigger di rinegoziazione, che avvia un nuovo handshake TLS dentro il tunnel esistente. Quell’handshake chiede di nuovo l’autenticazione. Se il percorso di autenticazione del server prevede una password più un codice monouso corrente, il client non ha un nuovo codice da offrire, a meno che l’utente non sia presente a digitarlo.

La maggior parte dei client non apre una richiesta a metà sessione, quindi l’handshake va in timeout e il tunnel cade. L’utente vede una riconnessione, non una richiesta di autenticazione: è per questo che il primo resoconto di solito dà la colpa alla rete.

auth-gen-token cambia chi risponde alla seconda domanda

L’opzione auth-gen-token consente al server di emettere un token dopo un login riuscito, e le rinegoziazioni successive presentano quel token invece di ripetere password e codice. Il manuale ne documenta durata e comportamento di rinnovo, e il token va trattato come una credenziale con una propria scadenza. Nel percorso predefinito il server convalida il token da solo invece di richiamare di nuovo l’autenticatore esterno della password.

Con un’integrazione di autenticazione esterna, quella divisione cambia. Il plugin deve comprendere lo stato del token e applicare i propri controlli, perché il server non è più l’unico componente che decide se la sessione continua. Trattare il token come un altro codice monouso numerico non è un’implementazione della funzione.

Decidi cosa succede allo stato dell’account

Un token che vive più a lungo dell’accesso di un account è un buco di policy. Decidi come un account disabilitato, un’appartenenza a un gruppo rimossa o un dispositivo revocato abbiano effetto mentre un token è ancora valido. Durate brevi del token restringono la finestra; un percorso di revoca esplicito la rende intenzionale. Scrivi la risposta prima di abilitare l’opzione, perché il percorso predefinito non consulta l’autenticatore esterno a ogni rinegoziazione.

In un deployment con più server il segreto di firma del token deve essere condiviso, altrimenti il client può essere inviato a un nodo che non può convalidare il suo token.

Metti alla prova scadenza e riconnessione, non solo il login

Riduci l’intervallo di rinegoziazione in un profilo di test, così il secondo handshake avviene mentre guardi, poi segui entrambi i log. Conferma che il token sia emesso al login, presentato al rekey e rinnovato o riemesso secondo la durata configurata. Poi forza una scadenza del token e una riconnessione completa, perché un client che si riconnette senza errori può comunque fallire sul percorso di rekey.

Prova per ultima la rimozione dell’account. Quel caso ti dice se la policy che hai scritto viene applicata o solo documentata.

Non risolverlo disabilitando il rinnovo

Portare a zero l’intervallo di rinegoziazione su entrambi i peer elimina il sintomo e con esso la rotazione delle chiavi. Questo nasconde un problema di replay delle credenziali dietro un cambio di policy che nessuno ha esaminato. Mantieni il rinnovo e scegli tra un token emesso dal server e una nuova richiesta interattiva in base alla presenza di un utente.

Un timer dei tentativi più lungo non rende di nuovo valido un codice già speso. Ritarda solo la disconnessione e rende il log più difficile da leggere.

Articoli correlati