問題描述
問題情境描述滿足以下三個條件:
- 多個網站綁定到Web伺服器的同一個IP地址和同一個連接埠。
- 對於用戶端的請求,伺服器可以區分不同的主機頭。
- 已為每一個SSL網站申請並安裝了認證,但在瀏覽網站時,使用者擷取到認證不匹配的資訊。
問題原因
當一個HTTPS請求到達Web伺服器時,該HTTPS請求為加密狀態,需要相應的伺服器憑證解密該HTTPS請求。由於每個網站對應的認證不同,因此伺服器需要通過請求中的主機頭來選擇用來解密的認證。但是主機頭作為請求的一部分資訊,也被作為加密對象,因此Web伺服器選擇第一個綁定到指定IP地址和連接埠的網站,使用該網站認證進行解密,導致Web伺服器對其他網站請求解密失敗從而發生報錯。
解決方案
本文提供了三種Web伺服器的解決方案,以下是詳細內容。
IIS
您可以在IIS伺服器中選擇以下四種方法解決問題:
- 綁定到多連接埠將每個HTTPS網站綁定到同一IP地址的不同連接埠。例如,將HTTPS網站綁定到
[$Domain]:[$Port]
,但是從用戶端瀏覽網頁時必須在地址欄中手動指定連接埠。說明- [$Domain]:網站網域名稱。
- [$Port]:指定連接埠。
- 綁定到多IP地址
將每個HTTPS網站綁定到不同IP地址。此時,不存在請求衝突的情況,同時請求中也可以不添加主機頭資訊,但是該方法的經濟成本較高。
- 通配認證
各網站採用通配認證,例如
example.aliyundoc.com
、demo.aliyundoc.com
和learn.aliyundoc.com
三個網站可以選擇頒發給.aliyundoc.com
的認證,此時任何訪問各網站的請求都可以通過該認證解密。 - 升級IIS
將IIS版本升級到IIS8,IIS8中支援SNI(Server Name Indication)功能,伺服器可以從請求中提取出相應的主機頭從而擷取相應的認證。關於SNI的開啟方式,請參見SSL Scalability。
Nginx
在Nginx伺服器中,可通過增加一個虛擬機器主機的方式,完成多網站綁定到伺服器同一個IP地址和同一個連接埠,請參考以下操作方法:
- 登入Nginx伺服器,執行以下命令,開啟Nginx設定檔。
vim [$Nginx_Dir]/conf/nginx.conf
說明 [$Nginx_Dir]為Nginx的安裝目錄,預設為/usr/local/nginx。 - 參考以下配置,編輯設定檔。
server { listen 443; server_name [$Domain1]; ssl on; ssl_certificate [$Certificate_Path1]; ssl_certificate_key [$Key_Path1]; ssl_session_timeout 5m; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_ciphers [$Ciphers_Suite1]; ssl_prefer_server_ciphers on; location / { root html; index index.html index.htm; } }server { listen 443; server_name [$Domain2]; ssl on; ssl_certificate [$Certificate_Path2]; ssl_certificate_key [$Key_Path2]; ssl_session_timeout 5m; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_ciphers [$Ciphers_Suite2]; ssl_prefer_server_ciphers on; location / { root html; index index.html index.htm; } }
Apache
- 登入Apache伺服器,執行以下命令,開啟ssl.conf設定檔。
vim [$Apache_Dir]/conf.d/ssl.conf
說明- [$Apache_Dir]為Apache的安裝目錄,預設為/etc/httpd。
- 若沒有找到ssl.conf設定檔,則請執行
yum install mod_ssl -y
命令,下載SSL相關模組。 - Apache開啟SNI後,需增加SSLStrictSNIVHostCheck off參數。
- 參考以下配置,編輯設定檔。
Listen 443 NameVirtualHost *:443 <VirtualHost *:443> …… ServerName [$Domain1] SSLCertificateFile [$Certificate_Path1]; SSLCertificateKeyFile [$Key_Path1]; SSLCertificateChainFile [$Certificate_Chain1]; …… </VirtualHost> <VirtualHost *:443> …… ServerName [$Domain1] SSLCertificateFile [$Certificate_Path2]; SSLCertificateKeyFile [$Key_Path2]; SSLCertificateChainFile [$Certificate_Chain2];
說明- 如果是一個認證包含
www.example.com
和example.com
的情況(例如阿里雲的免費認證),建議寫成以下格式,否則可能導致帶www的網域名稱無法串連。ServerName example.com
ServerAlias www.example.com
- [$Certificate_Chain1]:第一個網站的中級認證捆綁包路徑。
- [$Certificate_Chain2]:第二個網站的中級認證捆綁包路徑。
- 在Apache V2.4.8及更高版本中,SSLCertificateChainFile的配置資訊已被SSLCACertificatePath的配置資訊替換。
- 如果是一個認證包含