La password è corretta, l’accesso VPN fallisce comunque, e il server RADIUS ha forse fatto esattamente ciò che gli era stato ordinato. Il gateway ha probabilmente ricevuto un Access-Challenge, non ha mostrato nulla di utile e poi è andato in timeout o ha trattato quella risposta come un rifiuto. Dal lato del client sembra una credenziale errata o un tunnel rotto. La causa di solito si trova nel mezzo di una conversazione che nessuno ha catturato.

Un accesso, due scambi RADIUS

Quando il backend vuole un secondo fattore, non risponde alla prima richiesta con un’accettazione o un rifiuto. Risponde con il codice 11 e attende la risposta successiva dell’utente, che il gateway deve rimandare in una richiesta di follow-up. Quella richiesta di follow-up appartiene alla stessa conversazione di autenticazione, non a un nuovo tentativo di accesso.

In una configurazione funzionante l’utente vede un secondo prompt: prima la password, poi un codice monouso, oppure un unico prompt combinato se l’operatore ne ha documentato uno. In una configurazione rotta il secondo prompt non compare mai e l’accesso semplicemente fallisce.

È questo il sintomo da inseguire, ed è facile confermarlo solo dal lato client: se il client VPN chiede esattamente un segreto e poi rifiuta una password che sapete valida, lo scambio probabilmente si è fermato alla sfida.

Che cosa trasporta davvero la sfida

La specifica RADIUS descrive il codice 11 nella sezione 4.4 e consente due attributi che qui contano. Reply-Message contiene testo destinato all’utente, e State contiene un valore opaco che il server vuole indietro. Il NAS non deve interpretare State, solo restituirlo invariato.

La richiesta di follow-up usa un nuovo Identifier e un nuovo Request Authenticator, e deve portare lo stesso valore State più la risposta dell’utente. Il server la abbina alla sfida in sospeso tramite quello State, ed è per questo che un gateway che rigenera o scarta l’attributo non può completare la cerimonia. Anche il response authenticator di ogni risposta deve validare, altrimenti il NAS dovrebbe scartare il pacchetto.

La sezione 4.4 aggiunge il dettaglio che spiega la maggior parte dei fallimenti silenziosi: un NAS che non può supportare le sfide tratta Access-Challenge come un rifiuto. Se il servizio VPN del vostro gateway è precedente a quel supporto o lo omette, la richiesta del backend per un secondo fattore diventa un «autenticazione non riuscita» immediato senza alcun prompt.

Dove si perde la richiesta concatenata

Il primo sospetto è il percorso del prompt, non la credenziale. Un portale che mostra un campo OTP per gli accessi web non lo fa automaticamente per il servizio VPN, e alcuni gateway passano una sfida solo ai client che dichiarano la capacità. Provate lo stesso account su entrambi i punti di ingresso; se il portale funziona e la VPN no, state guardando la consegna, non il token.

Il formato di input è il secondo sospetto. Concatenare password e codice senza il separatore documentato dal fornitore, o lasciare che una credenziale salvata riproduca un vecchio codice, fallisce in un modo identico a una password errata. Usate il prompt separato o il formato combinato documentato dall’operatore, e non improvvisate mai un delimitatore.

Difetti specifici di versione esistono, ma un elenco di versioni corrette di anni fa non è una diagnosi per il deployment di oggi. Leggete le note di rilascio del software che eseguite davvero, e tenete la fase di scambio osservata come prova.

Tracciate un solo tentativo da capo a fondo

Riproducetelo una volta, con il debug lato server attivo, e tenete ogni altra sessione fuori dalla finestra di cattura:

$ sudo radsniff -i eth0 -x -f 'udp port 1812'
$ sudo freeradius -X
$ radtest alice 'password' 127.0.0.1 0 testing123

Nell’output cercate la forma della conversazione più che una singola riga. Una prima Access-Request con Identifier 3, un Access-Challenge che porta State, poi una seconda Access-Request con Identifier 4 che ripete quello State e include la risposta dell’utente. Se manca la seconda richiesta, il gateway non ha mai dato seguito. Se arriva senza State, il server non può abbinarla alla sfida in sospeso e di solito la rifiuta.

Oscurate credenziali, token e dati di identità non necessari quando condividete la traccia, e correlate gli eventi di un solo tentativo invece di mescolare ripetizioni da più schede del browser. I timestamp sono vostri amici qui; una sfida che arriva dopo che il client ha rinunciato sembra un rifiuto per l’utente e una risposta lenta nel log.

Lo stato finale che volete è una conversazione completata e autorizzata, seguita dall’accesso previsto al servizio. Una risposta che arriva dal server RADIUS dimostra molto meno di questo.

Articoli correlati