Nginx SSL Termination

阅读:446 2019-03-19 15:01:52 来源:新网

为了设置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,sslv3最好避免除非你需要支持遗留客户端为了poodle攻击。

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

启用keepalive连接通过一个连接发送多个请求

重用ssl回话参数避免并行和后续连接的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;

...

}

}

有些浏览器可能需要证书是由著名的证书认证机构颁发,然而其它浏览器可能接收证书没有问题。这是因为发布证书的服务器使用中间证书在特定的浏览器中不是权威的证书认证机构。在这种情况下,证书提供证书链束应该连接到签名服务器证书。服务器证书必须出现在合并后的文件证书链之前:

$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

...

certificatechain

0s:/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=07969287

1s:/c=us/st=arizona/l=scottsdale/o=godaddy.com,inc.

/ou=http://certificates.godaddy.com/repository

/cn=godaddysecurecertificationauthority

/serialnumber=07969287

i:/c=us/o=thegodaddygroup,inc.

/ou=godaddyclass2certificationauthority

2s:/c=us/o=thegodaddygroup,inc.

/ou=godaddyclass2certificationauthority

i:/l=valicertvalidationnetwork/o=valicert,inc.

/ou=valicertclass2policyvalidationauthority

/cn=http://www.valicert.com//emailaddress=info@valicert.com

...

inthisexamplethesubject(“s”)ofthewww.godaddy.comservercertificate#0issignedbyanissuer(“i”)whichitselfisthesubjectofthecertificate#1.thiscertificate#1issignedbyanissuerwhichitselfisthesubjectofthecertificate#2.thiscertificate,however,issignedbythewell-knownissuervalicert,inc.whosecertificateisstoredinthebrowsersthemselves.

ifacertificatebundlehasnotbeenadded,onlytheservercertificate#0willbeshown.

可以配置单个服务器处理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;

...

}

有其它方式在多个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;

...

}

amoregenericsolutionforrunningseveralhttpsserversonasingleipaddressisthetlsservernameindicationextension(sni,rfc6066),whichallowsabrowsertopassarequestedservernameduringthesslhandshake.withthissolution,theserverwillknowwhichcertificateitshouldusefortheconnection.however,snihaslimitedbrowsersupport.currentlyitissupportedstartingwiththefollowingbrowserversions:

opera8.0;

msie7.0(butonlyonwindowsvistaorhigher);

firefox2.0andotherbrowsersusingmozillaplatformrv:1.8.1;

safari3.2.1(windowsversionsupportssnionvistaorhigher);

andchrome(windowsversionsupportssnionvistaorhigher,too).

onlydomainnamescanbepassedinsni.however,somebrowserswillpasstheipaddressoftheserverasitsnameifarequestincludesaliteralipaddress.itisbestnottorelyonthis.

inordertousesniinnginx,itmustbesupportedinboththeopenssllibrarywithwhichthenginxbinaryhasbeenbuiltwithaswellasthelibrarywhichitisbeingdynamicallylinkedwithatruntime.opensslsupportssnisincethe0.9.8fversionifitwasbuiltwithconfigurationoption--enable-tlsext.sinceopensslversion0.9.8j,thisoptionisenabledbydefault.ifnginxwasbuiltwithsnisupport,nginxshowsthefollowingwhenrunwiththe-vswitch:

$nginx-v

...

tlssnisupportenabled

...

however,ifthesni-enablednginxislinkeddynamicallytoanopenssllibrarywithoutsnisupport,nginxdisplaysthewarning:

nginxwasbuiltwithsnisupport,however,nowitislinked

dynamicallytoanopenssllibrarywhichhasnotlsextsupport,

thereforesniisnotavailable

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

{{ v.name }}

{{ v.cls }}类

立即购买 联系客服