Долгое время мы поддерживали веб-сайт, который использует подстановочный SSL для защиты как основного сайта (https://www.OURSITE.com), так и субдоменов, специфичных для клиента (https://CLIENT.OURSITE.com). Для этого мы настроили один виртуальный хост для NGINX, и все работало плавно.SNI и виртуальные хосты с CNAME и SSL в NGINX
Недавно один клиент захотел использовать свой домен, чтобы показать CLIENT.OURSITE.com. Я сказал им создать запись CNAME с сайта www.CLIENTSITE.com на CLIENT.OURSITE.com. Затем я купил и настроил отдельный SSL-сертификат на www.CLIENTSITE.com и создал для него отдельный приз.
Однако, как только вы запустите браузер и перейдете на сайт www.CLIENTSITE.com, вы всегда получите неверную общую ошибку SSL, поскольку NGINX обслуживает сертификат подстановки для OURSITE.com вместо www.CLIENTSITE.com. NGINX правильно настроен для использования SNI.
NGINX конфигурации для OURSITE выглядит следующим образом:
upstream app_server {
server unix:/path/to/gunicorn.sock fail_timeout=0;
}
server {
listen 80;
server_name OURSITE.com;
client_body_buffer_size 2K;
client_header_buffer_size 2K;
client_max_body_size 1K;
server_tokens off;
if ($request_method !~ ^(GET|HEAD|POST|PATCH)$)
{
return 444;
}
return 301 https://www.$host$request_uri;
}
server {
listen 80;
server_name *.OURSITE.com;
error_log /path/to/logs/nginx-error.log;
access_log /path/to/logs/nginx-access.log;
client_body_buffer_size 2K;
client_header_buffer_size 2K;
client_max_body_size 1K;
server_tokens off;
if ($request_method !~ ^(GET|HEAD|POST|PATCH)$)
{
return 444;
}
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
server_name OURSITE.com;
root /path/to/root/;
ssl_certificate /etc/ssl/OURSITE.crt;
ssl_certificate_key /etc/ssl/OURSITE.key;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
ssl_dhparam /etc/ssl/dhparams.pem;
client_body_buffer_size 2K;
client_header_buffer_size 2K;
client_max_body_size 1K;
server_tokens off;
if ($request_method !~ ^(GET|HEAD|POST|PATCH)$)
{
return 444;
}
return 301 https://www.$host$request_uri;
}
server {
listen 443 ssl;
server_name *.OURSITE.com;
root /path/to/root/;
ssl_certificate /etc/ssl/OURSITE.crt;
ssl_certificate_key /etc/ssl/OURSITE.key;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers "ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:DES-CBC3-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4";
ssl_prefer_server_ciphers on;
ssl_dhparam /etc/ssl/dhparams.pem;
client_max_body_size 4G;
client_body_buffer_size 2K;
client_header_buffer_size 2K;
server_tokens off;
if ($request_method !~ ^(GET|HEAD|POST|PATCH)$)
{
return 444;
}
gzip on;
gzip_types application/x-javascript text/plain text/css text/xml application/xml text/javascript application/json;
error_log /path/to/logs/nginx-error.log;
access_log /path/to/logs/nginx-access.log;
location/{
# an HTTP header important enough to have its own Wikipedia entry:
# http://en.wikipedia.org/wiki/X-Forwarded-For
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# enable this if and only if you use HTTPS, this helps Rack
# set the proper protocol for doing redirects:
proxy_set_header X-Forwarded-Proto $scheme;
# pass the Host: header from the client right along so redirects
# can be set properly within the Rack application
proxy_set_header Host $http_host;
# we don't want nginx trying to do something clever with
# redirects, we set the Host: header above already.
proxy_redirect off;
# set "proxy_buffering off" *only* for Rainbows! when doing
# Comet/long-poll stuff. It's also safe to set if you're
# using only serving fast clients with Unicorn + nginx.
# Otherwise you _want_ nginx to buffer responses to slow
# clients, really.
# proxy_buffering off;
# Try to serve static files from nginx, no point in making an
# *application* server like Unicorn/Rainbows! serve static files.
if (!-f $request_filename) {
proxy_pass http://app_server;
break;
}
}
}
И конфигурации NGINX для www.CLIENTSITE.com выглядит следующим образом:
upstream app_server2 {
server unix:/path/to/gunicorn.sock fail_timeout=0;
}
server {
listen 80;
server_name www.CLIENTSITE.com;
error_log /path/to/logs/client-nginx-error.log;
access_log /path/to/logs/client-nginx-access.log;
client_body_buffer_size 2K;
client_header_buffer_size 2K;
client_max_body_size 1K;
server_tokens off;
if ($request_method !~ ^(GET|HEAD|POST|PATCH)$)
{
return 444;
}
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
server_name www.CLIENTSITE.com;
root /path/to/root/;
ssl_certificate /etc/ssl/CLIENTSITE.crt;
ssl_certificate_key /etc/ssl/CLIENTSITE.key;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers "ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:DES-CBC3-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4";
ssl_prefer_server_ciphers on;
ssl_dhparam /etc/ssl/dhparams.pem;
client_max_body_size 4G;
client_body_buffer_size 2K;
client_header_buffer_size 2K;
server_tokens off;
if ($request_method !~ ^(GET|HEAD|POST|PATCH)$)
{
return 444;
}
gzip on;
gzip_types application/x-javascript text/plain text/css text/xml application/xml text/javascript application/json;
error_log /path/to/logs/client-nginx-error.log;
access_log /path/to/logs/client-nginx-access.log;
location/{
# an HTTP header important enough to have its own Wikipedia entry:
# http://en.wikipedia.org/wiki/X-Forwarded-For
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# enable this if and only if you use HTTPS, this helps Rack
# set the proper protocol for doing redirects:
proxy_set_header X-Forwarded-Proto $scheme;
# pass the Host: header from the client right along so redirects
# can be set properly within the Rack application
proxy_set_header Host $http_host;
# we don't want nginx trying to do something clever with
# redirects, we set the Host: header above already.
proxy_redirect off;
# set "proxy_buffering off" *only* for Rainbows! when doing
# Comet/long-poll stuff. It's also safe to set if you're
# using only serving fast clients with Unicorn + nginx.
# Otherwise you _want_ nginx to buffer responses to slow
# clients, really.
# proxy_buffering off;
# Try to serve static files from nginx, no point in making an
# *application* server like Unicorn/Rainbows! serve static files.
if (!-f $request_filename) {
proxy_pass http://app_server2;
break;
}
}
}
И это то, что OpenSSL должен сказать о WWW. CLIENTSITE.com:
openssl s_client -connect www.CLIENTSITE.com:443 -servername www.CLIENTSITE.com
CONNECTED(00000003)
depth=2 C = GB, ST = Greater Manchester, L = Salford, O = COMODO CA Limited, CN = COMODO RSA Certification Authority
verify error:num=20:unable to get local issuer certificate
verify return:0
---
Certificate chain
0 s:/OU=Domain Control Validated/OU=PositiveSSL Wildcard/CN=*.OURSITE.com
i:/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Domain Validation Secure Server CA
1 s:/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Domain Validation Secure Server CA
i:/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Certification Authority
2 s:/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Certification Authority
i:/C=SE/O=AddTrust AB/OU=AddTrust External TTP Network/CN=AddTrust External CA Root
---
Server certificate
-----BEGIN CERTIFICATE-----
-- SNIP --
-----END CERTIFICATE-----
subject=/OU=Domain Control Validated/OU=PositiveSSL Wildcard/CN=*.OURSITE.com
issuer=/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Domain Validation Secure Server CA
---
No client certificate CA names sent
---
SSL handshake has read 4980 bytes and written 447 bytes
---
New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES128-GCM-SHA256
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
SSL-Session:
Protocol : TLSv1.2
Cipher : ECDHE-RSA-AES128-GCM-SHA256
Session-ID: XYZ
Session-ID-ctx:
Master-Key: ABC
Key-Arg : None
PSK identity: None
PSK identity hint: None
SRP username: None
TLS session ticket lifetime hint: 300 (seconds)
TLS session ticket:
-- SNIP --
Start Time: 1473804850
Timeout : 300 (sec)
Verify return code: 20 (unable to get local issuer certificate)
---
Благодарим за помощь!
Я думаю, вам нужно добавить CLIENTSITE.com (без WWW) тоже –
@AlexeyTen - для CNAME от WWW. CLIENTSITE.com - CLIENT.OURSITE.com, так что afaik никогда не должен это имя сервера CLIENTSITE.com – user2030378