第十节——NGINX SSL

阅读:458 2019-03-19 15:01:16 来源:新网

为了设置https服务器,可以在nginx.conf文件中为server块中的listen指令指定ssl参数,然后设置服务器证书和秘钥文件的位置:

server{listen443ssl;server_namewww.example.com;ssl_certificatewww.example.com.crt;ssl_certificate_keywww.example.com.key;ssl_protocolstlsv1tlsv1.1tlsv1.2;ssl_ciphershigh:!anull:!md5;#...}

服务器证书是公开的实体。它发送给每个连接服务器的客户端。秘钥是安全的实体并且应该存储在限制访问的文件中。然而,nginx的主进程必须能够读取该文件。秘钥和证书存储在相同的文件中:

ssl_certificatewww.example.com.cert;ssl_certificate_keywww.example.com.cert;

在这种情况下,文件访问权限应该是严格的。虽然证书和键存储在一个文件中,但只有证书会发送到客户端。

ssl_protocols和ssl_ciphers指令可以用于限制只有包含强版本和加密的ssl/tls的连接可以访问。

从1.0.5开始,nginx默认使用ssl_protocolssslv3tlsv1和ssl_ciphershigh:!anull:md5;从1.1.13和1.0.12开始,默认更新到ssl_protocolssslv3tlsv1tlsv1.1tlsv1.2。

有时会在老的密码设计中找到漏洞,最好在现代nginx配置中禁用(可惜,默认配置不易改变,因为要向后兼容)。请注意,cbc模式密码可能会受到大量攻击,尤其是beast攻击,由于poodle攻击,最好避免使用sslv3,除非你需要支持遗留客户端。

2https服务器优化

ssl操作消耗额外的cpu资源。大多数cpu密集操作是ssl握手。有两种方式可以减少每个客户端的这些操作数:

会话存储在ssl会话缓存中,在worker进程之间共享,通过ssl_session_cache指令配置。一兆字节缓存包含大约4000个会话。默认,5分钟超时。可以使用ssl_session_timeout指令调整超时时间。下面的配置是使用10兆字节共享会话缓存优化多核系统:

worker_processesauto;http{ssl_session_cacheshared:ssl:10m;ssl_session_timeout10m;server{listen443ssl;server_namewww.example.com;keepalive_timeout70;ssl_certificatewww.example.com.crt;ssl_certificate_keywww.example.com.key;ssl_protocolstlsv1tlsv1.1tlsv1.2;ssl_ciphershigh:!anull:!md5;#...}}3ssl证书链

有些浏览器可能需要知名证书认证机构颁发的证书,而其它浏览器可能接受没有问题的证书。这是因为分发给特定浏览器的证书是由发证机关已经使用非知名证书颁发机构的中间证书签名服务器证书。在这种情况下,发证机构提供证书链,应该可以连接到已签名的服务器证书。服务器证书必须出现在合并文件的证书链的前面:

$catwww.example.com.crtbundle.crt>www.example.com.chained.crt

ssl_certificate指令应该使用的文件:

server{listen443ssl;server_namewww.example.com;ssl_certificatewww.example.com.chained.crt;ssl_certificate_keywww.example.com.key;#...}

如果服务器证书和束连接顺序错误,nginx将启动失败并显示以下错误消息:

ssl_ctx_use_privatekey_file(".../www.example.com.key")failed(ssl:error:0b080074:x509certificateroutines:x509_check_private_key:keyvaluesmismatch)

错误发生,因为nginx尝试使用秘钥和束中的第一个证书替代服务器证书。

浏览器通常存储它们接收到的是授权机构颁发的中间证书。为了确保服务器发送完整的证书链可以使用openssl命令行工具:

$openssls_client-connectwww.godaddy.com:443...certificatechain0s:/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=misdepartment/cn=www.godaddy.com/serialnumber=0796928-7/2.5.4.15=v1.0,clause5.(b)i:/c=us/st=arizona/l=scottsdale/o=godaddy.com,inc./ou=http://certificates.godaddy.com/repository/cn=godaddysecurecertificationauthority/serialnumber=079692871s:/c=us/st=arizona/l=scottsdale/o=godaddy.com,inc./ou=http://certificates.godaddy.com/repository/cn=godaddysecurecertificationauthority/serialnumber=07969287i:/c=us/o=thegodaddygroup,inc./ou=godaddyclass2certificationauthority2s:/c=us/o=thegodaddygroup,inc./ou=godaddyclass2certificationauthorityi:/l=valicertvalidationnetwork/o=valicert,inc./ou=valicertclass2policyvalidationauthority/cn=http://www.valicert.com//emailaddress=info@valicert.com...4单个http/https服务器

可以配置单个服务器处理http和https请求,在相同的虚拟主机中,使用一个带有ssl参数和一个没有ssl参数的listen:

server{listen80;listen443ssl;server_namewww.example.com;ssl_certificatewww.example.com.crt;ssl_certificate_keywww.example.com.key;#...}

在nginx0.7.13和更早版本中,ssl不能选择性的启用监听套接字。只能使用ssl指令启用整个服务器的ssl,让它不能设置一个http/https服务器。listen指令的ssl参数解决了这个问题。

一个常见的问题出现了,当两个或多个https服务器配置监听一个ip地址时:

server{listen443ssl;server_namewww.example.com;ssl_certificatewww.example.com.crt;#...}server{listen443ssl;server_namewww.example.org;ssl_certificatewww.example.org.crt;#...}

使用该配置,浏览器接收默认的服务器证书。在这种情况下,无论请求的服务器名称是什么,浏览器接收的服务器证书总是www.example.com。这是ssl协议本身导致。浏览器发送http请求前,ssl连接已经建立,nginx不知道请求的服务器名称。因此,它可能只提供默认的服务器证书。

最好的方式是分配不同的ip地址给每个https服务器:

server{listen192.168.1.1:443ssl;server_namewww.example.com;ssl_certificatewww.example.com.crt;#...}server{listen192.168.1.2:443ssl;server_namewww.example.org;ssl_certificatewww.example.org.crt;#...}5.1一个ssl证书使用多个名称

有其它方式在多个https服务器间共享单个ip地址。然而,它们都有自己的缺点。第一种方式使用subjectaltname证书字段带有多个名字的证书,例如,www.example.com和www.example.org。然而,subjectaltname字段长度是有限制的。

另一种方式是使用通配符名称,例如*.example.org。通配符证书在特定预的所有子域名中安全,但只在一个级别。该证书匹配www.example.org,但不匹配example.org或www.sub.example.org。这两种方式可以联合。可以包含精确和通配符名称在subjectaltname字段。例如,example.org和*.example.org。

最好使用多个名称放置一个证书文件,它的秘钥在http级别配置,以至于它们继承单个内存副本给所有服务器:

ssl_certificatecommon.crt;ssl_certificate_keycommon.key;server{listen443ssl;server_namewww.example.com;#...}server{listen443ssl;server_namewww.example.org;#...}

相关文章
{{ v.title }}
{{ v.description||(cleanHtml(v.content)).substr(0,100)+'···' }}
你可能感兴趣
推荐阅读 更多>
推荐商标

{{ v.name }}

{{ v.cls }}类

立即购买 联系客服