Sostituire un'autorità di certificazione VPN non è uno scambio di file. Nel momento in cui la nuova CA firma il suo primo certificato, ogni validatore che continua a fidarsi solo della vecchia deve prendere una decisione, e gli host che non ricevono mai il nuovo ancoraggio continuano a rifiutare peer validi. L'ho visto fallire in entrambe le direzioni: il gateway aveva appreso la nuova CA e i client no, quindi le nuove connessioni fallivano, mentre i tunnel già attivi restavano attivi e facevano sembrare l'interruzione un problema di routing. Ecco cosa cambia, nell'ordine in cui compaiono i guasti.

Una sostituzione, due cambiamenti distinti

Un'autorità di certificazione è un nome, una chiave pubblica e la chiave privata che firma. I validatori non si fidano mai de «la CA» in astratto. Si fidano di uno specifico certificato che già si trova in un archivio di fiducia, e accettano un emittente solo se una catena di firme raggiunge quella copia memorizzata. Sostituire la CA cambia quindi due cose che falliscono indipendentemente: quali ancoraggi vengono accettati e quali identità dei peer sono state emesse sotto di essi.

La maggior parte delle distribuzioni VPN valida in entrambe le direzioni. Il client autentica il certificato del gateway e il gateway quello del client. Una rotazione che aggiorna solo il bundle del client lascia il server a rifiutare ogni client che presenta ancora un'identità della vecchia CA, e l'inverso è altrettanto comune. Inventariate prima i punti di applicazione: archivi di fiducia dei client, file ca del gateway, ogni proxy che termina TLS davanti a esso e la sonda che controlla l'endpoint dall'esterno.

Cosa controlla un validatore, in ordine

La validazione del percorso sale dal certificato del peer attraverso eventuali intermedi fino a raggiungere un ancoraggio fidato. A ogni passo verifica la firma, controlla che ogni certificato sia dentro la propria finestra di validità e conferma che i vincoli di base e l'uso della chiave consentano all'emittente di firmare. Solo allora l'applicazione guarda il certificato foglia: i nomi alternativi del soggetto devono coprire il nome chiamato, e l'uso esteso della chiave deve permettere l'autenticazione del server o del client.

Per ripetere quel percorso offline, puntate -CAfile esattamente al bundle che distribuirete e non all'archivio di sistema. Altrimenti state testando l'host, non la modifica:

openssl verify -CAfile new-ca.crt gateway.crt
openssl verify -CAfile new-ca.crt -untrusted intermediate.crt client.crt
openssl x509 -in gateway.crt -noout -subject -issuer -dates
openssl s_client -connect gw.example.net:443 -CAfile new-ca.crt

Quel comando funziona solo contro un listener TLS semplice come la pagina di amministrazione HTTPS del gateway; il canale di controllo di OpenVPN precede TLS, quindi s_client non può ispezionare lo handshake del tunnel.

Le regole di costruzione del percorso dietro questi errori sono nella RFC 5280 sezione 6. Spiegano i guasti che altrimenti sembrano arbitrari: un intermedio scaduto che nessuno ricordava, un certificato il cui uso della chiave vieta la firma o un vincolo di nome che esclude l'host che state testando.

Perché il vecchio tunnel continua a funzionare

TLS e OpenVPN mantengono viva una sessione stabilita dopo che lo handshake è terminato. Nulla rivalida il certificato del peer per ogni pacchetto, quindi un client connesso prima del cambiamento continua a passare traffico finché non rinegozia, si riconnette o il tunnel cade. È proprio questo varco che fa sembrare corretto un cambio di CA per un'ora e poi lo fa fallire nel momento peggiore: un portatile si sveglia, una mappatura NAT scade, un gateway si riavvia.

La ripresa della sessione allunga ancora l'illusione. Un ticket di sessione TLS consente al client di tornare senza reinviare certificati, e la ripresa salta la validazione del percorso perché il primo handshake l'ha già fatta. Quindi il test onesto è uno handshake completo in un processo nuovo. Riavviate il client invece di riconnettere il tunnel, e su un profilo di test valutate la disattivazione dei ticket perché il percorso di ripresa non possa nascondere una catena rotta.

Tenete lo strato della chiave statica separato da questo. tls-auth aggiunge un HMAC al canale di controllo, tls-crypt lo cifra e lo autentica, e nessuno dei due trasporta materiale di certificato, quindi ruotare l'uno o l'altro è un cambiamento separato con il proprio modo di guasto. Le distribuzioni che confondono i due finiscono con un client la cui chiave statica è a posto, il cui certificato è obsoleto e il cui messaggio di errore non menziona nessuno dei due.

La trappola del riutilizzo del nome del soggetto

È tentante riutilizzare il nome distinto del predecessore perché nulla a valle debba cambiare. Questo mantiene stabile la riga dell'emittente nell'interfaccia e distrugge l'unico segnale che vi serve. Due certificati con soggetti identici e chiavi diverse non si distinguono per nome, quindi un bundle che contiene entrambi gli ancoraggi dà al validatore due candidati e nessuna regola per scegliere.

La costruzione del percorso può allora scegliere quello sbagliato, segnalare «impossibile ottenere il certificato dell'emittente locale» mentre l'ancoraggio corretto è presente, o riuscire su un host e fallire su un altro con lo stesso bundle, perché l'ordine dei candidati era diverso. Se il nome deve essere riutilizzato, tenete entrambi gli ancoraggi in file separati durante la transizione e caricateli esplicitamente, e uniteli solo quando ogni peer presenta il nuovo emittente. Altrimenti date alla sostituzione un nome comune distinto — un suffisso di generazione o di data basta — perché i log e i testi di errore dicano sotto quale autorità è stato emesso il peer che fallisce.

Una rotazione che non abbatte la rete

Per una sostituzione pianificata, accettate entrambi gli ancoraggi per una finestra limitata invece di cambiare in un solo passo. Emettete la nuova CA e i suoi intermedi, mettete il nuovo ancoraggio nel bundle di ogni validatore accanto al vecchio, e solo allora iniziate a emettere certificati dei peer da essa. I peer con identità vecchie validano contro l'ancoraggio vecchio; quelli nuovi funzionano contro il nuovo.

Fatto in quest'ordine, ogni passo è reversibile. Il guasto che evitate è il cambio simultaneo, in cui un client che ha perso l'aggiornamento del bundle incontra un gateway che ha già ritirato il vecchio ancoraggio, lo handshake muore e nessun log dice quale lato è obsoleto.

Ritirate nella direzione opposta. Reiterate ogni identità che deve sopravvivere, confermate che ognuna presenti la nuova catena, poi rimuovete il vecchio ancoraggio dai bundle. Togliete dal servizio la chiave privata della vecchia CA, perché un emittente che può ancora firmare significa che la rotazione non è finita. Conservate certificati e registri di emissione per l'audit. Un emittente perso si ripristina verso la stessa fiducia; un'esposizione richiede nuove identità e nessun ritorno al vecchio ancoraggio.

Verificate il risultato, non l'elenco dei file

Un file di fiducia nella directory attesa dimostra poco. L'applicazione può leggere un percorso diverso, un formato diverso o una copia dentro un pacchetto che un aggiornamento sostituisce. Controllate il comportamento a entrambe le estremità, non l'esistenza di un file.

Confermate che una connessione nuova con una nuova identità riesca, poi confermate che un'identità emessa dalla CA ritirata venga rifiutata. È quella seconda prova che le persone saltano, e l'unica che mostra che l'autorità vecchia non concede più accesso. Dove la distribuzione si affida a CRL o OCSP, verificate che i punti di distribuzione nei nuovi certificati si risolvano e che i peer che interrogano raggiungano il responder.

Chiudete con un client che non si è mai connesso: cancellate lo stato del suo profilo, connettetelo e leggete la catena negoziata. Un peer che riprende una sessione in cache riferirà allegramente che la migrazione ha funzionato quando non ha validato nulla.

Articoli correlati