Fecha: 2017-05-29 Tiempo de lectura: 6 minutos Categoría: Sistemas Tags: easyrsa / openssl / ssl / 2 way ssl / certificado
Ya vimos en otro artículo como restringir los accesos a una web usando certificados SSL. Sin embargo, la generación de los mismos era un poco confusa. Sin embargo, existe una herramienta llamada easyrsa que nos permite generar peticiones de forma fácil, firmarlas con nuestra CA y obtener el producto final.
Vamos a intentar seguir los pasos del citado artículo, solo en la parte de generación de los certificados. Si no se necesitara, se puede obviar la parte del certificado cliente, o porque no, generar certificados para decenas o cientos de usuarios de forma fácil.
Vamos a partir de una distribución Alpine Linux. Para los que no lo sospechen ya es un contenedor Docker por la facilidad de crearlo y de destruirlo al acabar el artículo. Además, esta distribución nos ofrece la herramienta en la versión 3, que me ha parecido más intuitiva que la versión anterior. Asumo también que se dispone del paquete easy-rsa, que se puede instalar con apk add easy-rsa
.
lo primero para hacer una CA es copiar la estructura base a cualquier sitio. La idea es que tenemos una copia para cada CA que tengamos en el servidor, y no quiero trabajar en las carpetas de sistema para no destruir la plantilla.
rsa:~# cp -R /usr/share/easy-rsa/* .
rsa:~#
Otro paso necesario es inicializar las estructura de PKI, que básicamente es crear un esqueleto de carpetas para contener nuestros ficheros.
rsa:~# easyrsa init-pki
init-pki complete; you may now create a CA or requests.
Your newly created PKI dir is: /root/pki
rsa:~#
Finalmente creamos los certificados y claves necesarios para la CA con un simple comando único.
rsa:~# easyrsa build-ca
Generating a 2048 bit RSA private key
........................+++
...............................................+++
writing new private key to '/root/pki/private/ca.key.XXXXPPMHOb'
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.
-----
Common Name (eg: your user, host, or server name) [Easy-RSA CA]:
CA creation complete and you may now import and sign cert requests.
Your new CA certificate file for publishing is at:
/root/pki/ca.crt
rsa:~#
El resultado que deberemos exportar a nuestro servidor es el certificado de la CA, cuya localización es /root/pki/ca.crt.
Este paso se debe repetir tantas veces como servidores queramos que utilicen un certificado SSL. De momento, nos basta con uno. Además, lo vamos a crear sin contraseña porque no queremos tener que introducirla cada vez que se reinicie el servidor.
rsa:~# easyrsa gen-req private nopass
Generating a 2048 bit RSA private key
......................................................+++
.+++
writing new private key to '/root/pki/private/private.key.XXXXhfGNmO'
-----
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.
-----
Common Name (eg: your user, host, or server name) [private]:
Keypair and certificate request completed. Your files are:
req: /root/pki/reqs/private.req
key: /root/pki/private/private.key
rsa:~#
IMPORTANTE: el Common Name es el parámetro mas importante; debe coincidir con el dominio para que se dé por bueno.
Lo firmamos con nuestra CA y ya habremos acabado.
rsa:~# easyrsa sign-req server private
You are about to sign the following certificate.
Please check over the details shown below for accuracy. Note that this request
has not been cryptographically verified. Please be sure it came from a trusted
source or that you have verified the request checksum with the sender.
Request subject, to be signed as a server certificate for 3650 days:
subject=
commonName = private
Type the word 'yes' to continue, or any other input to abort.
Confirm request details: yes
Using configuration from /root/openssl-1.0.cnf
Enter pass phrase for /root/pki/private/ca.key:
Check that the request matches the signature
Signature ok
The Subject's Distinguished Name is as follows
commonName :ASN.1 12:'private'
Certificate is to be certified until Nov 9 11:24:39 2026 GMT (3650 days)
Write out database with 1 new entries
Data Base Updated
Certificate created at: /root/pki/issued/private.crt
rsa:~#
Vamos a necesitar los ficheros /root/pki/private/private.key y /root/pki/private/private.crt para ponerlos en nuestro servidor, juntamente con el certificado de la CA.
Se trata de la misma filosofía; generamos una request, la firmamos y finalmente la vamos a empaquetar en un fichero .p12 para su fácil y segura distribución.
Repetimos la generación de la request de la misma manera:
rsa:~# easyrsa gen-req gerard
Generating a 2048 bit RSA private key
............................................+++
...........+++
writing new private key to '/root/pki/private/gerard.key.XXXXfHJDkE'
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.
-----
Common Name (eg: your user, host, or server name) [gerard]:
Keypair and certificate request completed. Your files are:
req: /root/pki/reqs/gerard.req
key: /root/pki/private/gerard.key
rsa:~#
Firmamos la petición. Es especialmente importante el parámetro client, ya que sino, no va a funcionar.
rsa:~# easyrsa sign-req client gerard
You are about to sign the following certificate.
Please check over the details shown below for accuracy. Note that this request
has not been cryptographically verified. Please be sure it came from a trusted
source or that you have verified the request checksum with the sender.
Request subject, to be signed as a client certificate for 3650 days:
subject=
commonName = gerard
Type the word 'yes' to continue, or any other input to abort.
Confirm request details: yes
Using configuration from /root/openssl-1.0.cnf
Enter pass phrase for /root/pki/private/ca.key:
Check that the request matches the signature
Signature ok
The Subject's Distinguished Name is as follows
commonName :ASN.1 12:'gerard'
Certificate is to be certified until Nov 9 11:42:10 2026 GMT (3650 days)
Write out database with 1 new entries
Data Base Updated
Certificate created at: /root/pki/issued/gerard.crt
rsa:~#
Finalmente tenemos los ficheros gerard.key y gerard.crt, que no son lo que solemos importar en nuestro navegador. Para ellos lo empaquetamos en un fichero gerard.12 que está protegido por contraseña y es el que deberá importar el usuario de nuestra web.
rsa:~# openssl pkcs12 -export -in pki/issued/gerard.crt -inkey pki/private/gerard.key -out gerard.p12
Enter pass phrase for pki/private/gerard.key:
Enter Export Password:
Verifying - Enter Export Password:
rsa:~#
Tenemos 3 ficheros para nuestro servidor, que son ca.crt, server.crt y server.key, con los que podemos montar un dominio estándar, como en el artículo citado.
root@server:~# cat /etc/nginx/sites-enabled/private.linuxsysadmin.tk
server {
listen 443 ssl;
server_name private;
root /srv/www;
ssl_certificate /etc/ssl/certs/server.crt;
ssl_certificate_key /etc/ssl/private/server.key;
ssl_client_certificate /etc/ssl/certs/ca.crt;
ssl_verify_client on;
}
root@server:~#
Y suponiendo que el cliente ha importado su clave con éxito, ya tenemos el dominio montado.