Configurar nuestra propia Entidad Certificadora

Para este post se han utilizado dos servidores, un servidor que realizará la función de entidad certificadora y de servicio OCSP (comprobación de certificados) y otro servidor que tendrá instalado Apache con el certificado generado por la CA y que servirá la web por https https://webtest.local. El esquema siguiente muestra gráficamente la función de cada servidor:

Lo ideal es de disponer de una autoridad de certificado raíz y una o varias intermedias. La CA intermedia nos sirve para no exponer la CA raíz a los posibles ataques y en el caso de ser comprometida la CA intermedia no perderíamos todo el servicio de certificaciones. Es nuestro caso sólo configuraremos la CA raíz por ser para uso propio y no estar expuesta al exterior.

Otro elemento que configuraremos es la capacidad de que los certificados revocados no puedan ser usados en los servidores donde se han configurado los certificados. Se puede realizar a través de dos métodos:

  • Lista de revocación de certificados (CRL): Es el método que se utilizaba antiguamente. Cuando un certificado es revocado se genera un archivo (.crl) que contiene la lista de certificados revocados, los clientes (servidores) tienen que obtener y procesar estos ficheros con la lista de revocados (crlDistributionPoints).
  • Estado del certificado en línea (OCSP): Es el método que se está usando actualmente, en la CA (aunque puede estar en otro servidor) se inicia un servicio que permite a los clientes (servidores) consultar el estado del certificado.

Configurando nuestra propia CA

En el servidor que realizará la función de Entidad Certificadora el primer paso será comprobar que tenemos instalado el paquete openssl:

# openssl -version  

En el caso de no tenerlo instalado procederemos a instalarlo con el siguiente comando:

# apt install openssl 

Posteriormente crearemos toda la estructura de carpetas:

# mkdir /etc/ssl/SeguiNetCA
# cd /etc/ssl/SeguiNetCA
# mkdir certs private newcerts crl
# chmod 700 private 

Crearemos los ficheros que controlan el número de serie y el index.

# echo 01 > /etc/ssl/SeguiNetCA/serial
# touch /etc/ssl/SeguiNetCA/index.txt

Copiaremos el archivo de configuración openssl.cnf a nuestra nueva CA:

# cp /etc/ssl/openssl.cnf /etc/ssl/SeguiNetCA/ 

Una vez instalado, modificaremos el fichero de configuración /etc/ssl/SeguiNET/openssl.cnf para indicar donde se encontraran todos los archivos de configuración de nuestra CA y la configuración de OCSP.

  • Bajo el apartado [ CA_default ] modificar el parámetro “dir” cambiando el path por /etc/ssl/SeguiNetCA
  • Bajo el apartado [ usr_cert ] configurar donde estará el servidor OCSP, añadir la siguiente línea:

authorityInfoAccess = OCSP;URI:http://192.168.1.96:8080

  • Crear un nuevo apartado con las siguientes líneas de configuración del OCSP:

[ v3_OCSP ]
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
extendedKeyUsage = OCSPSigning

Finalmente crearemos el certificado para la entidad certificadora que se deberá exportar a los diferentes servidores que vayan a utilizar sus certificados:

openssl req -nodes -new -x509 -keyout private/cakey.pem -out certs/cacert.pem -days 3650 -config openssl.cnf

Para proteger la clave privada cambiaremos sus permisos:

chmod 400 ./private/cakey.pem

Si cambiamos el nombre a los ficheros generados (cakey.pem y cacert.pem) también deberemos indicarlo en el archivo de configuración openssl.cnf.

Podemos comprobar la clave pública con el siguiente comando:

# openssl x509 -in certs/cacert.pem -noout -text 

Creando solicitud y generación de certificado

Ahora que ya tenemos nuestro propia CA en marcha podemos solicitar que nos expida certificados, por ejemplo, para nuestras webs internas, en nuestro caso nos conectaremos a otro servidor (servidor web) y procederemos con la operativa.

El primer paso es realizar la solicitud de certificado “Certificate Signing Request” y crearnos una clave privada:

# openssl req -nodes -new -keyout /etc/ssl/private/micert.key -out peticion.csr

Ahora enviamos el fichero de solicitud de firma del certificado (peticion.csr) al servidor que hemos instalado la entidad certificadora.

En el servidor de certificados expediremos el certificado usando el fichero de petición de certificado:

# openssl ca -config openssl.cnf -policy policy_anything -cert certs/cacert.pem -out certs/web_test.crt -in peticion.csr 

La opción «-policy policy_anything» indica que no se requiere que los campos «Country», «State» o «City» coincidan con los de la CA.

El archivo firmado por la CA (web_test.crt) y que se usará como clave pública deberá ser copiado al servidor de la aplicación, en nuestro caso el servidor web, para poder ser usado en su configuración.

Para realizar la prueba del servidor web apache copiaremos la clave privada (micert.key), la clave pública firmada por la CA (web_test.crt) y la clave pública del propio servidor de CA (cacert.pem) a un lugar accesible por la configuración del servidor web apache, , además usaremos la directiva SSLUseStapling que forzará la comprobación del certificado en el servicio OCSP y su cache SSLStaplingCache. El fichero de configuración del vhost de nuestro ejemplo quedará así:

Cuando los navegadores accedan a la web, el primer mensaje de error que nos va a dar es que no conoce la entidad certificadora:

En el caso de Firefox la mejor forma es importar el certificado de nuestra entidad certificadora (cacert.pem), una vez importado comprobaremos que aparece en la lista de entidades certificadoras de confianza:

Ahora ya podremos comprobar que al acceder a la web el certificado es válido:

Configuración del servicio OCSP

Para crear un servidor/servicio OCSP primero crearemos un certificado y lo firmaremos por la CA, todos estos pasos los realizamos en el servidor de CA.

Realizamos la solicitud y creamos el key (el nombre de la organización debe ser el mismo que el de la CA):

# openssl req -new -nodes -out certs/ocspSigning.csr -keyout private/ocspSigning.key  

Firmamos la solicitud por la CA:

openssl ca -keyfile private/cakey.pem -cert certs/cacert.pem -in certs/ocspSigning.csr -out certs/ocspSigning.crt -config openssl.cnf

Finalmente lanzamos el servidor OCSP con el siguiente comando:

openssl ocsp -index index.txt -verify_ip 192.168.1.96 -port 8080 -rsigner certs/ocspSigning.crt -rkey private/ocspSigning.key -CA certs/cacert.pem -text -out log.txt & 

Para comprobar el funcionamiento del servicio OCSP revocaremos el certificado creado para el servidor web:

# openssl ca -keyfile private/cakey.pem -cert certs/cacert.pem -revoke certs/web_test.crt -config openssl.cnf 

Reiniciamos el servicio OCSP y ya podemos consultar el estado del certificado a través del servicio OCSP:

# openssl ocsp -CAfile certs/cacert.pem -issuer certs/cacert.pem -cert  certs/web_test.crt -url http://192.168.1.96:8080 -resp_text –noverify 

En el servidor Web cada vez que alguien consulte la web https://webtest.local que tiene el certificado revocado aparecerá el siguiente mensaje de error en el log de Apache:

Y en el navegador del cliente se mostrará el siguiente error: