默認(rèn)配置
要配置HTTPS服務(wù)器,必須 在服務(wù)器塊中的偵聽套接字上啟用ssl參數(shù) 蜕该,并且 應(yīng)指定服務(wù)器證書 和 私鑰文件的位置 :
server {
listen 443 ssl;
server_name www.example.com;
ssl_certificate www.example.com.crt;
ssl_certificate_key www.example.com.key;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers HIGH:!aNULL:!MD5;
...
}
服務(wù)器證書是公共實體洲鸠。它被發(fā)送到連接到服務(wù)器的每個客戶端。私鑰是一個安全的實體扒腕,應(yīng)該存儲在具有受限訪問權(quán)限的文件中,但是皆的,它必須是nginx的主進(jìn)程可讀的蹋盆。私鑰可以替代地存儲在與證書相同的文件中:
ssl_certificate www.example.com.cert;
ssl_certificate_key www.example.com.cert;
在這種情況下,還應(yīng)限制文件訪問權(quán)限栖雾。雖然證書和密鑰存儲在一個文件中,但只有證書才會發(fā)送到客戶端拌倍。
指令ssl_protocols和 ssl_ciphers 可用于限制連接以僅包括SSL/TLS的強版本和密碼。默認(rèn)情況下数初,nginx使用“ssl_protocols TLSv1 TLSv1.1 TLSv1.2”和“ssl_ciphers HIGH:!aNULL:!MD5”梗顺,因此通常不需要顯式配置它們。請注意寺谤,這些指令的默認(rèn)值已 多次更改。
HTTPS服務(wù)器優(yōu)化
SSL操作會消耗額外的CPU資源眼俊。在多處理器系統(tǒng)上粟关, 應(yīng)運行多個工作進(jìn)程,不少于可用CPU核心數(shù)澎灸。CPU占用最多的操作是SSL握手遮晚。有兩種方法可以最大限度地減少每個客戶端的這些操作數(shù)量:第一種方法是通過啟用 keepalive 連接來通過一個連接發(fā)送多個請求,第二種方法是重用SSL會話參數(shù)以避免SSL并行連接和后續(xù)連接糜颠。會話存儲在worker之間共享的SSL會話高速緩存中艺玲,并由ssl_session_cache 指令配置 。一兆字節(jié)的緩存包含大約4000個會話饭聚。默認(rèn)緩存超時為5分鐘秒梳。它可以通過使用增加 ssl_session_timeout 指令。以下是針對具有10兆字節(jié)共享會話緩存的多核系統(tǒng)優(yōu)化的示例配置:
worker_processes auto;
http {
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
server {
listen 443 ssl;
server_name www.example.com;
keepalive_timeout 70;
ssl_certificate www.example.com.crt;
ssl_certificate_key www.example.com.key;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers HIGH:!aNULL:!MD5;
...
SSL證書鏈
某些瀏覽器可能會對由知名證書頒發(fā)機構(gòu)簽名的證書發(fā)出警告朋譬,而其他瀏覽器可能會毫無問題地接受證書兴垦。發(fā)生這種情況是因為頒發(fā)機構(gòu)使用中間證書對服務(wù)器證書進(jìn)行了簽名字柠,該中間證書不存在于與特定瀏覽器一起分發(fā)的眾所周知的可信證書頒發(fā)機構(gòu)的證書庫中狡赐。在這種情況下,授權(quán)機構(gòu)提供一組鏈?zhǔn)阶C書常柄,這些證書應(yīng)連接到簽名的服務(wù)器證書搀擂。服務(wù)器證書必須出現(xiàn)在組合文件中的鏈?zhǔn)阶C書之前:
$ cat www.example.com.crt bundle.crt > www.example.com.chained.crt
生成的文件應(yīng)該在 ssl_certificate指令中使用:
server {
listen 443 ssl;
server_name www.example.com;
ssl_certificate www.example.com.chained.crt;
ssl_certificate_key www.example.com.key;
...
}
如果服務(wù)器證書和軟件包的連接(cat bundle.crt > chained.crt )順序錯誤,則nginx將無法啟動并顯示錯誤消息:
SSL_CTX_use_PrivateKey_file(" ... /www.example.com.key") failed
(SSL: error:0B080074:x509 certificate routines:
X509_check_private_key:key values mismatch)
因為nginx嘗試將私鑰與bundle的第一個證書而不是服務(wù)器證書一起使用喷市。
瀏覽器通常存儲他們收到的中間證書咆蒿,并由受信任的權(quán)威機構(gòu)簽名,因此主動使用的瀏覽器可能已經(jīng)擁有所需的中間證書,并且可能不會警告沒有證書鏈發(fā)送的證書食茎。要確保服務(wù)器發(fā)送完整的證書鏈,openssl可以使用命令行實用程序附迷,例如:
$ 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
...
使用SNI測試配置時喇伯,指定-servername選項非常重要拨与,因為openssl默認(rèn)情況下不使用SNI。
In this example the subject (“s”) of the www.GoDaddy.com server certificate #0 is signed by an issuer (“i”) which itself is the subject of the certificate #1, which is signed by an issuer which itself is the subject of the certificate #2, which signed by the well-known issuer ValiCert, Inc. whose certificate is stored in the browsers’ built-in certificate base (that lay in the house that Jack built).
在該示例中买喧,服務(wù)器證書#0 的主題(“ s ”) www.GoDaddy.com由發(fā)行者(“ i ”)簽名淤毛,發(fā)行者本身是證書#1的主題,其由發(fā)行者簽署低淡,發(fā)行者本身是發(fā)行者的主題瞬项。證書#2何荚,由知名發(fā)行人ValiCert,Inc绎橘。簽署唠倦, 其證書存儲在瀏覽器的內(nèi)置證書庫(位于Jack建造的房屋內(nèi))中。
如果尚未添加證書包冈止,則僅顯示服務(wù)器證書#0候齿。
單個HTTP / HTTPS服務(wù)器
可以配置處理HTTP和HTTPS請求的單個服務(wù)器:
server{
listen 80;
listen 443 ssl;
server_name www.example.com;
ssl_certificate www.example.com.crt;
ssl_certificate_key www.example.com.key;
...
}
在0.7.14之前,無法為個別偵聽套接字選擇性地啟用SSL周霉,如上所示亚皂。只能使用ssl指令為整個服務(wù)器啟用 SSL,從而無法設(shè)置單個HTTP / HTTPS服務(wù)器灭必。添加ssl了listen指令的參數(shù) 來解決此問題。因此不鼓勵在現(xiàn)代版本中使用 ssl指令跟衅。
基于名稱的HTTPS服務(wù)器
配置偵聽單個IP地址的兩個或多個HTTPS服務(wù)器時會出現(xiàn)一個常見問題:
server {
listen 443 ssl;
server_name www.example.com;
ssl_certificate www.example.com.crt;
...
}
server {
listen 443 ssl;
server_name www.example.org;
ssl_certificate www.example.org.crt;
...
}
使用此配置播歼,瀏覽器將接收默認(rèn)服務(wù)器的證書,即www.example.com,無論請求的服務(wù)器名稱如何,這是由SSL協(xié)議行為引起的撩穿。在瀏覽器發(fā)送HTTP請求之前建立SSL連接谒撼,并且nginx不知道所請求服務(wù)器的名稱。因此抵皱,它可能只提供默認(rèn)服務(wù)器的證書。
解決此問題的最古老呻畸,最強大的方法是為每個HTTPS服務(wù)器分配一個單獨的IP地址:
server {
listen 192.168.1.1:443 ssl;
server_name www.example.com;
ssl_certificate www.example.com.crt;
...
}
server {
listen 192.168.1.2:443 ssl;
server_name www.example.org;
ssl_certificate www.example.org.crt;
...
}
具有多個名稱的SSL證書
還有其他方法允許在多個HTTPS服務(wù)器之間共享單個IP地址伤为。但是,所有這些都有它們的缺點绞愚。一種方法是在SubjectAltName證書字段中使用具有多個名稱的證書,例如裆蒸, www.example.com和www.example.org糖驴。但是,SubjectAltName字段長度是有限的辙谜。
另一種方法是使用帶有通配符名稱的證書感昼,例如 .example.org。通配符證書可保護指定域的所有子域抑诸,但僅限于一個級別爹殊。此證書匹配www.example.org梗夸,但不匹配 example.org和www.sub.example.org。這兩種方法也可以組合使用反症。證書可以包含在SubjectAltName字段準(zhǔn)確和通配符的名稱,例如润绵, example.org和.example.org胞谈。
最好將具有多個名稱的證書文件及其私鑰文件放在配置的http級別憨愉,以在所有服務(wù)器中繼承其單個內(nèi)存副本:
ssl_certificate common.crt;
ssl_certificate_key common.key;
server {
listen 443 ssl;
server_name www.example.com;
...
}
server {
listen 443 ssl;
server_name www.example.org;
...
}
服務(wù)器名稱指示(SNI)
在單個IP地址上運行多個HTTPS服務(wù)器的更通用的解決方案是 TLS服務(wù)器名稱指示擴展(SNI卿捎,RFC 6066),它允許瀏覽器在SSL握手期間傳遞請求的服務(wù)器名稱午阵,因此,服務(wù)器將知道哪個它應(yīng)該用于連接的證書植袍。目前 大多數(shù)現(xiàn)代瀏覽器都支持 SNI 戚啥,但某些老瀏覽器或特殊瀏覽器可能無法使用。
只有域名可以在SNI中傳遞览濒,但是如果請求包含文字IP地址拖云,某些瀏覽器可能會錯誤地將服務(wù)器的IP地址作為其名稱傳遞。人們不應(yīng)該依賴于此宙项。
為了在nginx中使用SNI,必須在構(gòu)建nginx二進(jìn)制文件的OpenSSL庫以及在運行時動態(tài)鏈接到的庫中支持它汇荐。如果使用配置選項“--enable-tlsext”構(gòu)建盆繁,OpenSSL支持0.9.8f版本的SNI 。 自O(shè)penSSL 0.9.8j以來革娄,默認(rèn)情況下啟用此選項冕碟。如果nginx是使用SNI支持構(gòu)建的,那么當(dāng)使用“-V”開關(guān)運行時厕妖,nginx將顯示:
$ nginx -V
...
TLS SNI support enabled
...
但是我衬,如果啟用SNI的nginx動態(tài)鏈接到?jīng)]有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”開關(guān)顯示SNI支持狀態(tài)。
自0.7.14起支持listen指令 的ssl參數(shù) 雹嗦。在0.8.21之前合是,它只能與參數(shù)default一起指定 。
SNI自0.5.23以來一直受到支持聪全。
自0.5.6以來一直支持共享SSL會話緩存难礼。
版本1.9.1及更高版本:默認(rèn)的SSL協(xié)議是TLSv1,TLSv1.1和TLSv1.2(如果受OpenSSL庫支持)蛾茉。
版本0.7.65,0.8.19及更高版本:默認(rèn)的SSL協(xié)議是SSLv3,TLSv1悦屏,TLSv1.1和TLSv1.2(如果OpenSSL庫支持)键思。
版本0.7.64,0.8.18及更早版本:默認(rèn)的SSL協(xié)議是SSLv2,SSLv3和TLSv1幕帆。
版本1.0.5及更高版本:默認(rèn)的SSL密碼為“ HIGH:!aNULL:!MD5”赖条。
版本0.7.65,0.8.20及更高版本:默認(rèn)SSL密碼為“ HIGH:!ADH:!MD5”常熙。
版本0.8.19:默認(rèn)的SSL密碼為“ ALL:!ADH:RC4+RSA:+HIGH:+MEDIUM”。
版本0.7.64,0.8.18及更早版本:默認(rèn)SSL密碼為
“ ALL:!ADH:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP”仿贬。