apache详解
(1)基本配置
ServerRoot"/usr/local/apache2"你的apache软件安装的位置。其它指定的目录如果没有指定绝对路径,则目录是相对于该目录。 PidFilelogs/httpd.pid#第一个httpd进程(所有其他进程的父进程)的进程号文件位置。 Listen80#服务器监听的端口号。 ServerNamewww.clusting.com:80#主站点名称(网站的主机名)。 [email protected]#管理员的邮件地址。 DocumentRoot"/mnt/web/clusting"#主站点的网页存储位置。 以下是对主站点的目录进行访问控制: <Directory"/usr/local/apache2/htdocs"> OptionsFollowSymLinks AllowOverrideNone Orderallow,deny Allowfromall </Directory> 在上面这段目录属性配置中,主要有下面的选项: Options:配置在特定目录使用哪些特性,常用的值和基本含义如下: ExecCGI:在该目录下允许执行CGI脚本。 FollowSymLinks:在该目录下允许文件系统使用符号连接。 Indexes:当用户访问该目录时,如果用户找不到DirectoryIndex指定的主页文件(例如index.html),则返回该目录下的文件列表给用户。 SymLinksIfOwnerMatch:当使用符号连接时,只有当符号连接的文件拥有者与实际文件的拥有者相同时才可以访问。 AllowOverride:允许存在于.htaccess文件中的指令类型(.htaccess文件名是可以改变的,其文件名由AccessFileName指令决定): None:当AllowOverride被设置为None时。不搜索该目录下的.htaccess文件(可以减小服务器开销)。 All:在.htaccess文件中可以使用所有的指令。 而对于URLrewrite来说,至少需要把目录设置为 <Directory/myblogroot/> AllowOverrideFileInfo </Directory> DirectoryIndexindex.htmlindex.htmindex.php#主页文件的设置(本例将主页文件设置为:index.html,index.htm和index.php) Order:控制在访问时Allow和Deny两个访问规则哪个优先: Allow:允许访问的主机列表(可用域名或子网,例如:Allowfrom192.168.0.0/16)。 Deny:拒绝访问的主机列表。 OrderDeny,Allow AllowfromAll
注意“Deny,Allow”中间只有一个逗号,也只能有一个逗号,有空格都会出错;单词的大小写不限。上面设定的含义是先设定“先检查禁止设定,没有禁止的全部允许”,而第二句没有Deny,也就是没有禁止访问的设定,直接就是允许所有访问了。这个主要是用来确保或者覆盖上级目录的设置,开放所有内容的访问权。 按照上面的解释,下面的设定是无条件禁止访问: Order Allow,Deny Deny from All 如果要禁止部分内容的访问,其他的全部开放: Order Deny,Allow Deny from ip1 ip2 或者 Order Allow,Deny Allow from all Deny from ip1 ip2 apache会按照order决定最后使用哪一条规则,比如上面的第二种方式,虽然第二句allow允许了访问,但由于在order中allow不是最后规则,因此还需要看有没有deny规则,于是到了第三句,符合ip1和ip2的访问就被禁止了。注意,order决定的“最后”规则非常重要,下面是两个错误的例子和改正方式: Order Deny,Allow Allow from all Deny from domain.org 错误:想禁止来自domain.org的访问,但是deny不是最后规则,apache在处理到第二句allow的时候就已经匹配成功,根本就不会去看第三句。 解决方法:Order Allow,Deny,后面两句不动,即可。 Order Allow,Deny Allow from ip1 Deny from all 错误:想只允许来自ip1的访问,但是,虽然第二句中设定了allow规则,由于order中deny在后,所以会以第三句deny为准,而第三句的范围中又明显包含了ip1(all include ip1),所以所有的访问都被禁止了。 解决方法一:直接去掉第三句。 解决方法二: Order Deny,Allow Deny from all Allow from ip1 下面是测试过的例子: -------------------------------- Order deny,allow allow from all deny from 219.204.253.8 #全部都可以通行 ------------------------------- Order deny,allow deny from 219.204.253.8 allow from all #全部都可以通行 ------------------------------- Order allow,deny deny from 219.204.253.8 allow from all #只有219.204.253.8不能通行 ------------------------------- Order allow,deny allow from all deny from 219.204.253.8 #只有219.204.253.8不能通行 ------------------------------- ------------------------------- Order allow,deny deny from all allow from 219.204.253.8 #全部都不能通行 ------------------------------- Order allow,deny allow from 219.204.253.8 deny from all #全部都不能通行 ------------------------------- Order deny,allow allow from 219.204.253.8 deny from all #只允许219.204.253.8通行 ------------------------------- Order deny,allow deny from all allow from 219.204.253.8 #只允许219.204.253.8通行 ------------------------------- -------------------------------- Order deny,allow #全部都可以通行(默认的) ------------------------------- Order allow,deny #全部都不能通行(默认的) ------------------------------- Order allow,deny deny from all #全部都不能通行 ------------------------------- Order deny,allow deny from all #全部都不能通行 ------------------------------- 对于上面两种情况,如果换成allow from all,则全部都可以通行! ------------------------------- Order deny,allow deny from 219.204.253.8 #只有219.204.253.8不能通行 ------------------------------- Order allow,deny deny from 219.204.253.8 #全部都不能通行 ------------------------------- Order allow,deny allow from 219.204.253.8 #只允许219.204.253.8通行 ------------------------------- Order deny,allow allow from 219.204.253.8 #全部都可以通行 ------------------------------- ------------------------------- order deny,allow allow from 218.20.253.2 deny from 218.20 #代表拒绝218.20开头的IP,但允许218.20.253.2通过;而其它非218.20开头的IP也都允许通过。 ------------------------------- order allow,deny allow from 218.20.253.2 deny from 218.20 #和上面的差不多,只是掉换的order语句中的allow、deny先后顺序,但最终结果表示全部都拒绝! 前段时间做了个Apache的HTTP代理服务器,其中的order allow,deny这部分弄的不太懂,于是上网找资料看,谁知道越看越糊涂,其中有些难以分辨对错甚至是误导。就像破解windows系统密码的一些文章那样,很多都是人云亦云的,并没有经过测试。废话少说,先把我经过测试后分析总结出来的结论show出来,相信这对大家的理解非常有帮助。 总则―― 影响最终判断结果的只有两点: 1. order语句中allow、deny的先后顺序; 2. allow、deny语句中各自包含的范围。 温馨提醒―― 1. 修改完配置后要保存好并重启Apache服务,配置才能生效; 2. 开头字母不分大小写; 3. allow、deny语句不分先后顺序,谁先谁后不影响最终判断结果;但都会被判断到; 4. order语句中,“allow,deny”之间“有且只有”一个逗号(英文格式的),而且先后顺序很重要; 5. Apache有一条缺省规则,“order allow,deny”本身就默认了拒绝所有的意思,因为deny在allow的后面;同理,“order deny,allow”本身默认的是允许所有;当然,最终判断结果还要综合下面的allow、deny语句中各自所包含的范围;(也就是说order语句后面可以没有allow、deny语句) 6. allow、deny语句中,第二个单词一定是“from”,否则Apache会因错而无法启动, 7. “order allow,deny”代表先判断allow语句再判断deny语句,反之亦然。 判断原则分4步走―― 1. 首先判断默认的; 2. 然后判断逗号前的; 3. 最后判断逗号后的; 4. 最终按顺序叠加而得出判断结果。 上面三点我说的简单而形象,主要是为了便于记忆。暂时不理解不要紧,继续看下面详细的解说自然会明白。下面以一个普通例子来做解释―― order deny,allow allow from 218.20.253.2 deny from 218.20 1. 所谓“首先判断默认的”,就是判断“order deny,allow”这句,它默认是允许所有; 2. 所谓“然后判断逗号前的”,因为在本例子中的order语句里面,deny在逗号的前面,所以现在轮到判断下面的deny语句了――“deny from 218.20”; 3. 所谓“最后判断逗号后的”,因为在本例子中的order语句里面,allow在逗号的后面,所以最后轮到判断下面的allow语句了――“allow from 218.20.253.2”。 4. 所谓“最终按顺序叠加而得出判断结果”,这是一个形象化了的说法,我把每一步判断都看作一个“不透明的图层”,然后一步步按顺序叠加上去,最终得出的“图像”就是判断结果。 用过作图软件的人应该都知道“图层”是怎么回事,我估计Apache关于order allow deny这方面的设计理念和photoshop等作图软件关于图层的设计理念是一样的。即“游戏规则”是一样的。 那么上面的例子就可以是这么一个步骤和图像―― 1. 先画一个白色的大圆,代表“order deny,allow”语句,默认意思是允许所有; 2. 然后画一个小一点的黑色圆,代表“deny from 218.20”语句,意思是拒绝所有以218.20开头的IP,放进白色的大圆里面; 3. 最后再画一个白色的圆,代表“allow from 218.20.253.2”语句,意思是允许218.20.253.2通过,放在黑色圆的上面。 4. 到此为止,我们已经可以看到一个结果了,白色大圆上面有一个黑色圆,黑色圆上面还有一个白色圆。最后,我们所能看到的黑色部分就是拒绝通行的,剩下的白色部分都是允许通行的。判断的结果就是这么简单形象! 如果不懂的用作图软件,我们再来个非常贴近生活的比喻―― 把上面的例子改动一点点,以便更好的理解: order deny,allow allow from 218.20.253.2 deny from 219.30 1. 首先拿一张A4白纸,代表第order语句,意思是允许全部; 2. 然后拿一张黑色纸剪一个圆,放在A4纸里面的某个位置上,代表deny语句,意思是拒绝所有以219.30开头的IP; 3. 最后拿白纸再剪一个圆,放在黑色圆的旁边,代表allow语句,意思是允许218.20.253.2通过;注意,这个例子不是放进黑色圆里面了,因为deny和allow语句不再有相互包含的关系了。 4. A4纸上面有一个黑色圆和一个白色圆,结果自然很明显了。不过白色的A4纸上再放一个白色的圆,显然是多余的了,因为大家都是白色的,都代表允许,所以就重复了,可以去掉白色的圆而不会影响判断结果。 在这里再��嗦一下,allow、deny语句后面跟的参数有多种形式,有不同的表达方式,我在网上看到的做法是deny from IP1 IP2 IP3或allow from domain.com等。其它的表达方式大家再找别的资料看吧。我想说的是另一种表达方式: order deny,allow allow from IP1 IP2 allow from domain.info allow from 219.20.55.0/24 deny from all 我没具体验证过这是否对,不过这样是可以正常启动Apache服务的,按道理应该是正确的表达方式。哈哈,像我这样的入门者只能这样了,还希望大家多多指教! 下面是测试过的例子: -------------------------------- Order deny,allow allow from all deny from 219.204.253.8 #全部都可以通行 ------------------------------- Order deny,allow deny from 219.204.253.8 allow from all #全部都可以通行 ------------------------------- Order allow,deny deny from 219.204.253.8 allow from all #只有219.204.253.8不能通行 ------------------------------- Order allow,deny allow from all deny from 219.204.253.8 #只有219.204.253.8不能通行 ------------------------------- ------------------------------- Order allow,deny deny from all allow from 219.204.253.8 #全部都不能通行 ------------------------------- Order allow,deny allow from 219.204.253.8 deny from all #全部都不能通行 ------------------------------- Order deny,allow allow from 219.204.253.8 deny from all #只允许219.204.253.8通行 ------------------------------- Order deny,allow deny from all allow from 219.204.253.8 #只允许219.204.253.8通行 ------------------------------- -------------------------------- Order deny,allow #全部都可以通行(默认的) ------------------------------- Order allow,deny #全部都不能通行(默认的) ------------------------------- Order allow,deny deny from all #全部都不能通行 ------------------------------- Order deny,allow deny from all #全部都不能通行 ------------------------------- 对于上面两种情况,如果换成allow from all,则全部都可以通行! ------------------------------- Order deny,allow deny from 219.204.253.8 #只有219.204.253.8不能通行 ------------------------------- Order allow,deny deny from 219.204.253.8 #全部都不能通行 ------------------------------- Order allow,deny allow from 219.204.253.8 #只允许219.204.253.8通行 ------------------------------- Order deny,allow allow from 219.204.253.8 #全部都可以通行 ------------------------------- ------------------------------- order deny,allow allow from 218.20.253.2 deny from 218.20 #代表拒绝218.20开头的IP,但允许218.20.253.2通过;而其它非218.20开头的IP也都允许通过。 ------------------------------- order allow,deny allow from 218.20.253.2 deny from 218.20 #和上面的差不多,只是掉换的order语句中的allow、deny先后顺序,但最终结果表示全部都拒绝!
(2)用户认证的配置
1)vimhttpd.conf文件 AccessFileName .htaccess ......... Alias/download/"/var/www/download/" <Directory"/var/www/download"> OptionsIndexes AllowOverrideAuthConfig </Directory> 2)创建用户密码文件 /usr/local/apache2/bin/htpasswd -c /var/httpuser/passwordsbearzhang 3)配置.htaccess文件 vi /var/www/download/.htaccess: AuthType Basic AuthName "RestrictedFiles" AuthUserFile /var/httpuser/passwords Require user bearzhang #Require valid-user #allvaliduser
(3)日志的设置
1)错误日志的设置 ErrorLog logs/error_log#日志的保存位置 LogLevel warn#日志的级别 显示的格式日下: [MonOct1015:54:292005][error][client192.168.10.22]accessto/download/failed,reason:useradminnotallowedaccess 2)访问日志设置 日志的缺省格式有如下几种: LogFormat"%h%l%u%t"%r"%>s%b"%{Referer}i""%{User-Agent}i""combined LogFormat"%h%l%u%t"%r"%>s%b"common#common为日志格式名称 LogFormat"%{Referer}i->%U"referer LogFormat"%{User-agent}i"agent CustomLoglogs/access_logcommon 格式中的各个参数如下: %h--客户端的ip地址或主机名 %l--The这是由客户端identd判断的RFC1413身份,输出中的符号"-"表示此处信息无效。 %u--由HTTP认证系统得到的访问该网页的客户名。有认证时才有效,输出中的符号"-"表示此处信息无效。 %t--服务器完成对请求的处理时的时间。 "%r"--引号中是客户发出的包含了许多有用信息的请求内容。 %>s--这个是服务器返回给客户端的状态码。 %b--最后这项是返回给客户端的不包括响应头的字节数。 "%{Referer}i"--此项指明了该请求是从被哪个网页提交过来的。 "%{User-Agent}i"--此项是客户浏览器提供的浏览器识别信息。 下面是一段访问日志的实例: 192.168.10.22-bearzhang[10/Oct/2005:16:53:06+0800]"GET/download/HTTP/1.1"2001228 192.168.10.22--[10/Oct/2005:16:53:06+0800]"GET/icons/blank.gifHTTP/1.1"304- 192.168.10.22--[10/Oct/2005:16:53:06+0800]"GET/icons/back.gifHTTP/1.1"304-
(4)服务器的优化(MPM:Multi-ProcessingModules)
1,编译安装apache工作在worker或者prefork模式下 [[email protected]]#./configure --prefix=/usr/local/apache2 --enable-so --with-mpm=worker 2, prefork工作模式 apache2主要的优势就是对多处理器的支持更好,在编译时同过使用--with-mpm选项来决定apache2的工作模式。 prefork工作原理: (1)控制进程在最初建立StartServers个进程; (2)为了满足MinSpareServers设置,则等待1秒钟,继续创建2个进程,再等待1秒钟,创建4个进程......如此指数级的创建进程,最多达到每秒创建32个进程(这种方式,可以在请求没有来之前,提前创建好进程,避免请求到来之时创建进程带来的系统开销,这也是预派生的由来);如果kill掉一个子进程之后,就会等待一秒钟,然后创建一个进程 (3)MaxSpareServers设置了最大的空闲进程数,如果空闲进程数大于这个值,Apache会自动kill掉一些多余进程。这个值不要设得过大,但如果设的值比MinSpareServers小,Apache会自动把其调整为MinSpareServers+1。如果站点负载较大,可考虑同时加大MinSpareServers和MaxSpareServers; (4)MaxRequestsPerChild设置的是每个子进程可处理的请求数。每个子进程在处理了“MaxRequestsPerChild”个请求后将自动销毁。0意味着无限,即子进程永不销毁。虽然缺省设为0可以使每个子进程处理更多的请求,但如果设成非零值也有两点重要的好处:可防止意外的内存泄漏;在服务器负载下降的时侯会自动减少子进程数。因此,可根据服务器的负载来调整这个值。笔者认为10000左右比较合适。 因此,httpd那些进程都是最近才启动的 (5)MaxClients是这些指令中最为重要的一个,设定的是Apache可以同时处理的请求,是对Apache性能影响最大的参数。其缺省值150是远远不够的,如果请求总数已达到这个值(可通过ps -ef|grep http|wc -l来确认),那么后面的请求就要排队,直到某个已处理请求完毕。这就是系统资源还剩下很多而HTTP访问却很慢的主要原因。系统管理员可以根据硬件配置和负载情况来动态调整这个值。虽然理论上这个值越大,可以处理的请求就越多,但Apache默认的限制是256(2.2.3最大限制也是256)。如果把这个值设为大于256,那么Apache将无法起动(我测试的结果是可以启动的)。事实上,256对于负载稍重的站点也是不够的。 (6)ServerLimint是当MaxClients在最大值仍然不够用的时候,可以使用此选项。2.2.23中,默认的ServerLimit是200000,可以在server/mpm/prefork/prefork.c中修改一个宏定义。 如果知道当前的apache2使用什么工作机制,可以通过httpd-l命令列出apache的所有模块,就可以知道其工作方式: prefork:如果httpd -l列出prefork.c,则需要对下面的段进行配置: <IfModule prefork.c> StartServers 5 #启动apache时启动的httpd进程个数。 MinSpareServers 5 #服务器保持的最小空闲进程数。 MaxSpareServers 10 #服务器保持的最大空闲进程数。 MaxClients 150 #最大并发连接数。 MaxRequestsPerChild 1000 #每个子进程被请求服务多少次后被kill掉。0表示不限制,推荐设置为1000。 </IfModule> 在该工作模式下,服务器启动后起动5个httpd进程(加父进程共6个,通过ps-ax|grephttpd命令可以看到)。当有用户连接时,apache会使用一个空闲进程为该连接服务,同时父进程会fork一个子进程。直到内存中的空闲进程达到MaxSpareServers。该模式是为了兼容一些旧版本的程序。我缺省编译时的选项。 3.worker的工作模式 worker:如果httpd-l列出worker.c,则需要对下面的段进行配置: <IfModule worker.c> StartServers 2#启动apache时启动的httpd进程个数。 MaxClients 150#最大并发连接数。 MinSpareThreads 25#服务器保持的最小空闲线程数。 MaxSpareThreads 75#服务器保持的最大空闲线程数。 ThreadsPerChild 25#每个子进程的产生的线程数。 MaxRequestsPerChild 0#每个子进程被请求服务多少次后被kill掉。0表示不限制,推荐设置为1000。 </IfModule> 该模式是由线程来监听客户的连接。当有新客户连接时,由其中的一个空闲线程接受连接。服务器在启动时启动两个进程,每个进程产生的线程数是固定的(ThreadsPerChild决定),因此启动时有50个线程。当50个线程不够用时,服务器自动prefork一个进程,再产生25个线程。 Worker 由主控制进程生成“StartServers”个子进程,每个子进程中包含固定的ThreadsPerChild线程数,各个线程独立地处理请求。同样, 为了不在请求到来时再生成线程,MinSpareThreads和MaxSpareThreads设置了最少和最多的空闲线程数;而MaxClients 设置了同时连入的clients最大总数。如果现有子进程中的线程总数不能满足负载,控制进程将派生新的子进程。MinSpareThreads和 MaxSpareThreads的最大缺省值分别是75和250。这两个参数对Apache的性能影响并不大,可以按照实际情况相应调节。 ThreadsPerChild是worker MPM中与性能相关最密切的指令。ThreadsPerChild的最大缺省值是64,如果负载较大,64也是不够的。这时要显式使用 ThreadLimit指令,它的最大缺省值是20000。Worker模式下所能同时处理的请求总数是由子进程总数乘以ThreadsPerChild 值决定的,应该大于等于MaxClients。如果负载很大,现有的子进程数不能满足时,控制进程会派生新的子进程。默认最大的子进程总数是16,加大时 也需要显式声明ServerLimit(最大值是20000)。需要注意的是,如果显式声明了ServerLimit,那么它乘以 ThreadsPerChild的值必须大于等于MaxClients,而且MaxClients必须是ThreadsPerChild的整数倍,否则 Apache将会自动调节到一个相应值。 4.比较worker和prefork prefork MPM 这个多路处理模块(MPM)实现了一个非线程型的、预派生的web服务器,使用多个子进程,每个子进程只有一个线程。每个进程在某个确定的时间只能维持一个连接。在大多数平台上,Prefork MPM在效率上要比Worker MPM要高,但是内存使用大得多。 worker MPM 此多路处理模块(MPM)使网络服务器支持混合的多线程多进程。由于使用线程来处理请求,所以可以处理海量请求,而系统资源的开销小于基于进程的MPM。使用多个子进程,每个子进程有多个线程。每个线程在某个确定的时间只能维持一个连接。通常来说,在一个高流量的HTTP服务器上,Worker MPM是个比较好的选择,因为Worker MPM的内存使用比Prefork MPM要低得多。但worker MPM也由不完善的地方,假如一个线程崩溃,整个进程就会连同其任何线程一起"死掉".
(5)HTTP返头回信息配置:
ServerTokensProd#该参数设置http头部返回的apache版本信息,可用的值和含义如下: Prod:仅软件名称,例如:apache Major:包括主版本号,例如:apache/2 Minor:包括次版本号,例如:apache/2.0 Min:仅apache的完整版本号,例如:apache/2.0.54 OS:包括操作系统类型,例如:apache/2.0.54(Unix) Full:包括apache支持的模块及模块版本号,例如:Apache/2.0.54(Unix)mod_ssl/2.0.54OpenSSL/0.9.7g ServerSignatureOff#在页面产生错误时是否出现服务器版本信息。推荐设置为Off
(6)持久性连接设置
KeepAliveOn#开启持久性连接功能。即当客户端连接到服务器,下载完数据后仍然保持连接状态。 MaxKeepAliveRequests100#一个连接服务的最多请求次数。 KeepAliveTimeout30#持续连接多长时间,该连接没有再请求数据,则断开该连接。缺省为15秒。
(7)别名设置
对于不在DocumentRoot指定的目录内的页面,既可以使用符号连接,也可以使用别名。别名的设置如下: Alias/download/"/var/www/download/"#访问时可以输入:http://www.custing.com/download/ <Directory"/var/www/download">#对该目录进行访问控制设置 OptionsIndexesMultiViews AllowOverrideAuthConfig Orderallow,deny Allowfromall </Directory>
(8)CGI设置
ScriptAlias/cgi-bin/"/mnt/software/apache2/cgi-bin/"#访问时可以:http://www.clusting.com/cgi-bin/。但是该目录下的CGI脚本文件要加可执行权限! <Directory"/usr/local/apache2/cgi-bin">#设置目录属性 AllowOverrideNone OptionsNone Orderallow,deny Allowfromall </Directory>
(9)虚拟主机的配置
1)基于IP地址的虚拟主机配置 Listen 80 <VirtualHost 172.20.30.40> DocumentRoot /www/example1 ServerNamewww.example1.com </VirtualHost> <VirtualHost172.20.30.50> DocumentRoot/www/example2 ServerNamewww.example2.org </VirtualHost> (2)基于IP和多端口的虚拟主机配置 Listen 172.20.30.40:80 Listen 172.20.30.40:8080 Listen 172.20.30.50:80 Listen 172.20.30.50:8080 <VirtualHost172.20.30.40:80> DocumentRoot/www/example1-80 ServerNamewww.example1.com </VirtualHost> <VirtualHost172.20.30.40:8080> DocumentRoot/www/example1-8080 ServerNamewww.example1.com </VirtualHost> <VirtualHost172.20.30.50:80> DocumentRoot/www/example2-80 ServerNamewww.example1.org </VirtualHost> <VirtualHost172.20.30.50:8080> DocumentRoot/www/example2-8080 ServerNamewww.example2.org </VirtualHost> (3)单个IP地址的服务器上基于域名的虚拟主机配置: #EnsurethatApachelistensonport80 Listen80 #ListenforvirtualhostrequestsonallIPaddresses NameVirtualHost*:80 <VirtualHost*:80> DocumentRoot/www/example1 ServerNamewww.example1.com ServerAliasexample1.com.*.example1.com #Otherdirectiveshere </VirtualHost> <VirtualHost*:80> DocumentRoot/www/example2 ServerNamewww.example2.org #Otherdirectiveshere </VirtualHost> (4)在多个IP地址的服务器上配置基于域名的虚拟主机: Listen80 #Thisisthe"main"serverrunningon172.20.30.40 ServerNameserver.domain.com DocumentRoot/www/mainserver #Thisistheotheraddress NameVirtualHost172.20.30.50 <VirtualHost172.20.30.50> DocumentRoot/www/example1 ServerNamewww.example1.com #Otherdirectiveshere... </VirtualHost> <VirtualHost172.20.30.50> DocumentRoot/www/example2 ServerNamewww.example2.org #Otherdirectiveshere... </VirtualHost> (5)在不同的端口上运行不同的站点(基于多端口的服务器上配置基于域名的虚拟主机): Listen80 Listen8080 NameVirtualHost172.20.30.40:80 NameVirtualHost172.20.30.40:8080 <VirtualHost172.20.30.40:80> ServerNamewww.example1.com DocumentRoot/www/domain-80 </VirtualHost> <VirtualHost172.20.30.40:8080> ServerNamewww.example1.com DocumentRoot/www/domain-8080 </VirtualHost> <VirtualHost172.20.30.40:80> ServerNamewww.example2.org DocumentRoot/www/otherdomain-80 </VirtualHost> <VirtualHost172.20.30.40:8080> ServerNamewww.example2.org DocumentRoot/www/otherdomain-8080 </VirtualHost> (6)基于域名和基于IP的混合虚拟主机的配置: Listen80 NameVirtualHost172.20.30.40 <VirtualHost172.20.30.40> DocumentRoot/www/example1 ServerNamewww.example1.com </VirtualHost> <VirtualHost172.20.30.40> DocumentRoot/www/example2 ServerNamewww.example2.org </VirtualHost> <VirtualHost172.20.30.40> DocumentRoot/www/example3 ServerNamewww.example3.net </VirtualHost>