Apache reescribe cualquier subdominio excepto uno en https que no sea www.

Jan 30 2020

Estoy tratando de reducir la cantidad de encadenamiento de redireccionamiento 301 en mi servidor, por lo que me gustaría combinar un subdominio con un redireccionamiento que no sea www (excepto donde está el subdominio dev) con un redireccionamiento de HTTP a HTTPS (usando %{HTTP:X-Forwarded-Proto}) ya que la instancia está detrás un equilibrador de carga.

Esto es lo que tengo hasta ahora en mi .htaccess:

# move http to https 
RewriteCond %{HTTP:X-Forwarded-Proto} =http
RewriteRule .* https://%{HTTP:Host}%{REQUEST_URI} [L,R=301]

# Remove leading www 
RewriteCond %{HTTP_HOST} ^www.example.net [NC]
RewriteRule ^(.*)$ https://example.net/$1 [R=301,L]

Hay tres problemas con mi implementación actual:

  1. Una solicitud a http://www.example.nettendrá dos redireccionamientos.

  2. Como la mayoría de los ejemplos de redireccionamiento de www a no www en este sitio, no redirigirá ww.o, wwww.por lo tanto, mi análisis tiene muchos subdominios mal escritos que no han sido redirigidos.

  3. Me gustaría excluir el dev.subdominio de la redirección, así http://dev.example.netcomo su httpshermano, como lo uso dev.para el desarrollo y la puesta en escena.

¿Cómo debo combinar esto?

Respuestas

1 MrWhite Jan 31 2020 at 05:43

1) Una solicitud a http://www.example.nettendrá dos redireccionamientos.

Esto se puede resolver simplemente invirtiendo las dos reglas. Luego www.example.netse redirige a HTTPS en la primera redirección, por lo que no es necesario que se active la redirección de HTTP a HTTPS.

(Sin embargo, esto supone que no tiene intención de implementar HSTS , en cuyo caso deberá mantenerlos como dos redireccionamientos, ya que el redireccionamiento a HTTPS en el mismo nombre de host primero es un requisito).

2) Como la mayoría de los ejemplos de redireccionamiento de www a no www en este sitio, no redireccionará ww.o, wwww.por lo tanto, mi análisis tiene muchos subdominios mal escritos que no han sido redirigidos.

Por lo general, las solicitudes ww.o wwww.subdominios simplemente no se resuelven, por lo que normalmente no es un problema. Para que esto funcione, debe haber configurado un subdominio comodín en DNS y configurado el servidor para aceptar tales solicitudes.

Pero esto se puede explicar modificando la expresión regular (fragmento) de ^www\.a ^w{2,4}\..

3) Me gustaría excluir el dev.subdominio de la redirección, así http://dev.example.netcomo su httpshermano, como lo uso dev.para el desarrollo y la puesta en escena.

Esto solo se aplica a la regla HTTP a HTTPS, por lo que se puede aplicar una condición adicional aquí para excluir los nombres de host que comienzan dev..

Juntando los puntos anteriores, intente lo siguiente:

# Remove leading ww, www or wwww (and redirect to HTTPS)
RewriteCond %{HTTP_HOST} ^w{2,4}\.example\.net [NC]
RewriteRule (.*) https://example.net/$1 [R=301,L]

# Move http to https (except dev subdomain)
RewriteCond %{HTTP:Host} !^dev\. [NC]
RewriteCond %{HTTP:X-Forwarded-Proto} =http
RewriteRule ^ https://%{HTTP:Host}%{REQUEST_URI} [R=301,L]

He mantenido su uso del HTTP:Hostmismo (para acceder al Hostencabezado de la solicitud HTTP) en caso de que esto sea un requisito del balanceador de carga. De lo contrario, es más común usar HTTP_HOSTaquí la variable de servidor.

El !prefijo en el CondPattern (es decir. !^dev\.) Niega la expresión regular, por lo que la condición es exitosa cuando el Hostqué no empezar con dev.. (¿Asumo www.dev.que no es una cosa?)

(.*)es lo mismo que ^(.*)$ya que la expresión regular es codiciosa por defecto.

Deberá borrar la memoria caché de su navegador antes de realizar la prueba. Es aconsejable probar primero con redirecciones 302 (temporales) para evitar problemas de almacenamiento en caché.

2 Jin-ohKang Jan 31 2020 at 05:52
# Remove leading www, always using https regardless of the current URL scheme
RewriteCond %{HTTP_HOST} ^w{2,4}.example.net(?::|$) [NC,NV] RewriteRule .* https://example.net%{REQUEST_URI} [L,R=301] # move http to https, except for dev.example.net RewriteCond %{HTTP:X-Forwarded-Proto} =http [NC,NV] RewriteCond %{HTTP_HOST} !^dev.example.net(?::|$) [NC,NV]
RewriteRule .* https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
  1. Se agregó la bandera NC( nocase) a la X-Forwarded-Protocondición, ya que su valor parecía no tener importancia entre mayúsculas y minúsculas, es decir HTTP = Http = hTTp = http. Eres libre de eliminar esto.
  2. Se agregó la bandera NV( novary) a la X-Forwarded-Protocondición para ocultarla del Varyencabezado de respuesta. Una vez más, usted es libre de eliminar esta sobre todo si no es el caso (el proxy inverso filtra automáticamente por usted de todos modos antes de enviarlo al cliente) o necesarios para el comportamiento Cacheing correcta (la caché de otro modo no se distinguen httpy httpscontenido).
  3. Se agregó el indicador NV( novary) a la Hostcondición del encabezado para ocultarlo del Varyencabezado de respuesta. También puede eliminar esto si tiene un servidor de caché roto.
  4. Hizo que el RewriteRuleorden de las banderas sea consistente ( L,R=301y R=301,Lson esencialmente iguales).
  5. Evitado www.example.net.but.not.actually.yours.comde ser reconocido, pero aún permite, por ejemplo www.example.net:443.
  6. Úselo constantemente %{REQUEST_URI}como sustitución.
  7. También reconozca wwy wwww.