Apache-2.4

Apache 2.4 上的包羅萬象的 HTTPS 虛擬主機

  • April 9, 2017

是否可以在 Apache 2.4 上配置一個包羅萬象(預設)的 HTTPS Vhost?我目前有 4 個域,並且 HTTP 擷取所有內容,但只要我嘗試添加任何類型的配置,我的其他虛擬主機就會中斷。這是我的配置的樣子:

<VirtualHost _default_:80>
   # Default catch-all virtual host.
   Redirect permanent / https://example-prod.com
</VirtualHost>

<VirtualHost _default_:80>
   ServerName example-prod.com
   ServerName www.example-prod.com
   Include conf/sites/example-prod.com.conf
</VirtualHost>

<VirtualHost _default_:80>
   ServerName example-dev.com
   Include conf/sites/example-dev.com.conf
</VirtualHost>

#
# This is the virtual host I'm missing and that I cannot get to work.
#
#<VirtualHost _default_:443>
#   # Default catch-all virtual host.
#   ServerAlias *
#   SSLEngine on
#   SSLCertificateFile "C:/prod/hosts.crt.pem"
#   SSLCertificateKeyFile "C:/prod/hosts.key.pem"
#   SSLCertificateChainFile "C:/prod/intermediate.crt.pem"  
#   Redirect permanent / https://example-prod.com
#</VirtualHost>

<VirtualHost _default_:443>
   ServerName example-prod.com
   ServerName www.example-prod.com
   SSLEngine on
   SSLCertificateFile "C:/prod/hosts.crt.pem"
   SSLCertificateKeyFile "C:/prod/hosts.key.pem"
   SSLCertificateChainFile "C:/prod/intermediate.crt.pem"  
   Include conf/sites/example-prod.com.conf
</VirtualHost>

<VirtualHost _default_:443>
   ServerName example-dev.com
   SSLEngine on
   SSLCertificateFile "C:/dev/hosts.crt.pem"
   SSLCertificateKeyFile "C:/dev/hosts.key.pem"
   SSLCertificateChainFile "C:/dev/intermediate.crt.pem"   
   Include conf/sites/example-dev.com.conf
</VirtualHost>

我的 httpd.conf 沒有更多DocumentRoot內容 - 一切都在虛擬主機中並包含在內。這也是一個專用伺服器和IP。

我怎樣才能解決這個問題?

*問題解決了,但出現了一些誤會。*確實存在 HTTPS 需要匹配證書的要求,但由此引起的問題是主機名不匹配證書Common Name或在Subject Alternative Name中列出的連接將不受信任:

  • RewriteRule即使使用另一個答案中給出的解決方案,相同的不匹配仍然存在。
  • 如果“catch-all”主機名都是 的子域,example.com並且您有 的萬用字元證書*.example.com,它將匹配。
  • 另一方面,大多數人在嘗試訪問時something.example.com,在瀏覽器地址欄中鍵入不帶http://orhttps://前綴的內容,並且瀏覽器預設使用 HTTP。因此,即使證書不匹配,在 HTTPS 上進行“包羅萬象”重定向通常也不會導致任何實際問題:只有少數人會看到SSL_ERROR_BAD_CERT_DOMAIN錯誤。

無論是否使用 TLS,虛擬主機匹配的工作方式都相同

如果您沒有SNI

給定對的配置文件中的第一個基於名稱的虛擬主機 IP:port很重要,因為它用於在該地址和埠上接收到的所有請求,而該 IP:port對的其他虛擬主機沒有匹配的ServerNameor ServerAlias。如果伺服器不支持 伺服器名稱指示,它也用於所有 SSL 連接。

如果沒有 SNI,則第一個證書VirtualHost用於握手:

實際上,Apache 將允許您配置基於名稱的 SSL 虛擬主機,但它始終使用第一個列出的虛擬主機(在選定的 IP 地址和埠上)的配置來設置加密層。

您最初嘗試的主要問題是擁有ServerAlias *和沒有任何ServerName. 對於“包羅萬象”的主機,它可以與其他 s 中的其他s 以外的任何東西一起使用。如果沒有其他匹配項,Apache 將回退到預設部分;以第一部分為準(當基於名稱的查找失敗時匹配基於 IP 的查找)。ServerName``VirtualHost``VirtualHost

最匹配的<virtualhost>s 集的基於名稱的虛擬主機按照它們在配置中出現的順序進行處理。使用第一個匹配的ServerNameor ServerAlias,萬用字元沒有不同的優先級(也沒有ServerNamevs. ServerAlias)。

一定有一些ServerName,因為:

ServerName指令可能出現在伺服器定義中的任何位置。但是,每個外觀都會覆蓋以前的外觀(在該伺服器內)。

如果沒有ServerName指定,伺服器嘗試通過首先向作業系統詢問系統主機名來推斷客戶端可見主機名,如果失敗,則對系統上存在的 IP 地址執行反向查找。

這將導致如下配置:

<VirtualHost *:443>
   # Default catch-all (everything that won't match the following VirtualHosts)
   ServerName catch-all.example.com
   ServerAlias www.example.com
   SSLEngine on
   SSLCertificateFile "C:/prod/hosts.crt.pem"
   SSLCertificateKeyFile "C:/prod/hosts.key.pem"
   SSLCertificateChainFile "C:/prod/intermediate.crt.pem"  
   Redirect permanent / https://example.com
</VirtualHost>

<VirtualHost *:443>
   ServerName example.com
   SSLEngine on
   SSLCertificateFile "C:/prod/hosts.crt.pem"
   SSLCertificateKeyFile "C:/prod/hosts.key.pem"
   SSLCertificateChainFile "C:/prod/intermediate.crt.pem"  
   Include conf/sites/example.com.conf
</VirtualHost>

<VirtualHost *:443>
   ServerName dev.example.com
   SSLEngine on
   SSLCertificateFile "C:/prod/hosts.crt.pem"
   SSLCertificateKeyFile "C:/prod/hosts.key.pem"
   SSLCertificateChainFile "C:/prod/intermediate.crt.pem"  
   Include conf/sites/dev.example.com.conf
</VirtualHost>

請注意我更改的其他內容:

  1. dev.example.com使用與在沒有 SNI 的情況下無論如何都會使用相同的證書。
  2. 使用<VirtualHost *:443>而不是_default_:443as_default_有一個特殊的目的:

任何包含魔術_default_萬用字元的虛擬主機都被賦予與主伺服器相同的 ServerName。

(這也意味著可以_default_:443在你的“包羅萬象”中使用,而不是在其他人中。你可以試試!) 3. 域被替換為保留的範例域名。 4. 我更願意將其www.example.com作為“包羅萬象”的一部分(而不是作為別名),以便您的站點只有一個規範地址。因此我把它移到了那裡。


如果您有SNI,則處理會模仿相同的行為,但在細節上會有所不同:

在 SSL 握手之前,Apache 會找到與建立連接的 IP 地址和 TCP 埠的最佳匹配(基於 IP 的虛擬主機)

如果有一個NameVirtualHost指令與這個 best-matching 具有相同的文字參數VirtualHost,Apache 將改為考慮VirtualHost與匹配的 VirtualHost 具有相同參數的所有條目。否則,SNI 處理沒有選擇執行。

如果客戶端連同它的 TLS 握手請求一起發送一個主機名,Apache 將把這個 TLS 主機名與前面步驟中確定的候選集的ServerName/進行比較。ServerAlias``VirtualHost

在前面選擇的任何一個 VirtualHost 都將使用其 SSL 配置來繼續握手。值得注意的是,證書的內容並未用於任何比較。

使用 SNI,您可以獲得dev.example.com.

如果滿足 SNI 的所有先決條件,它應該會自動執行並error.log顯示[warn] Init: Name-based SSL virtual hosts only work for clients with TLS server name indication support (RFC 4366).

引用自:https://serverfault.com/questions/843481