Prima o poi, un utente VPN si offre di inviare una chiave privata via e-mail perché l'amministratore possa creare un certificato, e proprio quell'offerta va rifiutata. Il flusso che funziona tiene la chiave sul client fin dal primo comando: il client la genera, invia una richiesta di firma del certificato, l'emittente la verifica e la autorizza, e il certificato firmato torna a sedersi accanto alla chiave che l'ha creata. La lista di controllo qui sotto fallisce in modo chiuso a ogni passo, ed è proprio questo il punto, perché due dei cinque passi sono quelli che le persone saltano quando hanno fretta.

Passo 1: generate la chiave dove vivrà

Generate sulla macchina che terrà la chiave e lasciatela lì. Una chiave software finisce in un file con permessi restrittivi; una chiave supportata da hardware o in un archivio gestito non diventa mai un file, e il suo percorso di registrazione è di solito uno strumento separato e non un comando OpenSSL. In ogni caso, nessuno ha bisogno di vedere la metà privata.

Il flusso software è così, con la chiave e la richiesta create in un'unica sessione:

umask 077
openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:3072 -out client.key
openssl req -new -key client.key -out client.csr -subj "/CN=alice-vpn/O=Example"

La riga umask conta più di quanto sembri. Senza di essa la chiave viene scritta leggibile da tutti su un sistema permissivo per impostazione predefinita, e copiare il file in giro poi lo diffonde. Riusare una chiave esistente è legittimo quando è già protetta e coerente con la vostra politica; generarne una nuova per dispositivo è più facile da giustificare.

Passo 2: mettete l'identità nella richiesta, non nell'e-mail

Decidete che cosa autentica davvero la VPN prima che la richiesta venga creata, perché quella risposta appartiene all'interno della CSR. OpenVPN lega tradizionalmente l'identità del client al nome comune del certificato, e strumenti come strongSwan confrontano una stringa di identità con il soggetto o un nome alternativo del soggetto. Un'e-mail che dice che mi chiamo alice non è una prova, e una richiesta il cui soggetto dice lo stesso è solo leggermente migliore.

Aggiungete un nome alternativo del soggetto quando il vostro verificatore ne controlla uno, dato che la corrispondenza moderna spesso ignora il vecchio CN:

openssl req -new -key client.key -out client.csr \
  -subj "/CN=alice-vpn/O=Example" \
  -addext "subjectAltName=DNS:alice-vpn"

Tenete il CN corto, stabile e legato all'account invece che al modello di portatile. Un nome che contiene il numero di serie del dispositivo dell'utente è un problema di supporto in attesa della prima sostituzione hardware.

Passo 3: verificate la richiesta prima di firmarla

L'emittente verifica due cose diverse, e confonderle è l'errore classico. Primo, che la richiesta sia internamente coerente: la firma si verifica contro la chiave pubblica che porta. Secondo, che il richiedente abbia diritto a ciò che la richiesta chiede, e a questo nessun controllo crittografico può rispondere.

La parte meccanica è un solo comando, e dovrebbe stampare un risultato di verifica insieme al soggetto:

openssl req -in client.csr -noout -verify -subject
openssl req -in client.csr -noout -pubkey | openssl pkey -pubin -noout -text

Notate che cosa dimostra. Una richiesta che si verifica mostra solo che il mittente possedeva la chiave privata corrispondente al momento dell'invio; non dimostra che il mittente sia la persona nominata nel soggetto, e non autorizza l'accesso al gruppo o alla rotta richiesti. La revisione dell'iscrizione è un cancello separato, e una richiesta per un gruppo che nessuno ha approvato dovrebbe essere respinta invece che modificata in silenzio.

Passo 4: autorizzate, poi firmate con estensioni esplicite

La firma è il punto in cui la CA decide la politica invece di accettare la richiesta alla lettera. Validità, uso della chiave ed estensione del ruolo appartengono a un file di estensioni, non a valori predefiniti che non ricorderete sei mesi dopo. Un certificato client per l'autenticazione VPN ha bisogno dell'autenticazione client come scopo.

cat > client.ext <<'EOF'
basicConstraints = CA:FALSE
keyUsage = digitalSignature
extendedKeyUsage = clientAuth
EOF
openssl x509 -req -in client.csr -CA ca.crt -CAkey ca.key \
  -CAcreateserial -days 365 -extfile client.ext -out client.crt

Usate -CAserial con il file di serie esistente se ce n'è già uno in uso, e tenete la chiave della CA offline o nell'archivio protetto che la vostra politica nomina. I numeri di serie dei certificati devono essere unici per emittente; ricreare il file di serie da zero rischia collisioni che rendono ambigua la revoca.

Registrate ciò che è stato emesso: numero di serie, soggetto, identità richiesta, persona che ha approvato e scadenza. Quel registro è ciò da cui dipende poi una decisione di revoca, e non può essere ricostruito dal solo certificato se la traccia dell'iscrizione vive solo in una casella di posta.

Passo 5: installatelo accanto alla chiave corrispondente e provate la coppia

Il client riceve il certificato e la catena dell'emittente, mai una chiave. Prima di connettervi, confermate che il certificato si accoppi davvero con la chiave già presente sul disco, perché una coppia che non corrisponde produce un fallimento di stretta di mano confuso molto più tardi:

openssl x509 -in client.crt -noout -pubkey | openssl pkey -pubin -outform DER | openssl sha256
openssl pkey -in client.key -pubout -outform DER | openssl sha256

I due digest devono coincidere. Poi connettetevi e confermate che l'identità che il server registra sia quella che avete autorizzato, e non solo che il tunnel è salito. Se la chiave si perde o il dispositivo viene sostituito, la risposta è la revoca più una nuova richiesta dal nuovo dispositivo; chiedere all'amministratore di rimandare indietro una chiave da altrove non recupera l'originale e rompe in silenzio il modello che rendeva sicura la richiesta.

Articoli correlati