Apache: solicitud insegura enviada al puerto seguro ... desea redirigir

9

Prefacio

En primer lugar: una simple reescritura del puerto 80 -> puerto 443 NO solucionará esto. En casi todas las preguntas anteriores, hilo de correo, hilo de foro, etc., he encontrado que esta fue la primera respuesta ignorante y fue repitió varias veces.

En segundo lugar: sí, sé que no puede servir tráfico HTTP y HTTPS en el mismo puerto. Esto no es eso.

Guión:

Servidor Apache que aloja múltiples sitios a través de la multiplicación de puertos. El puerto 80 sirve un sitio público. El puerto 443 sirve la versión segura de ese sitio.

Los puertos 7443, 8443 y 9443 sirven cada uno a sitios separados con seguridad SSL.

Si un usuario escribe mal la URL, o se le da un enlace que no es válido, por ejemplo http: //hostname.tld: 7443 , se le da la siguiente página ridícula:

Mensaje de error Apache Bad Request

En lugar del servidor, simplemente los redirige a https: //hostname.tld: 7443 .

Mi pregunta es, ¿cómo, en nombre del ano de Zeus, puede modificar el comportamiento de Apache o este mensaje de error para redirigir al usuario automáticamente?

Apache obviamente está atendiendo una solicitud que no es https (para mostrar ese mensaje de error) a pesar de que está configurado para HTTPS. Me parece notablemente tonto no solo hacer la redirección de forma predeterminada, sino que puedo entender por qué siguieron el comportamiento que hicieron, incluso si no estoy de acuerdo. Entonces mi pregunta es: ¿puedes cambiarlo? Están manejando el error EN ALGÚN LUGAR, y con Apache siendo la cornucopia de configuración que es, es lógico que haya alguna directiva en algún lugar para manejar este comportamiento, pero hasta ahora no he podido encontrarlo en varias horas de ajustes.

Actualizar:

He intentado una variedad de cosas que incluyen:

  • usando ErrorDocument 400directivas para llegar a un script CGI y PHP que solo envía Status 301y Locationencabezados. Esto da como resultado una página en blanco. El uso ErrorDocument 400 https://hostname.tld:7443simple da como resultado que ese enlace se muestre en la página.

  • El uso de casi todas las combinaciones de mod_rewriteI o Google puede generar, incluidas las declaraciones generales que dirigen el sitio por completo; Estos nunca funcionan. Literalmente, no hacen nada. Supongo que Apache está pateando el error anterior incluso antes de intentar procesar las directivas de reescritura.

No puedo usar redirecciones basadas en puertos, debido al uso de puertos personalizados. No puedo usar redireccionamientos basados ​​en scripts porque nunca se reciben debido a la falta de coincidencia http / https. Estoy casi dispuesto a atribuir esto a un error o un comportamiento no intencionado, pero alguien tuvo la idea de poner un mensaje de error muy personalizado, no se molestaron en pensar que tal vez querrías simplemente llevarlo al URL que ya están proporcionando ?

pelador
fuente
Daniel: Esa fue una de las muchas preguntas que encontré y las soluciones que intenté antes de publicar esta pregunta. Creo que el problema era el componente PHP, pero como la actualización de la respuesta de @ hrunting está funcionando muy bien para mí en este momento, no voy a dedicar más tiempo del que ya tengo; al menos no hasta que tenga que hacerlo.
peelman
2
voto positivo para el video vinculado, transmite mis emociones perfectamente
michele b

Respuestas:

6

Creo que esto es probablemente un error en cómo Apache 2.2 y versiones anteriores manejan esta circunstancia particular.

Parece que en un 400 Bad Requesterror de lectura SSL , Apache 2.2 no devuelve el código de respuesta HTTP o los encabezados, solo el cuerpo de respuesta HTTP. Pruebo haciendo telnet al puerto 443 y enviando:

GET / HTTP/1.1

El servidor devuelve inmediatamente (para mí):

<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>400 Bad Request</title>
</head><body>
<h1>Bad Request</h1>
<p>Your browser sent a request that this server could not understand.<br />
Reason: You're speaking plain HTTP to an SSL-enabled server port.<br />
Instead use the HTTPS scheme to access this URL, please.<br />
<blockquote>Hint: <a href="https://server.tld/"><b>https://server.tld/</b></a></blockquote></p>
</body></html>

Tenga en cuenta la falta de un código de respuesta HTTP o cualquier encabezado HTTP.

Cuando hago esto en un servidor Apache 2.4, obtengo:

HTTP/1.1 400 Bad Request
Date: Sun, 10 Feb 2013 00:47:23 GMT
Server: Apache/2.4.3 (Unix) OpenSSL/1.0.0g
Content-Length: 462
Connection: close
Content-Type: text/html; charset=iso-8859-1

<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>400 Bad Request</title>
</head><body>
<h1>Bad Request</h1>
<p>Your browser sent a request that this server could not understand.<br />
Reason: You're speaking plain HTTP to an SSL-enabled server port.<br />
Instead use the HTTPS scheme to access this URL, please.<br />
</p>
<hr>
<address>Apache/2.4.3 (Unix) OpenSSL/1.0.0g Server at server.tld Port 443</address>
</body></html>

Si configuro una línea ErrorDocument como lo hiciste:

ErrorDocument 400 https://server.tld/

Luego obtengo el HTML para una redirección 302, pero de nuevo, ninguno de los encabezados. Sin el código de respuesta de redireccionamiento 302 y el Location:encabezado, el navegador no redirigirá.

Intente actualizar a Apache 2.4 y vea si funciona. He probado y confirmado con al menos Apache 2.4.3, pero no me he esforzado por encontrar exactamente cuándo se actualizó este comportamiento. Sospecho que en la gran cantidad de trabajo que hicieron preparando 2.4, corrigieron el comportamiento indeseable como un efecto secundario.

Errores httpd relevantes de Apache:

ACTUALIZAR

Puede forzar un Apache con errores para que le dé el comportamiento que desea (la redirección) haciendo que el script imprima sus encabezados (que no se enviarán al cliente) y luego imprima manualmente los encabezados que desea. Aquí hay un script básico de Perl que funciona bajo Apache 2.2.22:

#!/usr/bin/perl

use strict;
use CGI;

my $q = CGI->new();

# this will cause Apache to handle the response properly, but is meaningless otherwise
print $q->redirect("https://localhost/");

# this actually performs the redirect
print "HTTP/1.1 302 Found\r\n";
print "Location: https://localhost/\r\n";
print "\r\n";

# you can do whatever you want here; this will be the HTML body

Debe tener en cuenta que hay otras razones por las que se puede generar un 400 además de hablar con un puerto SSL sin SSL. La manera fácil de determinar esto es buscar la HTTPSvariable de entorno. Si está configurado, entonces SSL se negoció correctamente y algo más está causando el 400 (no haga el truco de doble encabezado si ese es el caso). Si HTTPSno está configurado, devuelva su redirección como se indicó anteriormente.

cazando
fuente
1
Santo. Mierda. Respuesta perfecta. Gracias
peelman
Sabes, mientras leo esto, pienso: "Hombre, realmente apesta si tienes Apache 2.2 y quieres este tipo de comportamiento de redireccionamiento". No voy a pasar por el esfuerzo de encontrar un deb Apache 2.4 apropiado (o hacer el mío) para mi sistema Ubuntu. Apuesto a que puedes hackear una solución desde tu script PHP. Apache claramente solo está volcando la salida al cliente, así que si devuelve el contenido esperado específico, apuesto a que puede obtener el comportamiento que está buscando sin actualizar Apache. Intente que su script PHP imprima "HTTP / 1.1 302 Found \ r \ nUbicación: server.tld \ r \ n \ r \ n".
cazando
El problema es que no parece que el script PHP se esté procesando. Debo señalar que esto es actual en Apache 2.2.22 en Ubuntu Server 12.04. Y sí, realmente, realmente apesta; especialmente cuando observa que en esos informes de errores, parecen estar completamente en contra de proporcionar incluso una opción para hacer automáticamente la redirección, y no parece haber mucha esperanza de que 2.2 alguna vez obtenga la solución.
peelman
1
Y como dije anteriormente, simplemente no tiene sentido para mí por qué te tomas la molestia de escribir ese mensaje de error, en lugar de redirigir a seguro (en serio, ¿por qué no simplemente redirigir? Cuanto más lo pienso, menos Creo que es una mala idea).
peelman
1
He agotado todo el sistema de archivos buscando el texto de ese mensaje sangriento para ver si puedo de dónde lo están extrayendo, en el caso de que pudiera inyectar una <javascriptetiqueta y tener la suerte de piratear la redirección de esa manera, pero hasta ahora, no dado. Nada de esto parece ser manejados de una manera que sigue lo impresionante de Apache por lo demás bastante rígida ...
Peelman
-1

Puedes arreglar esto con mod-rewrite. Establecer una regla para que coincida con cualquier cosa. Ver esta respuesta en Stackoverflow

Trent
fuente
No, ya lo intenté, no funciona. Es como si ni siquiera llegara a los pasos de ModRewrite porque está llegando primero al desajuste http / https.
peelman
Gestión de recursos humanos, así que supongo que han comenzado desde lo alto de que Apache archivo de configuración y trabajado su camino hacia abajo para ver lo que está llamando
Trent
Prácticamente he memorizado todo el sites-availabledirectorio. Incluso si solo lo redirige a tonterías, o lo redirige a un sitio diferente, a un puerto diferente, etc., sigue cargando esa 400 Solicitud incorrecta.
peelman