首頁 >後端開發 >php教程 >nginx 設定HTTPS伺服器

nginx 設定HTTPS伺服器

WBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWB
WBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWB原創
2016-08-08 09:30:14925瀏覽

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

設定HTTPS伺服器

翻譯內容可能已經過舊。 你可以透過 英文版本 查看最近的更新。

設定HTTPS主機,必須在server設定區塊中開啟SSL協議,還需要指定伺服器端憑證和金鑰檔案的位置:

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

伺服器憑證是公開的,會被傳送到每一個連接到伺服器的客戶端。而私鑰不是公開的,需要存放在存取受限的檔案中,當然,nginx主進程必須有讀取金鑰的權限。私鑰和憑證可以存放在同一個檔案中:

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

這種情況下,憑證檔案同樣得設定存取限制。當然,雖然證書和密鑰存放在同一個文件,只有證書會發送給客戶端,密鑰不會發送。

ssl_protocols和ssl_ciphers指令可以用來強制使用者連線只能引入SSL/TLS那些強壯的協定版本和強大的加密演算法。從1.0.5版本開始,nginx預設使用「ssl_protocols SSLv3 TLSv1”和“ssl_ciphers HIGH:!aNULL:!MD5”,所以只有在先前的版本,明確地配置它們才是有意義的。從1.1.13和1.0.12版本開始,nginx預設使用“ ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2」。

CBC模式的加密演算法容易受到一些攻擊,尤其是BEAST攻擊(請參閱CVE-2011-3389)。可以透過下面配置調整為優先使用RC4-SHA加密演算法:

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

HTTPS伺服器最佳化

SSL操作需要消耗CPU資源,所以在多處理器的系統,需要啟動多個工作進程,而且數量需要不少於可用CPU的數量。 CPU資源的SSL操作是SSL握手,有兩種方法可以將每個客戶端的握手操作數量降到最低:第一種是保持客戶端長連接,在一個SSL連接發送多個請求,第二種是在並發的連線或後續的連線中重複使用SSL會話參數,這樣可以避免SSL握手的操作。個會話。有些瀏覽器不接受那些眾所周知的證書認證機構簽署的證書,而另一些瀏覽器卻接受它們。但是它們本身卻不被廣泛認知,所以有些客戶端不予識別。包裹與伺服器憑證合併成一個檔案。方證書鏈合併時順序弄錯了,nginx就不能正常啟動,而且會顯示下面的錯誤訊息:

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;
        ...
因為nginx首先需要用私鑰去解密伺服器證書,而遇到的卻是認證方的憑證。中間認證機構的訊息,所以不會報錯。可以使用

openssl

命令列工具來確認伺服器發送了完整的憑證鏈:

$ cat www.example.com.crt bundle.crt > www.example.com.chained.crt
在這個範例中,www.GoDaddy.com的伺服器憑證(#0)的受簽者(「s」)是被簽發機構(「i」)簽署的,而這個簽發機構又是證書(#1)的受簽者,接著證書(#1)的簽發機構又是證書(#2)的受簽者,最後證書(#2)是被眾所周知的簽發機構ValiCert, Inc簽發。 ValiCert, Inc的證書內嵌在瀏覽器中,被瀏覽器自動辨識(這段話神似英國詩《在Jack蓋的房子裡》裡面的內容)。

如果沒有加入認證方憑證鏈,就只會顯示伺服器憑證(#0)。

合併HTTP/HTTPS主機

如果HTTP和HTTPS虛擬主機的功能是一致的,可以配置一個虛擬主機,既處理HTTP請求,又處理HTTPS請求。 配置的方法是刪除
ssl on

的指令,並在*:443連接埠中新增參數

ssl

server {
    listen              443;
    server_name         www.example.com;
    ssl                 on;
    ssl_certificate     www.example.com.chained.crt;
    ssl_certificate_key www.example.com.key;
    ...
}
在0.8.21版本以前,只有新增了
default

在0.8.21版本以前,只有新增了

default

參數的監聽埠才能加入
參數:

SSL_CTX_use_PrivateKey_file(" ... /www.example.com.key") failed
   (SSL: error:0B080074:x509 certificate routines:
    X509_check_private_key:key values mismatch)

基於名字的HTTPS主機如果在同一個IP上配置多個HTTPS主機,會出現一個很普遍的問題:

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
HTTPS伺服器最佳化
SSL憑證鏈
合併HTTP/HTTPS主機
基於名字的HTTPS主機
帶有多個主機名稱的SSL憑證
主機名稱指示
相容性
作者: Igor Sysoev
编辑: Brian Mercer
翻译: cfsego

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

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn