Error de certificado SSL: error de verificación: num = 20: no se puede obtener el certificado de emisor local

11

He intentado que funcione una conexión SSL a un servidor LDAPS (Active Directory), pero sigo teniendo problemas. Intenté usar esto:

openssl s_client -connect the.server.edu:3269 

Con el siguiente resultado:

verify error:num=20:unable to get local issuer certificate 

Pensé, OK, bueno, el servidor es un viejo servidor de producción de hace unos años. Quizás el CA no está presente. Luego saqué el certificado de la salida a un archivo pem e intenté:

openssl s_client -CAfile mycert.pem -connect the.server.edu:3269

Y eso tampoco funcionó.

¿Qué me estoy perdiendo? ¿No debería eso SIEMPRE funcionar?


fuente
En aras de la claridad, parece que LDAPS, cuando se sirve desde Windows, no presenta el certificado de CA cuando se realiza una conexión. Por lo tanto, debe obtener el certificado CA X.509, exportar como base64 y asignar como se describe en las respuestas a continuación. En mi caso, usando python-ldap lo asigna al alcance GLOBAL (no a su instancia ldap.initialize ()) como: ldap.set_option(ldap.OPT_X_TLS_CACERTFILE,'./ca_issuer_cert.pem') Después de esto, pude usar STARTTLS (dentro del puerto LDAP 389) como se esperaba.
mbrownnyc

Respuestas:

4

Entonces, esto es lo que veo como el nombre del certificado de CA:

depth=1 /C=US/O=VeriSign, Inc./OU=VeriSign Trust Network/OU=Terms of use at //www.verisign.com/rpa (c)10/CN=VeriSign Class 3 International Server CA - G3
verify error:num=20:unable to get local issuer certificate
verify return:0

Ese era el nombre del certificado que había importado después de que hice las presentaciones en mi segundo intento anterior. Enumeré los certificados en el almacén de claves haciendo esto:

$JAVA_HOME/bin/keytool -list -v -keystore $JAVA_HOME/jre/lib/security/cacerts

Veo el certificado de CA allí.

Alias name: versign2006
Creation date: Jan 21, 2011
Entry type: trustedCertEntry

Owner: CN=VeriSign Class 3 International Server CA - G3, OU=Terms of use at www.verisign.com/rpa (c)10, OU=VeriSign Trust Network, O="VeriSign, Inc.", C=US
Issuer: CN=VeriSign Class 3 Public Primary Certification Authority - G5, OU="(c) 2006 VeriSign, Inc. - For authorized use only", OU=VeriSign Trust Network, O="VeriSign, Inc.", C=US
Serial number: 641be820ce020813f32d4d2d95d67e67
Valid from: Sun Feb 07 19:00:00 EST 2010 until: Fri Feb 07 18:59:59 EST 2020
Certificate fingerprints:
  MD5:  BA:B0:65:B4:3B:9C:E8:40:30:21:7D:C5:C6:CD:3F:EB
  SHA1: B1:8D:9D:19:56:69:BA:0F:78:29:51:75:66:C2:5F:42:2A:27:71:04

Para asegurarme de que openssl está usando el almacén de claves que estoy usando con el servidor, estoy usando el argumento -CAfile:

openssl s_client -connect the.server.edu:3269 -CAfile $JAVA_HOME/jre/lib/security/cacerts

Sabiendo que el almacén de claves de Java para CA tiene una contraseña, intenté usar la opción -pass pass: password de esta manera:

openssl s_client -connect the.server.edu:3269 -CAfile $JAVA_HOME/jre/lib/security/cacerts -pass pass:changeit

pero eso tampoco funcionó.

Lo curioso es que el archivo cacerts tiene una contraseña y openssl no se queja de que no puede leer el archivo cacerts. Eso me parece sospechoso. ¿Eso o algo más te suena?

Brian
fuente
3

Ese error es la forma en que OpenSL dice: "No puedo seguir la cadena de certificados hasta una raíz confiable". Acabo de hacer el mismo comando para mis propios servidores AD y obtengo una cadena de certificados completa, pero el certificado superior tiene ese error exacto. Si tiene la clave de pub de la CA que firmó el certificado, puede especificarlo con las opciones -CAfileo-CApath

sysadmin1138
fuente
Okay, gracias por la respuesta. Entonces lo intenté. Obtuve el certificado de CA haciendo lo mismo con la opción -showcerts activada, tomé el otro certificado. Ese debería ser el certificado de CA, ¿verdad? Intenté eso en lugar del certificado del servidor en el archivo pem y obtuve el mismo mensaje de error. ¿Alguna otra idea?
En ese caso, es probable que esté fallando la validación por otro motivo, como la caducidad.
sysadmin1138
1

He intentado que funcione una conexión SSL a un servidor LDAPS (Active Directory), pero sigo teniendo problemas. Intenté usar esto:

Si está utilizando OpenLDAP, puede configurar:

TLS_REQCERT=never

en su openldap.confarchivo, que le indica a OpenLDAP que no intente la verificación del certificado. Hay una opción similar si está haciendo autenticación LDAP con Apache.

Si realmente desea realizar la verificación del certificado, lo siguiente puede ser útil:

¿Qué me estoy perdiendo? ¿No debería eso SIEMPRE funcionar?

No lo creo. Si bien lo siguiente puede sonar definitivo, en realidad es solo mi mejor invitado:

Lo que intentó solo funcionaría para un certificado autofirmado. Debido a que el certificado fue emitido por la CA de Windows, intentar usar el certificado del servidor como argumento para -CAfileno obtener nada.

Obtuve el certificado de CA haciendo lo mismo con la opción -showcerts activada, agarré el otro certificado. Ese debería ser el certificado de CA, ¿verdad?

No necesariamente no. No hay garantía de que el servidor remoto presente el certificado de CA en su salida. Primero debe mirar al emisor del certificado del servidor:

openssl x509 -in server.crt -noout -text | grep Issuer

... y luego vea si uno de los otros certificados que tiene coincide con ese emisor.

larsks
fuente