Apache: solicitação insegura enviada para proteger a porta… deseja redirecionar

9

Prefácio

Em primeiro lugar: A simples porta 80 - > Port 443 Reescreva NÃO conserte isso. Em quase todas as questões anteriores, discussão de e-mail, discussão em fóruns, etc., descobri que esta foi a primeira resposta ignorante e foi repetida várias vezes.

Em segundo lugar: Sim, eu sei que você não pode veicular o tráfego HTTP e HTTPS na mesma porta. Isto não é isso.

cenário:

Servidor Apache hospedando vários sites através da multiplicação de portas. Port 80 serve um site público. A porta 443 serve a versão segura desse site.

As portas 7443, 8443 e 9443 servem sites separados por SSL.

Se um usuário digitar incorretamente o URL ou receber um link que não seja válido, diga link , eles receberão o seguinte ridículo página:

Emvezdeoservidorapenasredirecioná-losparao link .

Minha pergunta é: como, em nome de cunhada de Zeus , você pode modificar o comportamento do Apache ou esse erro? mensagem para redirecionar o usuário automagicamente?

O Apache obviamente está atendendo a uma solicitação não https (para exibir essa mensagem de erro), embora esteja configurada para HTTPS. Parece incrivelmente estúpido para mim não apenas fazer o redirecionamento por padrão, mas eu posso entender por que eles foram com o comportamento que fizeram, mesmo que eu não concorde com isso. Então minha pergunta é: você pode mudar isso? Eles estão lidando com o erro EM ALGUM LUGAR, e com o Apache sendo a cornucópia de configuração que é, é lógico que haja alguma diretiva em algum lugar para lidar com esse comportamento, mas não consegui encontrá-lo em várias horas de ajustes até agora.

Atualização:

Eu tentei várias coisas, incluindo:

  • usando ErrorDocument 400 diretivas para chegar a um CGI e um script PHP que apenas envia Status 301 e Location headers. Isso resulta em uma página em branco. Usar ErrorDocument 400 https://hostname.tld:7443 simplesmente resulta no link sendo exibido na página.

  • Usando praticamente todas as combinações de mod_rewrite I ou Google, incluindo declarações gerais que direcionam o site completamente; estes nunca funcionam. Literalmente, eles não fazem nada. Eu estou supondo que o Apache está chutando o erro acima antes mesmo de tentar processar as diretivas de reescrita.

Não posso usar redirecionamentos baseados em porta, devido ao uso de porta personalizada. Não consigo usar redirecionamentos baseados em script porque eles nunca são exibidos devido à incompatibilidade http / https. Estou quase disposto a descrever isso como um bug, ou um comportamento não intencional, mas alguém teve a premeditação de colocar uma mensagem de erro muito personalizada lá, eles não se incomodaram em pensar que talvez você queira apenas ir até o URL eles já estão fornecendo ?

    
por peelman 09.02.2013 / 23:09

2 respostas

6

Eu acho que este é provavelmente um bug em como o Apache 2.2 e inferior lida com essa circunstância particular.

Parece que em um erro 400 Bad Request de leitura SSL, o Apache 2.2 não retorna o código ou os cabeçalhos de resposta HTTP, apenas o corpo da resposta HTTP. Eu testo por telnet para a porta 443 e enviando:

GET / HTTP/1.1

O servidor retorna imediatamente (para mim):

<!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>

Observe a falta de um código de resposta HTTP ou de qualquer cabeçalho HTTP.

Quando faço isso em um servidor Apache 2.4, recebo:

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>

Se eu configurar uma linha ErrorDocument como você fez:

ErrorDocument 400 https://server.tld/

Depois, recebo o HTML de um redirecionamento 302, mas, novamente, nenhum dos cabeçalhos. Sem o código de resposta de redirecionamento 302 e o cabeçalho Location: , o navegador não redirecionará.

Tente atualizar para o Apache 2.4 e veja se funciona. Eu testei e confirmei com pelo menos o Apache 2.4.3, mas não passei pelo esforço de descobrir exatamente quando esse comportamento foi atualizado. Eu suspeito que na grande quantidade de trabalho que eles fizeram preparando o 2.4, eles corrigiram o comportamento indesejável como um efeito colateral.

Bugs httpd relevantes do Apache:

UPDATE

Você pode forçar um Apache buggy a fornecer o comportamento desejado (o redirecionamento) fazendo com que o script imprima seus cabeçalhos (que não serão enviados ao cliente) e, em seguida, imprima manualmente os cabeçalhos desejados. Aqui está um script Perl básico que funciona sob o 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

Você deve estar ciente de que há outras razões pelas quais um 400 pode ser gerado, além de apenas conversar com uma porta SSL sem SSL. A maneira fácil de determinar isso é procurar a variável de ambiente HTTPS . Se estiver definido, o SSL foi negociado corretamente e outra coisa está causando o 400 (não faça o truque de cabeçalho duplo, se for o caso). Se HTTPS não estiver definido, retorne seu redirecionamento como acima.

    
por 10.02.2013 / 02:05
-1

Você pode corrigir isso com mod-rewrite. Definir uma regra para corresponder a qualquer coisa. Veja esta resposta em Stackoverflow

    
por 09.02.2013 / 23:33