2009-02-16 2 views
4

Так вроде очень похож на «Detecting https requests in php»:Обнаружение HTTPS против HTTP на сервер не посылает обратно ничего полезного

Хотите иметь https://example.com/pog.php пойти http://example.com/pog.php или даже наоборот.

Проблемы:

  • Не можете что-нибудь от $ _SERVER чтения [ «HTTPS»], так как это не существует
  • Сервер отправляет как запросы через порт 80, поэтому он не может проверить на 443 на HTTPS версия
  • apache_request_headers() и apache_response_headers() посылает обратно то же самое
  • не могу сказать loadbalancer что-нибудь или иметь его послать дополнительные Somethings
  • данные обратной связи
  • сервера выплюнул на странице в обоих URL-адресах точно так же, кроме идентификатора сеанса. Облом.

Есть ли на странице способы определить, вызвано ли это вызовом через SSL или без SSL?

Редактировать: $_SERVER["HTTPS"] не существует, включено или нет, независимо от того, просматриваете ли вы сайт через SSL или без SSL. По какой-то причине хостинг решил обслуживать все HTTPS-запросы, зашифрованные, но вниз порт 80. И, таким образом, $_SERVER["HTTPS"] никогда не будет включен, а не там, просто нет никакой полезной обратной связи на этой серверной точке. Таким образом, этот параметр всегда будет пустым.

(И да, это означает, что он помечается в говорят FF или Chrome для частично недействительным сертификата SSL. Но эта часть не имеет значения.)

Кроме того, самое большее, что может быть получен от обнаружения URL до точки косых черт. PHP не видит, имеет ли запрос https или http спереди.

ответ

22

Ключевое слово - Load Balancer

Проблема сводится к тому, что балансир нагрузки обработки SSL шифрования/дешифрования и является полностью прозрачным для веб-сервера.

Request: Client -> 443or80 -> loadbalancer -> 80 -> php 
Response: PHP -> 80 -> loadbalancer -> 443or80 -> Client 

Реальный вопрос здесь «у вас есть контроль над конфигурацией балансировки нагрузки?»


Если вы делаете, Есть несколько способов справиться с этим. Настройте балансировщик нагрузки, чтобы иметь отдельные определения служб для HTTP и HTTPS. Затем отправьте HTTP-трафик на порт 80 веб-серверов и HTTPS-трафик на порт 81 веб-серверов. (порт 81 не используется ничем другим).

В апача, настроить два различных виртуальных хостов:

<VirtualHost 1.2.3.4:80> 
    ServerName foo.com 
    SetEnv USING_HTTPS 0 
    ... 
</VirtualHost> 

<VirtualHost 1.2.3.4:81> 
    ServerName foo.com 
    SetEnv USING_HTTPS 1 
    ... 
</VirtualHost> 

Затем переменная среды USING_HTTPS будет либо 1 | 0, в зависимости от того, какой виртуальный хост поднял его. Это будет доступно в массиве $_SERVER в PHP. Разве это не круто?


Если у вас нет доступа к конфигурации балансировки нагрузки, то все немного сложнее. Не будет способа окончательно узнать, используете ли вы HTTP или HTTPS, потому что HTTP и HTTPS - это протоколы . Они указывают, как подключиться и какой формат отправлять информацию, но в любом случае вы используете HTTP 1.1 для выполнения запроса. В фактическом запросе нет информации, если это HTTP или HTTPS.

Но не теряйте сердце. Есть пара идей.

6-й параметр функции setcookie() PHP может дать указание клиенту отправлять cookie ТОЛЬКО через соединения HTTPS (http://www.php.net/setcookie). Возможно, вы можете установить cookie с этим параметром, а затем проверить его на последующих запросах?

Другая возможность - использовать JavaScript для обновления ссылок на каждой странице в зависимости от протокола (добавление параметра GET).

(ни один из выше будет пуленепробиваемые)

Другой прагматический вариант был бы получить SSL на другом домене, например secure.foo.com. Тогда вы можете прибегнуть к трюку VirtualHost выше.


Я знаю, что это не самый простой вопрос, потому что я имею дело с ним в течение дня (с балансировкой нагрузки веб-кластера за балансировки нагрузки Cisco CSS с модулем SSL).

Наконец, вы всегда можете взглянуть на перспективу перехода вашего веб-приложения на режим SSL, если хотите, и не доверять пользователям НЕ перемещать их (в конце концов, это их данные на линии (обычно)).

Надеюсь, это поможет.

+1

Не доверяйте пользователю. Страница должна оставаться на HTTP-версии, поэтому, если они когда-либо попытаются перейти на HTTPS, они будут отброшены до версии HTTP. Понравился ваш ответ. – random

4
$ _SERVER ["HTTPS"] не существует, включен или нет, независимо от того, просматриваете ли вы сайт через SSL или без SSL. По какой-то причине хостинг решил обслуживать все HTTPS-запросы, зашифрованные, но вниз порт 80. И, таким образом, $ _SERVER ["HTTPS"] никогда не включен, а не там, просто нет никакой полезной обратной связи на этой серверной точке. Таким образом, этот параметр всегда будет пустым.

Вы должны убедиться, что у поставщика есть следующая строка в записи VHOST для вашего сайта: SSLOptions +StdEnvVars. В этой строке Apache включает в себя переменные SSL в среде для ваших скриптов (PHP).