Nginx 單IP下 配置多個server https 啟示錄
今天重新整合https時,出現在瀏覽器用 htttp能訪問 https訪問不了的情況
nginx的配置如下:
#其他服務匹配
server {
listen 4080;
listen 443 ssl;
server_name a.szy.net;
charset utf-8;
#ssl_certificate E:/https/113152522630995.pem;
#ssl_certificate_key E:/https/113152522630995.key;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
...
}
#授權服務匹配
server {listen 80;
server_name login.dev.51110.com;
listen 443 ssl;
ssl_certificate ca/uc_oauth.crt;
ssl_certificate_key ca/uc_oauth.key.unsecure;
...
}
繞了一圈才想到去看錯誤日誌:
2017/05/25 14:24:49 [error] 5992#11288: *13 no "ssl_certificate" is defined in server listening on SSL port while SSL handshaking, client: 172.16.52.100, server: 0.0.0.0:443
2017/05/25 14:24:49 [error] 5992#11288: *14 no "ssl_certificate" is defined in server listening on SSL port while SSL handshaking, client: 172.16.52.100, server: 0.0.0.0:443
果然,一堆的沒有找到證書的錯誤,但是在上述的配置明明已經設定了ca證書,
那是ca證書被刪除了嗎?ca證書路徑錯誤?都不是...
找到了我想要的答案:ssl的匹配 先於 server的匹配
原文:
事實上,SSL執行在TCP之上(SSL/TLS協議),ssl通過四次握手 和伺服器(這裡是Nginx,LVS純轉發,可忽略)的IP + PORT(443)建立ssl連線,建立連線之後瀏覽器才會傳送HTTP請求。所以在Nginx收到HTTP請求之後才知道Host,才知道轉到哪個server 去處理,所以在SSL連線建立的時候Nginx是不知道用哪個 Server 的SSL配置的,在這種情況下,Nginx會使用它載入到的第一個SSL配置(需驗證)。當然如果你在listen 443的後面加上 default_server,Nginx就會使用此SSL配置,即:
listen 443 default_server ssl;
那麼對於單域名的https,我更喜歡把SSL配置寫在http配置裡,在server只需要加上 listen 443 ssl;
雖然裡面碰到的問題和我的不大一樣,但是裡面闡述的 nginx 的 ssl協議請求過程 卻讓我意識到問題所在
因為我本地的nginx配置檔案是從連調環境拷貝過來的,配置中本身有多個開啟了 ssl的server,
出於偷懶沒有拷貝對應的ca證書,只保留了我想要的那份,結果在使用http訪問時一切正常,但是當用https訪問時,
需要先建立ssl連結,需要要到ca證書,而在沒有 配置 “listen 443 default_server ssl;” 時,預設去找了第一個
server的 ca證書,很不巧又被我給註釋了,於是就一直出現找不到ca證書的錯誤提示
以上:
日誌要善用,有問題先看有沒有錯誤日誌,在平常的程式碼書寫過程中也要有完善的日誌輸出,方便定位問題