虚拟主机-Apache虚拟主机配置

这里讲述一些Apache虚拟主机中比较容易发生的问题和解决的一些基本思路,给出一些比较典型的错误的示例理解。

一.设置虚拟主机会发生些什么问题?

基本上会最容易遇到两个问题:1.虚拟主机发生冲突。2.宿主机的丢失。(当然还会遇到其他很多的问题,但是这里我们先讨论这2个问题)

1.虚拟主机发生冲突:

无 论是采用哪种形式的虚拟主机,都会发生虚拟主机冲突的问题,尤其是在Apache的虚拟主机系统变得庞大而复杂的时候尤其容易发生。但是请记住,无论什么 采用什么形式的虚拟主机,甚至多种混用,如果造成虚拟主机冲突的话,根本原因就只有一个:“至少有一个原因,使得Apache不能区别一些虚拟主机”。

之 前一个一直强调的一个部分就是“Apache需要能够做到区分每个虚拟主机”。如果能够通过IP区分的话,那就通过IP区分;如果需要多个主机共享一个 IP的话,那么可以设定不同的端口让Apache去区分;如果需要多个虚拟主机使用一个IP并且端口也用同一个的话,那么也要通过不同的域名来让 Apache做到对不同虚拟主机的区分。

一个最经常发生的错误,就是在多个IP地址上进行基于域名方式虚拟主机的配置当中,没有指定和规划好哪几个虚拟主机是归属于哪个IP地址下,造成Apache对一些虚拟主机不能区别。沿用第二章中的示例,以下给出一个典型错例。

[root@kcentos5 ~]# vi /etc/httpd/myconf/virthosts.conf

————(注意:此为典型错误配置的示例)———-

NameVirtualHost 192.168.1.111:80

<VirtualHost *:80> (VirtualHost后面没有指定自己归属的IP地址)

DocumentRoot /var/www/vhost1/

ServerName aaa.aaa.com

</VirtualHost>

<VirtualHost *:80> (VirtualHost后面没有指定自己归属的IP地址)

DocumentRoot /var/www/vhost2/

ServerName bbb.bbb.com

</VirtualHost>

NameVirtualHost 192.168.1.222:80

<VirtualHost *:80> (VirtualHost后面没有指定自己归属的IP地址)

DocumentRoot /var/www/vhost3/

ServerName ccc.ccc.com

</VirtualHost>

<VirtualHost *:80> (VirtualHost后面没有指定自己归属的IP地址)

DocumentRoot /var/www/vhost4/

ServerName ddd.ddd.com

</VirtualHost>

————————————————– —–

在 这个虚拟主机的配置当中,通过2个NameVirtualHost配置项指出Apache将在192.168.1.111和192.168.1.222这 两个IP地址上分别做基于域名的虚拟主机。但是,在每个虚拟主机的配置当中,又没有在<VirtualHost>这个虚拟主机头配置当中指定 自己所归属的IP地址,虽然在每个虚拟主机里是同过ServerName写明了自己应该受理的域名,但是对于Apache来说,即使得到了客户端对哪个域 名的请求,但是它也不知道如何进一步给自己的哪个网络接口的IP地址上的虚拟主机去受理。那么这个时候Apache遇到这样的问题会怎么做呢?

我们就先按以上的错误配置来启动httpd服务看看响应。

[root@kcentos5 ~]# service httpd restart

————————————————– —–

Stopping httpd: [ OK ]

Starting httpd: [Sun Sep 23 19:53:38 2007] [warn] _default_ VirtualHost overlap on port 80, the first has precedence

告警:默认的虚拟主机在监听的80端口上有重叠,因此第一个虚拟主机将获得优先。

[Sun Sep 23 19:53:38 2007] [warn] _default_ VirtualHost overlap on port 80, the first has precedence

[Sun Sep 23 19:53:38 2007] [warn] _default_ VirtualHost overlap on port 80, the first has precedence

[Sun Sep 23 19:53:38 2007] [warn] NameVirtualHost 192.168.1.111:80 has no VirtualHosts

告警:网络接口192.168.1.111上不认为有虚拟主机的存在。

[Sun Sep 23 19:53:38 2007] [warn] NameVirtualHost 192.168.1.222:80 has no VirtualHosts

告警:网络接口192.168.1.222上不认为有虚拟主机的存在。

[ OK ]

————————————————– —–

再通过httpd -S命令来更加明确发生的问题,以及发生该问题后Apache所将采取的措施。

[root@kcentos5 ~]# httpd -S

————————————————– —–

[Sun Sep 23 20:22:43 2007] [warn] _default_ VirtualHost overlap on port 80, the first has precedence

[Sun Sep 23 20:22:43 2007] [warn] _default_ VirtualHost overlap on port 80, the first has precedence

[Sun Sep 23 20:22:43 2007] [warn] _default_ VirtualHost overlap on port 80, the first has precedence

告警:默认的虚拟主机在监听的80端口上有重叠,因此第一个虚拟主机将获得优先。

[Sun Sep 23 20:22:43 2007] [warn] NameVirtualHost 192.168.1.111:80 has no VirtualHosts

告警:网络接口192.168.1.111上不认为有虚拟主机的存在。

[Sun Sep 23 20:22:43 2007] [warn] NameVirtualHost 192.168.1.222:80 has no VirtualHosts

告警:网络接口192.168.1.222上不认为有虚拟主机的存在。

VirtualHost configuration:

wildcard NameVirtualHosts and _default_ servers:

*:80 aaa.aaa.com (/etc/httpd/myconf/virthosts.conf:16)

*:80 bbb.bbb.com (/etc/httpd/myconf/virthosts.conf:21)

*:80 ccc.ccc.com (/etc/httpd/myconf/virthosts.conf:28)

*:80 ddd.ddd.com (/etc/httpd/myconf/virthosts.conf:33)

以上是通配*:80的主机

Syntax OK

配置语法正确

————————————————– ——

所以我们可以根据上面的现象了解到一些事实:

(1) 在多个IP上面采用基于域名方式虚拟主机的时候,除非你只使用一个NameVirtualHost配置项来让Apache将所有自己监听的网络接口地址放 在一起共同随机监听。如果像这样你指定了多条NameVirtualHost来规划好哪些虚拟主机是归属于哪个IP地址的话,那么你也必须在每个虚拟主机的<VirtualHost>头配置项目里指定归属的NameVirtualHost的IP地址。否则Apache将无法对其辨认。

(2) 当发生了以上这样的失误,那么Apache首先将会把一些不能区分的虚拟主机作为“通配虚拟主机”,因为在Apache看来,这些通配的虚拟主机是不能区 分的,认为这已经造成了冲突。接下去Apache会做的就是将“通配虚拟主机”当中第一出现的虚拟主机作为“缺省主机”(在配置文件中位置上最先出现的出 现的),然后将所有接受到的发往这些通配虚拟主机的请求都递交给这个缺省主机造成其他缺省主机的无效。因此Apache也就认为了在自己的几个监听网络接 口上,用户并没有设定虚拟主机,因为Apache就只认可每个地址上配置文件中首先出现的虚拟主机,而强行使其他的通配主机无效。

(3)最后的Syntax OK,表示配置文件的语法没有错误。的确没有语法错误,本例中的错误是“逻辑错误”而不是语法上错误,Apache会检测语法通过,因此在这样的状况下,Apache也仍然启动OK。

正确的修改应该如下:

————————————————– —–

NameVirtualHost 192.168.1.111:80

<VirtualHost 192.168.1.111:80>

DocumentRoot /var/www/vhost1/

ServerName aaa.aaa.com

</VirtualHost>

<VirtualHost 192.168.1.111:80>

DocumentRoot /var/www/vhost2/

ServerName bbb.bbb.com

</VirtualHost>

NameVirtualHost 192.168.1.222:80

<VirtualHost 192.168.1.222:80>

DocumentRoot /var/www/vhost3/

ServerName ccc.ccc.com

</VirtualHost>

<VirtualHost 192.168.1.222:80>

DocumentRoot /var/www/vhost4/

ServerName ddd.ddd.com

</VirtualHost>

————————————————– —–

[root@kcentos5 ~]# service httpd restart

Stopping httpd: [ OK ]

Starting httpd: [ OK ]

2.虚拟主机的设定可能会造成宿主机的丢失:

当Apache启用虚拟主机的功能时候,另外一个可能发生的问题就是原本宿主机的站点丢失了。这通常发生在虚拟主机和宿主机站点共享一个IP所造成的。

举一个例子,这里我使用3个域名对应同一个IP

————————————————– —–

192.168.1.21 kcentos5.center.net (Apache宿主机主站点用的域名)

192.168.1.21 xxx.xxx.com (Apache虚拟主机站点用的域名)

192.168.1.21 yyy.yyy.com (Apache虚拟主机站点用的域名)

————————————————– —–

然后Apache的全局主配置文件相关设定如下(只取相关部分):

[root@kcentos5 ~]# cat /etc/httpd/conf/httpd.conf |grep -v “#”

————————————————– —–

ServerName kcentos5.center.net:80

宿主站点监听的域名和端口

DocumentRoot “/var/www/html” (主页显示为”MainHost”)

宿主站点主路径

Include conf.d/*.conf

Include myconf/*.conf

扩展配置文件路径

————————————————– —–

接着察看虚拟主机配置文件设定:

[root@kcentos5 ~]# cat /etc/httpd/myconf/virthosts.conf

————————————————– —–

NameVirtualHost 192.168.1.21:80

<VirtualHost 192.168.1.21:80>

DocumentRoot /var/www/vhost5/ (主页显示为”Vhost5″)

ServerName xxx.xxx.com

</VirtualHost>

<VirtualHost 192.168.1.21:80>

DocumentRoot /var/www/vhost6/ (主页显示为”Vhost6″)

ServerName yyy.yyy.com

</VirtualHost>

————————————————– —–

启动服务:

[root@kcentos5 ~]# service httpd restart

Stopping httpd: [ OK ]

Starting httpd: [ OK ]

测试:

使用Windows的客户端分别去访问三个域名,反馈结果如下:

————————————————– —–

http://kcentos.center.net &n … nbsp;”Vhost5″

http://xxx.xxx.com &n … sp;-> “Vhost5”

http://yyy.yyy.com … ;-> “Vhost6”

————————————————– —–

测试结果下访问宿主站点kcentos.center.net而反馈的内容和访问虚拟主机站点xxx.xxx.com相同。访问虚拟主机yyy.yyy.com反馈的信息正常。也就是说在现象上宿主站点反馈显示的内容并正确显示出来,却显示了一个虚拟主机站点的内容。

察看Apache虚拟站点的情况:

[root@kcentos5 ~]# httpd -S

————————————————– —–

VirtualHost configuration:

192.168.1.21:80 is a NameVirtualHost

default server xxx.xxx.com (/etc/httpd/myconf/virthosts.conf:3)

port 80 namevhost xxx.xxx.com (/etc/httpd/myconf/virthosts.conf:3)

port 80 namevhost yyy.yyy.com (/etc/httpd/myconf/virthosts.conf:8)

Syntax OK

————————————————– —–

根 据Apache汇报的虚拟主机情况看,192.168.1.21:80这个地址的缺省站点主机变成了xxx.xxx.com。也就是说 xxx.xxx.com和yyy.yyy.com将正常工作,并且xxx.xxx.com已经自动被Apache当作了192.168.1.21:80这 个地址的缺省站点主机。那么访问kcentos.center.net这个宿主站点的请求将会自动被递交给xxx.xxx.com这虚拟主机站点了,这 样,kcentos.center.net这个宿主站点就好像消失了一样。这种情况我称之为“宿主站点的丢失”。

二.那么我的宿主机去哪里了?

其 实事情是这样的。当设定基于域名区别的虚拟主机的时候,如果宿主站点使用的IP地址和一些虚拟主机共享的话,也就是说一些虚拟主机和宿主机站点同时使用一 个IP而只通过域名区别彼此的时候,那么宿主站点将自动被隐藏掉。对于这个大家都用的“IP地址:端口”来说,Apache将会把在虚拟主机配置文件里第 一个出现的虚拟主机作为这个“IP地址:端口”的Default Server即缺省站点,因此,即使有请求发送到Apache说要访问宿主站点的话,将统统由和宿主站点共用“IP地址:端口”的、在虚拟主机配置文件中 第一个出现的虚拟站点代替接受掉。从而造成宿主站点从来接收不到原本应该是他受理的请求。

三.怎样让我的宿主机出现?我要我的宿主机独立可以吗?

当然可以让宿主机站点独立出现被访问到!对于这个问题我一般会用2种方法来解决这个问题:

1.将宿主机站点也作为一个虚拟主机添加到配置当中去,并且把它放到最前,作为缺省主机,让它优先被访问:

[root@kcentos5 ~]# vi /etc/httpd/myconf/virthosts.conf

————————————————– —-

NameVirtualHost 192.168.1.21:80

<VirtualHost 192.168.1.21:80>

将宿主机站点也作为一个虚拟主机添加到配置当中去,并且把它排列到最前。

DocumentRoot /var/www/html/

ServerName kcentos.center.net

</VirtualHost>

<VirtualHost 192.168.1.21:80>

DocumentRoot /var/www/vhost5/

ServerName xxx.xxx.com

</VirtualHost>

<VirtualHost 192.168.1.21:80>

DocumentRoot /var/www/vhost6/

ServerName yyy.yyy.com

</VirtualHost>

————————————————– —-

察看Apache虚拟站点的情况:

[root@kcentos5 ~]# httpd -S

————————————————– —-

VirtualHost configuration:

192.168.1.21:80 is a NameVirtualHost

default server kcentos.center.net (/etc/httpd/myconf/virthosts.conf:3)

port 80 namevhost kcentos.center.net (/etc/httpd/myconf/virthosts.conf:3)

port 80 namevhost xxx.xxx.com (/etc/httpd/myconf/virthosts.conf:8)

port 80 namevhost yyy.yyy.com (/etc/httpd/myconf/virthosts.conf:13)

Syntax OK

————————————————– —-

这样,将宿主机站点也作为一个虚拟主机添加到配置当中去,并且把它放到最前,让它作为Default Server出现。那么,就能解决宿主站点隐藏的问题了。

2.给宿主站点独立的IP地址:

主要的手法就是无论你有多少个IP要分给基于域名区别的虚拟主机去分配,但是总给宿主站点一个独立的、不与任何虚拟主机共享的IP地址。

这里给一个简单的示例:

(1)Apache服务器上有三个网络接口。分别为192.168.1.21、192.168.1.111和192.168.1.222。

(2)将192.168.1.111和192.168.1.222这两个地址分配给虚拟主机,并且每个IP地址上面分别开设2个虚拟主机。

(3)为宿主站点独立分配192.168.1.21这个IP地址。不与其它任何虚拟主机共享。

主配置文件全局设置

[root@kcentos5 ~]# cat /etc/httpd/conf/httpd.conf |grep -v “#”

————————————————– —–

Listen 80

全局监听80端口。

ServerName kcentos5.center.net:80

宿主站点监听的域名和端口。

DocumentRoot “/var/www/html” (主页显示为”MainHost”)

宿主站点主路径。

Include conf.d/*.conf

Include myconf/*.conf

扩展配置文件路径。

————————————————– —–

虚拟主机配置文件

[root@kcentos5 ~]# cat /etc/httpd/myconf/virthosts.conf |grep -v “#”

————————————————– —–

NameVirtualHost 192.168.1.111:80

NameVirtualHost 192.168.1.222:80

虚拟主机只使用192.168.1.111和192.168.1.222这两个网络接口。

<VirtualHost 192.168.1.111:80>

DocumentRoot /var/www/vhost1/

ServerName aaa.aaa.com

</VirtualHost>

<VirtualHost 192.168.1.111:80>

DocumentRoot /var/www/vhost2/

ServerName bbb.bbb.com

</VirtualHost>

<VirtualHost 192.168.1.222:80>

DocumentRoot /var/www/vhost3/

ServerName ccc.ccc.com

</VirtualHost>

<VirtualHost 192.168.1.222:80>

DocumentRoot /var/www/vhost4/

ServerName ddd.ddd.com

</VirtualHost>

————————————————– —–

客户端连接测试,并在Apache服务器段察看网络连接状况:

[root@kcentos5 ~]# netstat -nap|less

————————————————– —–

Active Internet connections (servers and established)

Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name

tcp 0 0 0.0.0.0:111 0.0.0.0:* LISTEN 1649/portmap

tcp 0 0 0.0.0.0:1008 0.0.0.0:* LISTEN 1674/rpc.statd

tcp 0 0 0.0.0.0:21 0.0.0.0:* LISTEN 1973/vsftpd

tcp 0 0 127.0.0.1:631 0.0.0.0:* LISTEN 1908/cupsd

tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN 1997/sendmail: acce

tcp 0 0 :::80 :::* LISTEN 3663/httpd

由于Listen当中没有指定具体的IP地址,那么这里将显示所有可用的网络接口的80端口。

tcp 0 0 :::22 :::* LISTEN 1952/sshd

tcp 0 0 ::ffff:192.168.1.21:22 ::ffff:192.168.1.99:2950 ESTABLISHED 2462/0

tcp 0 0 ::ffff:192.168.1.222:80 ::ffff:192.168.1.98:1052 TIME_WAIT –

客户端对ddd.ddd.com虚拟主机站点测试访问的连接。

tcp 0 0 ::ffff:192.168.1.21:80 ::ffff:192.168.1.98:1044 TIME_WAIT –

客户端对kcentos5.center.net宿主站点测试访问的连接。

tcp 0 0 ::ffff:192.168.1.111:80 ::ffff:192.168.1.98:1048 TIME_WAIT –

客户端对aaa.aaa.com虚拟主机站点测试访问的连接。

tcp 0 0 ::ffff:192.168.1.222:80 ::ffff:192.168.1.98:1050 TIME_WAIT –

客户端对ccc.ccc.com虚拟主机站点测试访问的连接。

tcp 0 0 ::ffff:192.168.1.111:80 ::ffff:192.168.1.98:1046 TIME_WAIT –

客户端对bbb.bbb.com虚拟主机站点测试访问的连接。

————————————————– —–

这种方法就是将宿主站点与虚拟主机站点通过IP地址不同区分开,这样也可以避免“宿主站点的丢失”问题,但是需要多消耗一个IP地址。

四.混用可以吗?怎么混用?混用会发生哪些情况?

宿主机站点和各种形式的虚拟主机当然可以混用。在之前的许多示例中也交代的比较多了已经,最终要的一点就是避免冲突,其实根本的道理还是一个“能够让Apache区分彼此各个站点,以使得当不同的访问请求发来时,Apache可以非常明确知道该转交给那个主机处理^_^”

转载自:http://hi.baidu.com/5777033/blog/item/476fb318de0e e1b34aedbc97.html

虚拟主机-Apache虚拟主机配置》有1个想法

发表评论

返回顶部