Назад | Перейти на главную страницу

Apache: небезопасный запрос отправлен на защищенный порт… требуется перенаправить

Предисловие

Во-первых: просто переписать порт 80 -> порт 443 НЕ БУДУ почини это. Почти в каждом предыдущем вопросе, почтовой ветке, ветке форума и т. Д. Я обнаружил, что это был первый невежественный ответ, который повторяли несколько раз.

Во-вторых: да, я знаю, что вы не можете обслуживать трафик HTTP и HTTPS на одном порту. Это не то.

Сценарий:

Сервер Apache, на котором размещается несколько сайтов, за счет увеличения числа портов. Порт 80 служит общедоступным сайтом. Порт 443 обслуживает защищенную версию этого сайта.

Порты 7443, 8443 и 9443 обслуживают отдельные сайты, защищенные SSL.

Если пользователь неправильно набирает URL-адрес или получает недействительную ссылку, скажем, http: //hostname.tld: 7443, им выдают следующую нелепую страницу:

Вместо того, чтобы сервер просто перенаправлял их на https: //hostname.tld: 7443.

Мой вопрос в том, как во имя Анальное отверстие Зевса можете ли вы изменить поведение Apache или это сообщение об ошибке, чтобы автоматически перенаправить пользователя?

Очевидно, что Apache обслуживает не-https-запрос (для отображения этого сообщения об ошибке), даже если он настроен для HTTPS. Мне кажется удивительно глупым не просто выполнять перенаправление по умолчанию, но я могу понять, почему они пошли с таким поведением, даже если я не согласен с этим. Итак, мой вопрос: вы можете это изменить? Они обрабатывают ошибку ГДЕ-НИБУДЬ, и поскольку Apache является рогом изобилия конфигурации, понятно, что где-то есть какая-то директива для обработки этого поведения, но я не смог найти ее за несколько часов работы до сих пор.

Обновить:

Я пробовал разные вещи, в том числе:

Я не могу использовать перенаправление на основе порта из-за использования настраиваемого порта. Я не могу использовать перенаправления на основе сценариев, потому что они никогда не обслуживаются из-за несоответствия http / https. Я почти готов списать это на ошибку или непреднамеренное поведение, но кто-то предусмотрительно поместил туда очень нестандартное сообщение об ошибке, они не удосужились подумать, что, возможно, вы захотите просто URL они уже предоставляют?

Я думаю, что это, вероятно, ошибка в том, как Apache 2.2 и ниже справляется с этой конкретной ситуацией.

Похоже на SSL прочитал 400 Bad Request ошибка, Apache 2.2 не возвращает код ответа HTTP или заголовки, только тело ответа HTTP. Я тестирую, подключившись к порту 443 через Telnet и отправив:

GET / HTTP/1.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 />
<blockquote>Hint: <a href="https://server.tld/"><b>https://server.tld/</b></a></blockquote></p>
</body></html>

Обратите внимание на отсутствие кода ответа HTTP или каких-либо заголовков HTTP.

Когда я делаю это с сервером Apache 2.4, я получаю:

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>

Если я настрою строку ErrorDocument, как вы:

ErrorDocument 400 https://server.tld/

Затем я получаю HTML-код для перенаправления 302, но опять же, ни одного заголовка. Без кода ответа перенаправления 302 и Location: заголовок, браузер не будет перенаправлять.

Попробуйте перейти на Apache 2.4 и посмотрите, работает ли он. Я протестировал и подтвердил, по крайней мере, Apache 2.4.3, но я не приложил усилий, чтобы точно определить, когда это поведение было обновлено. Я подозреваю, что в ходе большой работы, которую они проделали над подготовкой 2.4, они исправили нежелательное поведение как побочный эффект.

Соответствующие ошибки Apache httpd:

ОБНОВИТЬ

Вы можете заставить Apache с ошибками дать вам желаемое поведение (перенаправление), заставив скрипт распечатать свои заголовки (которые не будут отправлены клиенту), а затем вручную снова распечатать нужные заголовки. Вот базовый сценарий Perl, который работает под 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

Вы должны знать, что есть и другие причины, по которым может быть сгенерировано 400, помимо простого разговора с портом SSL без SSL. Самый простой способ определить это - поискать HTTPS переменная окружения. Если он установлен, значит, SSL согласован правильно, и что-то еще вызывает 400 (не делайте трюк с двойным заголовком, если это так). Если HTTPS не установлен, верните свое перенаправление, как указано выше.

Вы можете исправить это с помощью mod-rewrite. Установите правило, соответствующее чему угодно. См. Этот ответ на Переполнение стека