Tenete la CA radice della VPN offline e continuate a emettere certificati
Tenete la chiave radice fuori dalla rete, firmate i certificati foglia con una CA intermedia, pubblicate una CRL in tempo e provate la catena prima che il primo client si connetta.
La vostra VPN risponde alle connessioni alle 3 di notte mentre la macchina che firma i suoi certificati è spenta in un cassetto. Un client che convalida il certificato del server non contatta mai la vostra CA, quindi la CA non deve essere raggiungibile per nessuna connessione. La parte che richiede pianificazione è il giorno in cui un certificato deve essere emesso, rinnovato o revocato mentre la chiave radice resta sotto chiave.
Che cosa convalida davvero una connessione
Quando il client OpenVPN si connette, percorre la catena di firme dal certificato foglia del server fino a un certificato di CA di cui si fida già, controlla la finestra di validità e, se il profilo lo prevede, consulta una lista di revoca. Non cerca mai la vostra CA radice. Il server fa l’immagine speculare per i certificati client. Al momento della connessione sono presenti solo la foglia, l’intermedio e il pacchetto di fiducia distribuito in precedenza.
Ciò che fallisce davvero è una delle tre cose: la chiave di firma non è disponibile all’emissione, una lista di revoca è diventata obsoleta oppure il pacchetto di fiducia del client è più vecchio della catena presentata dal server. La prima è un problema di processo; le altre due sono problemi di distribuzione. Nessuna di esse richiede che la chiave radice sia online, e un servizio VPN gestito che esige un certificato privato per l’autenticazione del tunnel sposta solo l’autorità di firma al fornitore. Azure da punto a sito funziona al contrario: caricate un certificato radice e i certificati firmati sotto di esso sono considerati attendibili, quindi chiedete chi firma, chi convalida e come un certificato viene ritirato in anticipo.
Costruite la radice su un host che non riceve mai un indirizzo
Una radice offline si usa di rado: per firmare il certificato della CA intermedia e, in seguito, per rinnovarlo o revocarlo. Tutto il resto avviene un livello più in basso. Fate il lavoro della radice su una macchina tenuta fuori dalla rete, se possibile da un sistema live, e annotate chi era nella stanza. I comandi presuppongono OpenSSL 1.1.1 o successivo, perché -addext non è disponibile nelle build più vecchie.
openssl genpkey -algorithm EC -pkeyopt ec_paramgen_curve:P-256 -out root.key
openssl req -x509 -new -key root.key -sha256 -days 7300 \
-subj "/CN=Example VPN Root CA" -out root.crt \
-addext "basicConstraints=critical,CA:TRUE" \
-addext "keyUsage=critical,keyCertSign,cRLSign"
Create l’intermedia sull’host di firma e portate solo la sua richiesta alla macchina offline. La radice firma quella richiesta con lunghezza di percorso zero, così la CA intermedia può firmare certificati di endpoint ma non può creare un’altra CA sotto di sé. Quell’unica estensione impedisce a un host di firma compromesso di coniare un’autorità equivalente alla radice. Usate ECDSA solo se ogni client esegue OpenVPN 2.4 o successivo; altrimenti generate chiavi RSA e mantenete lo stesso flusso.
openssl genpkey -algorithm EC -pkeyopt ec_paramgen_curve:P-256 -out intermediate.key
openssl req -new -key intermediate.key -subj "/CN=Example VPN Intermediate CA" -out intermediate.csr
openssl x509 -req -in intermediate.csr -CA root.crt -CAkey root.key \
-CAcreateserial -days 3650 -sha256 -extfile intermediate.ext -out intermediate.crt
intermediate.ext contiene basicConstraints=critical,CA:TRUE,pathlen:0, keyUsage=critical,keyCertSign,cRLSign e authorityKeyIdentifier=keyid:always. Riportate la chiave radice nella sua cassaforte prima di ricollegare l’host di firma. Se la radice deve poter revocare l’intermedia, firmatela con openssl ca -config root.cnf -extensions intermediate_ca contro un index.txt a livello di radice invece di openssl x509 -req, così il numero di serie viene registrato; poi inviate la lista radice risultante nel profilo del client, dove un crl-verify basato su file la legge all’avvio. Inviate ai client un pacchetto con entrambi i certificati CA; una foglia da sola non verrà convalidata contro la radice.
Emettere foglie dall’intermedia, con un database
Firmare con openssl x509 -req funziona finché non dovete revocare, perché nulla registra il numero di serie. Usate openssl ca dal primo certificato così numero di serie, scadenza e stato di revoca vivono in un unico database. Create i file del database una volta, poi puntate la configurazione su di essi:
mkdir -p /etc/vpn-ca/intermediate/newcerts
touch /etc/vpn-ca/intermediate/index.txt
echo 1000 > /etc/vpn-ca/intermediate/serial
echo 1000 > /etc/vpn-ca/intermediate/crlnumber
[ ca ]
default_ca = CA_default
[ CA_default ]
dir = /etc/vpn-ca/intermediate
database = $dir/index.txt
new_certs_dir = $dir/newcerts
serial = $dir/serial
crlnumber = $dir/crlnumber
certificate = $dir/intermediate.crt
private_key = $dir/intermediate.key
default_md = sha256
default_days = 365
default_crl_days = 30
unique_subject = no
policy = policy_any
[ policy_any ]
commonName = supplied
[ server_cert ]
basicConstraints = CA:FALSE
keyUsage = critical, digitalSignature
extendedKeyUsage = serverAuth
subjectAltName = @server_names
[ client_cert ]
basicConstraints = CA:FALSE
keyUsage = critical, digitalSignature
extendedKeyUsage = clientAuth
[ server_names ]
DNS.1 = vpn.example.com
La riga di utilizzo della chiave presuppone una chiave ECDSA; aggiungete keyEncipherment per RSA. Date a ogni client il proprio nome comune, perché OpenVPN identifica una connessione tramite quel campo, e due portatili che condividono CN=vpn-client non si distinguono nei log, nelle regole di client-config-dir né in alcun push per utente, e perdete l’attribuzione che rende difendibile una decisione di revoca. Emettete e convalidate una foglia così:
openssl req -new -key alice.key -subj "/CN=alice-laptop" -out alice.csr
openssl ca -config intermediate.cnf -extensions client_cert -in alice.csr -out alice.crt -batch
openssl verify -CAfile ca-bundle.crt -untrusted intermediate.crt alice.crt
Tenete la chiave di firma dietro un confine di policy invece di copiarla sull’host VPN: un piccolo servizio che autentica la richiesta, controlla il nome comune contro una lista di autorizzati e restituisce solo il certificato. Registrate ogni numero di serie; il log è l’unico collegamento tra un certificato e la persona che lo ha richiesto.
Pubblicate la revoca senza svegliare la radice
I certificati client sono revocati dall’intermedia, mai dalla radice. La lista radice conta solo quando un’intermedia viene bruciata. Puntate il server alla lista intermedia con crl-verify. Una CRL basata su file viene caricata all’avvio del servizio, quindi ricaricatela dopo ogni rigenerazione; la forma a directory legge lo stato al momento della connessione e costa un file per numero di serie.
Revocate e rigenerate con due comandi dallo stesso database:
openssl ca -config intermediate.cnf -revoke /etc/vpn-ca/intermediate/newcerts/1001.pem
openssl ca -config intermediate.cnf -gencrl -out /etc/openvpn/crl.pem
Poi osservate l’orologio. Una CRL porta un campo di prossimo aggiornamento, e quando quella data passa un pari che convalida rifiuta la lista invece di ignorarla. La rigenerazione mensile con default_crl_days = 30 lascia margine; quella annuale no. Durate di vita delle foglie più brevi sono il controllo più affidabile, perché la revoca vale solo dove la lista viene consultata.
Provate la catena, poi mettete per iscritto la cerimonia
Riproducete quattro guasti prima di fidarvi del progetto. Convalidate la catena con openssl verify -CAfile ca-bundle.crt -untrusted intermediate.crt server.crt. Collegatevi con un certificato client scaduto e confermate che il server lo rifiuta. Revocate un client di prova, ricaricate e confermate che la lista ha effetto. Spostate avanti di un giorno l’orologio di un host, perché un orologio sbagliato può emettere e rifiutare certificati che altrove sembrano validi.
Una radice offline è un controllo solo se esiste la documentazione: due persone nominate per la cerimonia, un registro di ogni numero di serie firmato, un backup cifrato conservato separatamente dalla macchina e un test di ripristino su un host isolato. Firmate un’intermedia di riserva durante la stessa cerimonia, così un host di firma morto non vi costringa a sbloccare la radice a mezzanotte.
Prima di dichiararlo finito, confermate cinque cose: la chiave radice non è su un host in rete, la chiave intermedia vive solo sull’host di firma, il pacchetto client porta entrambi i certificati CA, la CRL ha un prossimo aggiornamento futuro e qualcuno possiede una voce di calendario per ogni scadenza della catena. Se ne manca una, la configurazione che sembra offline è solo non documentata.