<-
Apache HTTP 服务器 2.4 > VirtualHost示例

VirtualHost示例

本文档尝试回答有关设置虚拟主机的常见问题。这些方案涉及通过基于名称基于IP的虚拟主机在单个服务器上运行的多个网站。

支持Apache!

也可以看看

最佳

在单个IP地址上运行多个基于名称的网站。

您的服务器具有多个解析为单个地址的主机名,并且您希望对www.example.com 和做出不同的响应www.example.org

注意

在Apache服务器上创建虚拟主机配置不会神奇地导致为这些主机名创建DNS条目。您 必须在DNS中输入名称,解析为IP地址,否则其他人将看不到您的网站。您可以将条目放入hosts文件中以进行本地测试,但这仅在具有这些hosts条目的计算机上有效 。

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

    # Other directives here
</VirtualHost>

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

    # Other directives here
</VirtualHost>

星号匹配所有地址,因此主服务器不处理任何请求。由于虚拟主机with ServerName www.example.com是配置文件中的第一个主机 ,因此它具有最高优先级,可以被视为默认服务器或服务器。这意味着,如果接收到与指定ServerName指令之一不匹配的请求 ,则此first将为其提供服务 <VirtualHost>

上面的配置是您几乎希望在所有基于名称的虚拟主机情况下使用的配置。实际上,此配置唯一不起作用的是基于不同的IP地址或端口提供不同的内容时。

注意

您可以用系统*上的特定IP地址替换。此类虚拟主机仅用于连接到指定IP地址时收到的HTTP请求。

但是,* 在IP地址不可预测的系统上使用还很有用-例如,如果您的ISP具有动态IP地址,并且您正在使用各种动态DNS解决方案。由于 *匹配任何IP地址,因此只要您的IP地址发生更改,此配置就可以正常工作。

最佳

基于名称的主机位于多个IP地址上。

注意

此处讨论的任何技术都可以扩展到任意数量的IP地址。

该服务器有两个IP地址。在一个(172.20.30.40)上,我们将为“主”服务器提供服务,server.example.com在另一个(172.20.30.50)上,我们将为两个或多个虚拟主机提供服务。

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>

172.20.30.50主地址外,其他任何对地址的请求都将得到响应。来自172.20.30.50的主机名未知或无Host:标头的请求将由发出 www.example.com

最佳

在不同的IP地址(例如内部和外部地址)上提供相同的内容。

服务器计算机有两个IP地址(192.168.1.1172.20.30.40)。机器位于内部(内部网)网络和外部(内部网)网络之间。在网络server.example.com外部,名称解析为外部地址(172.20.30.40),但在网络内部,相同名称解析为内部地址(192.168.1.1)。

只需一小<VirtualHost>部分,就可以使服务器以相同的内容响应内部和外部请求。

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

现在,来自两个网络的请求将通过相同的进行处理 <VirtualHost>

注意:

在内部网络上,仅可以使用名称server而不是完全限定的主机名 server.example.com

还要注意,在上面的示例中,您可以将IP地址列表替换为*,这将导致服务器在所有地址上做出相同的响应。

最佳

在不同的端口上运行不同的站点。

您有多个要使用相同IP的域,并且还想为多个端口提供服务。下面的示例说明了名称匹配是在确定最佳匹配的IP地址和端口组合之后进行的。

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>
最佳

基于IP的虚拟主机

服务器有两个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>

如果存在一个<VirtualHost>指令localhost,则对其中一个指令中 未指定的任何地址的请求 将转到主服务器。

最佳

基于端口和基于IP的混合虚拟主机

服务器计算机具有两个IP地址(172.20.30.40172.20.30.50), 分别解析为名称 www.example.comwww.example.org。在每种情况下,我们都希望在端口80和8080上运行主机。

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>
最佳

基于名称和基于IP的混合虚拟主机

在虚拟主机的参数中提到的从未出现在其他虚拟主机中的任何地址都是严格基于IP的虚拟主机。

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>
最佳

Virtual_host一起使用和mod_proxy

以下示例允许前端计算机将虚拟主机代理到另一台计算机上运行的服务器。在示例中,在的机器上配置了具有相同名称的虚拟主机192.168.111.2ProxyPreserveHost On如果我们将多个主机名代理到一台计算机,则使用该指令以便传递所需的主机名。

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

使用_default_ 虚拟主机

_default_ 所有端口的虚拟主机

每个请求捕获到任何未指定的IP地址和端口,未用于任何其他虚拟主机的地址/端口组合。

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

将这样的默认虚拟主机与通配符端口一起使用可有效防止任何请求发送到主服务器。

默认虚拟主机从不处理已发送到用于基于名称的虚拟主机的地址/端口的请求。如果请求中包含未知或不包含Host:标头,则始终从基于主名称的虚拟主机(该地址/端口的虚拟主机首先出现在配置文件中)提供服务。

您可以使用AliasMatchRewriteRule将任何请求重写到单个信息页面(或脚本)。

_default_ 不同端口的虚拟主机

与设置1相同,但是服务器侦听多个端口,并且我们想_default_为端口80 使用第二个虚拟主机。

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

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

端口80的默认虚拟主机(必须出现在任何带通配符端口的默认虚拟主机之前)捕获所有发送到未指定IP地址的请求。主服务器从不用于服务请求。

_default_ 一个端口的虚拟主机

我们希望为端口80提供一个默认虚拟主机,但没有其他默认虚拟主机。

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

默认虚拟主机将请求对端口80上未指定地址的请求。主服务器会处理对未指定地址和端口的任何其他请求。

*在虚拟主机声明中使用的优先级将高于_default_

最佳

将基于名称的虚拟主机迁移到基于IP的虚拟主机

具有主机名www.example.org基于我们的基于名称的示例,设置2)的基于名称的虚拟主机 应获得其自己的IP地址。为了避免名称服务器或为基于名称的虚拟主机缓存旧IP地址的代理出现问题,我们希望在迁移阶段提供两种变体。

解决方案很简单,因为我们可以简单地将新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>

现在,可以通过新地址(作为基于IP的虚拟主机)和旧地址(作为基于名称的虚拟主机)访问该虚拟主机。

最佳

使用ServerPath 指令

我们有一台带有两个基于名称的虚拟主机的服务器。为了匹配正确的虚拟主机,客户端必须发送正确的Host: 标头。旧的HTTP / 1.0客户端不会发送这样的标头,而Apache不知道客户端试图到达哪个虚拟主机(并服务于来自主要虚拟主机的请求)。为了提供尽可能多的向后兼容性,我们创建了一个主虚拟主机,该主机返回一个页面,该页面包含带有指向基于名称的虚拟主机的URL前缀的链接。

<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的虚拟主机服务。如果客户端发送了正确的标头,则仅从sub1-vhost
提供对URL的请求 。如果没有发送头,则客户端从主要主机获取信息页面。http://www.sub1.domain.tld/Host:Host:

请注意,有一个奇怪的地方:http://www.sub2.domain.tld/sub1/如果客户端未发送Host:标头,那么sub1-vhost也会向发送请求 。

RewriteRule指令用于确保发出了一个正确的客户端 Host:头可同时使用网址变体,,有或没有网址前缀。

可用语言: zh  |  fr  |  ja  |  ko  |  TR 

最佳

注释

注意:
这不是“问答”部分。此处放置的评论应指向有关改进文档或服务器的建议,如果实施或被认为无效/偏离主题,我们的主持人可以将其删除。有关如何管理Apache HTTP Server的问题,应直接指向我们的IRC频道#httpd(位于Freenode上),或发送至我们的邮件列表
目前,此页面已禁用评论。