设为首页 收藏本站
查看: 1769|回复: 0

[经验分享] Apache虚拟主机配置

[复制链接]
累计签到:1 天
连续签到:1 天
发表于 2014-7-30 08:38:36 | 显示全部楼层 |阅读模式
  "虚拟主机"是指在一个机器上运行多个网站(比如:www.company1.com和[url]www.company2.com[/url])。如果每个网站拥有不同的IP地址,则虚拟主机可以是"基于IP"的;如果只有一个IP地址,也可以是"基于主机名"的,其实现对最终用户是透明的。物理服务器只有一个,而且web服务器也只有一个,却可以服务多个不同的站点。    如果要调试你的虚拟主机配置,你会发现Apache的 -S 命令行开关很有用。比如:
1
[iyunv@localhost ~]# httpd -S



虚拟主机支持
  • 基于主机名的虚拟主机(一个IP地址,多个网站)

    同IP,同端口,不同域名,虽然被解析到同一个IP上,但是通过http头的host能够区分
  • 基于IP地址的虚拟主机(每个站点拥有一个的独立IP地址)

    不同IP, 同端口,每个虚拟主机使用不同的IP地址(但是IP地址有点贵)

  • 基于端口的虚拟主机

    同IP,不同端口,但是困扰的是浏览器默认的端口都是80
    基于IP的虚拟主机使用连接的IP地址来决定相应的虚拟主机。这样,你就需要为每个虚拟主机分配一个独立的IP地址。而基于域名的虚拟主机是根据客户端提交的HTTP头中标识主机名的部分决定的。使用这种技术,很多虚拟主机可以共享同一个IP地址。
    基于域名的虚拟主机相对比较简单,因为你只需要配置你的DNS服务器将每个主机名映射到正确的IP地址,然后配置Apache HTTP服务器,令其辨识不同的主机名就可以了。基于域名的服务器也可以缓解IP地址不足的问题。所以,如果没有特殊原因使你必须使用基于IP的虚拟主机,您最好还是使用基于域名的虚拟主机。
    我们知道,TCP/IP网络通信都是建立在socket <IP:PORT>之上的。IP:PORT就能唯一标识网络上的哪个主机哪个进程。当我们通过浏览器访问:http://www.baidu.com  的时候,首先DNS会把www.baidu.com这个域名解析为IP地址,然后才能在网络中路由。既然域名都会被解析为IP地址,那么怎么实现基于域名的虚拟主机呢?

    仅仅是TCP/IP是无法做到的,但是HTTP协议却能够实现这一点。在http协议首部,定义了一个host,通过它就可以区分究竟访问的哪个虚拟主机。


《HTTP权威指南》
  缺失主机信息是原始HTTP规范的疏忽,它错误的假设每个web服务器上只托管了一个网站。在这个期间涌现了以下4种技术来解决这个问题。
(1)通过URL路径进行虚拟主机托管
在url中添加专门的路径部分,以便服务器判断是哪个网站。
(2)通过端口号进行主机托管
为每个站点分配一个端口号。
(3)通过IP地址进行主机托管
为不同的虚拟站点分配专门的ip地址,把这些地址绑定到一台单独的机器上。
(4)通过Host首部进行主机托管
通过Htpp/1.0增强版和HTTP/1.1正式版定义Host请求首部来携带网站名称。

通过URL路径进行虚拟主机托管
通过分配不同的url路径,把共享服务器上的虚拟站点隔离开。
如:
http://www.xx123.com/zyt/index.html
http://www.xx356.com/icrt/index.html
    当请求到达服务时,其中并没有主机信息,但是服务器可以通过路径来区分它们。请求zyt的网址是:GET /zyt/index.html,请求icrt的网址是: GET /icrt/index.html 这不是一个好办法/zyt 和/icrt是多余的,更坏的是http://www.xx123.comhttp://www.xx356.com不能用了。
这种方案在实际中很少会用到。
通过端口号进行主机托管
    可在在web服务器上为不同网站指定不同的端口号,不再使用80端口,而是采用其它端口号。这个解决方案也有问题:终端用户不乐意在url中指定非标准的端口号。如http://www.xx123.com:89
通过IP地址进行主机托管
    通过ip地址进行主机托管,是一个更常用、更好的办法。为每个虚拟网站分配一个或者多个唯一的ip地址。所有虚拟网站的ip地址都绑定到同一个共享服务器上。服务器可以查询http连接的目的ip地址,并以此来判断客户端的目标网站。
    如:把ip:209.173.34.3分配给www.xxx123.com,把ip:209.172.34.2分配给www.xx356.com,把这两个ip地址都绑定到同一物理服务器上。
但是这样做也会带来一些麻烦:
    首先在计算机系统上能够绑定的虚拟ip地址通常是有限制的,其次ip地址是稀缺资源,最后托管都通过复制服务器来增加容量时,ip地址短缺的问题就更加严重了。
尽管有这样的缺陷,但是它仍然得到广泛的应用。
通过Host首部进行主机托管
    为了避免过度的地址消耗和虚拟ip地址的限制,我们希望在虚拟站点间共享同一个ip地址,且仍然能够区分站点。为了解决这个问题,浏览器来服务器的实现都扩展了HTTP,把原始主机名给了服务器。不过,浏览器不能只发送完整的URL,因为这会使许多只能接收路径的服务器无法工作。替代的方法是,把主机名和端口号放在所请求的Host扩展首部中传送。

绝大多数现代浏览器和服务器都支持Host首部,但仍然有一些客户端以及网络机器人不支持它。

配置虚拟主机对于Apache而言,主机有两类:一般不能同时使用
  • 中心主机(Mainhost)    未配置虚拟主机时
  • 虚拟主机(Vhost)      如果配置了中心主机,同时也想配置虚拟主机,那么把它也配置虚拟主机


  • 取消中心主机(Mainhost)
    如果你想在现有的web服务器上增加虚拟主机,你必须也为现存的主机建造一个<VirtualHost>定义块。这个虚拟主机中ServerNameDocumentRoot所包含的内容应该与全局的ServerNameDocumentRoot保持一致。还要把这个虚拟主机放在配置文件的最前面,来让它扮演默认主机的角色。
    如果不想使用中心主机,那么可以直接在httpd.conf配置文件中注释掉中心主机的 DocumentRoot即可。

  • 虚拟主机的配置文件
    可以直接在主配置文件httpd.conf中直接配置,但是这样不利于维护,建议在/etc/httpd/conf.d/建立 *.conf 配置文件。前提是在httpd.conf中配置 Include conf.d/*.conf


基于域名的虚拟主机    为了使用基于域名的虚拟主机,你必须指定服务器IP地址(和可能的端口)来使主机接受请求,这个可以用NameVirtualHost指令来进行配置。如果服务器上所有的IP地址都会用到,你可以用"*"作为NameVirtualHost的参数。如果你打算使用多端口(如运行SSL)你必须在参数中指定一个端口号,比如"*:80"。请注意,在NameVirtualHost指令中指定IP地址并不会使服务器自动侦听那个IP地址。请参阅设置Apache使用的地址和端口一章获取更多详情。另外,这里设定的IP地址必须对应服务器上的一个网络接口。
需要注意的是:apache2.2需要用NameVirtualHost指令配置, apache2.4 不需要

    下一步就是为每个虚拟主机建立<VirtualHost>段。<VirtualHost>的参数与NameVirtualHost的参数必须是一样的(比如说,一个IP地址或"*"代表的所有地址)。在每个<VirtualHost>段中,至少要有一个ServerName指令来指定伺服哪个主机和一个DocumentRoot指令来说明这个主机的内容位于文件系统的什么地方。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
# 修改配置文件
[iyunv@localhost ~]# vi /etc/httpd/conf.d/vitual.conf
NameVirtualHost *:80        # apache 2.2 必须

<VirtualHost *:80>
        serverName www.a.com
        DocumentRoot "/www/a.com"
</VirtualHost>

<VirtualHost *:80>
        serverName www.b.org
        DocumentRoot "/www/b.org"
</VirtualHost>

# 创建web目录
[iyunv@localhost ~]# mkdir -pv /www/a.com /www/b.org
mkdir: created directory `/www'
mkdir: created directory `/www/a.com'
mkdir: created directory `/www/b.org'

[iyunv@localhost ~]# service httpd reload

# 编辑index.html
[iyunv@localhost ~]# echo '<h1>www.a.com</h1>' > /www/a.com/index.html
[iyunv@localhost ~]# echo '<h1>www.b.org</h1>' > /www/b.org/index.html

# 我们只能通过域名进行访问,如果直接使用IP,那么则会返回默认的虚拟主机。
# 1 可以修改客户机的host文件, win: C:\Windows\System32\drivers\etc
# 2 也可以搭建DNS

# 编辑hosts文件,有些机器的hosts可能被隐藏了
192.168.11.101      www.a.com
192.168.11.101      www.b.org

C:\Users\yy>ping www.a.com
正在 Ping www.a.com [192.168.11.101] 具有 32 字节的数据:
来自 192.168.11.101 的回复: 字节=32 时间<1ms TTL=64
来自 192.168.11.101 的回复: 字节=32 时间<1ms TTL=64

C:\Users\yy>ping www.b.org
正在 Ping www.b.org [192.168.11.101] 具有 32 字节的数
来自 192.168.11.101 的回复: 字节=32 时间<1ms TTL=64
来自 192.168.11.101 的回复: 字节=32 时间<1ms TTL=64

# OK, 我们看到
# 通过浏览器访问, 注意首先要注释掉中心主机哈



wKiom1PXeDiwK8V7AABMUHOdsF0797.jpg
wKioL1PXeVLTITq4AABNWoZi4tA887.jpg
    最后,你可以把其他一些指令放入<VirtualHost>段中,以更好的配置一个虚拟主机。大部分指令都可以放入这些<VirtualHost>段中以改变相应虚拟主机配置。如果您想了解一个特定的指令是否可以这样运用,请参见指令的作用域。主服务器(main server)范围内的配置指令(在所有<VirtualHost>配置段之外的指令)仅在它们没有被虚拟主机的配置覆盖时才起作用。
    这样,当一个请求到达的时候,服务器会首先检查它是否使用了一个能和NameVirtualHost相匹配的IP地址。如果能够匹配,它就会查找每个与这个IP地址相对应的<VirtualHost>段,并尝试找出一个与请求的主机名相同的ServerName或ServerAlias配置项。如果找到了,它就会使用这个服务器。否则,将使用符合这个IP地址的第一个列出的虚拟主机。
    综上所述,第一个列出的虚拟主机充当了默认虚拟主机的角色。当一个IP地址与NameVirtualHost指令中的配置相符的时候,主服务器中的DocumentRoot将永远不会被用到。所以,如果你想创建一段特殊的配置用于处理不对应任何一个虚拟主机的请求的话,你只要简单的把这段配置放到<VirtualHost>段中,并把它放到配置文件的最前面就可以了。

基于IP的虚拟主机    这样的服务器中每个基于IP的虚拟主机必须拥有不同的IP地址。可以通过配备多个真实的物理网络接口来达到这一要求,也可以使用几乎所有流行的操作系统都支持的虚拟界面来达到这一要求(详情请参见您的系统文档,这种功能一般被称作"IP别名",一般用"ifconfig"命令来进行设置)。
    有两种配置方法来使apache支持多主机:为每个虚拟主机运行不同的httpd守护进程;或者用同一个守护进程来支持所有虚拟主机。
以下情况使用多个守护进程:
  • 出于安全的考虑,比如说公司甲不希望公司乙的任何人能用除web以外的方式访问到他们的数据。在这种情况下,
  • 您需要启动两个守护进程。每个进程都使用不同的User, Group, Listen,ServerRoot设置。
  • 您能够为机器上的每个IP地址提供内存和文件描述符需求。您只能Listen一个"通配符型"地址或一个特定的地址。
  • 所以不管出于什么原因,如果您需要侦听一个特定的地址,您就必须同时侦听所有特定的地址。(尽管可以让一
  • httpd侦听N-1个地址,而让另一个侦听剩下的地址)

以下情况使用单一守护进程:
  • httpd的配置可以为多个虚拟主机共享而不引起麻烦。
  • 机器要接受大量的访问请求,从而多启动一个守护进程会导致性能大幅度降低。


1、设置多个守护进程
    为每个虚拟主机创建一个不同的httpd安装。每次安装都在配置文件中使用Listen指令指定守护进程伺服的IP地址(或虚拟主机)。比如:
1
Listen www.smallco.com:80



2、配置拥有多个虚拟主机的单一守护进程

    在这种情况下,单一的httpd将伺服所有对主服务器和虚拟主机的请求。而配置文件中的VirtualHost指令将为每个虚拟主机配置不同的ServerAdmin, ServerName, DocumentRoot, ErrorLog,TransferLog, CustomLog
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
[iyunv@localhost ~]# vi /etc/httpd/conf.d/vitual.conf
<VirtualHost 192.168.11.101:80>
        serverName www.a.com
        DocumentRoot "/www/a.com"
</VirtualHost>

<VirtualHost 192.168.11.102:80>
        serverName www.b.org
        DocumentRoot "/www/b.org"
</VirtualHost>

# 重新读取配置文件
[iyunv@localhost ~]# service httpd reload

# 编辑index.html
[iyunv@localhost ~]# echo '<h1>192.168.11.101</h1>' > /www/a.com/index.html
[iyunv@localhost ~]# echo '<h1>192.168.11.102</h1>' > /www/b.org/index.html

# 如何测试呢?我们通过添加网卡别名来达成
[iyunv@localhost ~]# ifconfig eth1
eth1      Link encap:Ethernet  HWaddr 00:0C:29:FB:65:36  
          inet addr:192.168.11.101  Bcast:192.168.11.255  Mask:255.255.255.0
          inet6 addr: fe80::20c:29ff:fefb:6536/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:168196 errors:0 dropped:0 overruns:0 frame:0
          TX packets:44037 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:197148682 (188.0 MiB)  TX bytes:3998845 (3.8 MiB)
          Interrupt:19 Base address:0x2080

[iyunv@localhost ~]# ifconfig eth1:0 192.168.11.102/24 up    # 添加网卡别名



wKioL1PXfUnBvdlCAABZ51OP9lI797.jpg
wKiom1PXfDDAMLq8AABaVmHjbN4145.jpg

基于端口的虚拟主机
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
[iyunv@localhost ~]# vi /etc/httpd/conf.d/vitual.conf
NameVirtualHost *:80

<VirtualHost 192.168.11.101:80>
    serverName www.a.com
    DocumentRoot "/www/a.com"
</VirtualHost>

<VirtualHost 192.168.11.101:8080>
    serverName www.b.org
    DocumentRoot "/www/b.org"
</VirtualHost>

# 修改主配置文件,修改监听端口
# 这样httpd才能向linux内核(BIND)注册端口,然后TCP/IP协议栈才知道把包传给哪个应用程序。
[iyunv@localhost ~]# vi /etc/httpd/conf/httpd.conf
Listen 80
Listen 8080

[iyunv@localhost ~]# service httpd restart    # 由于修改了端口,建议restart

[iyunv@localhost ~]# echo '<h1>192.168.11.101: 80</h1>' > /www/a.com/index.html
[iyunv@localhost ~]# echo '<h1>192.168.11.101: 8080</h1>' > /www/b.org/index.html



wKiom1PXfrSwzvf9AABfchb0PEw343.jpg
wKioL1PXf87QcYNuAABqPds34tY037.jpg

总结定义一个站点,至少需要提供如下信息:

  • DocumentRoot
  • ServerName
  • IP
  • PORT


如果测试无法正常访问, 请检查iptables防火墙规则,以及SELinux设置。
更多详细信息, 请参考Apache官方网站。


运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-22894-1-1.html 上篇帖子: Apache服务器中prefork和worker工作模式 下篇帖子: Apache2.4 + MySQL5.5 + PHP5.5 FCGI方式运行 虚拟主机
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表