Cómo crear tu propia autoridad certificante
Este artículo describe en resumen cómo crear tu propia Autoridad Certificante (CA) y cómo crear y firmar tus propios pedidos de certificados. Estos certificados sólo sirven para uso personal ya que no son firmados por una autoridad de confianza, como un mecanismo de proveer una forma segura de comunicarse con tus servicios, para que las contraseñas o cualquier dato no viaje plano por la red.
Para realizar todos los pasos del tutorial se requiere el paquete openssl instalado en la máquina utilizada para administrar los certificados o crear los pedidos de certificado.
Este tutorial fue probado en Debian 6.02, pero funciona para cualquier distribución.
Para comenzar vamos a crear un directorio donde se almacenará toda la información relativa a certificados:
# mkdir -m 0755 /CA# mkdir -m 0755 /CA/privado# mkdir -m 0755 /CA/certificados# mkdir -m 0755 /CA/newcerts# mkdir -m 0755 /CA/crl
"CA" será el directorio de trabajo de la autoridad certificante. "certs" será el directorio donde se ubicarán los certificados. "newcerts" es el directorio donde openssl pone los certificados creados en formato PEM (sin encriptar) y en la forma [n° de serie].pem (por ejemplo: 15.pem). "crl" es el directorio donde se coloca la lista de revocación de certificados. "private" es el directorio donde se colocan las claves privadas (este directorio debe tener permisos extremadamente restrictivos, para que sólo sean leídos por root).
Las extensiones de archivos que se generarán en estos directorios serán las siguientes:
- KEY: Claves privadas (deben tener permisos restrictivos)
- CSR: Pedido de certificado (estos pedidos serán firmados por la CA para convertirse en certificados, luego pueden ser eliminados)
- CRT: Certificado (puede ser distribuido públicamente)
- PEM: Archivos que contienen tanto el certificado como la clave privada (deben tener permisos restrictivos)
- CRL: Lista de revocación de certificados (puede ser públicamente distribuida)
Para la configuración inicial de openssl, copiamos el archivo de configuración por defecto de openssl (openssl.cnf) al directorio /CA. En Debian se encuentra en el directorio /etc/ssl/openssl.cnf:
# cp /etc/ssl/openssl.cnf /CA# chmod 0600 /CA/openssl.cnf
Luego creamos dos archivos que funcionan como bases de datos para openssl:
# touch /CA/index.txt# echo '01' > /CA/serial
Luego de terminar la configuración inicial, podemos crear un certificado autofirmado que será utilizado como el certificado de nuestra CA. Este será utilizado para firmar los pedidos de certificados:
# cd /CA# openssl req -config openssl.cnf -new -x509 -extensions v3_ca -keyout private/ca.key -out certs
Este comando crea un certificado válido por 5 años, se debe ingresar una contraseña para la clave privada (debe ser una contraseña fuerte). Además se debe proveer información acerca de tu CA. Por ejemplo:
Country Name (2 letter code) [GB]:ARState or Province Name (full name) [Berkshire]:Buenos AiresLocality Name (eg, city) [Newbury]:La PlataOrganization Name (eg, company) [My Company Ltd]:LinuxitoOrganizational Unit Name (eg, section) []:SistemasCommon Name (eg, your name or your server's hostname) []:linuxito.comEmail Address []:admin(arroba)linuxito.com
Se crearán dos archivos: certs/ca.crt, certificado de la CA públcamente disponible y con lectura para todo el mundo; private/ca.key, clave privada del certificado de la CA, a pesar de que está protegida por una contraseña se debe restringir el acceso:
# chmod 0400 /CA/private/ca.key
Debido a que utilizamos un directorio personalizado para nuestros certificados, se necesitan algunas modificaciones en el archivo /CA/openssl.cnf, el cual debe quedar así:
[ CA_default ]dir = /CA # Directorio donde se guarda todo <== CAMBIAR ESTA LINEAcerts = $dir/certs # Directorio donde se guardan certificados emitidoscrl_dir = $dir/crl # Directorio donde se guardan crl enviadosdatabase = $dir/index.txt # Archivo indice de la base de datos#unique_subject = no # Setear en 'no' para permitir que se creen diferentes certificados con el mismo 'subject'new_certs_dir = $dir/newcerts # Directorio donde se guardan nuevos certificadoscertificate = $dir/ca.crt # Certificado de la CA <== CAMBIAR ESTA LINEAserial = $dir/serial # Número de serie actual#crlnumber = $dir/crlnumber # El número de crl actual debe comentarse para dejar una CRL V1crl = $dir/crl.pem # La CRL actualprivate_key = $dir/private/ca.key # La clave privada <== CAMBIAR ESTA LINEARANDFILE = $dir/private/.rand # Número aleatorio privadox509_extensions = usr_cert # Extensiones a agregar al certificado
Se puede personalizar aún más para definir políticas para la creación y firmado de los certificados, o definir extensiones deseadas para nuevos certificados.
Los certificados que vamos a crear con esta configuración, son certificados de propósito general y su uso no se restringe sólo a autenticación de servidores. Debe notarse que las claves privadas no serán protegidas por una passphrase, para que cuando los servicios se reinicien no soliciten el ingreso de passphrases. Esto implica que se debe restringir cuidadosamente el acceso de lectura sobre las claves privadas, para que sólo el usuario root, o el usuario privilegiado utilizado por los servicios, pueda leer estos archivos.
Para proceder con la creación de un certificado para un servidor, lo primero que hacemos es generar el pedido de certificado:
# cd /CA# openssl req -config openssl.cnf -new -nodes -keyout private/server.key -out server.csr -days 365
La opción "-nodes" es necesaria para que la clave privada no sea protegida con una passphrase. Si el certificado no se utilizará para autenticación de servidores, no se debería incluir en el comando anterior. Es posible personalizar el período de validez del certificado (-days).
Cuando ejecutamos el comando se debe ingresar la información del certificado, por ejemplo:
Country Name (2 letter code) [GB]:ARState or Province Name (full name) [Berkshire]:Buenos AiresLocality Name (eg, city) [Newbury]:La PlataOrganization Name (eg, company) [My Company Ltd]:LinuxitoOrganizational Unit Name (eg, section) []:SistemasCommon Name (eg, your name or your server's hostname) []:www.linuxito.comEmail Address []:admin(arroba)linuxito.com
El "Common Name" (CN) es la información que identifica de forma única al servicio, por lo que debemos asegurarnos de tipearlo correctamente. Para el resto de los atributos podemos simplemente presionar enter.
Al finalizar se crean dos archivos:
- server.csr: El pedido de certificado
- private/server.key: La clave privada, que no ha sido protegida con una passphrase
Se deben setear permisos restrictivos sobre la clave privada, por ejemplo:
# chown root.root /CA/private/server.key# chmod 0400 /CA/private/server.key
O (por ejemplo si el certificado es para un servidor Apache):
# chown root.apache /CA/private/server.key# chmod 0440 /CA/private/server.key
A continuación firmamos el pedido de certificado para generar el certificado para el servidor:
# cd /CA# openssl ca -config openssl.cnf -policy policy_anything -out certs/server.crt -infiles server.csr
Para firmar el pedido se debe proveer del certificado de la CA. La opción "-policy policy_anything" indica que no se requiere que los campos "Country", "State" o "City" coincidan con los de la CA.
Al finalizar se crean dos nuevos archivos:
- certs/server.crt - Certificado del servidor, que puede hacerse públicamente disponible
- newcerts/01.pem - El mismo certificado pero con el número de serie como nombre de archivo, no es necesario
En este momento podemos eliminar el pedido de certificado, el cual no es más necesario (server.csr):
# rm -f /CA/server.csr
Para verificar el certificado es posible obtener información del certificado con el siguiente comando:
# openssl x509 -subject -issuer -enddate -noout -in /CA/certs/server.crt
O el siguiente:
# openssl x509 -in certs/server.crt -noout -text
Y verificar que el certificado sea válido para autenticación de servidores con el siguiente:
# openssl verify -purpose sslserver -CAfile /CA/certs/myca.crt /CA/certs/server.crt
Algunos servidores o aplicaciones requieren que el certificado y la clave privada existan en el mismo archivo. Esto se puede lograr con el comando:
# cat certs/server.crt private/server.key > private/server-key-cert.pem
Se debe restringir el acceso al archivo .pem resultante y borrar server.crt y server.key si no son necesarios.
# chown root.root private/server-key-cert.pem# chmod 0400 private/server-key-cert.pem# rm -f certs/server.crt# rm -f private/server.key
Si deseamos que un certificado deje de ser válido debemos revocarlo. Esto se puede hacer con el comando:
# openssl ca -config openssl.cnf -revoke certs/server.crt
Entonces debemos generar un nueva CRL (Certificate Revokation List):
# openssl ca -config openssl.cnf -gencrl -out crl/myca.crl
El archivo de la CRL es crl/myca.crl.
El certificado de nuestra CA y nuestra lista de revocación (CRL) deben ser distribuidos a aquellos que confien en nuestra CA para que puedan importarlos en el software cliente (web browser, clientes ftp, clientes de e-mail, etc. Además la CRL debe ser pública.