我有一个 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 地址。
答案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
server
Nginx 将对所有请求使用默认证书
这是由 SSL 协议行为引起的。SSL 连接是在浏览器发送 HTTP 请求之前建立的,nginx 不知道所请求服务器的名称。因此,它可能只提供默认服务器的证书。