Apache 虛擬主機(jī)

2021-10-13 18:18 更新
Apache Web服務(wù)器可以在SAME服務(wù)器上托管多個(gè)網(wǎng)站。每個(gè)網(wǎng)站不需要單獨(dú)的服務(wù)器機(jī)器和apache軟件。這可以使用虛擬主機(jī)或VHost的概念來(lái)實(shí)現(xiàn)。

要在Web服務(wù)器上托管的任何域(網(wǎng)站應(yīng)用)都將在apache配置文件中具有單獨(dú)的條目。

Apache虛擬主機(jī)類型

Apache虛擬主機(jī)類型有兩種 -

  • 基于名稱的虛擬主機(jī)
  • 基于地址或基于IP的虛擬主機(jī)。

1. 基于名稱的虛擬主機(jī)

基于名稱的虛擬主機(jī)用于在單個(gè)IP地址上托管多個(gè)虛擬站點(diǎn)。

基于名稱的虛擬主機(jī)

要配置基于名稱的虛擬主機(jī),需要設(shè)置要在其上接收所有所需網(wǎng)站的Apache請(qǐng)求的IP地址??梢酝ㄟ^(guò)apache配置中的NameVirutalHost指令(即/etc/httpd/conf/httpd.conf文件)執(zhí)行此操作。如下所示 -

NameVirtualHost *:80
<VirtualHost 192.168.0.108:80>
    ServerAdmin webmaster@yiibai.com
    DocumentRoot /var/www/html/example1_com_dir 
    ServerName www.example1.com
</VirtualHost>
<VirtualHost 192.168.0.108:80>
    ServerAdmin admin@yiibai.com
    DocumentRoot /var/www/html/example2_com_dir
    ServerName www.example2.com
</VirtualHost>
Shell

您可以根據(jù)需要添加任意數(shù)量的虛擬主機(jī)。需要使用以下命令檢查Web配置文件是否有配置錯(cuò)誤:

[root@115 conf.d]# httpd -t

Syntax error on line 978 of /etc/httpd/conf/httpd.conf:

Invalid command '*', perhaps misspelled or defined by a module not included in the server configuration
Shell

如上面顯示的結(jié)果可以發(fā)現(xiàn),配置文件存在語(yǔ)法配置錯(cuò)誤,這時(shí)需要根據(jù)提示修改配置文件。直到?jīng)]有錯(cuò)誤提示為止。當(dāng)配置文件有錯(cuò)誤時(shí),Apache是不能啟動(dòng)的,這點(diǎn)需要注意。

2. 基于IP的虛擬主機(jī)

要設(shè)置基于IP的虛擬主機(jī),需要在服務(wù)器上配置多個(gè)IP地址。因此,vhost apache的數(shù)量取決于服務(wù)器上配置的IP地址數(shù)量。如果您的服務(wù)器有10個(gè)IP地址,則可以創(chuàng)建10個(gè)基于IP的虛擬主機(jī)。

基于IP的虛擬主機(jī)

在上圖中,兩個(gè)網(wǎng)站example1.comexample2.com分配了不同的IP并使用基于IP的虛擬主機(jī)。

Listen 192.168.0.100:80

<VirtualHost 192.168.10.108:80>
    ServerAdmin webmaster@example1.com
    DocumentRoot /var/www/html/example1_com_dir      
    ServerName www.example1.com
</VirtualHost>

<VirtualHost 192.168.10.109:80>
    ServerAdmin admin@example2.com
    DocumentRoot /var/www/html/example1_com_dir
    ServerName www.example2.com
</VirtualHost>
Shell

3. 虛擬主機(jī)配置示例

這一小節(jié)中將列出有關(guān)設(shè)置虛擬主機(jī)的常見(jiàn)問(wèn)題。這些方案涉及通過(guò)基于名稱或基于IP的虛擬主機(jī)在單個(gè)服務(wù)器上運(yùn)行的多個(gè)網(wǎng)站。

3.1. 在單個(gè)IP地址上運(yùn)行多個(gè)基于域名的網(wǎng)站

如果服務(wù)器有多個(gè)主機(jī)名可以解析為單個(gè)地址,您希望對(duì)www.example.comwww.example.org做出不同的響應(yīng)。

在Apache服務(wù)器上創(chuàng)建虛擬主機(jī)配置不會(huì)神奇地導(dǎo)致為這些主機(jī)名創(chuàng)建DNS條目。您必須擁有DNS中的名稱,解析為您的IP地址,否則其他人都無(wú)法訪問(wèn)您的網(wǎng)站??梢詫l目放在hosts文件中以進(jìn)行本地測(cè)試,但這僅適用于具有這些主機(jī)條目的計(jì)算機(jī)。

# Ensure that Apache listens on port 80
Listen 80
<VirtualHost *:80>
    DocumentRoot "/var/www/example1"
    ServerName www.example.com

    # Other directives here
</VirtualHost>

<VirtualHost *:80>
    DocumentRoot "/var/www/example2"
    ServerName www.example.org

    # Other directives here
</VirtualHost>
Shell

3.2. 多個(gè)IP地址上基于名稱的主機(jī)

服務(wù)器有兩個(gè)(或更多個(gè))IP地址。一個(gè)IP地址是:172.20.30.40,我們將服務(wù)于“主”服務(wù)器server.example.com,另一個(gè)IP地址是:172.20.30.50,我們將服務(wù)兩個(gè)或更多虛擬主機(jī)。

Listen 80

# This is the "main" server running on 172.20.30.40
ServerName server.example.com
DocumentRoot "/www/mainserver"

<VirtualHost 172.20.30.50>
    DocumentRoot "/www/example1"
    ServerName www.example.com

    # Other directives here ...
</VirtualHost>

<VirtualHost 172.20.30.50>
    DocumentRoot "/www/example2"
    ServerName www.example.org

    # Other directives here ...
</VirtualHost>
Shell

對(duì)172.20.30.50以外的地址的任何請(qǐng)求都將從主服務(wù)器提供。將向www.example.com提供對(duì)172.20.30.50的請(qǐng)求,其中包含未知主機(jī)名或無(wú)Host:標(biāo)頭。

3.3. 在不同的IP地址(例如內(nèi)部和外部地址)上提供相同的內(nèi)容

服務(wù)器計(jì)算機(jī)有兩個(gè)IP地址(192.168.1.1172.20.30.40)。機(jī)器位于內(nèi)部(Intranet)網(wǎng)絡(luò)和外部(Internet)網(wǎng)絡(luò)之間。在網(wǎng)絡(luò)外部,名稱server.example.com解析為外部地址(172.20.30.40),但在網(wǎng)絡(luò)內(nèi)部,同一名稱解析為內(nèi)部地址(192.168.1.1)。

只需一個(gè)<VirtualHost>部分,就可以使服務(wù)器響應(yīng)具有相同內(nèi)容的內(nèi)部和外部請(qǐng)求。

<VirtualHost 192.168.1.1 172.20.30.40>
    DocumentRoot "/www/server1"
    ServerName server.example.com
    ServerAlias server
</VirtualHost>
Shell

3.4. 在不同端口上運(yùn)行不同的站點(diǎn)

假設(shè)您有多個(gè)域轉(zhuǎn)到同一個(gè)IP,并且還希望為多個(gè)端口提供服務(wù)。下面的示例說(shuō)明了在確定最佳匹配的IP地址和端口組合之后進(jìn)行名稱匹配。

Listen 80
Listen 8080

<VirtualHost 172.20.30.40:80>
    ServerName www.example.com
    DocumentRoot "/www/domain-80"
</VirtualHost>

<VirtualHost 172.20.30.40:8080>
    ServerName www.example.com
    DocumentRoot "/www/domain-8080"
</VirtualHost>

<VirtualHost 172.20.30.40:80>
    ServerName www.example.org
    DocumentRoot "/www/otherdomain-80"
</VirtualHost>

<VirtualHost 172.20.30.40:8080>
    ServerName www.example.org
    DocumentRoot "/www/otherdomain-8080"
</VirtualHost>
Shell

3.4. 基于IP的虛擬主機(jī)

服務(wù)器有兩個(gè)IP地址(172.20.30.40172.20.30.50),分別解析為www.example.comwww.example.org。

Listen 80

<VirtualHost 172.20.30.40>
    DocumentRoot "/www/example1"
    ServerName www.example.com
</VirtualHost>

<VirtualHost 172.20.30.50>
    DocumentRoot "/www/example2"
    ServerName www.example.org
</VirtualHost>
Shell

對(duì)于未在其中一個(gè)<VirtualHost>指令中指定的任何地址(例如localhost)的請(qǐng)求將轉(zhuǎn)到主服務(wù)器(如果有)。

3.5. 基于混合端口和基于IP的虛擬主機(jī)

服務(wù)器機(jī)器有兩個(gè)IP地址(172.20.30.40172.20.30.50),分別解析為www.example.comwww.example.org。在每種情況下,都希望在端口808080上運(yùn)行主機(jī)。

Listen 172.20.30.40:80
Listen 172.20.30.40:8080
Listen 172.20.30.50:80
Listen 172.20.30.50:8080

<VirtualHost 172.20.30.40:80>
    DocumentRoot "/www/example1-80"
    ServerName www.example.com
</VirtualHost>

<VirtualHost 172.20.30.40:8080>
    DocumentRoot "/www/example1-8080"
    ServerName www.example.com
</VirtualHost>

<VirtualHost 172.20.30.50:80>
    DocumentRoot "/www/example2-80"
    ServerName www.example.org
</VirtualHost>

<VirtualHost 172.20.30.50:8080>
    DocumentRoot "/www/example2-8080"
    ServerName www.example.org
</VirtualHost>
Shell

3.6. 混合基于名稱和基于IP的虛擬主機(jī)

永遠(yuǎn)不會(huì)出現(xiàn)在另一個(gè)虛擬主機(jī)中的虛擬主機(jī)參數(shù)中提到的任何地址都是嚴(yán)格基于IP的虛擬主機(jī)。

Listen 80
<VirtualHost 172.20.30.40>
    DocumentRoot "/www/example1"
    ServerName www.example.com
</VirtualHost>

<VirtualHost 172.20.30.40>
    DocumentRoot "/www/example2"
    ServerName www.example.org
</VirtualHost>

<VirtualHost 172.20.30.40>
    DocumentRoot "/www/example3"
    ServerName www.example.net
</VirtualHost>

# IP-based
<VirtualHost 172.20.30.50>
    DocumentRoot "/www/example4"
    ServerName www.example.edu
</VirtualHost>

<VirtualHost 172.20.30.60>
    DocumentRoot "/www/example5"
    ServerName www.example.gov
</VirtualHost>
Shell

3.7. Virtual_host和mod_proxy一起使用

以下示例允許前端計(jì)算機(jī)將虛擬主機(jī)代理到另一臺(tái)計(jì)算機(jī)上運(yùn)行的服務(wù)器。在該示例中,在192.168.111.2的計(jì)算機(jī)上配置了同名的虛擬主機(jī)。如果我們將多個(gè)主機(jī)名代理到單個(gè)機(jī)器,則使用ProxyPreserveHost On指令以便傳遞所需的主機(jī)名。

<VirtualHost *:*>
    ProxyPreserveHost On
    ProxyPass        "/" "http://192.168.111.2/"
    ProxyPassReverse "/" "http://192.168.111.2/"
    ServerName hostname.example.com
</VirtualHost>
Shell

3.8. 使用 default vhosts

default vhosts適用于所有端口

捕獲對(duì)任何未指定的IP地址和端口的每個(gè)請(qǐng)求,即未用于任何其他虛擬主機(jī)的地址/端口組合。

<VirtualHost _default_:*>
    DocumentRoot "/www/default"
</VirtualHost>
Shell

使用帶有通配符端口的默認(rèn)虛擬主機(jī)可以有效地阻止任何請(qǐng)求進(jìn)入主服務(wù)器。

默認(rèn)虛擬主機(jī)從不提供發(fā)送到用于基于名稱的虛擬主機(jī)的地址/端口的請(qǐng)求。如果請(qǐng)求包含未知或無(wú)Host:標(biāo)頭,則始終從基于主名稱的虛擬主機(jī)(配置文件中首先出現(xiàn)的該地址/端口的虛擬主機(jī))提供服務(wù)。

您可以使用AliasMatchRewriteRule將任何請(qǐng)求重寫到單個(gè)信息頁(yè)面(或腳本)。

default vhosts 用于不同的端口
與上面的設(shè)置相同,但服務(wù)器偵聽(tīng)多個(gè)端口,我們希望將第二個(gè)_default_ vhost用于端口80

<VirtualHost _default_:80>
    DocumentRoot "/www/default80"
    # ...
</VirtualHost>

<VirtualHost _default_:*>
    DocumentRoot "/www/default"
    # ...
</VirtualHost>
Shell

端口80的默認(rèn)虛擬主機(jī)(必須出現(xiàn)在具有通配符端口的任何默認(rèn)虛擬主機(jī)之前)會(huì)捕獲發(fā)送到未指定IP地址的所有請(qǐng)求。主服務(wù)器從不用于提供請(qǐng)求。

default vhosts用于一個(gè)端口

我們希望端口80具有默認(rèn)虛擬主機(jī),但沒(méi)有其他默認(rèn)虛擬主機(jī)。

<VirtualHost _default_:80>
    DocumentRoot "/www/default"
...
</VirtualHost>
Shell

從默認(rèn)虛擬主機(jī)提供對(duì)端口80上未指定地址的請(qǐng)求。從主服務(wù)器提供對(duì)未指定地址和端口的任何其他請(qǐng)求。

在虛擬主機(jī)聲明中使用*的優(yōu)先級(jí)高于_default_

3.9. 將基于名稱的虛擬主機(jī)遷移到基于IP的虛擬主機(jī)

主機(jī)名為www.example.org的基于名稱的虛擬主機(jī)(來(lái)自我們基于名稱的示例,設(shè)置2)應(yīng)該獲得自己的IP地址。為避免名稱服務(wù)器或緩存基于名稱的虛擬主機(jī)的舊IP地址的代理出現(xiàn)問(wèn)題,我們希望在遷移階段提供這兩種變體。

解決方案很簡(jiǎn)單,因?yàn)槲覀兛梢院?jiǎn)單地將新的IP地址(172.20.30.50)添加到VirtualHost指令中。

Listen 80
ServerName www.example.com
DocumentRoot "/www/example1"

<VirtualHost 172.20.30.40 172.20.30.50>
    DocumentRoot "/www/example2"
    ServerName www.example.org
    # ...
</VirtualHost>

<VirtualHost 172.20.30.40>
    DocumentRoot "/www/example3"
    ServerName www.example.net
    ServerAlias *.example.net
    # ...
</VirtualHost>
Shell

現(xiàn)在可以通過(guò)新地址(作為基于IP的虛擬主機(jī))和舊地址(作為基于名稱的虛擬主機(jī))訪問(wèn)虛擬主機(jī)。

4.0. 使用ServerPath指令

我們有一個(gè)帶有兩個(gè)基于名稱的虛擬主機(jī)的服務(wù)器。為了匹配正確的虛擬主機(jī),客戶端必須發(fā)送正確的Host:頭。舊的HTTP/1.0客戶端不發(fā)送這樣的頭,Apache不知道客戶端試圖訪問(wèn)什么虛擬主機(jī)(并從主虛擬主機(jī)提供請(qǐng)求)。為了提供盡可能多的向后兼容性,我們創(chuàng)建了一個(gè)主虛擬主機(jī),它返回一個(gè)包含帶有URL前綴的鏈接的單個(gè)頁(yè)面到基于名稱的虛擬主機(jī)。

<VirtualHost 172.20.30.40>
    # primary vhost
    DocumentRoot "/www/subdomain"
    RewriteEngine On
    RewriteRule "." "/www/subdomain/index.html"
    # ...
</VirtualHost>

<VirtualHost 172.20.30.40>
    DocumentRoot "/www/subdomain/sub1"
    ServerName www.sub1.domain.tld
    ServerPath "/sub1/"
    RewriteEngine On
    RewriteRule "^(/sub1/.*)" "/www/subdomain$1"
    # ...
</VirtualHost>

<VirtualHost 172.20.30.40>
    DocumentRoot "/www/subdomain/sub2"
    ServerName www.sub2.domain.tld
    ServerPath "/sub2/"
    RewriteEngine On
    RewriteRule "^(/sub2/.*)" "/www/subdomain$1"
    # ...
</VirtualHost>
Shell

由于ServerPath指令,始終從sub1-vhost提供對(duì)URL http://www.sub1.domain.tld/sub1/的請(qǐng)求。
如果客戶端發(fā)送了正確的Host:頭,則僅從sub1-vhost提供對(duì)URL http://www.sub1.domain.tld/的請(qǐng)求。如果沒(méi)有發(fā)送Host:頭,則客戶端從主要主機(jī)獲取信息頁(yè)面。

請(qǐng)注意,有一個(gè)奇怪之處:如果客戶端沒(méi)有發(fā)送Host:頭,則還會(huì)從sub1-vhost提供對(duì)http://www.sub2.domain.tld/sub1/的請(qǐng)求。



以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)