配置HTTPS服務(wù)器
創(chuàng)新互聯(lián)建站是一家企業(yè)級(jí)云計(jì)算解決方案提供商,超15年IDC數(shù)據(jù)中心運(yùn)營(yíng)經(jīng)驗(yàn)。主營(yíng)GPU顯卡服務(wù)器,站群服務(wù)器,托管服務(wù)器,海外高防服務(wù)器,機(jī)柜大帶寬、租用·托管,動(dòng)態(tài)撥號(hào)VPS,海外云手機(jī),海外云服務(wù)器,海外服務(wù)器租用托管等。配置HTTPS主機(jī),必須在server配置塊中打開(kāi)SSL協(xié)議,還需要指定服務(wù)器端證書(shū)和密鑰文件的位置:
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;
…
}
服務(wù)器證書(shū)是公開(kāi)的,會(huì)被傳送到每一個(gè)連接到服務(wù)器的客戶端。而私鑰不是公開(kāi)的,需要存放在訪問(wèn)受限的文件中,當(dāng)然,nginx主進(jìn)程必須有讀取密鑰的權(quán)限。私鑰和證書(shū)可以存放在同一個(gè)文件中:
ssl_certificate www.example.com.cert;
ssl_certificate_key www.example.com.cert;
這種情況下,證書(shū)文件同樣得設(shè)置訪問(wèn)限制。當(dāng)然,雖然證書(shū)和密鑰存放在同一個(gè)文件,只有證書(shū)會(huì)發(fā)送給客戶端,密鑰不會(huì)發(fā)送。
ssl_protocols和ssl_ciphers指令可以用來(lái)強(qiáng)制用戶連接只能引入SSL/TLS那些強(qiáng)壯的協(xié)議版本和強(qiáng)大的加密算法。從1.0.5版本開(kāi)始,nginx默認(rèn)使用“ssl_protocols SSLv3 TLSv1”和“ssl_ciphers HIGH:!aNULL:!MD5”,所以只有在之前的版本,明確地配置它們才是有意義的。從1.1.13和1.0.12版本開(kāi)始,nginx默認(rèn)使用“ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2”。
CBC模式的加密算法容易受到一些攻擊,尤其是BEAST攻擊(參見(jiàn)CVE-2011-3389)??梢酝ㄟ^(guò)下面配置調(diào)整為優(yōu)先使用RC4-SHA加密算法:
ssl_ciphers RC4:HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
HTTPS服務(wù)器優(yōu)化
SSL操作需要消耗CPU資源,所以在多處理器的系統(tǒng),需要啟動(dòng)多個(gè)工作進(jìn)程,而且數(shù)量需要不少于可用CPU的個(gè)數(shù)。最消耗CPU資源的SSL操作是SSL握手,有兩種方法可以將每個(gè)客戶端的握手操作數(shù)量降到最低:第一種是保持客戶端長(zhǎng)連接,在一個(gè)SSL連接發(fā)送多個(gè)請(qǐng)求,第二種是在并發(fā)的連接或者后續(xù)的連接中重用SSL會(huì)話參數(shù),這樣可以避免SSL握手的操作。會(huì)話緩存用于保存SSL會(huì)話,這些緩存在工作進(jìn)程間共享,可以使用ssl_session_cache指令進(jìn)行配置。1M緩存可以存放大約4000個(gè)會(huì)話。默認(rèn)的緩存超時(shí)是5分鐘,可以使用ssl_session_timeout加大它。下面是一個(gè)針對(duì)4核系統(tǒng)的配置優(yōu)化的例子,使用10M的共享會(huì)話緩存:
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;
…
SSL證書(shū)鏈
有些瀏覽器不接受那些眾所周知的證書(shū)認(rèn)證機(jī)構(gòu)簽署的證書(shū),而另外一些瀏覽器卻接受它們。這是由于證書(shū)簽發(fā)使用了一些中間認(rèn)證機(jī)構(gòu),這些中間機(jī)構(gòu)被眾所周知的證書(shū)認(rèn)證機(jī)構(gòu)授權(quán)代為簽發(fā)證書(shū),但是它們自己卻不被廣泛認(rèn)知,所以有些客戶端不予識(shí)別。針對(duì)這種情況,證書(shū)認(rèn)證機(jī)構(gòu)提供一個(gè)證書(shū)鏈的包裹,用來(lái)聲明眾所周知的認(rèn)證機(jī)構(gòu)和自己的關(guān)系,需要將這個(gè)證書(shū)鏈包裹與服務(wù)器證書(shū)合并成一個(gè)文件。在這個(gè)文件里,服務(wù)器證書(shū)需要出現(xiàn)在認(rèn)證方證書(shū)鏈的前面:
$ cat www.example.com.crt bundle.crt > www.example.com.chained.crt
這個(gè)文件需要使用ssl_certificate指令來(lái)引用:
server {
listen 443;
server_name www.example.com;
ssl on;
ssl_certificate www.example.com.chained.crt;
ssl_certificate_key www.example.com.key;
…
}
如果服務(wù)器證書(shū)和認(rèn)證方證書(shū)鏈合并時(shí)順序弄錯(cuò)了,nginx就不能正常啟動(dòng),而且會(huì)顯示下面的錯(cuò)誤信息:
SSL_CTX_use_PrivateKey_file(” … /www.example.com.key”) failed
(SSL: error:0B080074:x509 certificate routines:
X509_check_private_key:key values mismatch)
因?yàn)閚ginx首先需要用私鑰去解密服務(wù)器證書(shū),而遇到的卻是認(rèn)證方的證書(shū)。
瀏覽器通常會(huì)將那些被受信的認(rèn)證機(jī)構(gòu)認(rèn)證的中間認(rèn)證機(jī)構(gòu)保存下來(lái),那么這些瀏覽器以后在遇到使用這些中間認(rèn)證機(jī)構(gòu)但不包含證書(shū)鏈的情況時(shí),因?yàn)橐呀?jīng)保存了這些中間認(rèn)證機(jī)構(gòu)的信息,所以不會(huì)報(bào)錯(cuò)??梢允褂胦penssl命令行工具來(lái)確認(rèn)服務(wù)器發(fā)送了完整的證書(shū)鏈:
$ 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
…
在這個(gè)例子中,www.GoDaddy.com的服務(wù)器證書(shū)(#0)的受簽者(“s”)是被簽發(fā)機(jī)構(gòu)(“i”)簽名的,而這個(gè)簽發(fā)機(jī)構(gòu)又是證書(shū)(#1)的受簽者,接著證書(shū)(#1)的簽發(fā)機(jī)構(gòu)又是證書(shū)(#2)的受簽者,最后證書(shū)(#2)是被眾所周知的簽發(fā)機(jī)構(gòu)ValiCert, Inc簽發(fā)。ValiCert, Inc的證書(shū)內(nèi)嵌在瀏覽器中,被瀏覽器自動(dòng)識(shí)別(這段話神似英國(guó)詩(shī)《在Jack蓋的房子里》里面的內(nèi)容)。
如果沒(méi)有加入認(rèn)證方證書(shū)鏈,就只會(huì)顯示服務(wù)器證書(shū)(#0)。
合并HTTP/HTTPS主機(jī)
如果HTTP和HTTPS虛擬主機(jī)的功能是一致的,可以配置一個(gè)虛擬主機(jī),既處理HTTP請(qǐng)求,又處理HTTPS請(qǐng)求。 配置的方法是刪除ssl on的指令,并在*:443端口添加參數(shù)ssl:
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.8.21版本以前,只有添加了default參數(shù)的監(jiān)聽(tīng)端口才能添加ssl參數(shù):
listen 443 default ssl;
基于名字的HTTPS主機(jī)
如果在同一個(gè)IP上配置多個(gè)HTTPS主機(jī),會(huì)出現(xiàn)一個(gè)很普遍的問(wèn)題:
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;
…
}
使用上面的配置,不論瀏覽器請(qǐng)求哪個(gè)主機(jī),都只會(huì)收到默認(rèn)主機(jī)www.example.com的證書(shū)。這是由SSL協(xié)議本身的行為引起的——先建立SSL連接,再發(fā)送HTTP請(qǐng)求,所以nginx建立SSL連接時(shí)不知道所請(qǐng)求主機(jī)的名字,因此,它只會(huì)返回默認(rèn)主機(jī)的證書(shū)。
最古老的也是最穩(wěn)定的解決方法就是每個(gè)HTTPS主機(jī)使用不同的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;
…
}
帶有多個(gè)主機(jī)名的SSL證書(shū)
也有其他一些方法可以實(shí)現(xiàn)多個(gè)HTTPS主機(jī)共享一個(gè)IP地址,但都有不足。其中一種方法是使用在“SubjectAltName”字段中存放多個(gè)名字的證書(shū),比如www.example.com和www.example.org。但是,“SubjectAltName”字段的長(zhǎng)度有限制。
另一種方式是使用主機(jī)名中含有通配符的證書(shū),比如*.example.org。這個(gè)證書(shū)匹配www.example.org,但是不匹配example.org和www.sub.example.org。這兩種方法可以結(jié)合在一起——使用在“SubjectAltName”字段中存放的多個(gè)名字的證書(shū),這些名字既可以是確切的名字,也可以是通配符,比如example.org和*.example.org。
最好將帶有多個(gè)名字的證書(shū)和它的密鑰文件配置在http配置塊中,這樣可以只保存一份內(nèi)容拷貝,所有主機(jī)的配置都從中繼承:
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;
…
}
主機(jī)名指示
在一個(gè)IP上運(yùn)行多個(gè)HTTPS主機(jī)的更通用的方案是TLS主機(jī)名指示擴(kuò)展(SNI,RFC6066),它允許瀏覽器和服務(wù)器進(jìn)行SSL握手時(shí),將請(qǐng)求的主機(jī)名傳遞給服務(wù)器,因此服務(wù)器可以知道使用哪一個(gè)證書(shū)來(lái)服務(wù)這個(gè)連接。但SNI只得到有限的瀏覽器的支持。下面列舉支持SNI的瀏覽器最低版本和平臺(tái)信息:
Opera 8.0;
MSIE 7.0(僅在Windows Vista操作系統(tǒng)及后續(xù)操作系統(tǒng));
Firefox 2.0和使用Mozilla平臺(tái)1.8.1版本的其他瀏覽器;
Safari 3.2.1(Windows版需要最低Vista操作系統(tǒng));
Chrome(Windows版需要最低Vista操作系統(tǒng))。
通過(guò)SNI只能傳遞域名,但是,當(dāng)請(qǐng)求中包含可讀的IP地址時(shí),某些瀏覽器將服務(wù)器的IP地址作為服務(wù)器的名字進(jìn)行了傳送。這是一個(gè)錯(cuò)誤,大家不應(yīng)該依賴于這個(gè)。
為了在nginx中使用SNI,那么無(wú)論是在編譯nginx時(shí)使用的OpenSSL類庫(kù),還是在運(yùn)行nginx時(shí)使用的OpenSSL運(yùn)行庫(kù),都必須支持SNI。從0.9.8f版本開(kāi)始,OpenSSL通過(guò)“–enable-tlsext”配置選項(xiàng)加入SNI支持,從0.9.8j版本開(kāi)始,此選項(xiàng)成為默認(rèn)選項(xiàng)。當(dāng)nginx被編譯成支持SNI時(shí),在使用“-V”選項(xiàng)運(yùn)行時(shí)會(huì)顯示如下信息:
$ nginx -V
…
TLS SNI support enabled
…
但是,當(dāng)開(kāi)啟SNI支持的nginx被動(dòng)態(tài)鏈接到不支持SNI的OpenSSL庫(kù)上時(shí),nginx會(huì)顯示如下警告:
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版本開(kāi)始,使用“-V”選項(xiàng)運(yùn)行nginx時(shí),將顯示SNI支持狀態(tài)信息。
從0.7.14版本開(kāi)始,listen指令支持ssl參數(shù)。
從0.5.32版本開(kāi)始,支持SNI。
從0.5.6版本開(kāi)始,支持SSL會(huì)話緩存,并可在工作進(jìn)程間共享。
0.7.65、0.8.19及以后版本,默認(rèn)SSL協(xié)議是SSLv3、TLSv1、TLSc1.1和TLSv1.2(如果OpenSSL庫(kù)支持)。
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。
全球可信CA機(jī)構(gòu)