TLS SNI

TLS SNI

我有一个 ubuntu hardy,其 nginx 版本为:nginx/0.5.33

我有多个服务器,它们在端口 80 上运行良好。

现在,我想要使用端口 443 上的 SSL 为其中一些提供服务,并且它们每个都有自己的 SSL 证书。

问题是每个域都使用相同的 SSL 证书,并且浏览器中会出现错误,提示 SSL 证书名称不匹配。

我确信所有证书都是有效且正确的,路径也正确。如果我只服务一个域,那么 SSL 证书没问题,因此所有文件都没问题。

为什么 nginx 对所有服务器配置始终使用相同的 ssl 证书?

这里有两个例子,如果两个都处于活动状态,则始终采用域 1 的 ssl,如果我删除域 1,则带有 ssl 的域 2 可以使用正确的 ssl 文件正常工作。

谢谢,

米。


nginx.conf 文件:

user www-data;
worker_processes  1;

error_log  /var/log/nginx/error.log;
pid        /var/run/nginx.pid;

events {
worker_connections  1024;
}

http {
include       /etc/nginx/mime.types;
default_type  application/octet-stream;

access_log  /var/log/nginx/access.log;

sendfile        on;
#tcp_nopush     on;

#keepalive_timeout  0;
keepalive_timeout  65;
tcp_nodelay        on;

gzip  on;

include /etc/nginx/conf.d/*.conf;
}

domain1.conf 文件:

server {

        listen 443;

        server_name domain1.montx.com;
        root /etc/nginx/sites-available/domain1;
        access_log /etc/nginx/sites-available/domain1/log/nginx.log;
        error_page 500 502 503 504 /500.html;
        client_max_body_size 50M;

        ssl on;
        ssl_certificate /etc/nginx/conf.d/domain1.crt;
        ssl_certificate_key /etc/nginx/conf.d/domain1.key;

         location / {

                auth_basic "Restricted";
                auth_basic_user_file  domain1_htpasswd;
                 }
}

domain2.conf 文件:

upstream thin_domain2 {
    server   unix:/tmp/thin_domain2.0.sock;
    server   unix:/tmp/thin_domain2.1.sock;
    server   unix:/tmp/thin_domain2.2.sock;
}


server {

    listen 443;
    ssl on;
    ssl_certificate /etc/nginx/conf.d/domain2.crt;
    ssl_certificate_key /etc/nginx/conf.d/domain2.key;




    server_name domain2.montx.com;
    root /u/apps/domain2/current/public;
    access_log /u/apps/domain2/shared/log/nginx.log;
    error_page 500 502 503 504 /500.html;
    client_max_body_size 50M;

    # First rewrite rule for handling maintenance page
    if (-f $document_root/system/maintenance.html) {
            rewrite ^(.*)$ /system/maintenance.html last;
            break;
    }

    location / {
            index index.html index.htm;

            # Forward information about the client and host
            # Otherwise our Rails app wouldn't have access to it
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header Host $http_host;
            proxy_max_temp_file_size 0;
            # Directly serve static content
            location ~ ^/(images|javascripts|stylesheets)/ {
                    expires 10y;
            }
            if (-f $request_filename) {
                    break;
            }

            # Directly serve cached pages
            if (-f $request_filename.html) {
                    rewrite (.*) $1.html break;
            }

            # Otherwise let Thin handle the request
            if (!-f $request_filename) {
                    proxy_pass http://thin_domain2;
                    break;
            }
    }
}

答案1

您需要为想要使用的每个 SSL 证书分配一个单独的 IP 地址。

http://httpd.apache.org/docs/2.0/ssl/ssl_faq.html#vhosts

http://www.ruby-forum.com/topic/186664#815383

答案2

为每个服务器块添加 IP 地址绑定:

listen yourIPaddress:443 ssl;

答案3

TLS SNI

SNI 允许浏览器在 SSL 握手期间传递请求的服务器名称

Nginx 支持 TLS SNI

检查 Nginx 是否启用了 TLS SNI

$ nginx -V
...
TLS SNI support enabled
...

并检查error_log没有这个警告

nginx was built with SNI support, however, now it is linked
dynamically to an OpenSSL library which has no tlsext support,
therefore SNI is not available

官方 HTTPS 文档有更多细节。

如果启用 TLS SNI,以下配置可以正常工作。

# Create the self signed certificate

openssl req -x509 -newkey rsa -nodes -keyout default.key -days 36500 -out default.crt -subj "/CN=example.org"

openssl req -x509 -newkey rsa -nodes -keyout a.key -days 36500 -out a.crt -subj "/CN=a.example.org"

openssl req -x509 -newkey rsa -nodes -keyout b.key -days 36500 -out b.crt -subj "/CN=b.example.org"
    server {
        listen       443 ssl default_server;
        server_name  "";

        ssl_certificate      default.crt;
        ssl_certificate_key  default.key;

        add_header "Content-Type" "text/plain";
        return 200 "default page";
    }

    server {
        listen       443 ssl;
        server_name  a.example.org;

        ssl_certificate      a.crt;
        ssl_certificate_key  a.key;

        add_header "Content-Type" "text/plain";
        return 200 "a.example.org page";
    }

    server {
        listen       443 ssl;
        server_name  b.example.org;

        ssl_certificate      b.crt;
        ssl_certificate_key  b.key;

        add_header "Content-Type" "text/plain";
        return 200 "b.example.org page";
    }
# Add -v to verify the certificate

$ curl --insecure --resolve "a.example.org:443:127.0.0.1" https://a.example.org

a.example.org page

$ curl --insecure --resolve "b.example.org:443:127.0.0.1" https://b.example.org

b.example.org page

$ curl --insecure https://127.0.0.1

default page

参考:Nginx TLS SNI

如果 Nginx 禁用 TLS SNI

serverNginx 将对所有请求使用默认证书

官方 HTTPS 文档

这是由 SSL 协议行为引起的。SSL 连接是在浏览器发送 HTTP 请求之前建立的,nginx 不知道所请求服务器的名称。因此,它可能只提供默认服务器的证书。

相关内容