The early SSLv2 was designed according to the classic PKI (public key Infrastructure), which by default assumed that a server (or an IP) would only provide a service, so at the time of the SSL handshake, the server side could be sure which certificate the client was requesting.
However, it is not expected that the virtual host has developed vigorously, which resulted in an IP will correspond to multiple domain names. There are some solutions, such as applying for a generic domain name certificate, which can be certified for all *.yourdomain.com domain names, but if you have a yourdomain.net domain name, you can't.
In the HTTP protocol, the requested domain name is placed in the HTTP header as the host header, so the server knows which domain name the request should be directed to, but the earlier SSL does not, because in the process of the SSL handshake, there is no Host information, So the server side typically returns the first available certificate in the configuration. Thus some older environments may generate multiple domain names with certificates, but the return is always the same.
Depending on how HTTPS works, the browser establishes an SSL connection with the server when it accesses an HTTPS site, and the first step in establishing a connection is to request the server's certificate. When the server sends the certificate, it is not know which domain name the browser accesses, so it can't send different certificates according to different domain names.
Since the problem is due to the lack of host header information in the SSL handshake, then fill it out.
SNI (server Name Indication) is a SSL/TLS extension that addresses a server that uses multiple domain names and certificates. defined in RFC 4366. is a technique for improving SSL/TLS, which is enabled in SSLV3/TLSV1. It allows the client to submit the host information of the request when initiating an SSL handshake request (specifically, the ClientHello phase in the client's SSL request), allowing the server to switch to the correct domain and return the corresponding certificate. In a nutshell, it works by sending the domain name (Hostname) to access the site before connecting to the server to establish an SSL link, so that the server returns a suitable certificate based on the domain name. Currently, most operating systems and browsers are well-supported for SNI extensions, and the OpenSSL 0.9.8 has built this functionality, and the new Nginx is said to support SNI.
to use SNI, you need both the client and server side to meet the conditions, but fortunately for modern browsers, most of them support SSLV3/TLSV1, so you can enjoy the convenience of SNI .
Use code to demonstrate:
server { Listen 443; server_name www.example.com; SSL on ; Ssl_certificate www.example.com.crt; ...} server { Listen 443; server_name www.example.org; SSL on ; Ssl_certificate www.example.org.crt; ...}
Using the above configuration, you will only receive the default host www.example.com certificate, regardless of which host the browser requests. This is caused by the behavior of the SSL protocol itself-establishing an SSL connection before sending an HTTP request, so nginx does not know the name of the requested host when establishing an SSL connection, so it only returns the certificate of the default host .
The oldest and most stable solution is to use a different IP address for each HTTPS host:
server { listen 192.168. 1.1:443; server_name www.example.com; SSL on ; Ssl_certificate www.example.com.crt; ...} server { Listen 192.168. 1.2:443; server_name www.example.org; SSL on ; Ssl_certificate www.example.org.crt; ...}
So, how to configure multiple HTTPS hosts on the same IP?
Nginx supports the SNI extension of the TLS protocol. However, the SNI extension must also have client support, and the local OpenSSL must support it.
If SSL support is enabled, Nginx automatically recognizes OpenSSL and enables SNI. Whether SNI support is enabled is determined at compile time by the ssl.h at the time (ssl_ctrl_set_tlsext_hostname), and if the OpenSSL library used by the compilation supports SNI, the OpenSSL library of the target system can use SNI as long as it supports it.
Nginx is the TLS SNI support disabled by default. If support is required, the compile time needs to be increased:
--with---with-openssl=./openssl-1.0
But I used the nginx/1.10.1, at compile time did not add--with-open-opt= "Enable-tlsext", can support SNI, so the latest version is open by default?
Relationship between HTTPS-SSL/TSL and SNI and SSL/TSL authentication with IP multi-domain virtual host