.htaccess para reescribir URL Y forzar https

.htaccess para reescribir URL Y forzar https

sitio: ejemplo.com

Subdirectorio de Joomla: ejemplo.com/joomla

Quiero que la instalación de Joomla en example.com/joomla sea (o parezca ser) la raíz del sitio, es decir, las personas que visitan example.com son redirigidas a example.com/joompla/index.php pero aún ven example.com en la barra de URL.También quiero aprovechar esta oportunidad para forzar que todas las conexiones entrantes utilicen HTTPS.. He podido hacer uno u otro utilizando scripts que encontré en línea, pero no ambos con coherencia.

Esto es lo que tengo hasta ahora para .htaccess:

RewriteEngine on
RewriteBase /

# Rewrites all URLS without joomla in them
RewriteCond %{REQUEST_URI} !^/joomla/

# Rewrites all URLS with example in them
RewriteCond %{HTTP_HOST} ^(www\.)?example\.

# Rewrite all those to insert /joomla
RewriteRule ^(.*)$ /joomla/$1 [L]

# This works SOME of the time to redirect to https
Header always set Content-Security-Policy "upgrade-insecure-requests;"

# If a request tries to access /joomla directly, redirect it to its secured canonical version
RewriteCond %{THE_REQUEST} joomla/
RewriteRule ^joomla/(.*) http://example.com/$1 [R=301,L]

Esto parece funcionar algunas veces en Chrome, redirigiendo a la instalación de Joomla y cambiando a https, pero a veces necesito forzar una recarga completa repetidamente para llegar allí. NUNCA funciona en Firefox y permanece en http en las raras ocasiones en que carga el sitio.

Soy muy nuevo en .htaccess y no estoy seguro de haber desarrollado la solución más elegante o completa para el problema anterior. He visto otros ejemplos en línea usando RewriteCond %{HTTPS} !=ono RewriteCond %{SERVER_PORT} 80junto con varios RewriteRulecomandos, pero no estoy seguro de cómo combinar estos comandos con las condiciones de reescritura de URL existentes y, como resultado, estoy seguro de que me estoy perdiendo los escenarios marginales.

¿Alguien con más experiencia puede guiarme a través de esto? Podria ser muy apreciado. He estado probando variaciones de scripts encontrados en línea desde hace unos días, pero no he encontrado las palabras mágicas.

Respuesta1

Algunas notas sobre sus directivas existentes:

ReescribirBase /

Si bien ha definido el RewriteBase, no se utiliza en ninguna de sus directivas. El RewriteBaseúnico se aplica a la ruta relativa.sustituciones(ha utilizado explícitamente una ruta URL relativa a la raíz en las directivas relevantes).

# Rewrites all URLS with example in them
RewriteCond %{HTTP_HOST} ^(www\.)?example\.

necesidadpara verificar el nombre de host solicitado? A menos que esté alojando varios dominios (o subdominios) a los que no desee aplicar esta regla, entonces estocondiciónes superfluo.

# This works SOME of the time to redirect to https
Header always set Content-Security-Policy "upgrade-insecure-requests;"

Estenuncaactiva una "redirección", así que no estoy seguro de lo que estás viendo en el tráfico de la red.

(De hecho, no hay nada en el código que publicó que pueda desencadenar una "redirección" de HTTP a HTTPS).

Este encabezado de respuesta HTTP hace que el navegador "actualice" automáticamente cualquier solicitud derecursos vinculados(CSS, JS, imágenes, recursos externos, etc.) de la respuesta HTML (página) inicial que de otro modo sería a través de HTTP (por ejemplo, porque la URL real contiene http://...) a HTTPS. No se produce ninguna "redirección" real. Y no sucede nada con la respuesta HTML inicial que podría haber sido a través de HTTP simple.

Este encabezado no es estrictamente necesario si ha implementado una redirección HTTP a HTTPS en todo el sitio y todos sus recursos vinculados ya son HTTPS o utilizan una URL relativa a la raíz (o relativa al protocolo). Pero sí proporciona una buena red de seguridad. Sin embargo, tenga en cuenta que cualquier recurso vinculado que no admita HTTPS simplemente se romperá, sin que el navegador advierta al usuario. Sin este encabezado, el usuario potencialmente recibe una advertencia de "contenido mixto" del navegador (y el recurso vinculado falla).

# If a request tries to access /joomla directly, redirect it to its secured canonical version
RewriteCond %{THE_REQUEST} joomla/
RewriteRule ^joomla/(.*) http://example.com/$1 [R=301,L]

La RewriteConddirectiva (utilizada para evitar un bucle de redireccionamiento en "condiciones normales") coincide joomla/en cualquier parte de la URL solicitada, incluso en la cadena de consulta, lo cual es incorrecto y podría resultar en redireccionamientos incorrectos si joomla/aparece en otra parte de la ruta URL o incluso la cadena de consulta. Por ejemplo, esto daría como resultado un bucle de redireccionamiento si simplemente lo agregara ?joomla/al final de cualquier URL.

Este "redireccionamiento" debería desaparecer.anteslas reescrituras internas. En general, las "redirecciones" deben ir antes de las "reescrituras" para evitar redirigir una URL reescrita y exponer la URL reescrita a los usuarios.

Como se indica en los comentarios, esta redirección es a HTTP, lo contrario de lo que está intentando hacer (y dará como resultado una pequeña cadena de redireccionamiento al implementar una redirección de HTTP a HTTPS).

Algunas suposiciones:

  • El certificado SSL se instala directamente en el servidor de aplicaciones, es decir. no hay Cloudflare (Flexible-SSL) u otro proxy front-end que administre el SSL.
  • No estás utilizando ningún otro subdominio. Justo www.
  • El nombre de host canónico no es www, es decir. example.com(de la redirección en su pregunta).
  • No está implementando HSTS en este momento, por lo que puede redirigir a HTTPS y al nombre de host canónico (es decir, example.com) en una sola redirección.
  • El propio Joomla ya se ha configurado para omitir el /joomlasubdirectorio de las URL. /joomlano está presente en ningún enlace interno, incluidos enlaces a recursos estáticos (CSS, JS, imágenes, etc.)
  • No está entregando ningún archivo desde la raíz del documento.Todoes ir al /joomlasubdirectorio.

Escenario n.º 1: un único .htaccessarchivo en la raíz del documento.

(Como se indica en los comentarios).

En este escenario, no hay ningún .htaccessarchivo "Joomla" en el subdirectorio de instalación ( /joomla) al que dirigir sus URL al controlador frontal de Joomla (es decir, index.php). En cuyo caso, index.phpdebe estar presente en la URL y no puede utilizar las URL "SEF" de Joomla.

El /.htaccessarchivo raíz se vería así:

RewriteEngine on

RewriteBase /joomla

# If a request tries to access /joomla directly, redirect it to its secured canonical 
RewriteCond %{THE_REQUEST} ^[A-Z]{3,7}\s/joomla
RewriteRule ^joomla(?:$|/(.*)) https://example.com/$1 [R=302,L]

# Canonicalise the hostname - ie. www to non-www and HTTPS
RewriteCond %{HTTP_HOST} ^www\.(.+?)\.?$ [NC]
RewriteRule ^ https://%1%{REQUEST_URI} [R=302,L]

# Redirect remaining requests from HTTP to HTTPS
# The hostname must already be canonical at this point
RewriteCond %{HTTPS} off
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [R=302,L]

# Rewrite everything to the /joomla subdirectory
# Uses the value defined in the RewriteBase directive above
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule (.*) $1 [L]

# Ensure that any linked resources are requested over HTTPS
Header always set Content-Security-Policy "upgrade-insecure-requests;"

Tenga en cuenta que he utilizado redirecciones 302 (temporales) aquí con fines de prueba. Pruebe siempre primero con redirecciones 302 y solo cambie a 301 (permanente) una vez que se haya confirmado que funciona correctamente. Los 301 se almacenan en caché de forma persistente en el navegador, por lo que las pruebas pueden resultar problemáticas.

La REDIRECT_STATUSvariable de entorno se usa para garantizar que solo reescribamos solicitudes directas y no solicitudes reescritas, de la misma manera que THE_REQUESTse usa en la primera regla. REDIRECT_STATUSestá vacío en la solicitud inicial y se establece en "200" (como en el estado de respuesta HTTP 200 OK) después de la primera reescritura exitosa. La directiva RewriteRule (.*) $1 [L]puede parecer un poco extraña al principio (parece que se reescribe a sí misma), sin embargo, RewriteBasela sustitución resultante tiene el prefijo, por lo que en realidad se reescribe en /joomla/<url>.

Escenario n.º 2: dos .htaccessarchivos: raíz del documento y subdirectorio

El .htaccessarchivo en el /joomlasubdirectorio sería el .htaccessarchivo razonablemente estándar que viene con Joomla. Esto enruta todas las solicitudes al controlador frontal de Joomla (es decir, index.php) y permite el uso de las URL "SEF" de Joomla (es decir, no es necesario incluirlas explícitamente index.phpen la URL).

El /.htaccessarchivo raíz se vería así:

RewriteEngine on

RewriteBase /joomla

# Canonicalise the hostname - ie. www to non-www and HTTPS
RewriteCond %{HTTP_HOST} ^www\.(.+?)\.?$ [NC]
RewriteRule ^ https://%1%{REQUEST_URI} [R=302,L]

# Redirect remaining requests from HTTP to HTTPS
# The hostname must already be canonical at this point
RewriteCond %{HTTPS} off
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [R=302,L]

# Rewrite everything to the /joomla subdirectory
# Uses the value defined in the RewriteBase directive above
RewriteRule (.*) $1 [L]

# Ensure that any linked resources are requested over HTTPS
Header always set Content-Security-Policy "upgrade-insecure-requests;"

Tenga en cuenta que la redirección para eliminar el /joomlasubdirectorio de la URL se eliminó y debe incluirse en el /joomla/.htaccessarchivo. (Sería completamente superfluo dejarlo aquí.)

REDIRECT_STATUSEsta vez no necesita verificar la var env ya que el /joomla/.htaccesstestamentoatraparla solicitud después de haber sido reescrita. (Suponiendo que la herencia mod_rewrite no esté habilitada).

La Headerdirectiva podría trasladarse a /joomla/.htaccesssi así lo desea; esto es opcional ya que se "heredará" de todos modos.

Entonces, el /joomla/.htaccessarchivo contendría algo como lo siguiente:

# JOOMLA: Set Options here

RewriteEngine on

# If a request tries to access here directly then redirect back to root
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule (.*) https://example.com/$1 [R=302,L]

# JOOMLA: Rewrite rules to block out some common exploits.
# :

# Leave the RewriteBase directive commented out - it's not required
#RewriteBase /joomla

## Begin - Joomla! core SEF Section.
RewriteRule ^ - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]

RewriteRule ^index\.php$ - [L]

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^ index.php [L]
## End - Joomla! core SEF Section.

El /joomla/.htaccessarchivo se basa libremente enel código en el sitio web Joomla, sin embargo, omití los elementos/comentarios comunes y cambié la "Sección SEF" para que sea relevante para el subdirectorio. (Joomla también usa una expresión regular menos eficiente .*en lugar de simplemente ^.)

información relacionada