Nginx, обслуживающий сертификат SSL другого сайта

Я обслуживаю два сайта с Nginx. На первом сайте (например, A) есть сертификат SSL, а второй сайт (скажем B) - нет. Сайт A отлично работает при открытии на https и B по http. Но когда я обращаюсь к сайту B на https, nginx обслуживает SSL-сертификат и содержимое сайта A с доменом B, чего не должно быть.

Конфигурация Nginx для сайта A выглядит следующим образом. Для сайта B это просто обратный прокси-сервер для приложения Flask.

server {
        listen 80;
        server_name siteA.com;
        return 301 https://$host$request_uri;
}

server {
        listen 443 ssl;
        server_name siteA.com;

        ssl_certificate /path/to/cert.cert
        ssl_certificate_key /path/to/cert_key.key;

        ssl_prefer_server_ciphers on;
        ssl_ciphers ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-RC4-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:RC4-SHA:AES256-GCM-SHA384:AES256-SHA256:CAMELLIA256-SHA:ECDHE-RSA-AES128-SHA:AES128-GCM-SHA256:AES128-SHA256:AES128-SHA:CAMELLIA128-SHA;

        ssl_session_cache   shared:SSL:10m;
        ssl_session_timeout 10m;
        keepalive_timeout   70;

        # and then the `location /` serving static files
}

Я не могу понять, что здесь не так.

Ответ 1

По-видимому мне нужен выделенный IP для сайта А.

Цитата из Что именно означает "каждый сертификат SSL требует выделенного IP-адреса" значит?

При закреплении какого-либо соединения с TLS вы обычно используете сертификат для аутентификации сервера (а иногда и клиента). Там один сервер на IP/порт, поэтому обычно нет проблем для сервера, чтобы выбрать, какой сертификат использовать. HTTPS - это исключение - несколько разных доменных имен могут ссылаться на один IP-адрес, а клиент (обычно браузер) подключается к одному и тому же серверу для разных доменных имен. Доменное имя передается серверу в запросе, который идет после установления связи TLS. Здесь, где возникает проблема - веб-сервер не знает, какой сертификат представить. Для этого в TLS добавлено новое расширение с именем SNI (идентификация имени сервера). Однако не все клиенты поддерживают его. Поэтому в целом рекомендуется иметь выделенный сервер на каждый IP/порт для каждого домена. Другими словами, каждый домен, к которому клиент может подключиться с помощью HTTPS, должен иметь свой собственный IP-адрес (или другой порт, но это не обычный).

Nginx прослушивал порт 443, и когда запрос на сайт B продолжался на https, было проведено рукопожатие TLS, и перед обслуживанием содержимого был представлен сертификат сайта A.

Ответ 2

NGINX поддерживает SNI, поэтому он может обслуживать разные домены с разными сертификатами с одного и того же IP-адреса. Это можно сделать с помощью нескольких серверных блоков. NGINX зафиксировал это в http://nginx.org/en/docs/http/configuring_https_servers.html

Для меня важны HTTP2 и IPv6, поэтому я слушаю [::] и устанавливаю ipv6only = off. По-видимому, этот параметр должен быть установлен только для первого блока сервера, иначе NGINX не запустится.

duplicate listen options for [::]:443

Эти серверные блоки

server {
    listen [::]:443 ssl http2 ipv6only=off;
    server_name siteA.com www.siteA.com;

    ssl_certificate /path/to/certA.cert
    ssl_certificate_key /path/to/certA_key.key;
}
server {
    listen [::]:443 ssl http2;
    server_name siteB.com www.siteB.com;

    ssl_certificate /path/to/certB.cert
    ssl_certificate_key /path/to/certB_key.key;
}

Ответ 3

Параметр ssl_certificate следует закрыть с помощью ;, чтобы получить ожидаемый результат.

Также убедитесь, что вы выполнили правильный синтаксис во всех параметрах файла конфигурации, используя следующую команду, а затем перезапустите или перезагрузите службу:

sudo nginx -t

Ответ 4

Если вы размещаете несколько сайтов на вашем сервере и в одной конфигурации Nginx, если у вас есть listen 443 ssl http2 default_server;

default_server предоставит тот же сертификат всем доменам. его устранение устранит проблему.

Следуя этому tutorial, я пропустил эту часть:

Примечание. У вас может быть только одна директива для прослушивания, включающая модификатор default_server для каждой версии IP и комбинации портов. Если у вас есть другие серверные блоки для этих портов с установленным параметром default_server, вы должны удалить модификатор из одного из блоков.