Confiando certificados autofirmados en Git

Hoy, me he estado pegando con el problema de cómo aceptar de antemano el certificado autofirmado que tiene el servidor del trabajo cuándo estás clonando un repositorio Git usando una URL HTTPS.
El tema está en que si intentar clonar un repositorio que está en hosteado en una máquina con un servidor autofirmado obtendrás el siguiente error:

$ git clone https://www.myserver.com/myrepo.git
fatal: unable to access 'https://www.myserver.com/myrepo.git/': SSL certificate problem: Invalid certificate chain  

Git no pregunta si quieres aceptar el certificado por lo que no se puede acceder al contenido si no nos saltamos la verificación SSL que lleva.

Probablemente te estarás preguntando porque no uso una conexión SSH para clonar el repositorio ¿no?. Por motivos que no vienen al caso no puedo usar conexión SSH y necesito acceder al respositorio por HTTP.

La primera opción que encontré es deshabilitar la verificación del certificado cuando clono el repositorio:

GIT_SSL_NO_VERIFY=true git clone https://www.myserver.com/myrepo.git  

Funciona pero no es nada trivial (a vece imposible) añadir el flag GIT_SSL_NO_VERIFY en todos los comandos git cuándo el problema lo tiene la máquina de integración continua o, como es mi caso, cuándo estás usando CocoaPods.

Forma insegura

La forma más fácil de solucionarlo es decirle a Git que no verifique ninguna conexión SSL en todos los repositorios:

git config --global http.sslVerify false  

Por favor, NO LO HAGAS o te cargarás de un plumazo toda la seguridad que ofrece HTTPS.

Forma segura

Resumen:

  1. Descargar el certificado autofirmado.
  2. Decir a Git que confíe en ese certificado.

Descargar el certificado autofirmado.

Si tienes openssl instalado lo puedes hacer de forma muy sencilla:

openssl s_client -connect myserver.com:443  

Captura la respuesta y crea un fichero con sólo el contenido entre las lineas BEGIN CERTIFICATE y END CERTIFICATE (ambas incluídas) y renómbralo a, por ejemplo, certificate.pem. Debe quedar algo así:

-----BEGIN CERTIFICATE-----
MIIGMDCCBRigAwIBAgIKGpFzcgADAABKojANBgkqhkiG9w0BAQUFADA/MRQwEgYK  
CZImiZPyLGQBGRYEaW5ldDESMBAGCgmSJomT8ixkARkWAmhpMRMwEQYDVQQDEwpJ  
U1NVRUNBVElEMB4XDTE1MDYwMzA2MTY1NFoXDTE3MDYwMjA2MTY1NFowZzELMAkG  
A1UEBhMCRVMxCzAJBgNVBAgTAk1BMQ8wDQYDVQQHEwZNYWRyaWQxEzARBgNVBAoT  
ClRlbGVmb25pY2ExDDAKBgNVBAsTA1RpRDEXMBUGA1UEAxMOcGRpaHViLmhpLmlu  
Oi8vb3JjYXRpZC5oaS5pbmV0L29jc3AwJgYIKwYBBQUHMAGGGmh0dHA6Ly9vcmNh  
dGlkLnRpZC5lcy9vY3NwMFUGCCsGAQUFBzAChklodHRwOi8vaXNzdWVjYXRpZC5o  
aS5pbmV0L0NlcnRFbnJvbGwvaXNzdWVjYXRpZC5oaS5pbmV0X0lTU1VFQ0FUSUQo  
MykuY3J0MFIGCCsGAQUFBzAChkZodHRwOi8vb3JjYXRpZC5oaS5pbmV0L0NlcnRF  
bnJvbGwvaXNzdWVjYXRpZC5oaS5pbmV0X0lTU1VFQ0FUSUQoMykuY3J0MFEGCCsG  
AQUFBzAChkVodHRwOi8vb3JjYXRpZC50aWQuZXMvQ2VydEVucm9sbC9pc3N1ZWNh  
dGlkLmhpLmluZXRfSVNTVUVDQVRJRCgzKS5jcnQwIQYJKwYBBAGCNxQCBBQeEgBX  
AGUAYgBTAGUAcgB2AGUAcjANBgkqhkiG9w0BAQUFAAOCAQEALn2uGPE5cuOsDVWC  
NJLJbFFH/+JwVWJjD7+oLg6z29fB17FJUdh7RgcV8ObPItvbqg2B5v773WSXRNp3  
LQ3pRxefbwZdg2dbKTkcU9HSIX/WZHUUIFYGtXeQq7+9OJ5UY+Ta/Wg7ljKeLb3+  
7gzyjDhBsipu/oXRMXInU3CppIoR802shofl4rXCoOTQNz9suQYISkLJJd2UBxsn  
v1ytyPhqpdFr6zdsr2p/jFcxvj/uKYtMp9xeenHS8Nm/6y0sfPnzNpGTbxAhAoD0  
jPIqRzg+X5Wo/A2bcS0hRkLWuQAWSnIJRUT1v+Bm62iB/C/OLR3zFRuxy+NwqHH5  
q8+fMA==  
-----END CERTIFICATE-----

Si no tienes openssl o no quieres instalarlo siempre puedes usar Firefox para descargar el certificado. Navega a tu servidor, clica en el Candado que aparece en la barra de direcciones para ver la información sobre la conexión segura, clica en Más Información, clica _Ver Certificado, ve a Detalles y clica en exportar para guardar el fichero, renómbralo a *certificate.pem.

Confiando el certificado autofirmado

Copia o mueve el fichero a la carpeta que quieras (personalmente prefiero crear una carpeta ocula en ~/.git-certs/). Sólo queda decir a Git que confíe el certificado:

git config --global http."https://www.myserver.com/".sslCAInfo ~/.git-certs/certificate.pem  

Eso es todo, Git no comprobará si el certificado es válido para nuestro servidor nunca más 🙂