El problema es que eso openssl -verify
no hace el trabajo.
Como mencionó Priyadi , se openssl -verify
detiene en el primer certificado autofirmado, por lo tanto, realmente no verifica la cadena, ya que a menudo el certificado intermedio está autofirmado.
Supongo que desea estar 101% seguro, que los archivos de certificado son correctos antes de intentar instalarlos en el productivo servicio web. Esta receta aquí realiza exactamente esta verificación previa al vuelo.
Tenga en cuenta que la respuesta de Peter es correcta , sin embargo, la salida de openssl -verify
no es una pista de que todo realmente funcione después. Sí, puede encontrar algunos problemas, pero no todos.
Aquí hay un script que hace el trabajo para verificar una cadena de certificados antes de instalarlo en Apache. Quizás esto se pueda mejorar con algunas de las magias más místicas de OpenSSL, pero no soy un gurú de OpenSSL y los siguientes trabajos:
#!/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
Tenga en cuenta que la salida posterior EVERYTHING OK
es la configuración de Apache, porque las personas que usan NginX
o haproxy
generalmente también pueden leer y comprender esto perfectamente;)
Hay un GitHub Gist de esto que podría tener algunas actualizaciones
Requisitos previos de este script:
- Tiene los datos raíz de CA de confianza
/etc/ssl/certs
como de costumbre, por ejemplo, en Ubuntu
- Cree un directorio
DIR
donde almacene 3 archivos:
DIR/certificate.crt
que contiene el certificado
DIR/certificate.key
que contiene la clave secreta para su servicio web (sin frase de contraseña)
DIR/certificate.bundle
que contiene el paquete CA. Sobre cómo preparar el paquete, ver abajo.
- Ahora ejecute el script:
./check DIR/certificate
(esto supone que el script se nombra check
en el directorio actual)
- Hay un caso muy poco probable de que salga el script
CA-Bundle is not needed
. Esto significa que usted (léase /etc/ssl/certs/
:) ya confía en el certificado de firma. Pero esto es muy poco probable en la WWW.
- Para esta prueba, el puerto 4433 no debe utilizarse en su estación de trabajo. Y mejor solo ejecute esto en un entorno seguro, ya que abre el puerto 4433 en breve al público, que podría ver conexiones externas en un entorno hostil.
¿Cómo crear el certificate.bundle
archivo?
En la WWW, la cadena de confianza generalmente se ve así:
- certificado de confianza de
/etc/ssl/certs
- certificado (s) intermedio (s) desconocido (s), posiblemente firmado cruzado por otra CA
- su certificado (
certificate.crt
)
Ahora, la evaluación se lleva a cabo de abajo hacia arriba, esto significa que primero se lee su certificado, luego se necesita el certificado intermedio desconocido, luego quizás el certificado de firma cruzada y luego /etc/ssl/certs
se consulta para encontrar el certificado de confianza adecuado.
El paquete ca debe estar formado exactamente en el orden de procesamiento correcto, esto significa que el primer certificado necesario (el certificado intermedio que firma su certificado) viene primero en el paquete. Entonces se necesita el certificado de firma cruzada.
Por lo general, su CA (la autoridad que firmó su certificado) ya le proporcionará un archivo ca-bundle tan apropiado. De lo contrario, debe elegir todos los certificados intermedios necesarios y cat
juntarlos en un solo archivo (en Unix). En Windows, solo puede abrir un editor de texto (como notepad.exe
) y pegar los certificados en el archivo, el primero necesario en la parte superior y siguiendo a los demás.
Hay otra cosa Los archivos deben estar en formato PEM. Algunas CA emiten el formato DER (un binario). PEM es fácil de detectar: es legible en ASCII. Para obtener más información sobre cómo convertir algo en PEM, consulte Cómo convertir .crt a .pem y siga el camino de ladrillos amarillos.
Ejemplo:
Tienes:
intermediate2.crt
el certificado intermedio que firmó su certificate.crt
intermediate1.crt
otro certificado intermedio, que chamuscó intermediate2.crt
crossigned.crt
que es un certificado de firma cruzada de otra CA, que firmó intermediate1.crt
crossintermediate.crt
que es otro intermedio de la otra CA que firmó crossigned.crt
(probablemente nunca verás tal cosa)
Entonces lo correcto cat
se vería así:
cat intermediate2.crt intermediate1.crt crossigned.crt crossintermediate.crt > certificate.bundle
¿Y cómo puede averiguar qué archivos se necesitan o no y en qué secuencia?
Bueno, experimenta, hasta que check
te diga que todo está bien. Es como un juego de rompecabezas de computadora para resolver el enigma. Cada. Soltero. Hora. Incluso para profesionales. Pero mejorará cada vez que necesite hacer esto. Así que definitivamente no estás solo con todo ese dolor. Es SSL, ¿sabes? SSL es probablemente uno de los peores diseños que he visto en más de 30 años de administración profesional de sistemas. ¿Alguna vez se preguntó por qué la criptografía no se ha convertido en la corriente principal en los últimos 30 años? Es por eso. 'Nuff dijo.
man verify
, encontré que el-untrusted
parámetro es el correcto para usar al especificar el certificado intermedio.