Crear certificados SSL para Apache 

Copyright © 2005-2017 LinuxTotal.com.mx
Se concede permiso para copiar, distribuir y/o modificar este documento siempre y cuando se cite al autor y la fuente de linuxtotal.com.mx y según los términos de la GNU Free Documentation License, Versión 1.2 o cualquiera posterior publicada por la Free Software Foundation.

Autor: Sergio González D.  

Introducción

Imaginémonos a la empresa "Pato, S.A." que ofrece a sus empleados y clientes el sitio http://www.pato.com/consulta, donde mediante un nombre de usuario y contraseña es posible para los empleados consultar saldos, órdenes, resurtir, estados de cuenta, etc. y para los clientes observar el estado de sus pedidos, su saldo, pagos, historial de compras, etc. El sitio esta perfectamente diseñado, protegido contra inyecciones sql, ataques mediante el url, el servidor al día con los últimos parches y actualizaciones, toda entrada de usuario, contraseña, y demás debidamente validadas para solo recibir caracteres válidos y excluir caracteres usados en consultas e instrucciones sql, etc. etc. Una belleza en cuanto a la seguridad de la aplicación Web. PERO, todo el sitio funciona bajo un servidor Web apache en el puerto 80, esta bien, pero implica que un empleado rencoroso porque no le aumentaron el sueldo o no lo promovieron de puesto y con intenciones de querer ser un hacker, instala un sniffer en su PC (dentro de la empresa), baja herramientas para envenenar mediante un ataque arp (arp poisoning) el switch al que corresponde a su segmento red de tal modo que puede observar todo el tráfico de red de los equipos conectados a su switch. Fácil, nada del otro mundo, cualquier chico de los scripts (script kiddie) le hubiera enseñado como hacerlo si no lo hubiese el sabido ya. En unas cuantas horas tiene ya varias cuentas de usuario y contraseñas, se introduce como ellas y baja información confidencial de varios de sus compañeros y como algunos son gerente, también obtiene información sensible de clientes. Listo, ahora a chantajear a la empresa por medio de un cómplice en el exterior o simplemente tratar de utilizar la información en su beneficio o peor aun causar algún tipo de destrozo con esta.

¿Ficción? Absolutamente no. Lo anterior es perfectamente posible porque el tráfico de red generado entre el cliente (navegador) y el servidor Web apache en el puerto 80 no esta encriptado, viaja tal cual. Entonces es posible, con la herramienta adecuada interceptar y observar este tráfico y obtener entre otras cosas contraseñas, números de tarjetas de crédito, etc. La solución es simple (la implementación no tanto), obtener un certificado de seguridad y hacer que el tráfico se dirija al puerto 443 (https) en vez del 80 (http). En el puerto 443 el tráfico se encripta a través del los protocolos SSL (Secure Sockets Layer) y TLS (Transport Layer Security). Entonces todo el tráfico será encriptado y aunque es posible interceptarlo y observarlo, no se verá mas que basura o cadenas de caracteres sin ningún significado todo el tiempo, logrando asi un canal seguro encriptado entre el cliente y el servidor.


Certificate Authority CA (Autoridad Certificadora)

Esta fuera del alcance de este documento toda la teoría detrás de SSL, hay varios documentos, tutoriales y manuales en Internet que lo explican, pero lo que si hay que entender que es un CA. Una autoridad certificadora como lo son Verisign, Thawte, beTRUSTed o ValiCert son empresas dedicadas a vender certificados de seguridad que la empresa que lo adquiere instala en su servidor web. Es decir "Pato, S.A." desea montar su apliación Web bajo un sitio seguro con https, crea su certificado y lo manda firmar con un CA, el CA verifica que "Pato, S.A." es realmente quien dice ser. Después de checar la autenticidad de la empresa en cuestión, el CA firma el certificado de seguridad de su cliente con alguno de sus certificados raíz bajo una fuerte encriptación y se lo regresa a "Pato, S.A.", este lo instala en su servidor Web y cuando los clientes (navegadores) se conectan, estarán tanto el cliente como el servidor bajo un tráfico encriptado y seguro, todo avalado por el CA otorgante del certificado. La enorme ventaja de este esquema es que todos los navegadores actuales (Internet Explorer, Firefox, Opera, Mozilla, etc) tienen incorporados los certificados raíz de todas las empresas CA conocidas del mundo, asi que cuando el cliente se conecta al servidor no hay ninguna molestia para el cliente, todo es transparente para el usuario final. Si eres una empresa dedicada a cualquier tipo de comercio electrónico donde se involucre dinero a través de tarjetas de crédito o servicios como paypal, firmarse con un CA como Verisign es la única alternativa que se tiene, esto para otorgar seguridad a los clientes del sitio.
Ahora bien, los CA como los mencionados no son almas de la caridad, cobran por el servicio de firmar los certificados, sus precios comienzan en alrededor de 200 a 300 dólares anuales por certificado y pueden subir mas dependiendo del tipo de encriptación que se solicite, es decir, para un sitio de comercio electrónico con un alto volumen de tráfico requerira de certificados mas seguros debido a que será mas tentador para posibles hackers de tratar de violarlo.
Lo interesante viene a continuación. "Pato, S.A." es como muchas empresas que solo ofrecen una aplicación sin transacciones de comercio, solo consulta a sus bases de datos y algunos formularios que involucran solicitudes de reportes o actualización de datos. "Pato, S.A." o quienquiera puede convertirse el mismo en CA, el mismo emitir un certificado raíz de seguridad y a través de este generar certificados para sitios Web. Y de hecho es el tema de este artículo, como crear certificados SSL para montarlo en nuestro propio servidor Web o de correo electrónico. ¿Cual es la deventaja?, solo una, que en el navegador del cliente al no estar importado el certificado (integrado) en su lista de certificados seguros, pedirá al usuario cuando se conecte al sitio que acepte el certificado. Si el usuario es desconfiado y no lo acepta no se podrá conectar a nuestro servidor Web seguro. Lo que se puede hacer es, por ejemplo, lo siguiente:

  • El usuario se conecta a "http://www.pato.com" puerto 80, trafico http normal sin seguridad.
  • En la página inicial del sitio desplegamos un botón y una leyenda que dice que al apretar el botón se redirigirá a la aplicación Web de consulta y que deberá aceptar el certificado de seguridad que la empresa "Pato, S.A." ofrece para establecer una conexión segura, que si tiene dudas puede comunicarse al siguiente teléfono o correo, etc.
  • Al apretar el botón se redirige a "https://www.pato.com/consulta" puerto 443, que es donde estará la apliación de consulta y en este momento se pedirá que se acepte el certificado. El usuario entonces, estuvo mas informado de lo que pasa.

Ya quedando mas claro lo anterior, entonces, comencemos a aclarar algunas cosas. Se requiere para lo anterior dos cosas:

  • Un par de claves, una pública y una privada (claves RSA o DSA, en otras palabras encriptación asimétrica). La clave es pública, como su nombre implica es expuesta a todo el mundo y la privada es solo conocida por el emisor, es decir, nosotros.
  • Un certificado de seguridad, que es una versión "firmada" o verificada de la clave pública RSA o DSA.

Entonces, se trata de que uno va a generar tanto la clave pública como la privada. Una vez teniendo esto volvemos a las dos opciones previamente mencionadas, podemos autofirmar nosotros mismos nuestra clave pública o podemos mandarla a un tercero, a un CA reconocido para que nos la firme cobrando por el servicio. Una vez que hacemos esto tendremos en ambos casos como producto un certificado firmado que será el que el navegador deberá importar en su lista de certificados de confianza para poder establecer la conexión.

Vamos a ponerlo mas ilustrado, primero con un certificado autofirmado:
- El usuario (cliente) se conecta a https://www.pato.com/consulta y este servidor le envia el certificado autofirmado para que sea aceptado (importado) por el navegador del cliente. Traducido en un diálogo de humanos sería de la siguiente manera: "Hey! hola navegador, soy el servidor www.pato.com tienes que confiar que soy de la empresa Pato, S.A. y nadie mas, y para demóstrartelo te envió mi clave pública que te permitirá autentificarte con mi clave privada en mi servidor, todo esto te lo mando en este certificado que espero aceptes, ya que yo mismo me convertí en mi propio CA. Y en serio yo el firmante Pato, S.A. te juro que soy yo, creeme, acéptame, vamos, si soy yo, por favor aprieta Aceptar para poder establecer la conexión segura."

Ahora veamos que pasa con un certificado de terceros:
- El usuario (cliente) se conecta a https://www.pato.com/consulta y este servidor le envia el certificado firmado, por ejemplo por el CA Verisign, los certificados de Verisign ya están por default en la lista de CA confiables del navegador, por lo que es aceptado sin mayor problema y sin preguntas. Traducido en un diálogo de humanos sería de la siguiente manera:
"Hey!, hola navegador, soy el servidor www.pato.com, te envió mi certificado con mi clave pública que te permitirá autentificarte con mi clave privada en mi servidor, esto te lo mando en un certificado firmado nada mas ni nada menos por Verisign. Verisign ya verificó que si soy la empresa Pato, me cobro un billete por esto, asi que mi certificado debe ser autorizado sin mayor problema por los certificados raíz que se encuentran en tu lista de certificados confiables. Listo, conexión segura establecida".

Bueno, espero que con esto quede claro cual es la idea detrás de los certificados y de las conexiones seguras, pero ya estuvo bueno de tanto rollo y pongamos manos a la obra en crear nuestros propios certificados autofirmados.

Nota cultural rápida: Hace algunos años fue muy sonado el caso de dos certificados que firmó Verisign para alguien que dijo ser empleado de Microsoft y Verisign ¡¡¡le creyó!!!. Lo mas increible es que todavía pasaron varios meses hasta que se descubrió el fraude de los certificados del supuesto empleado de Microsoft. Desde entonces todos los CA del mundo checan muy escrupulosamente tanto a la persona que representa a la empresa que desea obtener un certificado como a la empresa en si, por eso el proceso de obtener un certificado firmado por un tercero suele tardar de dos a tres semanas. (Si tienes curiosidad puedes checar estos dos certificados falsos están en la lista de "fabricantes que no son de confianza" en el Internet Explorer --> Herramientas - Opciones de Internet - Contenido - Certificados - Fabricantes que no son de confianza).


Prerequisitos

Para crear nuestros certificados usaremos la excelente aplicación Openssl, que deberás tener instalada, puedes verificarlo con una consulta rpm:

#> rpm -q openssl
openssl-0.9.7f-7

O directamente con el mismo comando openssl:

#> openssl version
OpenSSL 0.9.7f 22 Mar 2005

Si muestra que el comando no existe, deberás entonces descargarlo e instalarlo. También, por supuesto, que requieres del servidor Web Apache y todo lo que se hará a continuación se tiene que hacer en el equipo donde se tenga instalado el servidor Web configurado con un dominio FQDN (Fully Qualified Domain Name), es decir, un dominio auténtico de Internet, si es que es el caso, o bastará con la dirección IP privada del equipo si va a quedar dentro de una Intranet. En cualquier caso debe hacerse todo el procedimiento directamente en el equipo en cuestión.

Apache además deberá estar instalado con el módulo ModSSL. Si tienes OpenSSL seguramente tienes también este módulo.


Instalación inicial

Todo el trabajo lo haremos dentro de un directorio de trabajo, puedes ponerle el nombre que desees, para fines prácticos le pondré CA y dentro de este directorio a la vez hay que crear otros dos, llamados certificados y privado. El primero es donde se guardará una copia de cada certificado que firmemos y en el otro directorio se guardará la llave privada.

#> mkdir CA
#> cd CA
#> mkdir certificados privado

Es muy importante no perder la llave privada que se generé, ya que con esta podremos firmar o renovar certificados, y mucho menos dársela a nadie, ya que toda nuestra seguridad radica en la confidencialidad de la llave privada que se guardará en el directorio privado.

Lo siguiente será crear un par de archivos que en conjunto formarán la base de datos de los certificados autofirmados.

#> echo '01' > serial
#> > index.txt           
#> touch index.txt

El primer archivo 'serial' simplemente contiene el siguiente número de serie de nuestros certificados, ya que apenas vamos a crear el primero su número de serie será 01, después de crearlo se actualizará a 02 y asi sucesivamente.
'index.txt' será la base de datos propiamente en base al número de serie.


Archivo de configuración

Openssl tiene docenas de opciones y parámetros, mucha de la información que irá en el certificado es tomado del archivo de configuración, en vez de la línea de comandos. A continuación te muestro un archivo de configuración listo para ser usado, puedes personalizarlo a tu gusto, usa los comentarios que añadí y el sentido común para que te des una idea de lo que hace cada línea. A este archivo lo nombraremos openssl.cnf y lo guardaremos dentro de nuestro directorio CA. Añadí comentarios a cada variable para hacerlo mas claro. El archivo se divide en secciones indicadas entre [ corchetes ], y cada sección tiene sus propias variables. La idea principal del archivo de configuración es de simplificar el uso de los subcomados del comando openssl, que tiene tres subopciones principales: ca, req y x509, entonces, cuando se lee el archivo de configuración 'openssl.cnf' y usamos la opción req por ejemplo, esta opción toma sus argumentos de la sección correspondiente del archivo de configuración. Una explicación detallada de cada opción posible la encuentras aqui.

Hay una directiva o variable importante que es distinguished_name (DN) o nombre distinguido en español, esta a su vez hace referencia a una sección que tiene los datos básicos de la autoridad certificadora (CA) y que también servirán estos datos para cuando se generen certificados. Mas simple, el DN son los campos que identifican al propietario del certificado.

# *************************************************************************************
# www.linuxtotal.com.mx
# sergio.gonzalez.duran@gmail.com
# 
# Archivo de configuracion para openssl
#
# ***** openssl.cnf ******

dir           = .    # variable que establece el directorio de trabajo
  
# seccion que permite convertirnos en una CA
# solo se hace referncia a otra sección CA_default
[ ca ]
default_ca    = CA_default

[ CA_default ]
serial        = $dir/serial          # archivo que guarda el siguiente número de serie
database      = $dir/index.txt       # archvio que guarda la bd de certificados
new_certs_dir = $dir/certificados    # dir que guarda los certificados generados
certificate   = $dir/cacert.pem      # nombre del archivo del certificado raíz
private_key   = $dir/privado/cakey.pem # llave privada del certificado raíz
default_md    = md5                  # algoritmo de dispersión usado
preserve      = no                   # Indica si se preserva o no el orden de los 
                                     #   campos del DN cuando se pasa a los certs.
nameopt       = default_ca           # esta opcion y la siguiente permiten mostrar 
                                     #   detalles del certificado  
certopt       = default_ca           
policy        = policy_match         # indica el nombre de la seccion 
                                     #   donde se especifica que campos son 
                                     #   obligatorios, opcionales y cuales deben ser
                                     #   iguales al certificado raíz

# seccion de politicas para la emision de certificados
[ policy_match ]
countryName                 = match          # match, obligatorio
stateOrProvinceName         = match          
organizationName            = match
organizationalUnitName      = optional       # optional, campo opcional
commonName                  = supplied       # supplied, debe estar en la petición 
emailAddress                = optional

# seccion que indica como los certificados deben ser creados
[ req ]
default_bits       = 1024           # tamaño de la llave, si no se indica 512
default_keyfile    = key.pem        # nombre de la llave privada
default_md         = md5            # algoritmo de dispersión a utilizar
string_mask        = nombstr        # caracteres permitidos en la mascara de la llave
distinguished_name = req_distinguished_name  # seccion para el nombre distinguido (DN)
req_extensions     = v3_req         # seccion con mas extensiones que se añaden a la
                                    #   peticion del certificado

# seccion del nombre distinguido, el valor es el prompt que se vera en pantalla.
# datos del propietario del certificado.
# esta seccion define el contenido de datos de id que el certificado llevara.
[ req_distinguished_name ]
0.organizationName          = Nombre de la organizacion
0.organizationName_default  = Pato, S.A.
organizationalUnitName      = Departamento o division
emailAddress                = Correo electronico
emailAddress_max            = 40
localityName                = Ciudad o distrito
localityName_default        = Leon
stateOrProvinceName         = Estado o provincia
stateOrProvinceName_default = Guanajuato
countryName                 = Codigo del pais (dos letras)
countryName_default         = MX
countryName_min             = 2
countryName_max             = 2
commonName                  = Nombre comun (hostname o IP)
commonName_max              = 64

# si en la linea de comandos se indica la opcion -x509, 
# las siguientes extensiones tambien aplican 
[ v3_ca ]
# indica que se trata de un certificado CA raíz con autoridad para 
# firmar o revocar otros certificados
basicConstraints       = CA:TRUE  
                                 
# especifica bajo que metodo identificar a la llave publica que sera certificada
subjectKeyIdentifier   = hash     
                                  
# especifica como identifcar la	llave publica														
authorityKeyIdentifier = keyid:always,issuer:always  
                                        
# extensiones de la opcion req
[ v3_req ]
basicConstraints            = CA:FALSE  # los certificados firmados no son CA
subjectKeyIdentifier        = hash 
# *************************************************************************************

Como ya lo había mencionado guarda este archivo con el nombre de 'openssl.cnf' en tu directorio CA. En este punto esto es lo que debes de tener en el directorio CA.

#> ls -l
drwxr-xr-x  2 root root 4096 ene 26 13:23 certificados
-rw-r--r--  1 root root    0 ene 26 13:24 index.txt
-rwxr--r--  1 root root 4776 ene 26  2006 openssl.cnf
drwxr-xr-x  2 root root 4096 ene 26 13:23 privado
-rw-r--r--  1 root root    3 ene 26 13:23 serial
#>

Creando el certificado raíz

Todo esta casi listo para crear el certificado raíz, recordemos que este certificado es el que nos convertira en una autoridad certificadora CA, asi que cuando emitamos el comando lo primero que nos pedira es el "pass phrase" o mas llanamente, una contraseña pero en forma de una frase. Esta contraseña es de vital importancia ya que es con la que validaremos nuestra autoridad para después poder crear certificados autofirmados que son los que realmente usaremos en nuestro sitio, debe ser preferentemente muy compleja, con mayúsculas, minúsculas, espacios, números y por supuesto símbolos, un buen ejemplo sería:

el Der3ch0 al #respE5to( -a+jeño_Ez-la=pAz8%. =)

Puede parecer muy complicada para recordar y lo es, pero tengamos en cuenta que los algoritmos de cifrado son muy buenos y sumamente dificiles o al menos muy tardados para romper mediante fuerza bruta (hasta miles de años podría llevarse), asi que la verdadera debilidad es el uso de contraseñas débiles. Te recomiendo como "pass phrase" algo similar a lo anterior y al menos 20 caracteres.

Ok. Manos a la obra, tenemos todo listo incluyendo una buena contraseña.

#> openssl req -new -x509 -extensions v3_ca -keyout privado/cakey.pem \
-out cacert.pem -days 3650 -config ./openssl.cnf

Generating a 1024 bit RSA private key
....++++++
.......++++++
writing new private key to 'privado/cakey.pem'
Enter PEM pass phrase:
Verifying - Enter PEM pass phrase:
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Nombre de la organizacion [Pato, S.A.]:
Departamento o division []:Sistemas
Correo electronico []:info@pato.com
Ciudad o distrito [Leon]:
Estado o provincia [Guanajuato]:
Codigo del pais (dos letras) [MX]:
Nombre comun (hostname o IP) []:www.pato.com

Antes de analizar la salida, veamos las opciones indicadas:

  • req -new -x509 --->
  • -extensions v3_ca --->
  • -keyout --->
  • -out --->
  • -days 3650 --->
  • -config --->

Con respecto al resultado producido, lo primero que se indico fue escribir y verificar la contraseña, después vienen los datos para identificar al propietario del certificado CA, que como se puede apreciar los prompts y los datos por default provienen del archivo de configuración. Si no se especifica la opción -days entonces el certificado será válido por solo 30 días. (En el archivo de configuración es posible inicar la variable default_days = valor, en la sección de CA_default)

Lo anterior da por resultado dos archivos:

  • Un certificado raíz CA (cacert.pem)
  • Una llave privada (privado/cakey.pem) (La extensión "pem" es de Privacy Enhanced Message)

IMPORTANTE: El archivo cacert.pem es el que se podría mandar a nuestros clientes o usuarios del sistema, y que estos lo instalen (importen desde el punto de vista del navegador) en su navegador favorito, de esta manera quedaríamos como un CA más válido para el navegador y cada vez que el cliente se conecte a nuestro servidor, su navegador ya no estaría mostrando el diálogo donde se pide aceptar la conexión segura.

Veamos como lucen estos archivos:

#> more cacert.pem
-----BEGIN CERTIFICATE-----
MIIDkzCCAvygAwIBAgIJAKTOKYwDdhLRMA0GCSqGSIb3DQEBBAUAMIGOMRMwEQYD
VQQKEwpQYXRvLCBTLkEuMREwDwYDVQQLEwhTaXN0ZW1hczEcMBoGCSqGSIb3DQEJ
ARYNaW5mb0BwYXRvLmNvbTENMAsGA1UEBxMETGVvbjETMBEGA1UECBMKR3VhbmFq
dWF0bzELMAkGA1UEBhMCTVgxFTATBgNVBAMTDHd3dy5wYXRvLmNvbTAeFw0wNjAx
MjcwMTU4NDFaFw0wNjAyMjYwMTU4NDFaMIGOMRMwEQYDVQQKEwpQYXRvLCBTLkEu
MREwDwYDVQQLEwhTaXN0ZW1hczEcMBoGCSqGSIb3DQEJARYNaW5mb0BwYXRvLmNv
bTENMAsGA1UEBxMETGVvbjETMBEGA1UECBMKR3VhbmFqdWF0bzELMAkGA1UEBhMC
TVgxFTATBgNVBAMTDHd3dy5wYXRvLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAw
gYkCgYEA52zeMbFW2lSRfcZl6yrqXDAzbwL4ZoXCGRnbo6Wr8S1yp/KYW9/TMHlX
nFrKXzM+RP7St/LzlkW1Zt8L+bCZ3XMBLGaa7qHgOagZxhcq1XTLL3CcvaCuzzKT
8izENDnGr4abtvkAJW4QqRCP7iVvVf8Db624JclbhBYMBUqPEJsCAwEAAaOB9jCB
8zAMBgNVHRMEBTADAQH/MB0GA1UdDgQWBBS6tkzuiG3DR+AO1Oy32QjZvBbpLTCB
wwYDVR0jBIG7MIG4gBS6tkzuiG3DR+AO1Oy32QjZvBbpLaGBlKSBkTCBjjETMBEG
A1UEChMKUGF0bywgUy5BLjERMA8GA1UECxMIU2lzdGVtYXMxHDAaBgkqhkiG9w0B
CQEWDWluZm9AcGF0by5jb20xDTALBgNVBAcTBExlb24xEzARBgNVBAgTCkd1YW5h
anVhdG8xCzAJBgNVBAYTAk1YMRUwEwYDVQQDEwx3d3cucGF0by5jb22CCQCkzimM
A3YS0TANBgkqhkiG9w0BAQQFAAOBgQAEdK/hgtIqEVw551fs3G3+TKoH9b9t3TJa
aelLJtKSQAoKzsnhwl88Hm78LEXK/kYufX6M6rDQHDpmcBV3DhIkEEHrBPJ4KBuV
+aC559Xqb828YCkNVWDIIefFuxfaWBfd4HHPNKBBiyE5rp2IXN8AgUy7mVkMbsto
RCAZS/IhAg==
-----END CERTIFICATE-----
#>

Y la llave privada tiene el siguiente contenido:

#> more privado/cakey.pem
-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: DES-EDE3-CBC,0FC86D0DBD03A241

TQIqQQKIB2ZFaZUqTwk+k658Lj+RStlsdLKkAeWN+B7ibgtLPN8OHNZM2cOts9Se
qRSVfWSSXzhFsh2fbDoBNx+JYKgPh7+IeBhQ1PJNrPAbyrC1GEybtn+WPEWzBNdo
2e4kOeIzgm7LxeAoofmKgvqcDLRlY34TCFHgnSAQIuZC3iZ8YZAFcMWo3owoUpP7
TKL8W1PtFTVviMC5I7A0rN9en9EQY4QazXDIIVc60uIcKONyEF4fj3aE87+m2lD5
fqfMWG7Ce8GBBOUPL1YtLSC9LOBNhulFqceMvfysLFxToPUP4rs+n+upxnGsHnmF
YjsPR3lqAt41JehsO+sUSqoX6I83Q/706g/87XV0JPMDCXBejRI/vW5KgJ0Ux2gv
yQfYvHGs5RZl8NfK9AUEcC053VSkjwmuT/anu7czyJC+IG2XTHqoLu6g6CjLNe3b
bm/FhymOKENGnKSvA6Mny+NThhSOImhibB0fvsW5Fygi7SboZpXZFJBfEqHzUGvW
guzfVF4G7Rhs29Bue0dJOMT2ptFPrjUn0582O7WVIE7aV7msygmt2QUYIWykEt7s
O5hzdhguw2WZu0/gl2y5Mpjo3W5SrrCOoxC2mcPutoNhV+DFCQxcbCLsu5PnLBoF
HFBCe6ynh/6bIpakGJorzdsB9QqhGdgvbRQbrpYfAl+QHr6/8kyEu4OG+PmoD2ZR
O/gAGlSIlDowesmWXGk6l7vZc5BxU1qQVI5QLVr3X7ilavi6+EVSWDF8dFVetYBP
dPYYAEzVJVEiDH8yxQ4NoGk+9gmxKVfmejnmtbSHuR20cXbHOKJGmQ==
-----END RSA PRIVATE KEY-----

ADVERTENCIA: Esto jamás lo hagas en la vida real, el contenido de una llave privada jamás debe publicarse ni mostrarse, ni mandarse a nadie, esta es de prueba y es totalmente inútil. Una llave privada auténtica es tu mayor secreto. Podemos también consultar información específica del certificado raíz, fechas, a quien pertenece etc.

#> openssl x509 -in cacert.pem -noout -dates
notBefore=Jan 27 02:22:33 2006 GMT
notAfter=Jan 25 02:22:33 2016 GMT

En el ejemplo anterior se aprecia que el certificado si fue generado con una validez de 10 años, tal como se indico. Otros ejemplos de consulta pero se omite la salida:

#> openssl x509 -in cacert.pem -noout -text
#> openssl x509 -in cacert.pem -noout -purpose

Creando un Certificate Signing Request(CSR)
(Solicitud de firmado de certificado)

En este punto, ya tenemos un certificado raíz que nos válida como CA, claro sin mas autoridad que nuestro propio dominio pero podemos crear certificados no solo para https, sino también spop, o simap o crear autentificación para vpn's a través de aplicaciones como stunnel.

Los siguientes procedimientos son los que a continuación hay que realizar:

  • Crear una llave privada y una solicitud de certificado.
  • Firmar la solicitud para generar un certificado autofirmado.

Volveremos entonces a usar el comando openssl para lograr lo anterior. Casi todo será igual a lo anterior. Solo que en la solictud de firmado no es necesario especificar una contraseña, aunque si se generará una clave privada para la solictud. Veamos.

#> openssl req -new -nodes -out pato-cert.pem -config ./openssl.cnf
Generating a 1024 bit RSA private key
......................................................++++++
.......++++++
writing new private key to 'key.pem'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Nombre de la organizacion [Pato, S.A.]:
Departamento o division []:Sistemas
Correo electronico []:info@pato.com
Ciudad o distrito [Leon]:
Estado o provincia [Guanajuato]:
Codigo del pais (dos letras) [MX]:
Nombre comun (hostname o IP) []:www.pato.com

Lo último que nos pregunto en la parte DN (distinguished name) es el nombre común (CN common name), aqui es sumamente importante indicarlo igual a como esta el certificado raíz generado previamente, como se trata de un servidor web, lo correcto es poner su FQDN que es www.pato.com, no debe indicarse ni pato.com ni http://www.pato.com

Lo anterior genera dos archivos:

  • pato-cert.pem --->
  • key.pem --->

En cuanto a las opciones, se uso req de request solicitando un certificado nuevo, -out que es el nombre del certificado que deseamos firmar, -config de nuevo toma el archivo de configuración que creamos. La opción -nodes se especifica para indicar que no deseamos contraseña en la llave privada.

Observemos el contenido de la solictud:

#> more pato-cert.pem
-----BEGIN CERTIFICATE REQUEST-----
MIIBwTCCASoCAQAwRjETMBEGA1UEChMKUGF0bywgUy5BLjENMAsGA1UEBxMETGVv
bjETMBEGA1UECBMKR3VhbmFqdWF0bzELMAkGA1UEBhMCTVgwgZ8wDQYJKoZIhvcN
AQEBBQADgY0AMIGJAoGBAMMvo7xg3vmdlf/38yA68uzNq2WYTtkyecuBnUgocOqD
gc0Yl2hrfXN6lHl65kxeRFVdEBYhGgA7JoISivuDTvWwVOIxmH5HOFzZlIPIZ3xT
hHCdWUKipXhcsVCTGV+rbB1F9kkIAMrmtaNH2+Zj261jdB7eX960l1EqQaWt71dJ
AgMBAAGgOzA5BgkqhkiG9w0BCQ4xLDAqMAkGA1UdEwQCMAAwHQYDVR0OBBYEFGVf
A/CDDXl6LQs1MH/XItqJl/8kMA0GCSqGSIb3DQEBBAUAA4GBAJH0sO7bR+dJL67p
xK5oEG9LPA2KcP+W7Vn5edpaLtUs/jYyvhQaCdSBxbMkV42nmt9DGD5p5caTFk3M
5guV9f087K+eYnUGILGQS51tXFcmYramZLETzs7nVfwGnXGsDGyKDkG6VTkx46pz
JrRTJfWBpWpo4FWg/Fi2l4E4PLv8
-----END CERTIFICATE REQUEST-----

Observa claramente que se trata de una solicitud de certificación (Certificate Request), es decir todavía tiene que ser firmado por una autoridad certificadora CA que somos nosotros mismos. Y antes de hacer este último paso podemos observar el contenido de nuestra solictud en un formato mas legible e incluso verificar que estén los datos correctos. Se omite la salida, chécalo en tu pantalla : )

#> openssl req -in pato-cert.pem -text -verify -noout

Firmando el certificado

Por último firmaremos la solicitud que hicimos en el paso previo, para firmarlo necesitaremos indicar la contraseña que autentifique que somos la CA y que que por serlo tenemos la autoridad de autorizar (firmar) certificados. (Para nuestro propio uso).

#> openssl ca -out certificado-pato.pem -config ./openssl.cnf -days 3650 \
-infiles pato-cert.pem
Using configuration from ./openssl.cnf
Enter pass phrase for ./privado/cakey.pem:
Check that the request matches the signature
Signature ok
The Subject's Distinguished Name is as follows
organizationName      :PRINTABLE:'Pato, S.A.'
organizationalUnitName:PRINTABLE:'Sistemas'
localityName          :PRINTABLE:'Leon'
stateOrProvinceName   :PRINTABLE:'Guanajuato'
countryName           :PRINTABLE:'MX'
commonName            :PRINTABLE:'www.pato.com'
Certificate is to be certified until Jan 26 00:10:10 2016 GMT (3650 days)
Sign the certificate? [y/n]:y


1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries
Data Base Updated
#>

Observa que usamos la opción ca que indica que firmaremos un certificado como autoridad certificadora (CA) que somos, la salida -out será el archivo certificado-pato.pem usando las opciones -config del archivo de configuración y la solicitud de firmado se especificó con la opción -infiles que tomó los datos del archivo pato-cert.pem creado en el paso previo.

Aqui se nos pidió la contraseña, que es la que se indicó cuando creamos cacert.pem que corresponde a nuestro certificado raíz que nos identifica como CA. El certificado será válido por 10 años -days y después se nos preguntó que si queriamos firmarlo, por supuesto que si, y la última pregunta es por si queremos guardar este certificado ya autofirmado en la base de datos, a lo que también contestamos que si.

#> more serial
02

Se comprueba que ya aumento el número de serie a 02, es decir, el siguiente certificado que firmemos será ese número.

#> more index.txt
V 160126001010Z 01 unknown /C=MX/ST=Guanajuato/O=Pato, S.A./OU=Sistemas/CN=www.pato.com

En el archivo index.txt el tercer campo indica 01, que es el número de serie para el certificado recien creado y muestra también los campos del DN.

#> ls -l certificados
total 4
-rw-r--r--  1 root root 2597 ene 27 18:10 01.pem

En el directorio de certificados se guarda también con el correspondiente número de serie (01.pem) un archivo que complementa la base de datos de certificados que podemos ir creando.

Y por último tenemos el certificado en si:

#> ls -l certificado-pato.pem
-rw-r--r--  1 root root 2597 ene 27 18:10 certificado-pato.pem

Y podemos inspeccionarlo:

#> openssl x509 -in certificado-pato.pem -noout -text -purpose

Instalando el certificado y la llave para Apache

Tenemos entonces dos elementos ya generados que necesitaremos para Apache:

  • key.pem --->
  • certificado-pato.pem --->

Hay algunas aplicaciones (no Apache) que requieren estos dos elementos en un solo archivo, como en el caso de stunnel:

# > cat key.pem certificado-pato.pem > key-cert-pato.pem

Simplemente se concatenan los dos archivos en uno. Pero esto no es necesario para el caso del servidor Web Apache. Lo que hay que hacer es copiar nuestros dos archivos en un directorio, de hecho podrían quedarse donde están, es lo de menos, pero por cuestión de orden y organización vamos a copiarlos a /etc/httpd/conf que en la mayoría de distribucciones es el directorio de configuración del Apache.

NOTA IMPORTANTE: por ningún motivo los copies dentro del directorio raíz del servicio de Apache como /var/www/html ya que podrías dejar expuestos los archivos a todo el mundo y ser vulnerados.

#> cp key.pem certificado-pato.pem /etc/httpd/conf/.

Una vez copiados los archivos, hay que crear un servidor virtual en Apache, esto dentro del archivo de configuración httpd.conf, en algunas distribucciones como Fedora y otras dentro de /etc/httpd/conf.d hay un archivo llamado ssl.conf que es donde viene un servidor virtual ya creado, se puede tomar como plantilla.

    <VirtualHost 192.168.100.1:443>
    ServerName www.pato.com
    DocumentRoot /var/www/consulta
    ... (demás directivas del sitio)
    SSLEngine on
    SSLCertificateFile /etc/httpd/conf/certificado-pato.pem
    SSLCertificateKeyFile /etc/httpd/conf/key.pem
</VirtualHost<

También debe existir una línea que abre el puerto 443 a la escucha de paquetes. Esta fuera de las directivas del servidor virtual, búscala y si no esta agrégala, es la siguiente:

Listen 443

Forzosamente debe ser un servidor virtual basado en IP, aqui lo indique con una IP (192.168.100.1) de una red privada pero en tu caso indica la IP homologada o real de tu sitio web o deja tu IP privada si es una Intranet.

Observa también que la directiva DocumentRoot apunta a /var/www/consulta y no a /var/www/html, esto yo lo hago para que en /var/www/html dejes un simple index.html con una línea como la siguiente:

<meta http-equiv="refresh" content="0;url=https://www.pato.com">

Esto hará que el usuario en su navegador especifique http://www.pato.com, es decir dirigido al puerto 80 y es cachado por la página index.html con el código que redirige al mismo servidor pero a https, es decir, puerto 443 y es donde entra en función el servidor virtual que a la vez redirige a /var/www/consulta donde se inicia la apliación de consulta o lo que se tenga. Pero lo interesante es que no hay necesidad de indicarle al usuario que indique https en el url. Para estás alturas ya sabes que al usuario le aparecerá un diálogo pidiéndole que acepte el certificado de la empresa Pato, S.A.

Distribuir el certificado raíz CA

Como ya había mencionado antes, si quieres evitar que a tus clientes cada vez que ingresen a tu sitio salga el molesto diálogo que pide aceptar el certificado, la única solución es que distribuyas el archivo cacert.pem, recuerda que este archivo es el que te identifica como una autoridad certificadora. Lo puedes poner a descarga desde tu propio sitio, o mandarlo por correo, como sea. Cuando el cliente lo tenga en su equipo deberá importarlo dentro del browser o navegador. Todos los navegadores en sus preferencias o herramientas tienen una opción de certificados y desde ahí existe un botón importar para realizar esto.

Pues eso es todo, si todo funcionó bien, tienes ahora un sitio con encriptación de extremo a extremo y todo el tráfico viaja seguro, haciéndoles la vida mas difcil a los hackers de sombrero negro (black hat) que abundan por ahí. Suerte y por favor contáctame si tienes problemas, en la medida de lo posible te ayudaré.


Referencias

Buena parte de esta guía la tomé de los siguientes sitios:

  • http://www.eclectica.ca/howto/ssl-cert-howto.php
  • http://www.technoids.org/openssl.cnf.html
  • http://www.squarebox.co.uk/cgi-squarebox/manServer/usr/share/man/man1/ca.1ssl
  • http://www.openssl.org

Y también de las mismas páginas del manual:

#> man openssl
#> man req
#> man ca
#> man x509

LinuxTotal en:

Si encuentras útil la información que proveé LinuxTotal, considera realizar un donativo que estimule a seguir proporcionando contenido de calidad y utilidad. Gracias.

Más artículos de LinuxTotal

En el artículo de LinuxTotal.com.mx sobre permisos se explica lo que es un archivo con permisos SUID o SGID, pueden ser potencial....


Cuando tu creas un documento de texto en MSDOS/Windows (como por ejemplo en notepad.exe), Windows añade al final de cada línea u....


De acuerdo a la definición en wikipedia un rootkit es una herramienta, o un grupo de ellas que tiene como finalidad esconderse a ....


Linux ofrece multitud de servicios o servidores, estos pueden iniciar o arrancar junto con la carga del sistema o pueden después ....


Muchos validadores de direcciones de correo electrónico devolverán errores cuando se enfrenten con una inusual pero válida dire....


La más simple definición de un proceso podría ser que es una instancia de un programa en ejecución (corriendo). A los procesos....


Aqui, traté de enviar un archivo ejecutable (notepad.exe) a través de gmail, y sus mecanismos de seguridad me lo impidieron. Gma....


La siguiente combinación de comandos te permite extraer los 10 comandos más usados directamente del historial (comando history) ....


Una tarea administrativa algo común, es eventualmente tener que añadir un nuevo disco duro (IDE) al o a los que ya se tienen, de....


En ambientes donde varios usuarios usan uno o más sistemas GNU/Linux, es necesario otorgar distintos permisos o privilegios para ....



Copyright © LinuxTotal.com.mx 2006-2017
info@linuxtotal.com.mx · linuxtotal.com.mx@gmail.com