基於名稱的虛擬主機和基於IP的虛擬主機的對比
基於IP的虛擬主機使用連接的IP地址來識別(區分)正確的虛擬主機,所以對於每一個虛擬主機,你都需要有獨立的IP地址。
基於名稱的虛擬主機,服務器依賴於客戶端報告的HTTP headers中的hostname。基於這個技術,許多不同的主機可以共享同一個IP地址。
基於名稱的虛擬主機通常來說更簡單,因為你只需要配置你的DNS服務,讓每一個hostname和正確的IP地址相匹配,然后配置Apache去識別不同的hostname。基於名稱的虛擬主機也有助於緩解IP地址越來越少的局面。除非你正在使用的設備明確要求基於IP的虛擬主機,你都應該使用基於名稱的虛擬主機。歷史原因使得基於客戶端支持的基於IP的虛擬主機不再適用於多功能的web服務器。
Apache如何選擇正確的基於名稱的虛擬主機?
必須承認,基於名稱的虛擬主機解析的第一步就是基於IP的解析。在篩選了最好的基於IP的候選匹配之后,基於名稱的虛擬主機的解析只選擇最合適的基於名稱的虛擬主機。在虛擬主機指令里對IP地址使用通配符(*)使得基於IP的映射變得無關緊要(<VirtualHost *:80>)。
當一個請求到達時,服務器在請求的IP地址和端口號的基礎上,會找出最好的(大多數特征)匹配<VirtualHost>參數。如果有不止一個虛擬主機包含最匹配的地址和端口號組合,Apache將會進而比較ServerName、ServerAlias指令和請求中的server name。
對於基於名稱的虛擬主機,如果你忽略了ServerName指令,服務器將會根據系統的hostname為ServerName生成一個“完全限定域名(FQDN)”作為默認值。這種隱藏式地設置ServerName可能導致與正常預期相反的虛擬主機匹配,不推薦這樣做。
如果在設置的虛擬主機的集合中沒有找到相匹配的ServerName或者ServerAlias,那么將會使用集合中的第一個虛擬主機。
使用基於名稱的虛擬主機
第一步是為每一個不同的host創建一個<VirtualHost>塊。在每一個<VirtualHost>塊中,至少需要一個ServerName指令來標明服務於哪一個主機和一個DocumentRoot指令指定內容在文件系統的位置。
Main host將不再起作用
如果一個請求不匹配任何現有的<VirtualHost>,那么這個請求將會被全局服務器配置處理,並且將不再考慮hostname和ServerName。
當你在向一個服務器添加一個基於名稱的虛擬主機時,並且這個虛擬主機參數匹配已存在的IP和端口號組合,那么請求將被唯一的虛擬主機處理。在這種情況下,創建一個ServerName匹配base server的default virtual host通常來說是明智的選擇。在相同的接口和端口上的新域名,但是請求對立的配置,可以被添加為子(subsequent)虛擬主機(non-default)。
ServerName繼承性
最好總是在每一個基於名稱的虛擬主機中明確地列出ServerName。
如果一個虛擬主機沒有指定ServerName,那么ServerName將會繼承base server 的配置。如果沒有指定全局server name,那么將會使用啟動時第一個監聽的地址反向DNS解析所得的IP地址。其他情況下,繼承ServerName將會影響基於名稱的虛擬主機解析,所以最好是在每一個基於名稱的虛擬主機中總是指定ServerName。
例如:假設你的域名是www.example.com,並且你希望添加虛擬主機other.example.com並指向相同的IP地址。你可以簡單地在http.conf添加如下代碼:
<VirtualHost *:80> # This first-listed virtual host is also the default for *:80 ServerName www.example.com ServerAlias example.com DocumentRoot "/www/domain" </VirtualHost>
<VirtualHost *:80> ServerName other.example.com DocumentRoot "/www/otherdomain" </VirtualHost>
你可以使用顯示的IP來代替<VirtualHost>中的*。
許多服務器都有處理多個名稱需求,通過在<VirtualHost>節中設置ServerAlias可以實現。例如:
<VirtualHost *:80> # This first-listed virtual host is also the default for *:80 ServerName www.example.com ServerAlias example.com *.example.com DocumentRoot "/www/domain" </VirtualHost>
這樣,所有請求example.com域名的請求都將會被www.example.com虛擬主機處理。通配符*和?可以用來匹配名稱。當然,這些都基於你的DNS服務能正確地將名稱、IP地址和你的服務器相關聯。
基於名稱的虛擬主機對於最匹配的<VirtualHost>是按照它們在配置文件中的位置來排序的。第一個匹配ServerName或者ServerAlias將會被使用,通配符、ServerName、ServerAlias之間沒有優先級之分。
在VirtualHost指令中的完整的名稱,相當於一個沒有通配符的ServerAlias。
最后,你可以在<VirtualHost>節中添加其他的指令來調整虛擬主機的配置。大多數指令都可以放置在這里,並且會且僅會改變相關的虛擬主機的配置。要想知道一個特定的指令是否被允許,可以參考:http://httpd.apache.org/docs/2.4/mod/directive-dict.html#Context。<VirtualHost>之外的配置指令僅在沒有被當前虛擬主機配置重寫(overridden)的情況下才會生效。
如果您覺得閱讀本文對您有幫助,歡迎轉載本文,但是轉載文章之后必須在文章頁面明顯位置保留此段聲明,否則保留追究法律責任的權利。
作 者:blog.jpdou.top