Cómo: Redirigir HTTP a HTTPS en Apache

Con la popularización del uso de certificados digitales (SSL/TLS) en los sitios web, en buena parte gracias iniciativas como las de Let’s Encrypt; es cada vez más frecuente la necesidad de redirigir el tráfico hacia HTTPS, una vez que se ha implementado el certificado en un sitio. Esto se lo puede hacer de múltiples formas, dependiendo entre otras cosas del servidor web que usemos. En este caso revisamos cómo hacerlo en un Apache (httpd).

Mediante hosts virtuales (con redirect).

Cuando se ha implementado SSL, lo más común es que se haya creado un nuevo VirtualHost para atender por el puerto 443, además del que ya existía previamente por el puerto 80. De ser así, se podría usar la directiva Redirect para redirigir el tráfico del sitio no seguro al seguro:

NameVirtualHost *:80
<VirtualHost *:80>
  ServerName sitio.ejemplo.com
  DocumentRoot /var/www/html
  Redirect /seguro https://sitio.ejemplo.com/seguro
</VirtualHost>

<VirtualHost _default_:443>
  ServerName sitio.ejemplo.com
  DocumentRoot /var/www/html
  SSLEngine On
#  etc...
</VirtualHost>

En este caso se redirige una ruta específica (/seguro) hacia la versión con SSL. Si lo que se desea es redirigir todo el tráfico hacia la versión segura, se podría hacer lo siguiente, nótese que ni siquiera se requiere el DocumentRoot en este caso:

NameVirtualHost *:80
<VirtualHost *:80>
  ServerName sitio.ejemplo.com
  Redirect / https://sitio.ejemplo.com/
</VirtualHost>

<VirtualHost _default_:443>
  ServerName sitio.ejemplo.com
  DocumentRoot /var/www/html
  SSLEngine On
#  etc...
</VirtualHost>

Si el cambio fue efectivo y decidimos que el cambio será permanente, se podría evitar problemas de caching en los navegadores así:

Redirect permanent / https://sitio.ejemplo.com/

Usando archivos .htaccess con redirect.

En ocasiones no se tiene acceso a reconfigurar el host virtual, en cuyo caso se podría poner un archivo .htaccess, por ejemplo:

Redirect /login https://sitio.ejemplo.com/login

Usando mod_rewrite.

Hay que partir indicando que el uso de mod_rewrite no es el método recomendado para estos casos y debería preferirse los métodos descritos anteriormente. Sin embargo, así es como se implementaría:

RewriteEngine On
# Con esto validamos que la conexión no es ya HTTPS
RewriteCond %{HTTPS} !=on

# Esto redirigirá a los usuarios de su ubicación original, a la misma ubicación, pero usando HTTPS.
# El slash por delante es opcional para que esto pueda funcionar tanto en httpd.conf y .htaccess
RewriteRule ^/?(.*) https://%{SERVER_NAME}/$1 [R,L]

Para especificar el redireccionamiento para un directorio específico:

RewriteEngine On

RewriteCond %{HTTPS} !=on

# De esta forma no forzamos a usar HTTPS para todos los directorios, sino sólo una sección del sitio.
RewriteRule ^/?secure/(.*) https://%{SERVER_NAME}/secure/$1 [R,L]