Как обслуживать несколько SSL-сертификатов для виртуального хоста по умолчанию в NGINX?

Как обслуживать несколько SSL-сертификатов для виртуального хоста по умолчанию в NGINX?

У меня есть статическое приложение на Amazon S3, которое обслуживается через прокси-сервер NGINX. Цель использования прокси-сервера — позволить пользователям указывать свои домены на мой экземпляр Amazon EC2 (через запись CNAME, указывающую на custom-domain.myproduct.com), чтобы они могли получить доступ к моему приложению через свой собственный URL-адрес, например: myproduct.happyclient.com.

Для этого у меня есть следующая конфигурация nginx (некоторые части удалены для краткости):

http {
    server {
    # This is my default route. References:
    # http://stackoverflow.com/a/15799883/91403
    # http://nginx.org/en/docs/http/request_processing.html

    listen 80 default_server;
    server_name custom-domain.myproduct.com;
    location / {
        proxy_pass http://static.myproduct.com; # points to Amazon S3
        proxy_set_header Host myproduct.com;
    }
}

Хотя мое статическое приложение на 100% открыто (никакого клиентского секрета, только html и javascript), некоторые мои клиенты хотят получить к нему доступ через SSL. Как мне динамически выбирать, какой сертификат использовать для SSL-соединения на основе заголовка Host? Обратите внимание, что я не могу просто жестко закодировать путь к сертификату.

ПС.: Клиенты смогут загружать свои сертификаты в мой экземпляр
ПС2.: Эта настройка уже отлично работает только с HTTP.

Что я пробовал

Я пробовал что-то вроде этого, но безуспешно:

server {
    listen 443 default_server;
    server_name custom-domain.myproduct.com;
    ssl on;
    ssl_certificate /etc/nginx/ssl/$http_host/server.crt; # note the http_host variable
    ssl_certificate_key /etc/nginx/ssl/$http_host/server.key; # also here
}

решение1

Как можно динамически выбирать, какой сертификат использовать для SSL-соединения, на основе заголовка Host?

Заголовок Host является частью протокола HTTP, но HTTPS — это HTTP, встроенный в SSL-соединение. Это означает, что сначала вам нужно установить SSL-соединение (которому нужен сертификат), прежде чем вы получите доступ к заголовку Host.

Если клиент поддерживает SNI (все современные браузеры поддерживают, но IE/XP нет), он отправит целевое имя внутри SSL-рукопожатия. Предоставление различных сертификатов на основе целевого имени обычно выполняется с помощью различных разделов сервера в nginx. Вы можете попробовать использовать $ssl_server_nameв разделе по умолчанию, но я не уверен, что это сработает, и даже если это сработает, это может негативно повлиять на оптимизацию, например на кэширование сеанса.

Связанный контент