in Let's Encrypt NginX ~ read.

Let's Encrypt + Nginx: Comunicación segura

Muchas veces ni nos damos cuenta de como nuestra privacidad es violada, y mas ahora que gracias a Internet nuestra información viaja por medios que escapan a nuestro control. Por lo que poder cifrar esa información mientras se trasmite, debería estar al alcance de cualquiera. Pero no es así, parece ser que para algunos la privacidad es mas un privilegio que un derecho.

Facilitar la visitas a páginas webs de forma segura, en parte, esta en manos de aquellos que las sirven. Es decir, los que tenemos algún tipo de web, ya sea tienda online, blog o cualquier otro servicio mediante http, deberíamos facilitar que nuestros visitantes pudiesen cifrar la comunicación entre sus dispositivos y nuestras webs. Para ello se deberían implantar certificados SSL en ellas, y de este modo se habilitaría el cifrado de la comunicación.

Por parte del visitante solamente tendría que poner HTTPS en vez de HTTP a la hora de entrar en esa página de noticia, tienda online u otro servicio basado en la web.

Poniendo esa S de mas, lo que se consigue es que, la comunicación entre el servidor web y el dispositivo solicitante de la web este cifrada. Pero para ello es necesario que la parte del servidor tenga un certificado SSL, cosa que asta hace poco te obligaba a pasar por caja, ya que para hacerse con uno tenias que dejar un pastizal. La alternativa barata consistía en crear tus propios certificados, pero ninguna aplicación la daría por valida ya que no esta emitida por ninguna entidad certificadora.

Así que para facilitar el cifrado de las comunicaciones deberías de comprar un certificado a aquellas empresas emisoras que te los venden por un ojo de la cara. Asta que llego Let's Encrypt.

La EFF presento Let's Encrypt para evitar tener que pasar por caja y así facilitar a que cualquiera pudiese hacerse con un certificado respaldado, totalmente gratis. En estos momentos están en beta publica por lo que podemos obtener nuestros certificados de forma gratuita, cosa que asta hace poco era algo impensable.

Animo a todo aquel que tenga un servicio basado en la web, que se haga con un certificado de Let's Encrypt y así facilite el cifrado de la comunicación entre sus visitante y sus webs. A continuación encontrareis los pasos para haceros con un certificado y como implantarlo en un servidor web Nginx bajo Debian 8 Jessie.

Obtener un certificado con Let's Encrypt

Para hacernos con uno, antes de nada deberemos hacernos con un cliente que nos facilitara la solicitud del mismo. Pero antes de nada deberemos liberar el puerto 80 del servidor, ya que el cliente de Let's Encrypt hará uso del el. Por lo que, si tenéis nginx o cualquier otro servidor web a la escucha en ese puerto, tendréis que pararlo. En mi caso tengo nginx por lo que paro el servicio:

sudo service ghost stop  

Tampoco olvidaros de habilitar el puerto 443 en el firewall, si es que lo tenéis habilitado, ya que se usará para las comunicaciones cifradas mediante HTTPS:

sudo ufw allow 443  

Ahora que esta todo bien preparado, ya podemos clonar el cliente oficial de Let's Encrypt desde GitHub para hacernos con el certificado:

git clone https://github.com/letsencrypt/letsencrypt  
cd letsencrypt  

Con permisos de administrador o haciendo uso de sudo, ejecutamos el cliente:

sudo ./letsencrypt-auto certonly  

Nos aparecerá un asistente que nos guiara en el proceso.

Primero nos pedirá que metamos nuestra dirección de mail. Poner alguna que utilicéis realmente, ya que para la renovación del certificado o cualquier otra gestión se tramitara mediante esta dirección de mail.

let's encrypt mail

A continuación nos propone leer los términos del servicio y aceptarlos.

let's encrypt terms of service

Por ultimo tendremos que introducir el dominio de nuestra web. Si tenemos varios sub-dominios y queremos hacer uso del mimo certificado, bastaría con ponerlos separados con un espacio.

let's encrypt domains

El asistente terminara indicándonos que los certificados ya han sido creados y donde quedarán almacenados:

IMPORTANT NOTES:  
 - Congratulations! Your certificate and chain have been saved at
   /etc/letsencrypt/live/dominio.com/fullchain.pem. Your cert will expire
   on 2016-04-25. To obtain a new version of the certificate in the
   future, simply run Let's Encrypt again.

Por lo que se puede leer, los certificados estarán almacenados en /etc/letsencrypt/live/dominio.com/ y estos expiraran el 25/04/2016. Por lo tendremos que renovar antes de esa fecha, pero antes de que eso pase nos enviaran un correa la cuenta de mail que hemos puesto en el asistente.

Configurar Nginx

Ahora ya tenemos los certificados y solo nos hace falta indicarle a nginx donde están. Nos dirigimos a la carpeta de configuration de nginx /etc/nginx/sites-available/ y abrimos el archivo de configuration de la web que estemos sirviendo, en mi caso el archivo es ghost.blog:

cd /etc/nginx/sites-available/  
nano ghost.blog  

Ahora deberíamos modificar el archivo para que quede como a continuación. Salvo aquellos apartados como puede ser el dominio.com o algún otro parámetro personalizado.

server {  
       listen 80;
       server_name fortu.io www.fortu.io;
       return 301 https://$server_name$request_uri;
}

server {  
    listen 443 ssl spdy;
    server_name dominio.com www.dominio.com;
    ssl_certificate /etc/letsencrypt/live/dominio.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/dominio.com/privkey.pem;
    ssl_session_timeout 1d;
    ssl_session_cache shared:SSL:50m;
    ssl_session_tickets off;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SH$
    ssl_prefer_server_ciphers on;

    # HSTS (ngx_http_headers_module is required) (15768000 seconds = 6 months)
    add_header Strict-Transport-Security max-age=15768000;

    # OCSP Stapling ---
    # fetch OCSP records from URL in ssl_certificate and cache them
    ssl_stapling on;
    ssl_stapling_verify on;

    error_log /var/log/nginx/ghost.log crit;
    access_log off;
    location / {
        proxy_set_header   X-Real-IP $remote_addr;
        proxy_set_header   Host      $http_host;
        proxy_pass         http://0.0.0.0:3000;
    }
}

Con en el primer bloque server se indica es que, toda aquella petición al puerto 80, es decir peticiones HTTP, se redirecione al puerto 443. Forzando de esta manera forzamos el uso de HTTPS, ya que ese puerto esta configurado con el segundo bloque server que contiene la configuración con nuestros certificados.

Por ultimo deberemos reiniciar nginx para que los cambios que hemos efectuado se apliquen.

sudo service nginx restart  

Ahora si accedemos a nuestra web mediante http://dominio.com seremos redireccionados a https://dominio.com. De esta manera tanto si ponemos la S o no en la url, seremos forzados a utilizar una comunicación cifrada entre nuestro dispositivo y el servidor de la web. una vez dentro si os fijáis en la url podréis ver un candado, esto es un indicador de que la comunicación esta siendo cifrada.

fortu.io certificate

Este es mi primer contacto con los certificados. Todavía tengo mucho que aprender, pero gracias a Let's Encrypt y a un montón de manuales que me he encontrado12 por la red, he tenido la oportunidad de hacer un poco mas privada nuestras comunicaciones.

Para efectuar este post se han tomado datos de las siguientes webs:

comments powered by Disqus