免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 848 | 回复: 0
打印 上一主题 下一主题

虚拟主机相关资料! [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2007-02-25 22:46 |只看该作者 |倒序浏览
在一个IP地址上运行多个基于域名的web站 点。
您的服务器有一个IP地址,而在DNS中有很多映射(CNAMES)到这个机器。 您而您想要在这个机器上运行www.example1.com和 www.example2.org两个站点。
注意
在您Apache服务器的配置中创建一个虚拟主 机并不会自动在您的DNS中对主机名做相应更新。您必须自 己在DNS中添加域名来指向您的IP地址。否则别人是无法看到您的web 站点的。您可以在您的hosts文件中添加这一条目来进 行测试,但这种方法仅适用于那些有这些条目的机器来使用。
服务器配置
# Ensure that Apache listens on port 80
Listen 80
# Listen for virtual host requests on all IP addresses
NameVirtualHost *
DocumentRoot /www/example1
ServerName www.example1.com
# Other directives here
DocumentRoot /www/example2
ServerName www.example2.org
# Other directives here

因为星号匹配所有的地址,所以主服务器不接收任何请求。因为 www.example1.com首先出现在配置文件中,所以它拥有最高 优先级,可以认为是默认或首要服务器。这意 味着如果一个接受的请求不能与某个ServerName指令相匹配, 它将会由第一个VirtualHost所伺服。
注意
如果您愿意,您可以用确定的IP地址来取代*。 在这种情况下,VirtualHost的参数必须 与NameVirtualHost的参数相符:
NameVirtualHost 172.20.30.40
# etc ...
不论如何,当您的IP地址无法确定的时候,使用* 是很方便的——比如说,您的ISP给您配置的是动态IP地址,而您有 使用了某种动态域名解析系统时。因为*匹配任何IP 地址,所以在这样的情况下,不论IP地址如何变化,您都不需要另 外进行配置。
上述配置就是您在绝大多数情况下使用基于域名的虚拟主机时将要用到 的。事实上,仅在一种情况下这样的配置不会让您满意:当您想为不同的IP 地址或是端口提供不同的内容时。
在多于一个IP的情况下使用基于域名的虚拟 主机。
注意
在这里讨论的任何技术都可以推广到使用任意数量的IP 地址。
服务器有两个IP地址。一个(172.20.30.40)用于“主”服务器—— server.domain.com而另外一个 (172.20.30.50),我们将用于构建两个或多个虚拟主机。
服务器配置
Listen 80
# This is the "main" server running on 172.20.30.40
ServerName server.domain.com
DocumentRoot /www/mainserver
# This is the other address
NameVirtualHost 172.20.30.50
DocumentRoot /www/example1
ServerName www.example1.com
# Other directives here ...
DocumentRoot /www/example2
ServerName www.example2.org
# Other directives here ...

任何不是针对172.20.30.50的请求都将由主服务器来伺服。 而提交给172.20.30.50却没有主机名或没有 Host:头的请求,都将为www.example1.com伺 服。
在不同的IP的地址(比如一个内部和一个外部地址) 上提供相同的内容。
服务器有两个IP地址(192.168.1.1和 172.20.30.40)。这个机器位于内部(局域网)网络和外部 (广域网)之间。在外部,域名server.example.com指向 外部地址(172.20.30.40),而在内部,同样的域名指向内 部地址(192.168.1.1)。
服务器可以配置为向来自内部和外部的请求提供同样的内容,您只需要 一个VirtualHost配置段就可以达到这个目的。
服务器配置
NameVirtualHost 192.168.1.1
NameVirtualHost 172.20.30.40
DocumentRoot /www/server1
ServerName server.example.com
ServerAlias server

现在,从不同的网络提交的请求都会由同一个 VirtualHost来伺服。
注意:
在内网中,您可以使用 server这个名字来代替 server.example.com全名。
跟上面一样,在上述的例子里,您可以用*来取代 具体的IP地址,这样就可以对所有的地址返回相同的内容了。
在不同的端口上运行不同的站点。
如果您想让同一IP的不同端口伺服多个域名。您可以借助在 “NameVirtualHost”标签中定义端口这样的方法来达到这个目的。如果您 想使用不带NameVirtualHost name:port的或是直接用Listen指令,您的配置将无法生效。
服务器配置
Listen 80
Listen 8080
NameVirtualHost 172.20.30.40:80
NameVirtualHost 172.20.30.40:8080
ServerName www.example1.com
DocumentRoot /www/domain-80
ServerName www.example1.com
DocumentRoot /www/domain-8080
ServerName www.example2.org
DocumentRoot /www/otherdomain-80
ServerName www.example2.org
DocumentRoot /www/otherdomain-8080

建立基于IP的虚拟主机
一个有两个IP地址(172.20.30.40和 172.20.30.50)分别对应域名 www.example1.com和www.example2.org的服务 配置如下:
服务器配置
Listen 80
DocumentRoot /www/example1
ServerName www.example1.com
DocumentRoot /www/example2
ServerName www.example2.org

如果存在主服务器(main server),那么对没有出现在任一个 指令中的请求(比如,对 localhost的请求)都会由主服务器来伺服。
混用基于端口和基于IP的虚拟主机
如果您的服务器有两个IP地址(172.20.30.40和 172.20.30.50)分别对应域名 www.example1.com和www.example2.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
DocumentRoot /www/example1-80
ServerName www.example1.com
DocumentRoot /www/example1-8080
ServerName www.example1.com
DocumentRoot /www/example2-80
ServerName www.example1.org
DocumentRoot /www/example2-8080
ServerName www.example2.org

混用基于域名和基于ip的虚拟主机
如果您想在一些地址上配置基于域名的虚拟主机而在另外一些配置基于 IP的虚拟主机。
服务器配置
Listen 80
NameVirtualHost 172.20.30.40
DocumentRoot /www/example1
ServerName www.example1.com
DocumentRoot /www/example2
ServerName www.example2.org
DocumentRoot /www/example3
ServerName www.example3.net
# IP-based
DocumentRoot /www/example4
ServerName www.example4.edu
DocumentRoot /www/example5
ServerName www.example5.gov

使用_default_虚拟主机
为所有端口配置 _default_虚拟主机
这样配置,以捕获任何指向没指定的IP地址和端口的请求。比如 说:一个没被任何虚拟主机使用的地址/端口对。
服务器配置
DocumentRoot /www/default

使用这样一个使用通配符端口的默认虚拟主机可以有效的防止请求被主 服务器接收。
如果一个地址/端口对已经被一个基于域名的虚拟主机使用,那么默认虚 拟主机决不会处理发向这个地址/端口的请求。如果一个请求的 Host:头中包含未知信息,或者干脆就没有,那么它会被第一 个基于域名的虚拟主机(就是在配置文件中首先出现的使用了那个地址/端 口对的虚拟主机)处理。
您可以用AliasMatch或 RewriteRule来重写任何 请求,使它指向一个简单信息页面(a single information page)(或脚 本)。
为不同的端口部署 _default_虚拟主机
与第一种一样,但我们想让服务器侦听很多端口而第二个 _default_虚拟主机单独侦听80端口。
服务器配置
DocumentRoot /www/default80
# ...
DocumentRoot /www/default
# ...

侦听80端口的默认虚拟主机(必须出现在所有使用通配符端口 的虚拟主机之前)会捕获所有发向一个没有指定的IP地址的请求。主服务器 将不会用于伺服任何请求。
为一个端口配置 _default_虚拟主机
如果我们只想在80端口上建立唯一的一个默认虚拟主机,我们应该这样 配置:
服务器配置
DocumentRoot /www/default
...

发向一个未进行设定的地址的80端口的请求将会为这个虚拟主机伺服; 而发向未进行设定的地址的其他端口的请求为主服务器伺服。
将一个基于域名的虚拟主机移植为一个基于 IP的虚拟主机
如果一个具有www.example2.org域名的虚拟主机(就是基于域名配置示例中的第二个)得到了自己的IP地址。 为了避免一些域名服务器或代理服务器在移植期间仍对这个域名做老的解析, 我们可以采用一种过渡方法:同时提供新旧两个IP地址的解析。
达到这个目的很简单。因为我们只要简单的把新地址 (172.20.30.50)加入VirtualHost指令就行 了。
服务器配置
Listen 80
ServerName www.example1.com
DocumentRoot /www/example1
NameVirtualHost 172.20.30.40
DocumentRoot /www/example2
ServerName www.example2.org
# ...
DocumentRoot /www/example3
ServerName www.example3.net
ServerAlias *.example3.net
# ...

现在这个虚拟主机就可以用新地址(表现为一个基于IP的虚拟主机)和 旧地址(表现为一个基于域名的虚拟主机)同时进行访问了。
使用ServerPath指令
如果我们在一个服务器上运行了两个基于域名的虚拟主机。为了匹配正 确的虚拟主机,客户端必须发送正确的Host:头。而旧的使用 HTTP/1.0的客户端无法发送这样的头,这样,Apache就无法辨别客户端想要 连接哪个虚拟主机(会用主虚拟主机来伺服这个请求)。为了尽量提供向下 兼容性,我们可以可以提供一个主虚拟主机来返回一个页面,在页面中加入 指向基于域名的虚拟主机的URL前缀的链接。
Server configuration
NameVirtualHost 172.20.30.40
# primary vhost
DocumentRoot /www/subdomain
RewriteEngine On
RewriteRule ^/.* /www/subdomain/index.html
# ...
DocumentRoot /www/subdomain/sub1
ServerName www.sub1.domain.tld
ServerPath /sub1/
RewriteEngine On
RewriteRule ^(/sub1/.*) /www/subdomain$1
# ...
DocumentRoot /www/subdomain/sub2
ServerName www.sub2.domain.tld
ServerPath /sub2/
RewriteEngine On
RewriteRule ^(/sub2/.*) /www/subdomain$1
# ...

由于ServerPath指令的作用, 发送到http://www.sub1.domain.tld/sub1/的请求总会 被sub1-vhost所伺服。
如果客户端发送了正确的Host:头,发送到 http://www.sub1.domain.tld/的请求指挥被sub1-vhost伺服。 如果没有发送Host:头,客户端会得到从主虚拟主机发送的信 息页面。
请注意,这里还有一点小问题:如果客户端没有发送Host:头, 发送到http://www.sub2.domain.tld/sub1/的请求还是会被 sub1-vhost伺服。
RewriteRule指令用以确 保正确发送了Host:头的客户端可以任意使用这两种URL变量, 比如说:使用或不使用URL前缀。
--------------------------------------------------------------------------------
动机
如果你的配置文件 httpd.conf 中包含类似下面的许多  部分,并且其中的内容都大致相同的话, 你应该会对这里所要讲的技术比较感兴趣。
NameVirtualHost 111.22.33.44
ServerName www.customer-1.com
DocumentRoot /www/hosts/www.customer-1.com/docs
ScriptAlias /cgi-bin/ /www/hosts/www.customer-1.com/cgi-bin
ServerName www.customer-2.com
DocumentRoot /www/hosts/www.customer-2.com/docs
ScriptAlias /cgi-bin/ /www/hosts/www.customer-2.com/cgi-bin
# blah blah blah
ServerName www.customer-N.com
DocumentRoot /www/hosts/www.customer-N.com/docs
ScriptAlias /cgi-bin/ /www/hosts/www.customer-N.com/cgi-bin

最基本的思想是用动态的机制来实现所有这些静态的  配置。这样做有许多优点:
配置文件变小,使得 Apache 可以更快的启动,同时消耗更少的内存。
添加一个虚拟主机,应该只是简单的在文件系统中创建合适的目录, 以及配置相关的 DNS 信息,并且无需重新启动 Apache。
主要的缺点是你无法针对每个虚拟主机用户使用不同的日志文件。 然而,如果真的在配置有大量虚拟主机的服务器上记录不同的日志文件的话, 很有可能会达到操作系统所允许的最大文件描述符(file descriptors)的数量。 更好的办法是把日志写到管道(pipe)或者先入先出(fifo)的堆栈, 并启用其他的进程来分发所得到的日志信息给用户(同时也可以做一些历史纪录的统计等等)。
概要
一个虚拟主机有两部分来定义:一个是它的 IP 地址, 还有一个是 HTTP 请求中 Host: 头的内容。 动态大容量虚拟主机的技术, 是基于自动在所要返回的文件的路径中插入相关信息的想法而实现的。 使用mod_vhost_alias 可以很容易的实现, 但如果你的 Apache 版本低于 1.3.6 ,则你必须使用 mod_rewrite。 两者在默认情况下都不启用; 要使用他们,必须在配置和编译 Apache 的阶段声明启用(enable)。
我们需要做很多伪装,才能使动态虚拟主机看起来像普通情况。 最重要的一点是 Apache 使用虚拟主机名字(Server Name)来生成自我参考(self-referential) 的 URLs 等等信息。这是用 ServerName 指令来配置的, 并且可以通过环境变量 SERVER_NAME 传递给 CGI 脚本。 在运行时所实际使用的值是由指令 UseCanonicalName 的设置情况来控制的。当 UseCanonicalName Off 时, 虚拟主机名字(server name)取自请求中的 Host: 头的内容。 当 UseCanonicalName DNS 时,则通过 DNS 反解析虚拟主机的IP 地址得到主机名字。 以前的做法是用基于名称的动态虚拟主机,近来常用基于 IP 地址的虚拟主机设置。 如果 Apache 无法决策虚拟主机名字,则可能是没有 Host: 头信息或者 DNS 解析失败, 遇到这样的情况,Apache 使用配置 ServerName 时所填写的主机名字。
简单的动态虚拟主机
这是 httpd.conf 文件中,完成和上文 动机 部分所提到的虚拟主机一样效果的配置方法,但这里采用了 mod_vhost_alias 。
# 从 Host: 头中取得服务器名字 Server Name
UseCanonicalName Off
# 这里的日志格式,可以在将来通过第一个参数域来分隔不同的虚拟主机的日志
LogFormat "%V %h %l %u %t "%r" %s %b" vcommon
CustomLog logs/access_log vcommon
# 在返回请求的文件名的路径中包含进服务器名字: server name
VirtualDocumentRoot /www/hosts/%0/docs
VirtualScriptAlias /www/hosts/%0/cgi-bin
将 UseCanonicalName Off 的配置改为 UseCanonicalName DNS 即可实现基于 IP 地址的虚拟主机。而在文件路径中所要插入的服务器名字(server name) 则通过虚拟主机的 IP 地址解析而得。
一个实际的个人主页主机系统
这里对上面的系统作了一点调整,便可作为 ISP 的个人主页服务器。 我们使用了略微复杂的方法,从服务器名字(Server Name)中提取子字符串, 并插入到文件路径中。在这个例子中,www.user.isp.com 的文档将在 /home/user/ 中定位。并对所有虚拟主机使用单个 cgi-bin 目录。
# 所有之前的准备事项和上面一样,然后
# 在文件路径中包含服务器名字(server name)
VirtualDocumentRoot /www/hosts/%2/docs
# 单个 cgi-bin 目录
ScriptAlias /cgi-bin/ /www/std-cgi/
更复杂的关于 VirtualDocumentRoot 的设置,可以查阅 mod_vhost_alias 文档。
在同一个服务器上架设多个主机的虚拟系统
更复杂的设置,应该使用 Apache 的  指令来管理各种虚拟主机配置的作用域。例如,你可以用一个 IP 地址来给个人主页客户使用, 同时用下面的配置提供给商业客户使用。自然的, 这两者通过运用 结合到一起。
UseCanonicalName Off
LogFormat "%V %h %l %u %t "%r" %s %b" vcommon
Options FollowSymLinks
AllowOverride All
Options FollowSymLinks
AllowOverride None
ServerName www.commercial.isp.com
CustomLog logs/access_log.commercial vcommon
VirtualDocumentRoot /www/commercial/%0/docs
VirtualScriptAlias /www/commercial/%0/cgi-bin
ServerName www.homepages.isp.com
CustomLog logs/access_log.homepages vcommon
VirtualDocumentRoot /www/homepages/%0/docs
ScriptAlias /cgi-bin/ /www/std-cgi/

更为有效的基于 IP 地址的虚拟主机
在 第一个例子 中说过,转为基于 IP 地址的虚拟主机设置很容易做到。 但不幸的是,那种做法并不高效,因为这样会在每次处理请求时,需要查询 DNS 。 通过在文件系统中包含IP 地址的做法可以避免这样的问题。这样一来, 免去了和服务器名字的关联,在日志记录中也一样可以用 IP 来分离不同日志。 Apache 将不会为了确定服务器名字(server name)而去做 DNS 查询。
# 从 IP 地址反解析得到服务器名字(server name)
UseCanonicalName DNS
# 在日志中包含 IP 地址,便于后续分发
LogFormat "%A %h %l %u %t "%r" %s %b" vcommon
CustomLog logs/access_log vcommon
# 在文件路径中包含 IP 地址
VirtualDocumentRootIP /www/hosts/%0/docs
VirtualScriptAliasIP /www/hosts/%0/cgi-bin
使用老版本的 Apache
上面的例子基于 mod_vhost_alias ,但它是在版本 1.3.6 之后才出现的。 如果你的版本比较老,可以通过使用 mod_rewrite 来达到相同的目的, 如下所示。但只能是基于 Host: 头方式的虚拟主机。
此外还须注意日志方面的问题。Apache 1.3.6 是第一个支持 %V日志格式指令的版本, 在版本 1.3.0 - 1.3.3 中,%v 选项做和 %V 一样的事情; 而在版本 1.3.4 中没有等价指令。在所有的这些版本中,指令 UseCanonicalName 可以出现在 .htaccess 文件中,这意味着客户的设置可能会导致日志记录紊乱。 所以最好的做法是使用 %{Host}i 指令,它可以直接记录 Host: 头; 注意,这样可能在末尾包含 :port ,而使用 %V 则不会这样。
使用 mod_rewrite 实现简单的动态虚拟主机
这里的例子摘自 httpd.conf ,效果等同于 第一个例子中的情况。 前半部分和上面的例子大致相似,只是为了后向兼容 mod_rewrite 作了适当修改; 后半部分配置 mod_rewrite 来做实际的工作。
有些特别的地方需要注意:默认情况下,mod_rewrite 在所有其他 URI 转换模块 (mod_alias 等)之前运行,所以如果使用这些模块的话, mod_rewrite 必须作相应的调整。同时,我们还要为每个动态虚拟主机变些戏法, 使之等效于 ScriptAlias。
# 从 Host: 头获取服务器名字
UseCanonicalName Off
# 可分割的日志
LogFormat "%{Host}i %h %l %u %t "%r" %s %b" vcommon
CustomLog logs/access_log vcommon
# ExecCGI is needed here because we can't force
# CGI execution in the way that ScriptAlias does
Options FollowSymLinks ExecCGI
# 接下来是关键部分
RewriteEngine On
# a ServerName derived from a Host: header may be any case at all RewriteMap lowercase int:tolower
## 首先处理普通文档:
# 允许变名 /icons/ 起作用 - 其他变名类同
RewriteCond %{REQUEST_URI} !^/icons/
# 允许 CGIs
RewriteCond %{REQUEST_URI} !^/cgi-bin/
# 开始“变戏法”
RewriteRule ^/(.*)$ /www/hosts/${lowercase:%{SERVER_NAME}}/docs/$1
## 现在处理 CGIs - 我们需要强制使用一个 MIME 类型
RewriteCond %{REQUEST_URI} ^/cgi-bin/
RewriteRule ^/(.*)$ /www/hosts/${lowercase:%{SERVER_NAME}}/cgi-bin/$1 [T=application/x-httpd-cgi]
# 好了!
使用 mod_rewrite 的个人主页系统
这里的配置完成和第二个例子相同的工作。
RewriteEngine on
RewriteMap lowercase int:tolower
# 允许 CGIs 工作
RewriteCond %{REQUEST_URI} !^/cgi-bin/
# 检查 hostname 正确与否,之后才能使 RewriteRule 起作用
RewriteCond ${lowercase:%{SERVER_NAME}} ^www.[a-z-]+.isp.com$
# 将虚拟主机名字廉洁到 URI 的开头
# [C] 表明本次重写的结果将在下一个 rewrite 规则中使用
RewriteRule ^(.+) ${lowercase:%{SERVER_NAME}}$1 [C]
# 现在创建实际的文件名
RewriteRule ^www.([a-z-]+).isp.com/(.*) /home/$1/$2
# 定义全局 CGI 目录
ScriptAlias /cgi-bin/ /www/std-cgi/
使用独立的虚拟主机配置文件
这样的布局利用了 mod_rewrite 的高级特性, 在独立的虚拟主机配置文件中转换。如此可以更为灵活,但需要较为复杂的设置。
vhost.map 文件包含了类似下面的内容:
www.customer-1.com /www/customers/1
www.customer-2.com /www/customers/2
# ...
www.customer-N.com /www/customers/N
http.conf 包含了:
RewriteEngine on
RewriteMap lowercase int:tolower
# 定义映像文件
RewriteMap vhost txt:/www/conf/vhost.map
# 和上面的例子一样,处理变名
RewriteCond %{REQUEST_URI} !^/icons/
RewriteCond %{REQUEST_URI} !^/cgi-bin/
RewriteCond ${lowercase:%{SERVER_NAME}} ^(.+)$
# 这里做基于文件的重新映射
RewriteCond ${vhost:%1} ^(/.*)$
RewriteRule ^/(.*)$ %1/docs/$1
RewriteCond %{REQUEST_URI} ^/cgi-bin/
RewriteCond ${lowercase:%{SERVER_NAME}} ^(.+)$
RewriteCond ${vhost:%1} ^(/.*)$
RewriteRule ^/(.*)$ %1/cgi-bin/$1


本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u/16907/showart_249789.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP