記一次nginx部署https訪問出現證書鏈不全的問題
前情提要:
現在這個環境下,公司的專案基本上都是要求用https訪問的,不然後續安全檢測過不去,以前專案一開始用的http,後面轉成https,一改各種問題出現,web端app端還好說,重新發包,改下介面呼叫地址的事情,最麻煩的是那些自助終端,以及各種需要調我們服務的第三方也得改,七改八改的總會有遺漏的地方,這次專案正好從頭開始(其實已經兩個月了),乾脆一開始就配置成https訪問了。
和別的專案一樣,這邊的後臺還是我搭一個nginx來進行軟負載,並且對映到外網提供介面服務,不同的是,其他專案客戶那邊都早已經申請過https的證書,我提出來要過來配置一下就行了,而這邊專案,說是app之前已經執行幾年了(原app公司不維護了,我們過來重新開發app去替代他們的),結果並沒有申請過ssl證書,然後這邊客戶方的人員對應證書這塊也是都不懂,我也不懂,大家都摸石頭過河,臨時採購證書,然後我找客戶要證書時,給我甩了一坨。。。。以前專案基本上就給一個key和pfx啥的,搞得我也挺懵的,硬著頭皮瞎配,各種報錯各種百度,發現是key和cer、crt啥的反正就是對不上,不是一對,這裡推薦一個網站
總之,可算是成功配上去了,也測試過,能用https訪問對應地址下的圖片檔案,介面請求了,本來到此基本上告一段落了,結果要和第三方對接嘛,我提供的地址肯定也是配好後的https地址,那邊反饋說介面無法呼叫,經百度說是什麼證書鏈不完整的問題,這我可沒遇到過呀,雖然理論上說他們那邊配個什麼過濾好像就可以了,但是我感覺這個問題應該是可以解決的,而且問題應該在我這邊,配置好後更省事,不然對個第三方就得處理一遍。
處理過程:
1.首先,找出配對的key檔案和cer或crt檔案,配置進nginx配置,使對應地址可以https進行訪問(這個比較簡單,網上說明很多,反正最終配置的主體部分大概如下)
1 #後臺地址 2 upstream serv{ 3 server xx.xxx.xxA:8080 max_fails=3 weight=1 fail_timeout=60s; 4 server xx.xxx.xxB:8080 max_fails=3 weight=1 fail_timeout=60s; 5 ip_hash; 6 } 7 8 #https訪問 9 server { 10 listen 10086; #http訪問埠 11 listen 443 ssl; #https訪問埠12 server_name xx.xxx.cn; 13 14 ssl_certificate /usr/local/nginx/cert/_.xxx.com.cer; #ssl證書cer 15 ssl_certificate_key /usr/local/nginx/cert/_.xxx.com.key; #ssl證書key 16 ssl_session_timeout 5m; 17 ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4; 18 ssl_protocols TLSv1 TLSv1.1 TLSv1.2; 19 ssl_prefer_server_ciphers on; 20 21 access_log logs/xxx_access.log; 22 error_log logs/xxx_error.log; 23 24 #後臺介面 25 location /serv {28 proxy_read_timeout 300; 29 proxy_connect_timeout 300; 30 proxy_redirect off; 31 proxy_set_header Host $http_host; 32 proxy_set_header X-Real-IP $remote_addr; 33 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 34 proxy_set_header X-Forwarded-Proto $scheme; 35 proxy_set_header X-Frame-Options SAMEORIGIN; 36 proxy_pass http://serv/; 37 } 38 39 #ftp配置 40 location /ftp{ 41 proxy_pass http://xxx.xx.xx:port/files; 42 proxy_set_header Host $host; 43 proxy_set_header X-Real-IP $remote_addr; 44 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 45 client_max_body_size 100m; 46 root html; 47 index index.html index.htm; 48 } 49 50 error_page 500 502 503 504 /50x.html; 51 location = /50x.html { 52 root html; 53 } 54 }
2.然後,這時候,用程式碼呼叫對應域名地址時,會報錯,經百度查詢說明就是證書鏈不完整,這裡推薦這個網址 https://myssl.com/ ,在這個網站中輸入你配好的域名,它會進行檢測,告知各項問題,包括證書不完整這一項,最重要的是,這個網站最後還會告知如何處理,並有超連結點選就可以直接跳轉(這裡我是想截圖的,但是又不好臨時又把域名搞成之前的狀態,人家第三方都已經上生產釋出了),比如我的證書鏈不完整,就是跳轉後直接幫你補全,就是直接將原cer的內容輸入以後,它能給你生成另外的中間證書,複製回原cer檔案內即可,大致結果如下:
原本的cer檔案內容:
-----BEGIN CERTIFICATE-----
原證書內容
-----END CERTIFICATE-----
補全後的cer檔案內容:
-----BEGIN CERTIFICATE----- 原證書內容 -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- 中間證書內容 -----END CERTIFICATE-----
3.將完成補全後的cer檔案覆蓋回去,放到伺服器上就可以了
雖然最後是把問題解決了,其實百度上關於這個證書鏈不完整的處理,帖子還是挺多的,比如也有說用 https://certificatechain.io/ 這個網站進行補全證書的,我也不知道為什麼我用起來不行,大概率原因在於我當時找的cer檔案不對?或者是補全的方式不對,因為我記得當時嘗試用這個補全的時候,提示我“This is not a valid certificate”,然後我換了別的證書丟進去(客戶給了我一坨證書,都不知道該用哪個),最後補出來除了中間證書,還有根證書啥的,反正最後我是沒用起來。
這個問題當天處理了也有三五個小時,感覺處理這麼久,最大的原因之一就是對於證書方面還是不懂,然後第二大原因就是客戶給一坨證書,我都不知道哪個才是對的,單單找配對的證書和金鑰都費勁