
У меня есть статическое приложение на 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
в разделе по умолчанию, но я не уверен, что это сработает, и даже если это сработает, это может негативно повлиять на оптимизацию, например на кэширование сеанса.