CentOS系统中Apache虚拟服务器的配置 - Apache - 服务器之家

服务器之家

专注于服务器技术!
当前位置:首页 > Web服务器 > Apache

CentOS系统中Apache虚拟服务器的配置

发布时间:2014-04-02 来源:服务器之家

[root@localhost ~]# yum -y install httpd

Loaded plugins: fastestmirror

Loading mirror speeds from cached hostfile

Setting up Install Process

Package httpd-2.2.3-43.el5.centos.3.x86_64 already installed and latest version

Nothing to do

 

 

#

# Use name-based virtual hosting.

#取消下面的注释,这个表示发往所有IP的请求使用虚拟主机配置,也可以限定成特定IP地址才启用虚拟主机配置

NameVirtualHost *:80   

注意一:NameVirtualHost 指定虚拟主机所使用的IP地址或域名,但是最好是IP地址。使用基于域名的虚拟主机时,NameVirtualHost是必要的指令。NameVirtualHost可以定义多个。 
注意二:所有符合NameVirtualHost或<VirtualHost>标签定义的请求,都会被作为虚拟主机处理,而主服务器将不理 会。NameVirtualHost定义了而<VirtualHost>标签没有定义的的请求,服务器会找不到相应的虚拟主机而将无法处理。 所以每个NameVirtualHost定义的参数至少要有一个<VirtualHost>相匹配。
注意三:如果设置NameVirtualHost 或<VirtualHost>为*:80的话,所有针对80端口的请求,都会被虚拟主机处理,请求会根据域名指向某个虚拟主机。如果有来自 80端口的请求,而所请求的域名没有被配置为虚拟主机,那将指向第一个虚拟主机。这样主服务器将无法收到来自80端口的任何请求。为此也要为主服务器配置 一个虚拟主机。

原理:

 

Apache的虚拟主机主要分两种:基于ip的虚拟主机和基于域名的虚拟主机

对于单纯的基于ip的虚拟主机来说,配置像这样:

NameVirtualHost 10.10.10.11:80
NameVirtualHost 10.10.10.12:80

#VirtualHost 1
<VirtualHost 10.10.10.11:80>
DocumentRoot "/aaa/"
ServerName domain1 
</VirtualHost>

#VirtualHost 2
<VirtualHost 10.10.10.12:80>
DocumentRoot "/bbb/"
ServerName domain2 
</VirtualHost>

说明:因为每个ip都配置了虚拟主机,所以只需根据ip就可以判断要访问的是哪个虚拟主机,如果用domain2来访问,而hosts里设置 domain2指向10.10.10.11,那么会访问到哪个虚拟主机呢?当然,先根据ip判断,访问 VirtualHost 1了,所以ServerName没有多大用途,师傅说可以作为环境变量(就是说环境变量里会出现ServerName的);或许您会问了,如果用 127.0.0.1来访问呢,确实没有给该ip指定使用哪个虚拟主机,这种情况下排在第一个的那个(就是VirtualHost 1)就是默认虚拟主机了,就是说,没有能匹配的上的(用ip和域名匹配,ip优先),就使用默认虚拟主机

对于单纯的基于域名的虚拟主机,配置像这样:

 

#任何ip都是用虚拟主机
NameVirtualHost *:80

#VirtualHost 1
<VirtualHost *:80>
DocumentRoot "/aaa/"
ServerName domain1 
</VirtualHost> #VirtualHost 2
<VirtualHost *:80>
DocumentRoot "/bbb/"
ServerName domain2 
</VirtualHost> 

说明:这样的话,不管走哪个ip(因为根据ip没法区分),用domain1访问,就访问到VirtualHost 1,用domain2访问,就访问到VirtualHost 2;

 

对于既有基于ip的虚拟主机也有基于域名的虚拟主机,配置像这样:

#任何ip都是用虚拟主机
NameVirtualHost *:80

#VirtualHost 1
<VirtualHost 10.10.10.11:80>
DocumentRoot "/aaa/"
ServerName domain1 
</VirtualHost> #VirtualHost 2
<VirtualHost 10.10.10.12:80>
DocumentRoot "/bbb/"
ServerName domain2 
</VirtualHost>

#VirtualHost 3
<VirtualHost domain3:80>
DocumentRoot "/ccc/"
ServerName domain3
</VirtualHost>

说明:
1. 要注意启动apache时,domain3指向的是哪个ip,因为<VirtualHost domain3:80>里的domain3是要解释成ip的,分析的时候就把这里当作解析成的ip来对待

2. 假设domain3解释为10.10.10.11,如果客户端用domain3指向10.10.10.11来访问,我们发现就有两个10.10.10.11:80的虚拟主机,然后根据ServerName判断,发现#VirtualHost 3是最匹配的一个虚拟主机,于是#VirtualHost 3就是要访问到的虚拟主机;

3. 假设domain3解释为10.10.10.11,如果客户端用domain3指向10.10.10.12来访问,先根据ip判断,只有#VirtualHost 2是匹配的,所以#VirtualHost 2就是要访问到的虚拟主机;

4. 要想只要用domain3访问,都是访问/ccc/目录,那么就要对两个ip都配置ServerName为domain3的虚拟主机;我们想,将#VirtualHost 3改成如下行吗:
#VirtualHost 3
<VirtualHost *:80>
DocumentRoot "/ccc/"
ServerName domain3
</VirtualHost> 
答案是:不行;因为做ip匹配的时候,优先选用更精确匹配的一个,显然与另外两个虚拟主机相比,通过任何一个ip访问,* 都不如直接用ip定义的虚拟主机精确,所以这时的#VirtualHost 3只有通过环回地址访问,而且只要通过环回地址访问,使用任何主机名访问的都是#VirtualHost 3;

对于NameVirtualHost的使用:
如果某个ip:port 上只设置了一个虚拟主机,那么NameVirtualHost ip:port 可以不写,因为从这个ip:port的访问不需要做任何选择;
如果某个ip:port 上设置了多于一个虚拟主机,那么必须使用指令NameVirtualHost ip:port ,否则从该ip:port的访问只访问第一个该ip:port 的虚拟主机(因为它优先,apache启动时会提示的);
如果使用了指令NameVirtualHost ip:port ,却没有为该ip:port定义任何虚拟主机,好像不会出现访问到错误的虚拟主机的问题(因为谁也不知道你想干什么,不过apache还是会提示你:[warn] NameVirtualHost ip:port has no VirtualHosts);
如果VirtualHost 指定的虚拟主机没有匹配一个NameVirtualHost 指令,那么该虚拟主机不会被用到(除非他是第一个虚拟主机),这相当于没有NameVirtualHost 指令,即:如果有多个虚拟主机,一定要有NameVirtualHost 指令

 

注意一:NameVirtualHost 指定虚拟主机所使用的IP地址或域名,但是最好是IP地址。使用基于域名的虚拟主机时,NameVirtualHost是必要的指令。NameVirtualHost可以定义多个。 
注 意二:所有符合NameVirtualHost或<VirtualHost>标签定义的请求,都会被作为虚拟主机处理,而主服务器将不理会。 NameVirtualHost定义了而<VirtualHost>标签没有定义的的请求,服务器会找不到相应的虚拟主机而将无法处理。所以 每个NameVirtualHost定义的参数至少要有一个<VirtualHost>相匹配。
注意三:如果设置 NameVirtualHost 或<VirtualHost>为*:80的话,所有针对80端口的请求,都会被虚拟主机处理,请求会根据域名指向某个虚拟主机。如果有来自 80端口的请求,而所请求的域名没有被配置为虚拟主机,那将指向第一个虚拟主机。这样主服务器将无法收到来自80端口的任何请求。为此也要为主服务器配置 一个虚拟主机。

虚拟主机混用时的问题:
一、虚拟主机混用可以这样理解:一行NameVirtualHost指令定义的所有虚拟主机为一组;该组与一个基于IP的虚拟主机平级。即把一行NameVirtualHost定义的整个组看作是一个基于IP的虚拟主机。
二、虚拟主机指定的端口必须是Listen定义的。如果虚拟主机没有指定端口,则认为是80端口。如果NameVirtualHost * 这样定义,是指所有地址的所有已定义端口。
三、 更具体的地址定义优先。比如NameVirtualHost指令定义了*:80,而某个基于IP的虚拟主机定义为192.168.0.1:80,那么此时 如有对192.168.0.1:80的请求,那请求会被优先指向192.168.0.1:80定义的虚拟主机。所以为了避免混乱,不要定义相互有交叉或包 含的地址区间。
四、一个虚拟主机,可以同时为基于域名和基于IP的。如上一例中最后一个虚拟主机。这样符合两种定义的请求都会被指同一个虚拟主机。有时要区别内外网对虚拟主机的访问时可以这样,因为来自内网的请求可能和来自外网的请求可能不一样,但是它们需要指向同一个虚拟主机。

注:

虚拟主机中可以缺省很多指令,我曾经只是想给通过不同域名的访问分别记录日志,实际上他们访问的都是相同的东西,所以DocumentRoot指令就可以省略了,里面我只写了三条指令,如:

<VirtualHost *:80 >
        ServerName *
        TransferLog "|rotatelogs /backup/apachelog/%Y%m/access_log.%Y%m%d 86400 480"
        ErrorLog "|/rotatelogs /backup/apachelog/%Y%m/error_log.%Y%m%d 86400 480"
</VirtualHost>