Como servir vários certificados SSL para o host virtual padrão no NGINX?

Como servir vários certificados SSL para o host virtual padrão no NGINX?

Tenho um aplicativo estático no Amazon S3 que é servido por meio de um proxy NGINX. O objetivo de usar um proxy é permitir que os usuários apontem seus domínios para minha instância do Amazon EC2 (por meio do registro CNAME apontando para custom-domain.myproduct.com) para que possam acessar meu aplicativo por meio de seu próprio URL personalizado, como este: myproduct.happyclient.com.

Para conseguir isso, tenho a seguinte configuração nginx (partes removidas por questões de brevidade):

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;
    }
}

Mesmo que meu aplicativo estático seja 100% público (sem segredo do cliente, apenas html e javascript), alguns dos meus clientes desejam acessá-lo por meio de SSL. Como posso escolher dinamicamente qual certificado usar para a conexão SSL com base no cabeçalho Host? Observe que não posso simplesmente codificar o caminho do certificado.

PS.: Os clientes poderão enviar seus certificados para minha instância
PS2.: Essa configuração já funciona perfeitamente apenas com HTTP.

O que eu tentei

Eu tentei algo assim, sem sucesso:

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
}

Responder1

Como posso escolher dinamicamente qual certificado usar para a conexão SSL com base no cabeçalho Host?

O cabeçalho Host faz parte do protocolo HTTP, mas HTTPS é HTTP incorporado em uma conexão SSL. O que significa que primeiro você precisa estabelecer a conexão SSL (que precisa do certificado) antes de ter acesso ao cabeçalho Host.

Se o cliente suportar SNI (todos os navegadores modernos suportam, mas o IE/XP não), ele já enviará o nome do destino dentro do handshake SSL. O fornecimento de certificados diferentes com base no nome de destino geralmente é feito com diferentes seções de servidor no nginx. Você pode tentar usar a $ssl_server_nameseção padrão, mas não tenho certeza se isso funcionará e, mesmo que funcione, pode afetar otimizações como o cache de sessão de maneira negativa.

informação relacionada