У меня есть веб-сервер со многими виртуальными серверами. Только 1 из которых является SSL. Проблема заключается в том, что из-за того, что серверный блок catchall не прослушивает SSL, любой запрос https на другие сайты обслуживается блоком 1 SSL.
Моя конфигурация, по сути, выглядит так:
# the catch all
server {
listen 80 default;
# I could add this, but since I have no default cert, I cannot enable SSL,
# and this listen ends up doing nothing (apparently).
# listen 443;
server_name _;
# ...
}
# some server
server {
listen 80;
server_name server1.com;
# ...
}
# some other server ...
server {
listen 80;
server_name server2.com;
# ...
}
# ... and it's https equivalent
server {
listen 443;
ssl on;
server_name server2.com;
# ...
}
Теперь, когда для 443 нет прослушивателя по умолчанию, такой запрос в https://server1.com
итоге будет обслуживаться server2.com
блоком https. Это следует логике для server_name
в документах.
Если совпадений нет, будет использован блок сервера {...} в файле конфигурации в следующем порядке:
- блок сервера с соответствующей директивой прослушивания, помеченной как [default | default_server]
- первый серверный блок с соответствующей директивой прослушивания (или неявным прослушиванием 80;)
Какое решение для этой проблемы является предпочтительным? Нужно ли мне устанавливать фиктивный сертификат для моего блока перехвата всех серверов, чтобы я мог прослушивать 443 и обрабатывать неправильные запросы? Есть ли параметр, о котором я не знаю, который заставляет точное имя хоста соответствовать server
?
Ответы:
Ни то, ни другое невозможно. Соединение от клиента, которое идет к https://foo.example.com/, не может быть принято ничем, кроме сертификата SSL с foo.example.com в качестве одного из его имен. Нет возможности перенаправить, пока не будет принято SSL-соединение.
Если вы настраиваете каждый сайт для SSL, пользователь, который щелкает по ошибке сертификата, получит запрошенный сайт. Если вы настраиваете сайт «поймать все» для SSL, который предоставляет только страницу ошибок, и настраиваете виртуальный хостинг на основе имен для одного сайта, который должен поддерживать SSL, вы можете предоставить эту страницу клиентам.
Виртуальный хостинг SSL и HTTP просто не играют друг с другом.
источник
Единственный способ сделать это - создать самозаверяющий SSL-сертификат и использовать его для получения контроля над входящими https-запросами. Вы можете создать свой самозаверяющий сертификат SSL в несколько простых шагов, описанных в этом посте .
Допустим, вы создаете самозаверяющий сертификат с именем файла server.crt. Затем вы добавили бы следующее в вашу конфигурацию nginx:
Вы все равно получите предупреждение SSL от браузера, но, по крайней мере, вы будете контролировать, что будет дальше.
источник
Добавьте универсальный блок сервера и верните код состояния 444. Он сообщает nginx закрыть соединение перед отправкой каких-либо данных.
источник
В эти дни вы можете использовать расширение индикации имени сервера TLS (SNI, RFC 6066). Приемник HTTPS сможет распознать доменное имя до подачи соответствующего сертификата.
Это означает, что вам понадобятся сертификаты для ВСЕХ ваших доменов, и когда SNI используется для распознавания одного из других доменов, вы можете просто использовать перенаправление HTTP 301 на незашифрованную версию HTTP, если только имя сервера не соответствует тому, который нужен шифрование.
Дополнительную информацию о SNI можно найти в документации по nginx http://nginx.org/en/docs/http/configuring_https_servers.html.
источник
Сопоставьте запрошенное имя хоста с действительными именами хостов в
http {}
блоке:А затем в
server {}
блоке уничтожить соединения с неправильным именем хоста:При необходимости используйте несколько карт для нескольких блоков серверов. Соединение будет по-прежнему устанавливаться с использованием одного из ваших сертификатов, но если этот последний блок присутствует в каждом блоке сервера, который обслуживает SSL, тогда вы фактически «заблокируете» соединения с неверными именами хостов. Это может быть необходимо только в первом блоке сервера, но добавление его в каждый блок сервера гарантирует, что порядок не имеет значения.
$ssl_server_name
Переменная присутствует в Nginx 1.7 или выше.источник
Вот как я решил проблему:
openssl req -nodes -x509 -newkey rsa:4096 -keyout self_key.pem -out self_cert.pem -days 3650
cp self*.pem /etc/nginx/ssl/
Что это будет делать: оно выдаст вам предупреждение (никак не обойти) на любом сервере, который не имеет собственного сертификата, но в предупреждении не будет указано неправильное имя сертификата. Если пользователь нажимает «посетить в любом случае», он будет перенаправлен на не-ssl версию сайта, которую он напечатал.
предостережение :
если ваш сайт с поддержкой SLL только определяет
www.example.com
(и не определяетexample.com
), тогда ваш маршрут перехвата в конечном итоге будет обслуживатьсяhttps://example.com
самозаверяющим сертификатом и соответствующим предупреждением.источник
Перенаправить на http:
Возврат 404 :
источник