Cómo redirigir peticiones de HTTP a HTTPS en Nginx, Apache, Tomcat, Jetty y WildFly

Escrito por el .
planeta-codigo seguridad software software-libre web
Enlace permanente Comentarios

Usar el protocolo seguro HTTPS proporciona confidencialidad en la comunicación entre el navegador del usuario y el servidor, es una forma de mejorar la seguridad y privacidad. Por ello el buscador de Google lo tiene en cuenta como un parámetro que afecta al SEO siendo mejor usar el protocolo seguro. Sin embargo, el usuario puede estar accediendo por el protocolo no seguro a la página web al poner la dirección en la barra de direcciones o hay enlaces hacia nuestro sitio en otros que hacen uso del protocolo HTTP. Si queremos que nuestro sitio sea accedido únicamente usando el protocolo seguro deberemos hacer una redirección en el servidor.

Nginx

Apache HTTPD

Si tenemos una aplicación o una bitácora que hasta el momento era accedido por el protocolo no cifrado HTTP ahora que Google tiene en cuenta para el SEO que usar el protocolo seguro es un parámetro que tiene en cuenta el algoritmo de posicionamiento en el buscador quizá queramos redirigir todo el tráfico de HTTP al protocolo cifrado HTTPS.

Para usar HTTPS deberemos primero configurar el protocolo TLS/SSL en el servidor web o de aplicaciones usando un certificado SSL que podemos obtener ahora con Let’s Encrypt de forma gratuita o generar un certificado nosotros y que sea firmado por una autoridad de confianza. Una vez que el servidor es capaz de servir el tráfico por el protocolo HTTPS estamos en condiciones de realizar la redirección al protocolo cifrado HTTPS en el puerto 443 cuando sea accedido por el protocolo no cifrado HTTP en el puerto 80.

Dependiendo del servidor web o de aplicaciones que usemos la configuración será distinta, incluso lo podemos hacer a nivel de aplicación con la ayuda del framework web si este ofrece algún soporte para ello. A continuación incluiré la configuración necesaria para los servidores web y de aplicaciones más populares como son Nginx, Apache HTTPD, Tomcat, Jetty y WildFly y finalmente el caso haciendo la redirección a nivel de aplicación con el framework Apache Tapestry para desarrollar aplicaciones web con el lenguaje Java.

Redirigir de HTTP a HTTPS en Nginx

Usando Docker nos resultará más sencillo hacer la prueba que teniendo que instalar el paquete de Nginx en nuestra distribución. Puedes consultar varios artículos sobre Docker que he escrito a modo introducción y para empezar a usarlo.

En la sección del servidor que escucha en el puerto HTTP (80) realizamos la redirección permanente con el código de estado 301 hacia el protocolo HTTPS. En la sección del servidor que escucha en el puerto HTTPS (443) activa el uso de TLS/SSL usando varias directivas y sirve los documentos de /usr/share/nginx/html en la ruta /.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
server {
    listen       80;
    server_name  localhost;

    return 301 https://$host$request_uri;
}

server {
    listen       443 ssl;
    server_name  localhost;

    ssl_certificate      localhost.pem;
    ssl_certificate_key  localhost.key;

    ssl_session_timeout  5m;

    ssl_protocols  SSLv2 SSLv3 TLSv1;
    ssl_ciphers  HIGH:!aNULL:!MD5;
    ssl_prefer_server_ciphers   on;

    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
    }
}
nginx.conf
1
2
$ docker run --rm --name nginx -p 80:80 -p 443:443 -v `pwd`/nginx.conf:/etc/nginx/conf.d/default.conf:ro -v `pwd`/localhost.key:/etc/nginx/localhost.key:ro -v `pwd`/localhost.pem:/etc/nginx/localhost.pem:ro nginx

docker-nginx.sh

Redirección de HTTP a HTTPS en Nginx

Redirección de HTTP a HTTPS en Nginx

Redirigir de HTTP a HTTPS en Apache HTTPD

La configuración para Apache HTTPD es similar simplemente cambian las directivas según su propia configuración. Se activan los módulos para usar TLS/SSL y el que permite hacer reescrituras de las URL.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
...

LoadModule ssl_module modules/mod_ssl.so
LoadModule rewrite_module modules/mod_rewrite.so

...

<VirtualHost *:80>
   ServerName localhost
   RewriteEngine On
   RewriteCond %{HTTPS} off
   RewriteRule (.*) https://%{SERVER_NAME}$1 [R,L] 
</VirtualHost>

<VirtualHost *:443>
   ServerName localhost
   DocumentRoot /usr/local/apache2/htdocs
   SSLEngine On
   SSLCertificateFile conf/localhost.crt
   SSLCertificateKeyFile conf/localhost.key
</VirtualHost>
httpd.conf
1
2
$ docker run --rm --name apache -p 80:80 -p 443:443 -v `pwd`/httpd.conf:/usr/local/apache2/conf/httpd.conf:ro -v `pwd`/localhost.key:/usr/local/apache2/conf/localhost.key:ro -v `pwd`/localhost.crt:/usr/local/apache2/conf/localhost.crt:ro httpd

docker-httpd.sh

Redirección de HTTP a HTTPS en Apache HTTPD

Redirección de HTTP a HTTPS en Apache HTTPD

Redirigir de HTTP a HTTPS en Tomcat, Jetty y WildFly

Es muy habitual que los servidores de aplicaciones como Tomcat, Jetty o WildFly sean accedidos no directamente por el navegador del usuario sino a través de un servidor web como Nginx o Apache haciendo de proxy. Cuando hay un servidor web que actúa de proxy para el servidor de aplicaciones es posible decidir que el establecimiento de la conexión cifrada TLS/SSL del protocolo HTTPS se realice en el servidor web y la comunicación cifrada termine al mismo tiempo en él, la comunicación entre el servidor web y el servidor de aplicaciones se realizaría usando el protocolo HTTP. Esto descarga del servidor de aplicaciones la tarea algo costosa del establecimiento de la conexión cifrada y tener que cifrar el tráfico.

Para el caso de Tomcat, Jetty y WildFly habiendo configurado la posibilidad de usar el protocolo seguro la configuración para hacer la redirección es la misma para los tres, habría que añadir al archivo descriptor web.xml de la aplicación el siguiente fragmento XML. Esto hace que el servidor fuerce la conexión segura para los recursos indicados, en este caso todos al usar el patrón /*.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
...
<security-constraint>
  <web-resource-collection>
	<web-resource-name>Confidential URLs</web-resource-name>
	<url-pattern>/*</url-pattern>
  </web-resource-collection>
  <user-data-constraint>
	<transport-guarantee>CONFIDENTIAL</transport-guarantee>
  </user-data-constraint>
</security-constraint>
...
web.xml

Redirigir de HTTP a HTTPS en en una aplicación Java

Con algún mecanismo propio que empleemos al programar la aplicación (en Java por ejemplo con un filtro) o el framework web que usemos para desarrollar la aplicación web quizá nos ofrezca algún mecanismo para redirigir las peticiones al puerto seguro cuando sea accedida por el puerto inseguro, por ejemplo, para que la redirección la haga la aplicación en vez del servidor con el framework Apache Tapestry basta añadir la siguiente configuración en el módulo de la aplicación.

1
2
3
public void contributeMetaDataLocator(MappedConfiguration<String,String> configuration) {
	configuration.add(MetaDataConstants.SECURE_PAGE, "true");
}
AppModule.java
Terminal

El código fuente completo del ejemplo puedes descargarlo del repositorio de ejemplos de Blog Bitix alojado en GitHub y probarlo en tu equipo ejecutando siguiente comando:
./docker-nginx.sh o ./docker-httpd.sh


Comparte el artículo: