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

9

Предисловие

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

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

Сценарий:

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

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

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

Apache Bad Request сообщение об ошибке

Вместо сервера просто перенаправьте их на https: //hostname.tld: 7443 .

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

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

Обновить:

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

  • используя ErrorDocument 400директивы , чтобы получить к CGI и PHP скрипт , который просто отправить Status 301и Locationзаголовки. Это приводит к пустой странице. Использование ErrorDocument 400 https://hostname.tld:7443просто приводит к тому, что эта ссылка отображается на странице.

  • mod_rewriteМожно использовать почти каждую комбинацию I или Google, включая общие заявления, которые полностью управляют сайтом; это никогда не работает. Буквально они ничего не делают. Я предполагаю, что Apache пытается выполнить описанную выше ошибку еще до того, как попытается обработать директивы перезаписи.

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

PeelMan
источник
Смотрите принятый ответ для ssl и non-ssl на одном порту
Даниэль Верите
Даниэль, Это был один из многих вопросов, которые я нашел, и решения, которые я пытался найти, прежде чем опубликовать этот вопрос. Я думаю, что проблема заключалась в PHP-компоненте, но поскольку обновление ответа @ hrunting в данный момент работает для меня прекрасно, я не собираюсь впадать в него больше времени, чем у меня уже есть; по крайней мере, пока я не должен.
Пилман
2
upvote для связанного видео, оно передает мои эмоции отлично
michele b

Ответы:

6

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

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

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не установлено, верните перенаправление, как указано выше.

хрунтинг
источник
1
Святой. Дерьмо. Идеальный ответ. Gracias.
Пилман
Вы знаете, когда я читаю это, я думаю про себя: «Чувак, это действительно отстой, если у вас есть Apache 2.2, и вы хотите такое поведение перенаправления» Я не собираюсь пытаться найти подходящий Debian Apache 2.4 (или сделать свой собственный) для моей системы Ubuntu. Могу поспорить, что вы можете взломать решение из вашего сценария PHP. Очевидно, что Apache просто выводит выходные данные на клиент, поэтому, если вы вернете конкретный ожидаемый контент, я уверен, что вы можете получить требуемое поведение без обновления Apache. Попробуйте распечатать свой PHP-скрипт «HTTP / 1.1 302 Found \ r \ nLocation: server.tld \ r \ n \ r \ n».
13
Проблема в том, что не похоже, что скрипт PHP обрабатывается. Я должен отметить, что это текущее заседание на Apache 2.2.22 на Ubuntu Server 12.04. И да, это действительно, действительно отстой; особенно если вы заметите, что в этих отчетах об ошибках они, кажется, полностью настроены против даже предоставления возможности просто автоматически выполнять перенаправление, и вряд ли есть надежда, что 2.2 когда-нибудь получит исправление.
Пилман
1
И, как я уже говорил выше, для меня просто не имеет смысла, почему вы пытаетесь написать это сообщение об ошибке, а не перенаправлять на безопасный (серьезно, почему бы просто не перенаправить? Чем больше я об этом думаю, тем меньше Я думаю, что это плохая идея).
Пилман
1
Я собрал всю файловую систему в поисках текста этого кровавого сообщения, чтобы посмотреть, смогу ли я, откуда они его вылавливают, если не получится, я смогу внедрить <javascriptтег и мне повезло с таким перенаправлением взлома, но пока нет игральная кость. Ничего из этого, похоже, не обрабатывается так, как это следует за довольно жесткой, по-другому, Apache ...
peelman
-1

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

трент
источник
Нет, я уже пробовал это, это не работает. Похоже, что он даже не доходит до шагов ModRewrite, потому что он сначала не соответствует http / https.
Пилман
Хм, так что я предполагаю, что вы начали с самого начала вашего конфигурационного файла apache и прошли путь вниз, чтобы посмотреть, что он вызывает
trent
Я практически запомнил весь sites-availableкаталог. Даже если вы просто перенаправите его на ерунду или перенаправите на другой сайт, на другой порт и т. Д., Он просто продолжит загружать эти 400 неверных запросов.
Пилман