Home  >  Article  >  Backend Development  >  nginx configure HTTPS server

nginx configure HTTPS server

WBOY
WBOYOriginal
2016-08-08 09:30:14848browse

http://nginx.org/cn/docs/http/configuring_https_servers.html

Configuring HTTPS Servers

The translated content may be out of date. You can view the latest updates via the English version . +

To configure the HTTPS host, you must open the SSL protocol in the server configuration block and specify the location of the server-side certificate and key files:

server {
    listen              443;
    server_name         www.example.com;
    ssl                 on;
    ssl_certificate     www.example.com.crt;
    ssl_certificate_key www.example.com.key;
    ssl_protocols       SSLv3 TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers         HIGH:!aNULL:!MD5;
    ...
}

The server certificate is public and will be transmitted to every client connected to the server end. The private key is not public and needs to be stored in a file with restricted access. Of course, the nginx main process must have permission to read the key. The private key and certificate can be stored in the same file:

    ssl_certificate     www.example.com.cert;
    ssl_certificate_key www.example.com.cert;

In this case, access restrictions must also be set on the certificate file. Of course, although the certificate and key are stored in the same file, only the certificate will be sent to the client, not the key.

The ssl_protocols and ssl_ciphers directives can be used to force user connections to only introduce strong protocol versions and powerful encryption algorithms of SSL/TLS. Starting from version 1.0.5, nginx uses "ssl_protocols" by default SSLv3 TLSv1" and "ssl_ciphers HIGH:!aNULL:!MD5", so only in previous versions, it makes sense to configure them explicitly. Starting from version 1.1.13 and 1.0.12, nginx uses " ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2".

The encryption algorithm in CBC mode is vulnerable to some attacks, especially the BEAST attack (see CVE-2011-3389). It can be adjusted to preferentially use RC4-SHA encryption through the following configuration Algorithm:

    ssl_ciphers RC4:HIGH:!aNULL:!MD5;
    ssl_prefer_server_ciphers on;

HTTPS server optimization

SSL operations consume CPU resources, so in a multi-processor system, multiple worker processes need to be started, and the number needs to be no less than the number of available CPUs. The SSL operation of CPU resources is the SSL handshake. There are two methods to minimize the number of handshake operations for each client: the first is to keep the client long connected and send multiple requests in one SSL connection; the second is to Reuse SSL session parameters in concurrent connections or subsequent connections to avoid SSL handshake operations. The session cache is used to save SSL sessions. These caches are shared between worker processes and can be configured using the ssl_session_cache directive. The 1M cache can store approximately 4000. session. The default cache timeout is 5 minutes, you can use ssl_session_timeout to increase it. Here is an example of configuration optimization for a 4-core system, using a 10M shared session cache:

SSL certificate chain

Some browsers do not accept certificates signed by well-known certificate authorities, while other browsers do accept them. This is because the certificate issuance uses some intermediate certificate authorities, which are authorized by the well-known certificate authorities to issue certificates on their behalf. However, they themselves are not widely recognized, so some clients do not recognize them. In this case, the certificate certification authority provides a certificate chain package to declare the relationship between the well-known certification authority and itself. This certificate chain needs to be included. The package is combined with the server certificate into one file. In this file, the server certificate needs to appear at the front of the authenticator certificate chain:

worker_processes  4;

http {
    ssl_session_cache    shared:SSL:10m;
    ssl_session_timeout  10m;

    server {
        listen              443;
        server_name         www.example.com;
        keepalive_timeout   70;

        ssl                 on;
        ssl_certificate     www.example.com.crt;
        ssl_certificate_key www.example.com.key;
        ssl_protocols       SSLv3 TLSv1 TLSv1.1 TLSv1.2;
        ssl_ciphers         HIGH:!aNULL:!MD5;
        ...
This file needs to be referenced using the ssl_certificate directive:

$ cat www.example.com.crt bundle.crt > www.example.com.chained.crt
If the server certificate and certification The order of the party certificate chain is wrong when merging, nginx cannot start normally, and the following error message will be displayed:

server {
    listen              443;
    server_name         www.example.com;
    ssl                 on;
    ssl_certificate     www.example.com.chained.crt;
    ssl_certificate_key www.example.com.key;
    ...
}
Because nginx first needs to use the private key to decrypt the server certificate, but what it encounters is the authenticator's. Certificates.

Browsers usually save intermediate certification authorities that are certified by trusted certification authorities. Then when these browsers encounter the situation of using these intermediate certification authorities but do not include the certificate chain, they have already saved them. The information of the intermediate certification authority, so no error will be reported. You can use the

openssl

command line tool to confirm that the server sent the complete certificate chain:

SSL_CTX_use_PrivateKey_file(" ... /www.example.com.key") failed
   (SSL: error:0B080074:x509 certificate routines:
    X509_check_private_key:key values mismatch)
In this example, the signee ("s") of the server certificate (#0) for www.GoDaddy.com is Signed by the issuing authority ("i"), which is the signee of the certificate (#1), then the issuing authority of the certificate (#1) is the signee of the certificate (#2), and finally the certificate (#2) is issued by ValiCert, Inc, a well-known issuing agency. The certificate of ValiCert, Inc is embedded in the browser and is automatically recognized by the browser (this passage is similar to the content of the British poem "In the House That Jack Built").

If the authenticator certificate chain is not added, only the server certificate (#0) will be displayed.

Merge HTTP/HTTPS host

If the functions of HTTP and HTTPS virtual hosts are consistent, you can configure a virtual host to handle both HTTP requests and HTTPS requests. The configuration method is to delete the
ssl on

command and add the parameter ssl to the *:443 port:

$ openssl s_client -connect www.godaddy.com:443
...
Certificate chain
 0 s:/C=US/ST=Arizona/L=Scottsdale/1.3.6.1.4.1.311.60.2.1.3=US
     /1.3.6.1.4.1.311.60.2.1.2=AZ/O=GoDaddy.com, Inc
     /OU=MIS Department/CN=www.GoDaddy.com
     /serialNumber=0796928-7/2.5.4.15=V1.0, Clause 5.(b)
   i:/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc.
     /OU=http://certificates.godaddy.com/repository
     /CN=Go Daddy Secure Certification Authority
     /serialNumber=07969287
 1 s:/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc.
     /OU=http://certificates.godaddy.com/repository
     /CN=Go Daddy Secure Certification Authority
     /serialNumber=07969287
   i:/C=US/O=The Go Daddy Group, Inc.
     /OU=Go Daddy Class 2 Certification Authority
 2 s:/C=US/O=The Go Daddy Group, Inc.
     /OU=Go Daddy Class 2 Certification Authority
   i:/L=ValiCert Validation Network/O=ValiCert, Inc.
     /OU=ValiCert Class 2 Policy Validation Authority
     /CN=http://www.valicert.com//emailAddress=info@valicert.com
...
Before version 0.8.21, only the listening port with the
default
parameter added can add ssl Parameters: <pre class="brush:php;toolbar:false">server { listen 80; listen 443 ssl; server_name www.example.com; ssl_certificate www.example.com.crt; ssl_certificate_key www.example.com.key; ... } </pre>
Name-based HTTPS host

If you configure multiple HTTPS hosts on the same IP, a very common problem will occur:
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;
    ...
}

使用上面的配置,不论浏览器请求哪个主机,都只会收到默认主机www.example.com的证书。这是由SSL协议本身的行为引起的——先建立SSL连接,再发送HTTP请求,所以nginx建立SSL连接时不知道所请求主机的名字,因此,它只会返回默认主机的证书。

最古老的也是最稳定的解决方法就是每个HTTPS主机使用不同的IP地址:

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;
    ...
}

带有多个主机名的SSL证书

也有其他一些方法可以实现多个HTTPS主机共享一个IP地址,但都有不足。其中一种方法是使用在“SubjectAltName”字段中存放多个名字的证书,比如www.example.comwww.example.org。但是,“SubjectAltName”字段的长度有限制。

另一种方式是使用主机名中含有通配符的证书,比如*.example.org。这个证书匹配www.example.org,但是不匹配example.orgwww.sub.example.org。这两种方法可以结合在一起——使用在“SubjectAltName”字段中存放的多个名字的证书,这些名字既可以是确切的名字,也可以是通配符,比如example.org*.example.org

最好将带有多个名字的证书和它的密钥文件配置在http配置块中,这样可以只保存一份内容拷贝,所有主机的配置都从中继承:

ssl_certificate      common.crt;
ssl_certificate_key  common.key;

server {
    listen          443;
    server_name     www.example.com;
    ssl             on;
    ...
}

server {
    listen          443;
    server_name     www.example.org;
    ssl             on;
    ...
}

主机名指示

在一个IP上运行多个HTTPS主机的更通用的方案是TLS主机名指示扩展(SNI,RFC6066),它允许浏览器和服务器进行SSL握手时,将请求的主机名传递给服务器,因此服务器可以知道使用哪一个证书来服务这个连接。但SNI只得到有限的浏览器的支持。下面列举支持SNI的浏览器最低版本和平台信息:

  • Opera 8.0;
  • MSIE 7.0(仅在Windows Vista操作系统及后续操作系统);
  • Firefox 2.0和使用Mozilla平台1.8.1版本的其他浏览器;
  • Safari 3.2.1(Windows版需要最低Vista操作系统);
  • Chrome(Windows版需要最低Vista操作系统)。
通过SNI只能传递域名,但是,当请求中包含可读的IP地址时,某些浏览器将服务器的IP地址作为服务器的名字进行了传送。这是一个错误,大家不应该依赖于这个。

为了在nginx中使用SNI,那么无论是在编译nginx时使用的OpenSSL类库,还是在运行nginx时使用的OpenSSL运行库,都必须支持SNI。从0.9.8f版本开始,OpenSSL通过“--enable-tlsext”配置选项加入SNI支持,从0.9.8j版本开始,此选项成为默认选项。当nginx被编译成支持SNI时,在使用“-V”选项运行时会显示如下信息:

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

但是,当开启SNI支持的nginx被动态链接到不支持SNI的OpenSSL库上时,nginx会显示如下警告:

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

兼容性

  • 从0.8.21和0.7.62版本开始,使用“-V”选项运行nginx时,将显示SNI支持状态信息。
  • 从0.7.14版本开始,listen指令支持ssl参数。
  • 从0.5.32版本开始,支持SNI。
  • 从0.5.6版本开始,支持SSL会话缓存,并可在工作进程间共享。
  • 0.7.65、0.8.19及以后版本,默认SSL协议是SSLv3、TLSv1、TLSc1.1和TLSv1.2(如果OpenSSL库支持)。
  • 0.7.64、0.8.18及以前版本,默认SSL协议是SSLv2、SSLv3和TLSv1。
  • 1.0.5及以后版本,默认SSL密码算法是HIGH:!aNULL:!MD5
  • 0.7.65、0.8.20及以后版本,默认SSL密码算法是HIGH:!ADH:!MD5
  • 0.8.19版本,默认SSL密码算法是ALL:!ADH:RC4+RSA:+HIGH:+MEDIUM
  • 0.7.64、0.8.18及以前版本,默认SSL密码算法是ALL:!ADH:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP
作者: Igor Sysoev
编辑: Brian Mercer
翻译: cfsego

以上就介绍了nginx 配置HTTPS服务器,包括了方面的内容,希望对PHP教程有兴趣的朋友有所帮助。

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn