Instalar certificados SSL con Apache y mod_nss


Índice:

  1. Introducciónssl-1
  2. Configuración de la máquina y requisitos
  3. Instalación y configuración del módulo mod_nss
  4. Generación de las claves pública y privada del servidor
  5. Obtención de un certificado firmado por una Autoridad Certificadora
  6. Obtención de un certificado autofirmado
  7. Instalación de certificados intermediarios
  8. Instalación del certificado firmado
  9. Configuración del host virtual y reinicio de Apache
  10. Logs de errores
  11. Dudas y contacto
  12. Agradecimientos
  13. Referencias


1. Introducción:

En mayo de 2000, se declaró el protocolo HTTPS como un estándar web en la publicación de RFC 2818 [1]. Este protocolo es una modificación de HTTP en el que se crea un canal cifrado por el protocolo SSL (Secure Socket Layer) ó TLS (Transport Layer Security) en los que se transmite la información codificada. Esto significa que un atacante que haya conseguido extraer datos de una conexión tan solo obtendrá información imposible de descifrar [2]. Su uso se ve especialmente representado en operaciones bancarias, pagos por internet, etc. No obstante, cada vez se exige más el uso de este tipo de comunicación, como por ejemplo en organismos públicos en las que se puede usar DNI electrónico o certificados digitales personales. Otro caso es el de Facebook, en el que desde octubre de 2011 exigen a los desarrolladores de aplicaciones que éstas se comuniquen mediante conexión segura ó https con sus propios servidores [3].

El cifrado de los datos se realiza mediante criptografía de clave pública [4]. Existen tres elementos principales en este mecanismo de encriptación:

  1. El mensaje: Los datos que van a ser cifrados.
  2. La clave privada: Es una cadena que encripta o desencripta el mensaje. Sólo el propietario puede conocerla.
  3. La clave pública: Es una cadena que encripta o desencripta el mensaje. Cualquiera puede conocerla.

Gracias a los métodos actuales de criptografía, el par clave pública – clave privada puede ser generado una sola vez, por lo que podemos asumir que no es posible que dos personas hayan obtenido casualmente la misma pareja de claves. De forma sucinta, la comunicación se lleva a cabo como sigue: Cuando el emisor cifra el mensaje con la clave privada, éste solo puede ser descifrado mediante la clave pública del emisor. Así, si el destinatario posee dicha clave pública y el descifrado del mensaje tiene éxito, no sólo se obtiene el mensaje sino que además se verifica su procedencia. Esta es la base conceptual de los protocolos SSL y TLS.

La comunicación por HTTPS necesita, además de un algoritmo de encriptación, un documento emitido por alguna Autoridad de Certificación (CA) [5] que verifique la identidad del propietario del servidor remoto. Algunas de estas autoridades son: VeriSign [6], GeoTrust [7] y Comodo [8].

El servicio web debe ser capaz de cifrar los datos y acceder a certificados instalados en la máquina. El módulo de Apache, mod_nss, se encarga del cifrado de los datos y de la gestión de cara al cliente de los certificados instalados en la máquina. Se creó en septiembre de 2005 a partir del módulo mod_ssl, incluyendo algunas funciones en sus directivas. Está especialmente diseñado para Fedora, aunque también se ha probado en Red Hat y Solaris [9]. En este artículo, se explica desde el principio, cómo configurar Apache, cómo instalar mod_nss y cómo obtener e instalar certificados firmados por algún CA para conseguir que nuestros clientes envíen y reciban información de forma totalmente confiable (figura 1).

Cuando el cliente navega por una conexión segura y con un certificado válido, aparece un candado verde junto a la barra de direcciones.

Figura 1. Cuando el cliente navega por una conexión segura y con un certificado válido, aparece un candado verde junto a la barra de direcciones.


2. Configuración de la máquina y requisitos

Sistema operativo

Según la documentación [9], mod_nss ha sido probado oficialmente sólo en las siguientes distribuciones:

  • Red Hat Enterprise Linux 5
  • Fedora Core 4-11
  • Solaris 9 y 10

aunque puede funcionar en otras plataformas siempre que estén presentes el resto de los requisitos.

Apache

Las versiones de Apache en las que el módulo ha sido probado son:

  • Apache 2.0.46 (RHEL 3)
  • Apache 2.0.52 (RHEL 4)
  • Apache 2.0.54 (Fedora Core 5 y Solaris)
  • Apache 2.2.0 (Fedora Core 5)

Bibliotecas

Se asume que las siguientes bibliotecas están instaladas por defecto en cualquiera de las distribuciones de Linux mencionadas anteriormente:

  • Network Security Services (NSS) [10]
  • Netscape Portable Runtime (NSPR) [11]

no obstante, en sus correspondientes páginas de documentación (ver referencias) se puede encontrar información para instalarlas.

Otras herramientas

Aunque no son del todo indispensables puesto que existen otras alternativas para la manipulación de los certificados, las siguientes herramientas son las que se usan en este trabajo.

openssl: Un conjunto de herramientas que implementan los protocolos SSL v2/v3 y TLS v1.

certutil: Es una herramienta destinada a la manipulación de certificados.

pk12util: Es la utilidad denominada PKCS #12, que permite importar certificados a bases de datos NSS (ver más abajo).


3. Instalación y configuración del módulo mod_nss

La instalación se puede llevar a cabo mediante yum:

~root $ yum install mod_nss

aunque también se pueden descargar los binarios y el código fuente desde aquí.

Dado que mod_nss es compatible con el módulo mod_ssl, la configuración que se instala por defecto deja a la escucha de conexiones https el puerto 8443 en lugar del 443 (el puerto estándar para el protocolo HTTPS), con la idea de no provocar conflictos. Sin embargo, si el puerto 443 está libre, se recomienda cambiar la configuración que viene por defecto en el archivo /etc/httpd/conf.d/nss.conf. Una forma correcta de hacerlo comienza creando una copia de seguridad del archivo que viene por defecto para poder revertir los cambios en el futuro:

# Es importante que la copia del archivo esté fuera del directorio
# /etc/httpd/conf.d
~root $ cp /etc/httpd/conf.d/nss.conf ~/nss.def.conf

La herramienta lsof verifica el estado de los puertos, así, se puede conocer si el puerto 443 está libre antes de cambiar la configuración en nss.conf:

~root $ lsof -i :443

Una vez que comprobemos que no está a la escucha en ningún servicio (no aparecería nada al ejecutar el comando anterior), modificamos la configuración del módulo como sigue:

# NOTA: La herramienta diff muestra la diferencia entre dos archivos
~root $ diff -U2 ~/nss.def.conf /etc/httpd/conf.d/nss.conf

--- ~/nss.def.conf
+++ /etc/httpd/conf.d/nss.conf
@@ -18,5 +18,5 @@
# Listen directives: "Listen [::]:8443" and "Listen 0.0.0.0:8443"
#
-Listen 8443
+Listen 443

##
@@ -82,5 +82,5 @@
##
- <VirtualHost _default_:8443>
+<VirtualHost _default_:443>

Después de esto, se debe comprobar que la sintaxis de la configuración de Apache es correcta antes de reiniciar el servicio, si la respuesta de la siguiente orden no fuera "Syntax OK" sería necesario revisar los archivos de configuración:

~root $ httpd -t
Syntax OK

Para reiniciar Apache:

~root $ /etc/init.d/httpd restart
Stopping httpd:                                            [  OK  ]
Starting httpd:                                            [  OK  ]

En este punto, Apache está funcionando y el módulo mod_nss ha sido cargado correctamente. El siguiente paso es obtener e instalar los certificados en el servidor.


4. Generación de las claves pública y privada del servidor

Para la obtención de certificados firmados por una CA y su posterior manipulación, es necesario obtener primero el par de claves, pública y privada, esto se lleva a cabo con openssl tal y como se describe en el knowledgebase de Comodo [12]:

~root $ openssl req -nodes -newkey rsa:2048 -keyout myserver.key -out server.csr

Se rellena el cuestionario que aparece a continuación:

For some fields there will be a default value, If you enter '.', the field will be left blank.

Country Name (2 letter code) [AU]: ES
State or Province Name (full name) [Some-State]: Malaga
Locality Name (eg, city) []: Velez Malaga
Organization Name (eg, company) [Internet Widgits Pty Ltd]: MyCompany Ltd
Organizational Unit Name (eg, section) []: Sports
Common Name (eg, YOUR name) []: mydomain.com
Email Address []: admin@mydomain.com

Please enter the following 'extra' attributes to be sent with your certificate request

A challenge password []: 
An optional company name []:

Y se generarán dos archivos:

  • myserver.key: que contiene la clave privada del servidor y tan solo el propietario debe conocerla. Se usará para encriptar los certificados (ver más abajo)
  • server.csr: que contiene la clave pública y una solicitud de firma de certificado o en inglés Certificate signing request, CSR. Es necesario enviar este archivo a la CA para obtener los certificados firmados oficialmente (ver más abajo) [13].

El siguiente paso es elegir un proveedor de certificados y la Autoridad de Certificación a la que se solicitará la firma. Sin embargo, si no se desea pagar por conseguir un certificado, puede obtenerse uno autofirmado, que el cliente tendrá que aceptar a falta de un respaldo oficial (ver punto 6).

5. Obtención de un certificado firmado por una Autoridad de Certificación

Un proveedor donde se pueden obtener certificados firmados por distintas autoridades es Namecheap [14]. Como ejemplo se va a usar el certificado más barato que ofrecen a día de hoy (7,95 $): Comodo-PositiveSSL. En este caso, la CA es Comodo y el tipo de certificado que se obtiene es el llamado PositiveSSL. Después de completar el pago del certificado, se envía la clave contenida en al archivo server.csr (ver más arriba) a la CA para que lo verifiquen. Pocas horas después, el CA enviará al correo electrónico del administrador del servidor un archivo comprimido (usualmente) con los certificados firmados. En el caso del ejemplo, el correo contiene tres archivos: AddTrustExternalCARoot.crt y PositiveSSLCA2.crt, que son los llamados certificados intermediarios, y my_domain_com.crt, siendo «my_domain_com» el nombre de dominio que se haya especificado en la obtención del CSR.

Una vez que el administrador tiene los archivos en su poder, se procede a la instalación de éstos en una base de datos del servidor, que posteriormente podrá ser consultada por Apache.


6. Obtención de un certificado autofirmado

Si no se quiere depender de autoridades de certificación por los motivos que sean, se pueden obtener certificados autofirmados sin necesidad de pagar por ellos. Eso implica que la conexión con el cliente estará cifrada pero no existirá un certificado válido; así pues, el cliente tendrá la opción de rechazarlo o aceptarlo.

Para conseguir este certificado, se utiliza de nuevo la herramienta certutil:

~root $ certutil -S -s "CN=My SS Certificate" -n mysscert -x -t "C,C,C" -1 -2 -5 -m 1234 -f password-file -d path/to/certdir

Esta instrucción creará un nuevo certificado binario en la ubicación path/to/certdir. Si se desea conocer en profundidad el uso de cada uno de los argumentos, se puede consultar en el manual oficial de la herramienta certutil (aqui [15]).


7. Instalación de los certificados intermediarios

Los certificados que se instalan en la máquina se almacenan en bases de datos de certificados. Éstas están compuestas por tres archivos que se encuentran en la ubicación /etc/httpd/alias; cert8.db, key8.db y second.db. Si no existe ninguna base de datos se utiliza certutil para crearla:

~root $ certutil -N -d /etc/httpd/alias -P nss-

donde el argumento -N indica que se creará una nueva base de datos, -d es la ubicación donde se crearán los tres archivos y -P (opcional) añade un prefijo a los archivos (quedarían como: nss-cert8.db, nss-key8.db y second.db); así, pueden crearse múltiples bases de datos en el mismo directorio. Una vez creada se podrán añadir los certificados.

En primer lugar se añaden los intermediarios:

# El certificado CA
~root $ certutil -A -d /etc/httpd/alias -n "AddTrust External CA Root" -t "CT,C,C" -a -i AddTrustExternalCARoot.crt -P nss-
# El certificado PositiveSSL2
~root $ certutil -A -d /etc/httpd/alias -n "Positive SSL CA 2" -t "CT,C,C" -a -i PositiveSSLCA2.crt -P nss-

donde el argumento -A indica que se añadirá un nuevo item, -n es el nombre que se asigna al certificado o «NickName», -t son los atributos de confianza [16] y -i el archivo del certificado. Con el siguiente comando, que lista los items de una base de datos, se puede verificar si efectivamente se han añadido estos certificados:

~root $ certutil -L -d /etc/httpd/alias -P nss-

Certificate Nickname                                         Trust Attributes
                                                             SSL,S/MIME,JAR/XPI

AddTrust External CA Root                                    CT,C,C  
PositiveSSL CA 2                                             CT,C,C

El siguiente paso es instalar el certificado del dominio.


8. Instalación del certificado firmado

Para añadir el certificado firmado a la base de datos NSS, es necesario cambiar su formato y el de la clave a pkcs12 [17]. De nuevo con certutil:

~root $ openssl pkcs12 -export -in my_domain_com.crt -inkey myserver.key -out my_domain_com.p12 -name "My Domain Cert"
Enter Export Password:
Verifying - Enter Export Password:

El programa pide una contraseña para proteger el certificado, que puede quedar en blanco si se desea simplemente pulsando enter. En el ejemplo, se genera el archivo my_domain_com.p12 que contiene la clave y el certificado firmado en formato pkcs12. Este archivo se instala en la base de datos mediante la herramienta pk12util:

~root $ pk12util -i my_domain_com.p12 -n "My Domain Cert" -d /etc/httpd/alias -P nss-

De nuevo se listan los items para comprobar que se ha añadido correctamente:

~root $ certutil -L -d /etc/httpd/alias -P nss-

Certificate Nickname                                         Trust Attributes
                                                             SSL,S/MIME,JAR/XPI

My Domain Cert                                               u,u,u
AddTrust External CA Root                                    CT,C,C  
PositiveSSL CA 2                                             CT,C,C

Por último, se comprueba la validez del certificado:

~root $ certutil -V -u V -d /etc/httpd/alias -n "My Domain Cert" -P nss-
Certificate is valid

En el caso de que no fuera válido, se recomienda prestar especial atención a los atributos de confianza [15].


9. Configuración del host virtual y reinicio de Apache

En un archivo de configuración de hosts de Apache, cada host virtual se describe mediante la siguiente estructura:

<VirtualHost __ipMaquina__:__puerto__>
    ServerName                www.mydomain.com
    DocumentRoot              /home/user/public_html
    __Directiva__             __valor__
</VirtualHost>

En cada línea enmarcada en la etiqueta VirtualHost se define un par (Directiva, Valor) separados por al menos un espacio en blanco. Para configurar correctamente un host que se conecte por https y gestione los certificados que se han instalado, es necesario añadir algunas directivas propias del módulo mod_nss y modificar el puerto de escucha (443, en nuestro caso).

Es recomendable leer detenidamente la documentación del módulo donde se explica el uso de cada una de sus directivas (disponible aquí [18]). Un ejemplo de un host que hace uso del módulo sería:

<VirtualHost 256.13.24.12:443>

    ServerName         www.mydomain.com
    DocumentRoot       /home/user/mydomain
    ErrorLog           /home/user/logs/mydomain/error_log

    NSSEngine               On
    NSSNickname             "My Domain Cert"

</VirtualHost>

En este host, se requiere el certificado llamado «My Domain Cert», que se había instalado previamente en la base de datos de certificados. Si éste no estuviera, Apache no podría iniciarse y el servicio escribiría una nueva línea en el log de error.

En este punto, ya estaría todo listo para poner en marcha el nuevo host. De nuevo se comprueba la sintaxis de configuración de Apache y se reinicia el servicio:

~root $ httpd -t
Syntax OK
~root $ /etc/init.d/httpd restart
Stopping httpd:                                            [  OK  ]
Starting httpd:                                            [  OK  ]

En el caso de que Apache no pudiera iniciarse, se debe encontrar el error o errores que puedan estar ocurriendo, para ello se deben conocer los distintos archivos que contienen logs de apache (véase más abajo).


10. Logs de errores

Apache vuelca sus errores por defecto en el archivo /etc/httpd/logs/error_log, tal y como está dispuesto en el archivo principal de configuración de Apache (/etc/httpd/conf/httpd.conf), y es ahí donde hay que buscar errores en primer lugar. Sin embargo, en el caso del ejemplo se ha definido un archivo alternativo donde sólo se almacenarán los errores provocados por ese host virtual y no por otro (mediante la directiva «ErrorLog /home/user/logs/mydomain/error_log"). Si Apache no lograra iniciar, las causas se encontrarían descritas en este archivo.


11. Dudas y contacto

Todo este artículo procede de mi propia experiencia al tratar de establecer una conexión segura para una página web personal. A lo largo de todo el proceso he ido encontrando errores y resolviendo dudas y conflictos sobre la marcha. Es por esta razón por la que me siento potencialmente capacitado para resolver algunos problemas que el lector pudiera tener al seguir todos los pasos. Así, si el contenido de este trabajo no logra satisfacerles, no duden en escribirme o comentar en este mismo post.


12. Agradecimientos

Querría agradecer a iDaruma por su patrocinio y a David Valverde Pareja (@dvpareja) por revisar y discutir algunos aspectos de este trabajo.


13. Referencias

[1] Request for Comments, Mayo de 2000: http://www.ietf.org/rfc/rfc2818.txt
[2] Wikipedia – Hypertext Transfer Protocol: http://es.wikipedia.org/wiki/Hypertext_Transfer_Protocol_Secure
[3] Facebook Developers Documents: https://developers.facebook.com/docs/appsonfacebook/pagetabs/
[4] Criptografía asimétrica: http://es.wikipedia.org/wiki/Criptograf%C3%ADa_asim%C3%A9trica
[5] Autoridad de Certificación: http://es.wikipedia.org/wiki/Autoridad_de_certificaci%C3%B3n
[6] VeriSign (CA): http://www.verisign.com/
[7] GeoTrust (CA): http://www.geotrust.com/
[8] Comodo (CA): http://www.comodo.com/
[9] Documentación de mod_nss: http://directory.fedoraproject.org/wiki/Mod_nss
[10] Network Security Services (NSS): http://www.mozilla.org/projects/security/pki/nss/
[11] Netscape Portable Runtime (NSPR): http://www.mozilla.org/projects/nspr/
[12] Generación de CSR y clave privada. Comodo’s knowledgebase: https://support.comodo.com/index.php?_m=knowledgebase&_a=viewarticle&kbarticleid=3&nav=0,33
[13] Wikipedia – Certificate Signing Request: http://en.wikipedia.org/wiki/Certificate_signing_request
[14] Namecheap: http://www.namecheap.com/
[15] Certutil: http://www.mozilla.org/projects/security/pki/nss/tools/certutil.html
[16] Atributos de confianza: https://blogs.oracle.com/meena/entry/notes_about_trust_flags
[17] Convertir certificados a formato pkcs12 e instalación en una base de datos NSS: https://stomp.colorado.edu/blog/blog/2010/06/04/on-setting-up-mod_nss/
[18] Documentación de mod_nss: http://git.fedorahosted.org/cgit/mod_nss.git/plain/docs/mod_nss.html?id2=HEAD