Be a happy coder

You are here

HSTS o como volverse loco por el https

15 Mar 2012

Recientemente hice una adaptación bastante grande a la configuración de nginx en el servidor que tenemos en producción. Tras esa adaptación, que incluía el uso de un certificado SSL para la navegación segura por la web, hice un par de pruebas para comprobar que todo funcionaba correctamente. Oh, perfecto tenemos soporte https, todo funciona correctamente, bien ... un momento, ¿no puedo entrar por http? ¿Que ocurre aquí?

A partir de ese momento, comenzó una dura batalla por recuperar el acceso por http a la página. Reconozco que por desconocimiento, me ha costado mucho descubrir que el problema no estaba realmente en la configuración de nginx, aunque si tenía algo que ver. Veamos que ocurría:

Siempre que intento acceder a la dirección (ficticia) http://www.midominio.net tanto Firefox como Chrome me redirigen siempre a https://www.midominio.net. Obviamente, no tengo configurada dicha redirección y yo he solicitado acceder por http. Entonces, ¿a que se debe esto?

Compruebo las cabeceras que envía el domino, cosa que me deja aun más extrañado puesto que es totalmente correcto:

$ curl -I www.midominio.net
HTTP/1.1 200 OK
Server: nginx
Date: Thu, 15 Mar 2012 11:36:20 GMT
Content-Type: text/html; charset=utf-8
Connection: keep-alive
Keep-Alive: timeout=10
Vary: Accept-Encoding
Expires: Thu, 01 Jan 1970 00:00:01 GMT
Last-Modified: Thu, 15 Mar 2012 13:36:19 GMT
Cache-Control: no-cache

El servidor no indica ninguna redirección y sirve la petición como es de esperar.

El problema estaba en que en mi configuración de nginx, para la parte de https había declarado las siguientes líneas, como protección para el ataque BEAST:

ssl_session_cache shared:SSL:10m;
ssl_session_timeout 5m;
ssl_protocols SSLv3 TLSv1;
ssl_ciphers RC4:HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
add_header Strict-Transport-Security "max-age=2592000; includeSubdomains";

En concreto, la última es la que provoca este comportamiento ya que le estoy indicando al navegador que quiero que utilice siempre la conexión segura, y como los navegadores modernos (como Firefox o Chrome) implementan HSTS, se lo habían tomado bastante en serio. Lo que significa esto es que el navegador, cuando detecta que una página solicita el String-Transport-Security o STS, éste almacena en su caché nuestro dominio y lo marca para acceder siempre por https, mostrando cualquier elemento de la página por https aunque nosotros lo hayamos indicado de otro modo o pongamos en la barra de navegación que queremos acceder por http.

La solución para seguir protegido contra BEAST y no sufrir percibir este comportamiento como tal es dar un tiempo menor a la cabecera:

add_header Strict-Transport-Security "max-age=7200";  #Sólo 2 horas

El navegador también mantendrá una caché sobre los dominios que hicieron la solicitud, pero es posible borrar nuestro dominio para comprobar que el acceso por http es posible. Para Chrome se hace realizando los siguientes pasos:

1) Abrimos una nueva pestaña y vamos a chrome://net-internals/#hsts

2) Desde la opción Delete domain podemos borrar nuestro dominio, y también tenemos la opción Query domain para comprobar si nuestro dominio estaba cacheado y de que forma.

Espero que esto le sea útil a más gente y no pierda el tiempo como yo, dando vueltas a la configuración de nginx :-)

Etiquetas: