Apache 2.0 version
下面的例子都是在一个服务器上运行多个站点的情况,基于name-based或者IP-based virtual host
单IP,单PORT,多域名,Name-based web sites
- 相同IP,相同PORT
- 多个域名:www.example1.com;www.example2.com
来自作者的警告:在你的Apache服务器上配置虚拟主机文件并不能神奇的让DNS为你创建这些主机名。你必须在DNS服务器里将主机名与你的服务器IP关联!或者仅仅修改你客户机的host文件也可以,不过这个方法只能让被修改的机器识别。
Server configuration
# 监听80端口
Listen 80
# 为虚拟主机请求监听所有IP
NameVirtualHost *:80
<VirtualHost *:80>
DocumentRoot /www/example1
ServerName www.example1.com
# Other directives here
</VirtualHost>
<VirtualHost *:80>
DocumentRoot /www/example2
ServerName www.example2.org
# Other directives here
</VirtualHost>
www.example1.com最先出现在这个配置文件里,具有最高优先级。你可以将其视为默认服务器或者主要服务器。如果一个接收的请求没有匹配到任何ServerName,那么这个请求将被第一个VirtualHost处理。
你也可以配置具体的ip来替换,那样VirtualHost的参数必须匹配NameVirtualHost。但是,在IP地址不可预知的系统上使用也是有用的,例如,如果您的ISP有动态IP地址,并且您正在使用各种动态DNS解决方案。 由于*匹配任何IP地址,因此只要您的IP地址发生更改,此配置就可以在不更改的情况下运行
多IP,Name-based hosts
两个IP
- 172.20.30.40 : server.domain.com(main server)
- 172.20.30.50 : www.example1.com;www.example2.org
Server configuration
Listen 80
# This is the "main" server running on 172.20.30.40
ServerName server.domain.com
DocumentRoot /www/mainserver
# This is the other address
NameVirtualHost 172.20.30.50
<VirtualHost 172.20.30.50>
DocumentRoot /www/example1
ServerName www.example1.com
# Other directives here ...
</VirtualHost>
<VirtualHost 172.20.30.50>
DocumentRoot /www/example2
ServerName www.example2.org
# Other directives here ...
</VirtualHost>
多IP,同服务
服务器主机有两个IP:192.168.1.1,172.20.30.50.
机器的两个网卡分别接内网和外网。外网口使用172.20.30.50,使用域名server.example.com,内网口使用192.168.1.1。
服务器对于内网和外网的请求使用相同的内容响应,只使用一个VirtualHost。
Server configuration
NameVirtualHost 192.168.1.1
NameVirtualHost 172.20.30.40
<VirtualHost 192.168.1.1 172.20.30.40>
DocumentRoot /www/server1
ServerName server.example.com
ServerAlias server
</VirtualHost>
据介绍,用*替换ip地址列表也可以达到同样的目的<VirtualHost *>
单IP,多端口,多服务
如果你使用<VirtualHost name:port>
的同时不使用NameVirtualHost name:port
或者你使用Listen指令,你的配置将无法生效,NameVirtualHost
特指基于域名的访问情况
Server configuration
Listen 80
Listen 8080
NameVirtualHost 172.20.30.40:80
NameVirtualHost 172.20.30.40:8080
<VirtualHost 172.20.30.40:80>
ServerName www.example1.com
DocumentRoot /www/domain-80
</VirtualHost>
<VirtualHost 172.20.30.40:8080>
ServerName www.example1.com
DocumentRoot /www/domain-8080
</VirtualHost>
<VirtualHost 172.20.30.40:80>
ServerName www.example2.org
DocumentRoot /www/otherdomain-80
</VirtualHost>
<VirtualHost 172.20.30.40:8080>
ServerName www.example2.org
DocumentRoot /www/otherdomain-8080
</VirtualHost>
配置很多,但是逻辑很简单
四个服务:
- domain-80
- domain-8080
- otherdomain-80
- otherdomain-8080
但是只有一个IP,于是表演了用2个端口,2个域名排列组合共设置了4个虚拟主机,不要忘记了Listen和NameVirtualHost
IP-based virtual hosting
两个IP(172.20.30.40和172.20.30.50),
Server configuration
Listen 80
<VirtualHost 172.20.30.40>
DocumentRoot /www/example1
ServerName www.example1.com
</VirtualHost>
<VirtualHost 172.20.30.50>
DocumentRoot /www/example2
ServerName www.example2.org
</VirtualHost>
port-based和ip-based virtual hosts混用
Server configuration
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.example1.com
</VirtualHost>
<VirtualHost 172.20.30.40:8080>
DocumentRoot /www/example1-8080
ServerName www.example1.com
</VirtualHost>
<VirtualHost 172.20.30.50:80>
DocumentRoot /www/example2-80
ServerName www.example1.org
</VirtualHost>
<VirtualHost 172.20.30.50:8080>
DocumentRoot /www/example2-8080
ServerName www.example2.org
</VirtualHost>
又是排列组合的问题,不过令我感到奇怪的是,没有使用<NameVirtualHost>,猜测可能是由于ip和port的排列组合,不采用基于域名的方案,因此没用这个指令。
name-based和IP-based vhosts混用
Server configuration
Listen 80
NameVirtualHost 172.20.30.40
<VirtualHost 172.20.30.40>
DocumentRoot /www/example1
ServerName www.example1.com
</VirtualHost>
<VirtualHost 172.20.30.40>
DocumentRoot /www/example2
ServerName www.example2.org
</VirtualHost>
<VirtualHost 172.20.30.40>
DocumentRoot /www/example3
ServerName www.example3.net
</VirtualHost>
# IP-based
<VirtualHost 172.20.30.50>
DocumentRoot /www/example4
ServerName www.example4.edu
</VirtualHost>
<VirtualHost 172.20.30.60>
DocumentRoot /www/example5
ServerName www.example5.gov
</VirtualHost>
NameVirtualHost 172.20.30.40
指定了前三个VirtualHost是基于域名的
同时使用Virtual_host和mod_proxy
以下示例允许前端机器将虚拟主机代理到另一台计算机上运行的服务器。 在本例中,在192.168.111.2的计算机上配置相同名称的虚拟主机。 如果我们将多个主机名代理到一台机器,则使用ProxyPreserveHost On指令来传递所需的主机名。
<VirtualHost *:*>
ProxyPreserveHost On
ProxyPass / http://192.168.111.2/
ProxyPassReverse / http://192.168.111.2/
ServerName hostname.example.com
</VirtualHost>
_default_
捕获未指定IP和port的请求
Server configuration
<VirtualHost _default_:*>
DocumentRoot /www/default
</VirtualHost>
将基于名称的虚拟主机迁移到基于IP的虚拟主机
Server configuration
Listen 80
ServerName www.example1.com
DocumentRoot /www/example1
NameVirtualHost 172.20.30.40
<VirtualHost 172.20.30.40 172.20.30.50>
DocumentRoot /www/example2
ServerName www.example2.org
# ...
</VirtualHost>
<VirtualHost 172.20.30.40>
DocumentRoot /www/example3
ServerName www.example3.net
ServerAlias *.example3.net
# ...
</VirtualHost>
主机名为www.example2.org的基于名称的虚拟主机(来自我们基于名称的示例setup 2)应该有自己的IP地址。 为了避免名称服务器或代理缓存基于名称的虚拟主机的旧IP地址的问题,我们希望在迁移阶段提供两种变体。
解决方案很简单,因为我们可以简单地将新的IP地址(172.20.30.50)添加到VirtualHost指令中。
ServerPath
我们有一个服务器与两个基于名称的虚拟主机。 为了匹配正确的虚拟主机,客户端必须发送正确的主机:标头。 旧的HTTP / 1.0客户端不会发送这样的头文件,Apache不知道客户端试图访问哪个虚拟主机(并且从主虚拟主机提供请求)。 为了提供尽可能多的向后兼容性,我们创建一个主要的虚拟主机,它返回一个包含带有URL前缀的链接的单个页面到基于名称的虚拟主机。
Server configuration
NameVirtualHost 172.20.30.40
<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>
由于ServerPath指令,对URL http://www.sub1.domain.tld/sub1/的请求总是从sub1-vhost提供。
如果客户端发送了正确的主机:标头,则仅向sub1-vhost提供对URL http://www.sub1.domain.tld/的请求。 如果没有发送主机:头部,客户端从主要主机获取信息页面。
请注意,有一个奇怪的情况:如果客户端没有发送Host:头,则也会从sub1-vhost提供对http://www.sub2.domain.tld/sub1/的请求。
RewriteRule指令用于确保发送正确Host:标头的客户端可以使用两种URL变体,即带或不带URL前缀。