虚拟主机(Virtual Host)是指在一个机器上运行多个网络站点(比如:www.fedora 61.com和www.fedora 62.com)。如果每个网络站点拥有不同的IP地址,则虚拟主机可以是“基于IP”的;如果只有一个IP地址,也可以是“基于主机名”的,虚拟主机实现对最终用户是透明的。使用虚拟主机后,一台服务器可以作为多台服务器使用,在外部用户看来,每一台服务器都是独立的。
Apache是率先支持基于IP虚拟主机的服务器之一。Apache 1.1及其更新版本同时支持基于IP和基于主机名的虚拟主机(vhosts),不同的虚拟主机有时会被称为基于主机(host-based)或非IP虚拟主机(non-IP virtual hosts)。
使用基于IP地址的虚拟主机,服务器中每个基于IP的虚拟主机必须拥有不同的IP地址。用户可以用真实的物理网络链接来达到这一需求,或者使用虚拟界面来实现——几乎现在流行的操作系统都提供这样的支持。
Apache有两种配置方法来使其支持多主机。
一般在出现以下情况时用多个进程:
出于安全的考虑,比如说公司甲不希望公司乙的任何人能用除Web以外的方式访问到他们的数据。在这种情况下,用户需要启动两个进程。每个都用不同的User、Group、Listen和ServerRoot设定。
用户能够为用户机器上的每个IP别名提供内存和文件描述符需求。用户只能侦听一个“通配符型”地址或一个特定的地址。所以不管出于什么原因,如果用户需要侦听一个特定的地址,用户就必须同时侦听所有特定的地址(尽管可以让一个httpd侦听N-1个地址,而让另一个侦听剩下的地址)。
一般在出现以下情况可以使用单一进程。
· httpd的配置可以为多个虚拟主机共享而不引起麻烦。
· 机器要接受大量的访问请求,从而多启动一个进程会导致性能的大幅度降低。
· 用户可以设置多个进程,为每个虚拟主机创建不同的httpd安装。每次安装都在配置文件中使用Listen指令以选择进程伺服的IP地址(或虚拟主机)。例如,
Listen www.fedora6.com:80
不过这里建议用户使用IP地址来取代域名。
假如用户要配置拥有多个虚拟主机的单一进程。在这种情况下,单一的httpd将伺服所有对主服务器和虚拟主机的请求。而配置文件中的VirtualHost指令将为每个虚拟主机配置不同的ServerAdmin、ServerName、DocumentRoot、ErrorLog和TransferLog或CustomLog。例如,
<VirtualHost www.smallco.com>
ServerAdmin webmaster@mail.fedora 6.com
DocumentRoot /groups/fedora 6/www
ServerName www.fedora 6.com
ErrorLog /groups/fedora 6/logs/error_log
TransferLog /groups/fedora 6/logs/access_log
</VirtualHost>
<VirtualHost www.apache.org>
ServerAdmin webmaster@mail.apache.org
DocumentRoot /groups/apache/www
ServerName www.apache.org
ErrorLog /groups/apache/logs/error_log
TransferLog /groups/apache/logs/access_log
</VirtualHost>
除了创建进程的指令和其他一些指令外,几乎所有的配置指令都能用于VirtualHost指令中,而且如果使用了suEXEC wrapper,那么User和Group也可以在VirtualHost指令中使用。
提示:当指定日志文件时,请记住有安全风险。一些别有用心的人会在那个目录拥有写权限。
基于IP的虚拟主机使用IP地址来决定相应的虚拟主机。这样,用户就需要为每个主机设定一个独立的IP地址。而基于域名的虚拟主机是根据客户端提交的HTTP头中的关于主机名的部分决定的。使用这种技术,很多虚拟主机可以共享同一个IP地址。这样就可以大量节省IP地址资源。
基于域名的虚拟主机相对比较简单,因为用户只需要配置DNS服务器将每个主机名映射到正确的IP地址,然后配置Apache HTTP服务器,令其辨识不同的主机名就可以了。基于域名的服务器也可以缓解IP地址不足的问题。
使用基于域名的虚拟主机,用户必须指定服务器的IP地址(和可能的端口)来使主机接受请求。可以用NameVirtualHost指令来进行配置。如果服务器上所有的IP地址都会用到,用户可以用*作为NameVirtualHost的参数。
注意:在NameVirtualHost指令中指明了IP地址并不会使服务器侦听那个IP地址。另外,这里设定的IP地址必须对应服务器上的一个网络接口。
接下来为建立的每个主机设定<VirtualHost>配置块。<VirtualHost>的参数与NameVir-
tualHost指令的参数是一样的(比如说,一个IP地址,或是*代表的所有地址)。在每个<VirtualHost>定义块中,至少都会有一个ServerName指令来指定伺服哪个主机和一个DocumentRoot指令来说明这个主机的内容存在于文件系统的什么地方。
提示:如果用户想在现有的Web服务器上增加虚拟主机,则必须为现存的主机建造一个<VirtualHost>定义块。这个虚拟主机中ServerName和DocumentRoot所包含的内容应该与全局的ServerName和DocumentRoot保持一致。还要把这个虚拟主机放在配置文件的最前面,来让它扮演默认主机的角色。
比如,假设用户正在为域名www.domain.tld提供服务,而又想在同一个IP地址上加一个名叫www.otherdomain.tld的虚拟主机,则只需在httpd.conf中加入以下内容:
NameVirtualHost *
<VirtualHost *>
ServerName www.domain.tld
ServerAlias domain.tld *.domain.tld
DocumentRoot /www/domain
</VirtualHost>
<VirtualHost *>
ServerName www.otherdomain.tld
DocumentRoot /www/otherdomain
</VirtualHost>
当然,用户也可以用一个固定的IP地址来代替NameVirtualHost和<VirtualHost>指令中的*号,以达到一些特定的目的。比如,用户希望在一个IP地址上运行一个基于域名的虚拟主机,而在另外一个地址上运行一个基于IP的或是另外一套基于域名的虚拟主机。
很多服务器都有多个域名,这样便于被访问者记住。如果想实现多个域名,用户可以把ServerAlias指令放入<VirtualHost>小节中,就可以解决这个问题。比如说在上面的第一个<VirtualHost>配置块ServerAlias指令中列出的名字就是用户可以用来访问同一个Web站点的其他名字:
ServerAlias domain.tld *.domain.tld
这样,所有对域domain.tld的访问请求都将被虚拟主机www.domain.tld所处理。通配符标记“*”和“?”可以用于域名的匹配。当然用户不能仅仅把名字放到ServerName或ServerAlias里就算完了。还必须先在DNS服务器上进行配置,将这些名字和服务器上的一个IP地址建立映射关系。