2016-09-13 2 views
1

Долгое время мы поддерживали веб-сайт, который использует подстановочный 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) 
--- 

Благодарим за помощь!

+0

Я думаю, вам нужно добавить CLIENTSITE.com (без WWW) тоже –

+0

@AlexeyTen - для CNAME от WWW. CLIENTSITE.com - CLIENT.OURSITE.com, так что afaik никогда не должен это имя сервера CLIENTSITE.com – user2030378

ответ

0

В соответствии с конфигурацией вы указали тот же сертификат и ключ для *.OURSITE.com; и www.CLIENTSITE.com. Так что это работает точно так, как вы настроили:

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; 

...

server { 

    listen 443 ssl; 
    server_name www.CLIENTSITE.com; 
    root /path/to/root/; 

    ssl_certificate  /etc/ssl/OURSITE.crt; 
    ssl_certificate_key /etc/ssl/OURSITE.key; 
+0

Простите, что - я пропустил редактирование, что в моем запутанном коде. Я только что проверил, и я использовал правильные сертификаты в реальных файлах. – user2030378

Смежные вопросы