Мне было интересно, если nginx может обрабатывать запросы http и https на одном и том же порту . [*]
Это то, что я пытаюсь сделать. Я использую веб-сервер (lighttpd), обрабатывающий запросы http, и программу на C, которая обслуживает определенный раздел дерева документов через https. Эти два процесса выполняются на одном сервере.
На уровне брандмауэра у меня может быть только один порт, перенаправляющий трафик на этот сервер . Итак, я хотел бы настроить nginx на этом сервере, чтобы он прослушивал запросы на один порт, а затем:
А) перенаправляет все запросы http://myhost.com/ *, чтобы они перешли на localhost: 8080 (где прослушивает lighttpd)
B) если пользователь запрашивает URL-адрес, начинающийся, например, с https: // myhost.com/app, он отправляет этот запрос на localhost: 8008 (программа C). Обратите внимание, что в этом случае трафик между удаленным браузером и nginx должен быть зашифрован.
Как вы думаете, это может быть возможно? Если это так, как это можно сделать?
Я знаю, как это сделать, используя два разных порта. Проблема, с которой я сталкиваюсь, заключается в том, чтобы сделать это только с одним портом (к сожалению, я не могу контролировать конфигурацию брандмауэра в этой конкретной среде, поэтому я не могу обойти это ограничение). Использование методов, таких как переадресация портов через ssh для обхода брандмауэра, также не будет работать, потому что это должно работать для удаленных пользователей, у которых нет ничего, кроме веб-браузера и интернет-ссылки.
Если это выходит за рамки возможностей nginx, знаете ли вы какой-либо другой продукт, который бы соответствовал этим требованиям? (до сих пор мне не удалось настроить это с помощью lighttpd и pound). Я также предпочел бы избегать Apache (хотя я готов использовать его, если это единственный возможный выбор).
Заранее спасибо Алекс
[*] Просто чтобы прояснить, я говорю об обработке зашифрованных и незашифрованных HTTP-соединений через один и тот же порт. Не имеет значения, выполняется ли шифрование через SSL или TLS.
Ответы:
Согласно статье в Википедии о кодах состояния, Nginx имеет собственный код ошибки при отправке http-трафика на порт https (код ошибки 497).
И в соответствии с документацией nginx на странице error_page вы можете определить URI, который будет отображаться для конкретной ошибки.
Таким образом, мы можем создать URI, на который будут отправляться клиенты при возникновении кода ошибки 497.
nginx.conf
Однако, если клиент делает запрос с помощью любого другого метода, кроме GET, этот запрос будет превращен в GET. Таким образом, чтобы сохранить метод запроса, через который пришел клиент; мы используем перенаправления обработки ошибок, как показано в документации nginx на странице error_page
И именно поэтому мы используем
301 =307
редирект.Используя файл nginx.conf, показанный здесь, мы можем прослушивать http и https через один и тот же порт
источник
Для тех, кто может искать:
Добавьте
ssl on;
иerror_page 497 $request_uri;
к вашему определению сервера.источник
ssl on;
иerror_page 497 =200 $request_uri;
определение вашего сервера. Это изменит код состояния на 200.Если вы хотите быть по-настоящему умным, вы можете использовать прокси-соединение для соединения с первой парой байтов входящего потока данных и передать соединение на основе содержимого байта 0: если это 0x16 (SSL / TLS ' рукопожатие (байт), передайте соединение стороне SSL, если это алфавитный символ, выполните обычный HTTP. Мой комментарий о нумерации портов применяется .
источник
Да, это возможно, но требует исправления исходного кода nginx (HoverHell предлагает решение без исправлений). Nginx рассматривает это как неправильную конфигурацию, а не как допустимую конфигурацию.
Переменная $ ssl_session_id может использоваться для различия между простым и ssl-соединением.
Патч против nginx-0.7.65:
Конфигурация сервера:
источник
Я не думаю, что есть что-то, что может обрабатывать два разных протокола на одном порту ...
Мне любопытно, почему вы можете переадресовывать только один порт, но это в сторону ... это не идеально, но если бы я был на вашем месте, я бы обслуживал все через https.
источник
Вы не можете поддерживать HTTP и HTTPS через один и тот же порт, потому что оба конца соединения ожидают разговора на определенном языке, и они недостаточно умны, чтобы понять, говорит ли другой конец что-то еще.
Как подсказывает ваш комментарий к ответу Уилла, вы можете использовать обновление TLS (я полагаю, что более новые выпуски nginx поддерживают его, хотя я не пробовал), но это не работает HTTP и HTTPS, это просто работает HTTP с обновлением TLS. Проблема все еще в поддержке браузеров - большинство браузеров (до сих пор) не поддерживают ее. Если у вас ограниченный пул клиентов, то это возможно.
источник
Я не уверен, как это происходит, но CUPSD отвечает и на http, и на https через порт 631. Если nginx не может сделать это сейчас, возможно, они смогут узнать, как команда CUPS выполняет это, но CUPS находится под GPL, поэтому nginx, возможно, придется посмотреть на изменение своей лицензии, если они действительно хотят реализовать такую возможность и не могут найти код для этого в другом месте.
источник
Теоретически, у вас может быть веб-страница, доступная через HTTP, которая может открыть WebSocket по https: 443 в любом месте, где она захочет. Начальное рукопожатие WebSocket - HTTP. Так что, да, возможно сделать незащищенную страницу, действительно способную к безопасному общению. Вы можете сделать это с помощью библиотеки Netty .
источник
Это, наконец, возможно сделать правильно, начиная с 1.15.2. Смотрите информацию здесь .
В вашем nginx.conf добавьте такой блок (вне блока http):
Затем вы можете создать свой обычный серверный блок, но прослушивая эти разные порты:
Таким образом, потоковый блок может предварительно прочитать и определить, является ли он TLS или нет (на порту 8080 в этом примере), а затем прокси-сервер передает его на правильный порт сервера локально.
источник