Il problema è che openssl -verify
non fa il lavoro.
Come accennato da Priyadi , si openssl -verify
ferma al primo certificato autofirmato, quindi non si verifica realmente la catena, poiché spesso il certificato intermedio è autofirmato.
Presumo che tu voglia essere sicuro al 101%, che i file del certificato siano corretti prima di provare a installarli nel servizio web produttivo. Questa ricetta qui esegue esattamente questo controllo pre-volo.
Si prega di notare che la risposta di Peter è corretta , tuttavia l'output di openssl -verify
non è un indizio del fatto che tutto in realtà dopo. Sì, potrebbe riscontrare alcuni problemi, ma non tutti.
Ecco uno script che fa il lavoro per verificare una catena di certificati prima di installarla in Apache. Forse questo può essere migliorato con alcune delle magie OpenSSL più mistiche, ma io non sono un guru OpenSSL e le seguenti opere:
#!/bin/bash
# This Works is placed under the terms of the Copyright Less License,
# see file COPYRIGHT.CLL. USE AT OWN RISK, ABSOLUTELY NO WARRANTY.
#
# COPYRIGHT.CLL can be found at http://permalink.de/tino/cll
# (CLL is CC0 as long as not covered by any Copyright)
OOPS() { echo "OOPS: $*" >&2; exit 23; }
PID=
kick() { [ -n "$PID" ] && kill "$PID" && sleep .2; PID=; }
trap 'kick' 0
serve()
{
kick
PID=
openssl s_server -key "$KEY" -cert "$CRT" "$@" -www &
PID=$!
sleep .5 # give it time to startup
}
check()
{
while read -r line
do
case "$line" in
'Verify return code: 0 (ok)') return 0;;
'Verify return code: '*) return 1;;
# *) echo "::: $line :::";;
esac
done < <(echo | openssl s_client -verify 8 -CApath /etc/ssl/certs/)
OOPS "Something failed, verification output not found!"
return 2
}
ARG="${1%.}"
KEY="$ARG.key"
CRT="$ARG.crt"
BND="$ARG.bundle"
for a in "$KEY" "$CRT" "$BND"
do
[ -s "$a" ] || OOPS "missing $a"
done
serve
check && echo "!!! =========> CA-Bundle is not needed! <========"
echo
serve -CAfile "$BND"
check
ret=$?
kick
echo
case $ret in
0) echo "EVERYTHING OK"
echo "SSLCertificateKeyFile $KEY"
echo "SSLCertificateFile $CRT"
echo "SSLCACertificateFile $BND"
;;
*) echo "!!! =========> something is wrong, verification failed! <======== ($ret)";;
esac
exit $ret
Nota che l'output successivo EVERYTHING OK
è l'impostazione di Apache, perché anche le persone che usano NginX
o di haproxy
solito possono leggere e capire perfettamente;)
C'è un GitHub Gist di questo che potrebbe avere alcuni aggiornamenti
Prerequisiti di questo script:
- Come al
/etc/ssl/certs
solito, hai i dati radice della CA attendibili, ad esempio su Ubuntu
- Creare una directory in
DIR
cui archiviare 3 file:
DIR/certificate.crt
che contiene il certificato
DIR/certificate.key
che contiene la chiave segreta per il tuo servizio web (senza passphrase)
DIR/certificate.bundle
che contiene il pacchetto CA. Su come preparare il pacchetto, vedi sotto.
- Ora esegui lo script:
./check DIR/certificate
(questo presuppone che lo script sia nominato check
nella directory corrente)
- C'è un caso molto improbabile che lo script produca
CA-Bundle is not needed
. Questo significa che tu (leggi:/etc/ssl/certs/
:) si fida già del certificato di firma. Ma questo è altamente improbabile nel WWW.
- Per questo test la porta 4433 non deve essere utilizzata sulla workstation. E meglio eseguirlo solo in un ambiente sicuro, poiché apre la porta 4433 a breve al pubblico, che potrebbe vedere connessioni esterne in un ambiente ostile.
Come creare il file certificate.bundle
file?
Nel WWW la catena di fiducia di solito assomiglia a questo:
- certificato attendibile da
/etc/ssl/certs
- certificato / i intermedio / i sconosciuto / i, possibilmente con firma incrociata di un'altra CA.
- il tuo certificato (
certificate.crt
)
Ora, la valutazione si svolge dal basso verso l'alto, questo significa che prima viene letto il certificato, quindi è necessario il certificato intermedio sconosciuto, quindi forse il certificato di firma incrociata e quindi /etc/ssl/certs
viene consultato per trovare il certificato attendibile corretto.
Il ca-bundle deve essere composto esattamente nel giusto ordine di elaborazione, questo significa che il primo certificato necessario (il certificato intermedio che firma il certificato) viene prima nel bundle. Quindi è necessario il cross-sign-cert.
Di solito la vostra CA (l'autorità che ha firmato il certificato) fornirà già un file ca-bundle adeguato. In caso contrario, è necessario selezionare tutti i certificati intermedi necessari e cat
riunirli in un unico file (su Unix). Su Windows puoi semplicemente aprire un editor di testo (come notepad.exe
) e incollare i certificati nel file, il primo necessario in alto e seguire gli altri.
C'è un'altra cosa I file devono essere in formato PEM. Alcune CA rilasciano il formato DER (binario). PEM è facile da individuare: è leggibile ASCII. Per maggiori informazioni su come convertire qualcosa in PEM, vedi Come convertire .crt in .pem e seguire la strada di mattoni gialli.
Esempio:
Hai:
intermediate2.crt
il certificato intermedio che ha firmato il tuo certificate.crt
intermediate1.crt
un altro certificato intermedio, che cantava intermediate2.crt
crossigned.crt
che è un certificato di firma incrociata di un'altra CA, che ha firmato intermediate1.crt
crossintermediate.crt
che è un altro intermedio dall'altra CA che ha firmato crossigned.crt
(probabilmente non vedrai mai una cosa del genere)
Quindi il proprio cat
dovrebbe apparire così:
cat intermediate2.crt intermediate1.crt crossigned.crt crossintermediate.crt > certificate.bundle
E come puoi scoprire quali file sono necessari o meno e in quale sequenza?
Bene, sperimenta, fino a quando non check
ti dice tutto è OK. È come un gioco puzzle per computer per risolvere l'enigma. Ogni. Singolo. Tempo. Anche per i professionisti. Ma migliorerai ogni volta che dovrai farlo. Quindi non sei assolutamente solo con tutto quel dolore. È SSL, lo sai? SSL è probabilmente uno dei peggiori progetti che abbia mai visto in oltre 30 anni di amministrazione professionale del sistema. Vi siete mai chiesti perché la criptovaluta non sia diventata mainstream negli ultimi 30 anni? Ecco perchè. 'ha detto Nuff.
man verify
, ho scoperto che il-untrusted
parametro è quello corretto da utilizzare quando si specifica il certificato intermedio.