当前位置:Linux教程 - Apache - apache - apache服务器

apache - apache服务器

apache服务器
2004-04-23 15:18 pm
来自:Linux文档
现载:Www.8s8s.coM
地址:无名

6.3 WWW服务器

现在要开始我们的重点内容了:www server。目前能做www server的程序很多,在UN
IX下较常见的免费服务器就有很多种,例如NSCA,Apache等等。我们讨论的将是世界上
最常用的一种,即Apache Server。

6.3.1 Apache服务器

按照apache开发组的说法,Apache代表“A patched Server”,因为它是在更古老的
一些服务程序上通过一连串的补丁开发出来的。除非你买的是sun那样的系统,否则几乎
每个UNIX发行商都可以免费提供apache的源代码或者是可以安装的软件包。几乎所有的
Linux发行版本都会附带apache的软件包或者源代码,当然你也可以到任何能够提供UNI
X系统应用的ftp站点去下载这个东西,所以我不想告诉你如何去下载它的代码了。

可以取得的apache软件包可以是目标代码形式或者源代码方式,我们这里假定你用的
是rpm包,例如redhat或者turbo Linux附带的apache rpm包。以下说明的内容将适用于
这种rpm的缺省设置,特别是缺省目录设置,在后面我们将解释apache的编译,在那里我
们将讨论目录设置和模块设置等功能。

Apache的缺省配置文件放在/etc/httpd/conf下面,在较早的版本中,配置被分成几个
文件,如/etc/httpd/conf/httpd.conf,/etc/httpd/conf/srm.conf和/etc/httpd/con
f/access.conf。在较新的apache版本中,建议你只使用一个配置文件,即/etc/httpd/
conf/httpd.conf。我们将主要的讨论比较新的这种配置方式。我的版本是apache-1.3.
9。特别需要注意的是,如果你的系统配置目录中除了httpd.conf之外还有srm.conf和a
ccess.conf的话,那么系统缺省要去察看这两个文件。因此,建议你将这两个文件从系
统上删除。

/etc/httpd/conf/httpd.conf文件相当长,我们首先介绍基本的内容,在设置apache
的工作中,第一个任务是设置html文档的位置。

新的httpd.conf一般被分成几个段落,第一部分是全局变量的位置,按照我们习惯的
方式,将在缺省的httpd.conf上进行必要的修改,下面列出一些我们比较感兴趣的选择


ServerType

这个选项用来设置你的apache如何启动,它有两个选择,即standalone和inetd。sta
ndalone表示你的服务器程序是直接作为服务器守护进程启动,而inetd表示apache服务
器将在inetd程序中启动。一般我们总是建议用standalone方式,因为inetd在请求较多
的时候会出现一些问题。即使用ServerType standalone子句。

ServerRoot "/home/httpd"

设置Apache的缺声运行路径。不过,除非你在某些配置选项中使用相对路径,否则它
从来不会影响什么。

ErrorLog

CustomLog


这两行设置缺省的记账文件的位置,errorlog和customlog分别是出错信息和正常工作
信息的记录地点,例如

ErrorLog /var/log/httpd/error_log

CustomLog /var/log/httpd/access_log common

Port

这个参数指明http服务器使用的端口,缺省值是80,当然你也可以选择其他的端口,
但是这意味着你在连接的时候必须明确地指出使用的端口。

范例:

Port 80

User

Group

设置服务器运行时使用的身份,通常我们为了安全,总是要把它设置成nobody,如:

User nobody

Group nobody

ServerAdmin

这个选项用来设置当服务器出现问题时,用来反馈问题的邮件地址,例如

ServerAdmin [email protected]


ServerName

通常apache服务器会从域名服务信息中得到服务器的域名,但是你也可以使用这个选
项来避免域名服务器出错时apache失效。例如

ServerName www.mydomain.com

DocumentRoot

这个选项设置缺省的服务器使用的html文件的位置,例如:下面的一行

DocumentRoot "/home/httpd/html"

意味着 http://www.mydomain.com/xxx.html 被解释为/home/httpd/html/xxx.html。

ScriptAlias

定义CGI脚本目录,例如

ScriptAlias /cgi-bin/ “/home/httpd/cgi-bin”

定义CGI脚本应该放在/home/httpd/cgi-bin/目录下,而反映在浏览器中的目录是/cg
i-bin/。

DirectoryIndex

这个选项定义缺省的主页文件,例如,DirectoryIndex index.html意味着http://ww
w.mydomain.com/将显示/home/httpd/html/index.html。

index.html

Alias

建立目录别名,例如

Alias /ftp/ “/home/httpd/html/ftp/”

UserDir

用宿主目录作为html目录。参考6.3.2节。

AccessFileName

定义身份控制的文件名,通常总是设置成为AccessFileName .htaccess

AddType

AddHandler

这两个选项用来加入各种文件映射,或者说MIME类型。通常AddType设定某种特定的文
件类型对应某个特定的扩展名字,而AddHandler则为这种类型定义一个处理程序。例如
,AddHandler cgi-script .cgi表示无论在什么地方,凡是看上去是一个.cgi的扩展名
的程序就作为CGI脚本执行(应该避免,对吗?不过对于那些~user的目录你可能只能用
这个办法了。好在还有一个options ExecCGI也对可以执行cgi的目录进行限制)

另外的一个常用的设定是

AddType text/html .shtml

AddHandler server-parsed .shtml

这两行允许服务器处理那些.shtml并且将它翻译成html送出。

显然,我们现在的任务主要是修改DocumentRoot和ScriptAlias,DirectoryIndex,写
一个简单的html文件,放到缺省的主页目录里,例如/home/httpd/html/index.html,设
置其属性为755,然后就可以启动apache了:

/usr/sbin/apachectl start

或者

/usr/sbin/httpd

如果是重新启动apache,执行/usr/sbin/apachectl restart或者killall –HUP ht
tpd。然后在浏览器中就可以实验页面服务是否可以使用了。如果apache抱怨找不到htt
pd.conf,可以执行

httpd –f /etc/httpd/httpd.conf


6.3.1 目录管理

如同其他所有的网络服务一样,Apache同样使用各种安全性控制,例如存取地址控制
和身份控制。这里我们先讲地址和目录控制。

Apache将目录作为单元来进行存取控制,每个目录在/etc/httpd/conf/httpd.conf中
使用一个段落,首先的是/目录,这实际是设置缺省值:

<Directory />

Options FollowSymLinks

AllowOverride None

</Directory>

每个段落都是由这样的两组尖括号构成的行夹起来的,其中最主要的句子是Options,
AllowOverride,Allow/Deny,Order等。

Options

这个子句用来说明一些主要的设置,目前可以使用的设置有Indexes,Includes,Fol
lowSymLinks,ExecCGI,MultiView,当然还有两个最简单的选择就是None和All。None
是禁止所有选择,而All允许上面的所有Options。一般我们主要关心的是Indexes和Fol
lowSymLinks。Indexes是设定是否允许在目录下面没有index.html的时候显示目录,而
FollowSymLinks决定是否可以通过符号连接跨越DocumentRoot。例如,尽管/ftp不在/h
ome/httpd/html下面,但是我们仍然可以使用符号连接建立一个/home/httpd/html/ftp
使得可以直接输入http://mydomain.com/ftp来访问这个目录。

使用FollowSymLinks的办法很简单,就是首先在合适的目录段落里面Options Follow
SymLinks,(符号连接的上层就可以)然后建立一个别名:

Alias /ftp/ “home/httpd/html/ftp/”

后面的是你建立的到/ftp的符号连接。注意这一行应该位于所有目录段落之外。

AllowOverride

AllowOverride定义是否允许各个目录用目录中的.htaccess(后面解释)覆盖这里设定
的Options。它的选择有Options,FileInfo,AuthConfig,Limit或者它们的组合,当然
还有None和All。

由于/是缺省设置,所以这里没有设置太多的内容,相反,我们应该在/之后独立设置
各个目录的控制,例如:

<Directory "/home/httpd/html">

Options Indexes FollowSymLinks

AllowOverride None

Order allow,deny

Allow from all

</Directory>

出现了两个新的选项:Order和Allow。

Order

它有两种用法,即Order allow,deny或者Order deny,allow。简单地说,它用来设置
是先执行deny还是先执行allow,例如,Order deny,allow意味着先看deny行,再看all
ow行,这样如果deny from all再allow from 202.112.58.0/24后来的allow子句就会超
越deny而对202.112.58.x打开访问。

Allow/Deny from

这两个选项和Order一起使用,Allow允许某个地址来的连接请求,Deny则禁止这个请
求,例如在Order deny,allow的情况下,Deny from all,Allow from 192.168.12.0/
24表示只有192.168.12.x的用户可以访问这个目录。


现在我们来看看下面的一个设定:

UserDir public_html

<Directory /home/*/public_html>

AllowOverride FileInfo AuthConfig Limit

Options MultiViews Indexes SymLinksIfOwnerMatch IncludesNoExec

<Limit GET POST OPTIONS PROPFIND>

Order allow,deny

Allow from all

</Limit>

<Limit PUT DELETE PATCH PROPPATCH MKCOL COPY MOVE LOCK UNLOCK>

Order deny,allow

Deny from all

</Limit>

</Directory>

这个有什么用处?UserDir是一个特殊的选项,用来在用户的宿主目录下设置主页,比
如,有一个名字叫wanghy的用户,其宿主目录是/home/wanghy,而且UserDir象我们刚才
那样设定,那么,你可以在浏览器中输入http://www.mydomain.com/~wanghy,它将对应
的是宿主目录+UserDir,也就是/home/wanghy/public_html。当然,为了使这个功能生
效,你得将这个目录设置为大家都可以读。(现在知道http://xxx.net/~yourname是怎
么回事了吧,:PP)

下面的行就是对这个功能的限制,注意要使得某人的这个功能生效,必须有这个段落
,这个段落里别的东西都是熟知的,唯一新的东西是Limit段,它用来提供存取限制,例
如<Limit GET POST>对应的段落设置GET和POST权限,诸如此类。上面的段落表示所有人
都可以通过www进行GET和POST,而任何人都不能PUT和DELETE、MOVE等等。

Limit

对某个路径进行存取限制。

6.3.2 proxy系统

Proxy就是代理,简单地说,客户机器把请求转发给服务器,服务器代替客户机器进行
Internet访问,将访问回来的结果再回送给客户机。通常我们说的Proxy有好几种,工作
方式也不同。例如,最常用的Proxy方式是服务器打开一个端口,在这个端口上接受客户
的请求,然后自己代替客户机器进行访问。这种方法不需要在客户端安装特殊的软件,
一般的浏览器都可以支持这种功能,缺陷是只能代理标准的一些服务,如WWW,FTP等等;
另外一种方法是在客户端安装专用的软件,然后应用软件通过这个代理工具提供的接口
与服务器联系;当然还有另一种最简单的办法就是IP伪装。我们这里介绍的Proxy是第一
种,即Apache本身提供的Proxy系统。这个代理系统可以将代替服务器取得的内容在服务
器硬盘上存贮起来,以后再有客户访问的时候可以直接从硬盘上取回,因此可以节省网
络流量并加快客户的访问速度。

要启动Apache的Proxy倒是非常的简单,只要在httpd.conf里面加上这样几行:

ProxyRequest ON

Listen 8080

CacheRoot /var/cache

然后在你的客户浏览器(比如IE)里面将代理服务器设置成你的Apache机器,端口号
8080就可以了。不过这时的Proxy由于Cache太小没有什么实际意义,我们现在来看一看
和Proxy相关的设置,按照我们的习惯,只列出有趣的内容:

ProxyRequest

它的值为ON的时候,启动Proxy功能

ProxyRemote

级联Proxy。例如你已经有了一个proxy1.mydomain.com的Proxy服务器,现在想让pro
xy2.mydomain.com来直接用proxy1代理,可以使用

ProxyRemote http://proxy1.domain.com:8080

ProxyPass

这个选项的意思比较古怪。例如你有一台www.mydomain.com的apache服务机器,另外
还有一个www2.mydomain.com也是个www服务器,然后你加上一行

ProxyPass /www2/ http://www2.mydomain.com/

那么以后访问http://www.mydomain.com/www2/就会直接将请求转发给www2,www2目
录看上去是一个本地映像。(这个到底有什么用处?你就当找个乐子吧)

ProxyBlock

一个有点恶心的功能,用来阻挡到某些站点的访问,例如ProxyBlock someone.com s
omefool.com将会断掉*.somefool.com,someone.com甚至someone.com.cn的访问。这里
的字符串都是匹配子串的方式使用的。

NoProxy

设置你对哪些站点的内容不使用Proxy。通常你显然不愿对同一局域网内的东西进行代
理,所以这个选项一般总是列出你自己内部网的地址。在它的地址列表里面可以使用同
配符和子网的形式,例如:

NoProxy .mydomain.com 192.168.12.0/24

ProxyVia

这个选项表示是否在返回内容中说明已经使用了代理,如果你使用级联代理,需要把
它设置成ON。

例如

ProxyVia on

CacheForceCompletion

这个选项用来设置一种特殊情况,就是客户的请求快要完成的时候却取消了,服务器
是否应该将未传完的内容保存,这个选项取一个0到100之间的数字,一般取为70,意思
是传递量超过70%的页面就应该缓冲。例如:

CacheForceCompletion 70

CacheRoot

存放缓存文件的位置,例如:

CacheRoot /var/cache

CacheSize

允许使用多少硬盘空间作为Cache。单位是KB。例如

CacheSize 200000

CacheGcInterval

每隔一段时间,Apache会检查cache目录,删除超过Cache空间的文件以便释放硬盘空
间。单位是小时,例如

CacheGcInterval 24

CacheMaxExpire

最大的Cache有效期。如果Cache中的文件的存放时间已经超过了这个有效期,那么再
访问这个页面的时候,apache将重新去下载对应页面。

CacheLastModifiedFactor

很难说清这个选项的含义,缺省的值是0.1,你只要按照这个值设置就没有问题了。例


CacheLastModifiedFactor 0.1

CacheDefaultExpire

对于那些不支持内容有效期的协议,使用这个值作为缺省的有效期,例如

CacheDefaultExpire 1

NoCache

类似于NoProxy和ProxyBlock,定义一个不进行本地缓存的列表,例如

NoCache Freemail.263.net

Listen

缺省的http和Proxy服务端口是80和8080。但是你可以定义一些其他的端口接收信息,
例如

Listen 8080

Listen 8081

Listen 192.168.12.21:8080

这个选项在做端口虚拟主机的时候也有用。


6.3.3 虚拟主机

随着Apache的流行,虚拟主机已经变得没有那么神秘了。流行的虚拟主机有几种,例
如,对每个虚拟主机分配一个IP,或者是一个主机端口,当然更好的方法是分配一个IP
对应多个域名,然后根据域名来提供正确的相应。

做一个基于IP的虚拟主机是最简单的。按照我们在前面提出的办法,给你的Apache服
务器提供几个IP,例如192.168.1.2,192.168.1.3,。。。,然后对每一个IP使用一个
这样的段落:

<VirtualHost 192.168.1.2>

DocumentRoot /home/httpd/html/www1/doc

ServerName www1.yourdomain.com

ScriptAlias /cgi-bin/ /home/httpd/html/www1/cgi-bin

</VirtualHost>

以后浏览192.168.1.2的内容就是/home/httpd/html/www1/doc/index.html的内容了。
有几个虚拟主机,就写上几个VirtualHost段落,注意这时候主机也必须是一个Virtual
Host。

在VirtualHost段落中,ErrorLog,CustomLog,DocumentRoot,ServerName,Script
Alias和ServerAdmin选项仍然可以使用,而User和Group选项必须SuEXEC附加模块的支持


然后要明确地启动Listen,例如:

Listen 192.168.1.2:80

Listen 192.168.1.3:80

每个地址Listen一次,这样就可以使用虚拟主机了。

也可以使用端口虚拟主机,不过我认为这意义不大,因为客户必须明确地给出服务器
的运行端口。

IP虚拟主机实际并不是一个特别好的功能,因为它需要为每一个虚拟主机提供一个IP
别名,对于IP地址比较紧张的商业单位,名字虚拟主机通常更有意义。

名字虚拟主机是为一个IP地址分配若干个域名记录,例如192.168.1.2可以同时设置为
www1.mydomain.com,www2.domain.com,等等,也就是在域名解析记录中写上:

www1 IN A 192.168.1.2

www2 IN A 192.168.1.2

而在域名的反向查询文件中加上对应的PTR记录:

2 IN PTR www1.mydomain.com.

2 IN PTR www2.mydomain.com

然后,根据对不同名字的请求,服务器将发回不同的页面。

要实现这个功能,假定你已经完成了DNS记录的设置,然后只要在httpd.conf中加入这
样的一行:

NameVirtualHost 192.168.1.2:80

这一行告诉服务器把192.168.1.2当成一个名字虚拟主机。然后,可以类似地设置虚拟
主机目录,只是这个时候需要使用的是名字来标示虚拟主机:

<VirtualHost www1.mydomain.com>

DocumentRoot /home/httpd/html/www1/doc

ServerName www1.yourdomain.com

ScriptAlias /cgi-bin/ /home/httpd/html/www1/cgi-bin

</VirtualHost>

这样就定义了一个名字虚拟主机。其他的虚拟主机入口可以同样地设置。

注意:如果你要使用名字虚拟主机,那么请记住:你需要用A记录定义多个主机名字,
而不是用CNAME来建立别名。CNAME建立的名字实际访问的时候仍然是原来的名字。

6.3.4 身份控制

现在我们来看看身份控制功能。身份控制功能其实很简单,就是对某个目录的存取权
限加上限制,最常用的功能是加上密码,要求用户必须输入正确的用户名和密码才能进
入。作用上,它和前面的地址控制类似,只是这一次限制的是用户的身份。

要设置某个目录的存取权限,首先必须允许身份认证,这是在对应的directory段落里
面设置的,例如,有个目录/home/public,要使用身份认证,需要使用AuthType进行定
义:

<Directory "/home/public">

AuthType Basic

AuthName "Give Your Name and Passwd"

Require valid-user

order allow,deny

allow from all

AuthGroupFile /etc/httpd/conf/groups

AuthUserFile /etc/httpd/conf/users

</Directory>

这里面涉及到了几个新的命令:

AuthType

使用的身份认证形式,就我所知道的,实际上只能使用Basic和Digest两个选项,而且
通常总是使用Basic。

AuthName

当进入一个需要身份认证的目录的时候,将弹出一个对话框让你输入用户名和口令,
AuthName是对话框的提示信息。

AuthGroupFile

AuthUserFile

这两个选项用来设置身份认证的用户名文件。注意Apache并不使用机器的真实账号,
相反你必须用htpasswd命令来建立WWW用户,格式是:

htpasswd [-c] 文件名 用户名

-c选项创建一个新的www用户名字文件,文件名是容纳www用户名和口令的文件名字,
例如

htpasswd –c /etc/httpd/conf/users user1将创建/etc/httpd/conf/users文件,并
且加入user1用户,htpasswd程序还同时提示你输入用户口令。htpasswd /etc/httpd/c
onf/users user2将继续加入user2。以此类推。

至于www的group文件就是一个普通的文本文件,每行格式是:

组名:用户1 用户2,....

例如:

group1:user1 user2

至于两个Auth命令的用法则可以看看刚才的那个例子,就是直接给出文件名。


Require

这个选项设定允许哪些用户进入,Require user [用户列表]将允许某些用户进入,例
如Require user user1 user2 将允许user1和user2访问,而Require group [组列表]将
允许某些组访问。另外有两个特殊的选项就是Require valid-user和Require valid-gr
oup,分别表示只允许在www用户/组文件中存在的用户和组访问。

如上面说的那样设置了httpd.conf并且建立了users和groups文件,然后重新启动Apa
che,现在就可以访问这个站点了。当你用IE或者Netscape 访问的时候,会弹出一个对
话窗口让你输入用户名和口令:



图6.1 身份认证

这是进行用户身份认证的标准方法。

一般来说,对于普通的站点,这样的处理方式就已经足够,问题是,在虚拟主机的情
况下,允许每个虚拟主机的Web管理者修改你的httpd.conf显然是无法想象的。还记得我
们前面提到的AccessFileName和AllowOverride选项吗?利用AccessFileName选项可以定
义缺省的存取控制文件的名字,一般是.htaccess。然后,你需要允许每个目录的自身设
定功能:

AllowOverride AuthConfig

这样的行将允许用户用自己的有关Auth的定义去覆盖缺省的定义,例如,我们可以把
上面的设置改成:

<Directory "/home/public">

order allow,deny

allow from all

AllowOverride AuthConfig

</Directory>

然后在/home/public这个目录下面建立一个文件.htaccess,内容是

AuthType Basic

AuthName "Give Your Name and Passwd"

Require valid-user

AuthGroupFile /etc/httpd/conf/groups

AuthUserFile /etc/httpd/conf/users

然后同样建立users和groups文件,当Apache准备访问这个目录的时候,会自动使用.
htaccess里面定义的信息去代替本来应该在httpd.conf里面设置的内容。当然,这种代
替只是对于这个目录有效。

Limit和Order,Allow/Deny也可以在.htaccess文件里面设置。当然,AccessFileNam
e则设置这个文件的缺省名字。

6.3.5 重新编译Apache和附加产品

Apache的功能已经十分强大了,但是很多人仍然认为它的功能还不够强大,于是为它
开发了许许多多的功能,这些功能通常都以源代码的形式提供。另外,由于某些原因,
Apache的一些特殊功能(比如我们马上要介绍的SuEXEC)在缺省设置里面是不包括的。
如果你只是要自己建立一个简单的Web站点,那可能并不需要这些功能,但是很多人总希
望自己的站点功能更强大,页面更美观。无论哪一种情况,你都很可能需要重新编译Ap
ache或者某些产品。

编译Apache是一件相当恶心的事情,因为有太多的东西需要设定,你可以安装apache
的源代码,将它展开后进入到里面,执行./configure –help可以显示configure命令的
选项,你看看需要设置多少东西。其中最主要的是设置允许使用哪些模块或者DSO,以及
缺省的系统目录。要在命令行输入如此之长的配置命令是不现实的,你肯定需要建立一
个脚本文件来处理这件事情,例如,下面是我的配置文件:

./configure --enable-module=ssl --enable-module=proxy

--enable-module=alias --enable-module=so --enable-module=auth_db

--enable-module=vhost_alias --with-perl=/usr/bin/perl

--prefix=/usr --exec-prefix=/usr

--bindir=/usr/bin --sbindir=/usr/sbin --libexecdir=/usr/libexec

--mandir=/usr/man --sysconfdir=/etc/httpd/conf --datadir=/home/httpd/html


--includedir=/usr/include/apache --localstatedir=/var/state/httpd

--runtimedir=/var/log --logfiledir=/var/log --proxycachedir=/var/cache

--enable-suexec --suexec-caller=nobody

--suexec-logfile=/var/log/httpd/suexec.log --suexec-userdir=cgi-bin

--suexec-uidmin=10 --suexec-gidmin=10

--suexec-safepath=/usr/bin:/bin:/usr/local/bin

--suexec-docroot=/home/

其中关于xxxdir=的选项的含义是一目了然的,通常Apache源代码的设置是将所有的东
西安装在/usr/local/apache下面,而你可以用-xxxdir=选项改变它,例如-mandir=/us
r/man表示手册页面将被安装到/usr/man,而-bindir=/usr/bin和-sbindir=/usr/sbin代
表apache的执行程序被安装到/usr/bin和/usr/sbin等等。

--enable-module是将某个模块编译入内核,通常用./configure –help可以显示那些
模块被设定为缺省打开而那些是缺省关闭的。例如-enable-module=ssl代表在apache执
行程序中直接启用ssl。还有一个相反的选项叫-disable-module。

而-enable-suexec是启动SuEXEC功能(见下节)。

执行配置文件之后,make,make install,然后重新启动Apache,就可以使用新的功能
了。

实际上,编译apache的主要理由是加入一些模块,所谓的模块是可以添加在Apache里
面提供新功能的产品。通常,我们可以象我刚才说的那样用-enable-module命令把模块
直接加入Apache里面。不过,也有时候,可以把模块编译成独立的模块文件-DSO(Dyna
mic Shared Object),以独立文件的形式提供,并且在httpd.conf文件里面用LoadMod
ule命令装入,这样就不需要重新编译源代码了。这要求你的apache编译的时候必须支持
装入模块(--enable-mudule=so,--enable-rule=SHARED_CODE)。

把模块编译成为DSO的命令是-enable-shared=xxx。例如把proxy支持编译成DSO的命令
就是-enable-shared=proxy。编译后会生成对应的.so文件,就可以用LoadModule命令装
入了。不过,一般我们建议将模块直接编译入apache程序,除非是使用后提供的模块。
(如下面说的PHP3)

由于可以使用模块扩展Apache的功能,有许多的人为它编写各种功能扩展程序,其中
最重要的是SSL支持和脚本语言支持。SSL支持我们将放在安全性的那一章来讲,现在主
要介绍服务器脚本。

用过Windows NT作页面服务的用户应该都知道ASP,ASP在服务器端运行,服务器将它
解释为HTML文件并且送交给客户。不过ASP只能在IIS Server上运行。

Apache有一个类似的东西叫php3,也是一种服务器端脚本语言,通常在Apache的缺省
安装中并没有php3支持,你需要自己安装php3源码并且编译成Apache模块。php3的源程
序在RedHat 6.1的源代码盘里面有,当然你也可以自己去下载它。另外,确定你已经安
装了apache-devel软件包。

为了把php3编译为apache模块,需要一个apache工具,称为apxs程序,缺省的情况下
,这个文件是/usr/sbin/apxs,先确定一下这个文件的位置,然后安装php3源代码。通
常这个代码是rpm文件,安装后是位于/usr/src/redhat/SOURCES下的一个tgz包,展开它
之后,进入php3源代码目录,先浏览一下configure程序的选项(./configure –help)
,然后开始编译,这里用的是最小编译选项:

./configure –with-apxs=/usr/sbin/apxs

make

然后将生成的libphp3.so拷贝到一个合适的地方,比如说/usr/lib。接着就可以装入
动态连接库了。这可以用LoadModule命令完成:

在httpd.conf中加入这样的行:

LoadModule php3_module /usr/lib/libphp3.so

AddModule mod_php3.c

AddType application/x-httpd-php3 .php3

AddType application/x-httpd-php3-source .phps

LoadModule的语法是LoadModule [模块名] [模块文件名],然后的AddType命令启用了
php3的解释功能,重新启动apache,php3功能就可以使用了。当然,如果你重新编译了
apache,要确保加入了装入模块支持。

为了测试php3是否正确安装了,可以建立这样的一个文件,命名为test.php3:

<html>

<?php phpinfo(); ?>

</html>

然后把它拷贝到你的DocumentRoot下面,在浏览器中输入(比如说)httpd://www.mydo
main.com/test.php3,你会看到好几屏的测试信息,这就表示php3已经工作了。

php3支持很多扩展功能,其中最重要的是和各种数据库的接口,例如可以用php3脚本
访问Oracle,Sybase,MySQL等等,由于本书不是主页指南,无法详细地向你叙述php3的
详情,你可以自己看php3的手册。

不过,尽管php3功能十分强大,但是它确实不容易学懂。为此,有一些其他的脚本工
具,例如服务器端的JavaScript等等,它们也经常被发行为Apache的模块,安装方法和
php3大同小异。另外,也有一些人开发了ASP到java或者php3的解释程序,这样就可以在
Apache上使用ASP了(主要是为了支持用FrontPage做的主页),安装起来也不复杂,例
如iasp,这个程序可以把ASP翻译成java程序,只要你安装了java jdk,使用它是一件很
轻松的事情。

6.3.6 SuEXEC和其他

对于许多用户来说,可能最常用的交互工具仍然是CGI。CGI程序从网页的输入得到信
息,并且存取服务器的文件。

在通常的情况下,我们可以像处理其他功能那样处理CGI。但是,当你的CGI程序试图
去写一个服务器上的文件时(比如说,留言板),你会发现浏览器将返回一个“服务器
内部错误”的信息。这是因为apache的服务程序缺省是使用nobody权限启动的,所以cg
i程序的权限也是nobody。这样,它不能写任何服务器文件(因为没有哪个文件的属主是
nobody)。

解决的方法有许多种,最简单的方法是更改httpd.conf中服务器的运行权限,例如,
将User和Group都改成someone,然后就可以写someone的文件了。问题在于,对于一个为
许多用户提供主页空间的服务器来说,这样的方法是行不通的,除非设置为root,但这
又很容易导致安全性问题。

常用的办法之一是使用setuid。按照我们前面讲的,setuid程序执行时按照自己的拥
有者权限执行。这个办法比较简单,但是许多时候,为了安全性和管理上的方便,系统
是不允许用户远程登陆的,因此也就无法使用chmod等等命令。

suEXEC是解决这个问题的比较好的方法,它允许下面两个功能:(1)对于虚拟主机,
允许每个VirtualHost段落使用自己的User和Group子句;(2)对于http://www.yourdoma
in.com/~someone这样的主页服务,允许每个用户在自己的目录下设置一个cgi目录,处
于这个目录中的cgi程序自动获得对应用户的权限。

要使用suEXEC功能,通常必须重新编译apache。可以看看我前面提到的那个编译例子
,与suEXEC相关的命令是:

--enable-suexec

这个选项设置允许suEXEC功能

--suexec-caller=nobody

suexec-caller是调用者的名字,通常就是httpd程序运行时缺省的权限,一般是nobo
dy。

--suexec-logfile=/var/log/httpd/suexec.log

suexec的记录文件的名字,以后每个调用都会被记录到/var/log/httpd/suexec.log中


--suexec-userdir=public_html

对于www.yourdomain.com/~someone这样的调用,缺省的suEXEC目录,例如这样设定之
后,/home/someone/public_html中的文件在调用的时候将自动赋予someone权限。注意
由于我们通常把文档和cgi脚本放在同一目录下,不要忘记设置脚本的执行权限。

--suexec-uidmin=100

--suexec-gidmin=100

最小的suEXEC使用的uid和gid。通常你可以把它们设置成一个合适的值,使得不会有
哪个程序以root,daemon,adm之类的危险身份执行。

--suexec-safepath=/usr/bin:/bin:/usr/local/bin

suEXEC程序可以安全调用的程序的目录,通常设定这个目录是为了调用/usr/bin/per
l之类的cgi解释器。

--suexec-docroot=/home/

suEXEC功能的底层目录,意味着用户不能用suEXEC功能直接执行/home之外的用户cgi
程序。

重新编译apache,启动后,就可以使用suEXEC了。

要启用suEXEC功能,如同我们说的,可以直接把cgi放到自己的suexec-userdir下面,
但是对于虚拟主机用户,一般由管理员直接在httpd.conf中加入对应虚拟主机段落的权
限:

<VirtualHost mail.asnc.edu.cn>

User wanghy

Group wanghy

DocumentRoot /home/wanghy/public_html

ServerName mail.asnc.edu.cn

ScriptAlias /cgi-bin/ "/home/wanghy/cgi-bin/"

</VirtualHost>

注意User和Group都要填写才行。

suEXEC有一个很重要的限制,就是cgi程序的拥有者、cgi程序所在的目录,VirtualH
ost的设定三者必须保证user/group的完全一致,否则suEXEC将拒绝执行。这个功能主要
是为了安全。

事实上,尽管cgi程序几乎是不可缺少的,但是它的运行必须执行大量的装入操作,特
别是装入perl解释器的过程更加耗费资源,因此通常cgi程序会成为服务器的瓶颈所在。
有一些特殊的方法用来处理这个问题,例如fast_cgi,mod_perl等等,详细的知识请参
考apache的手册。

6.3.7 高级课题

除了我们前面讲到的apache设置之外,还有一些Apache参数可以使用,它们对调整Ap
ache的性能很重要,这里只给出比较有意义的一些:

PidFile

PidFile指定的文件将记录httpd主守护进程的进程号,我们以前曾经描述过守护进程
的工作方式,显然,主守护进程将控制其他进程的运行,它为其他进程的父进程,对这
个进程发送信号将影响所有的httpd进程。范例:

pitfile /var/run/httpd.pid


ResourceConfig   

AccessConfig


这两个参数用于和旧版本Apache兼容。如果定义了这两项,系统还要察看这里设定的
两个文件。通常不需要设置它们。

Timeout

Timeout定义客户程序和服务器连接的超时间隔,超过相应秒数后服务器将断开与客户
机的连接。例如

Timeout 300

KeepAlive

KeepAlive参数用于支持HTTP 1.1版本的一次连接、多次传输功能,这样就可以在一次
连接中传递多个HTTP请求。范例:

KeepAlive ON


MaxKeepAliveRequests

MaxKeepAliveRequests为一次连接可以进行的HTTP请求的最大请求次数。0代表无限制
。例如:

MaxKeepAlive 100


KeepAliveTimeout

同一个连接之间的两次请求之间的最大时间间隔,例如:

  KeepAliveTimeout 15

MinSpareServers

MaxSpareServers

Apache服务器使用了一个特殊技术,就是预先生成多个空余的子进程驻留在系统中,
一旦有请求出现,就立即使用这些空余的子进程进行处理,这样就不存在生成子进程造
成的延迟了。在运行中随着客户请求的增多,启动的子进程会随之增多,但这些子进程
在处理完一次HTTP请求之后并不立即退出,而是停留在计算机中等待下次请求。如果子
进程数不够,就forks出一些;如果forks出了太多的子进程,就杀死一些。这两个参数
用来设置空闲子进程数的上下限。例如

MinSpareServers 5

MaxSpareServers 10

StartServers

httpd启动时启动的子进程个数,这个参数应该设置为前两个值之间的一个数值,小于
MinSpareServers和大于MaxS pareServers都没有意义。例如

StartServers 8

MaxClients

最多启动多少个子进程处理服务。例如

MaxClients 200

MaxRequestsPerChild

每个子进程最多处理多少个请求然后退出。由于许多系统会有内存泄漏或者其他的问
题,这个数值太大可能导致系统不稳定,太小又会造成不必要的forks和kill。通常的缺
省值是30,不过我们建议把它调整的稍大一些,特别由于2.2.14以后的内核已经修复了
内存泄漏的错误。例如

MaxRequestPerChild 300

当然如果你对自己的系统有绝对的信心也可以设置成0,代表无限次请求。


6.3.8 联机手册

从我们对Apache的描述中就可以看出Apache是一个极端复杂的产品。要知道,世界上
有将近一半的Web服务器系统在运行Apache,而且有大量的开发者在为Apache做模块开发
。因此,Apache的联机手册采用单独的HTML文件来提供,通常,在安装Apache的时候,
这些文件被安装到了/home/httpd/html/manual目录下,直接在浏览器中打开/home/htt
pd/html/manual/index.html就可以看到这些使用信息了。

6.4 BBS和MUD

6.4.1 BBS

如果你在教育网内,也许你会对BBS比其他任何Internet服务都要熟悉的多。理论上讲
,讨论组和基于页面的讨论区也不错,但是实际上学生通常更喜欢BBS。

我们讨论的BBS一般都是基于internet和telnet协议的终端BBS,尽管也有用页面或者
拨号构成的BBS,但是通常它们总是不太受人欢迎。

目前最常用的BBS服务工具是FireBird BBS,现在用的一般都是汉化版本。通常FireB
ird的安装文档写的十分详细,很容易按照说明安装,所以我们也不想再详细地叙述这个
东西了,通常FireBird系列的BBS服务程序的安装过程都是类似的,你可以看随FireBir
d的文档,主要包括下面的几步:

建立BBS相关账号,包括bbs,bbsadm,bbsuser。由于bbs账号是不需要口令的,所以
通常你可以用手工编辑/etc/passwd文件再pwconv的办法建立这么几个账号。

展开FireBird BBS的安装包

编译源代码,基本过程就是我们通常的办法:./configure;make;make install。然
后建立SYSOP账号和guest账号,就可以实验BBS了。如果你需要增加功能或者修改信息,
可以看随安装包来的文档。

目前的另外一个时髦的倾向是给基于终端的BBS加上从Web访问的功能。比如bbs2www等
。它们可以直接安装在已有的FireBird BBS上。

如果你要架设一个有许多人上站的BBS,通常可以考虑把bbsd服务进程改成直接由tel
net来执行,或者说用bbsd作为telnet守护进程。做法很简单,直接把inetd.conf里面的
相应部分改掉就可以了。

6.4.2 文本MUD

文本的MUD是telnet服务中仅次于BBS的,通常我们最常用的MUD系列是ES2系列,例如
ES II,XKX等等。这个系列的Mud基本的结构是"MUDOS+MUDLIB",就是一个telnet服务程
序加上相应的资源文件。一般这种Mud,架站的基本方法就是找到一个MudOS(用来支持M
ud服务的服务器程序),再下载一个已有的MUDLIB(包括故事,NPC,战斗规则等等,然后
慢慢修改)。

如果要了解更多的信息,最好是找到一个完整的MUDOS+MUDLIB,然后自己研究,实际
上,对于架设过BBS的用户,架设文本MUD是很简单的事情。真正的问题,在于架站之后
还要经常修正MUDLIB里面的BUG,增加MUDLIB的新代码等等。