跳转至内容

LPI Linux 认证/实施 Web 服务器

来自维基教科书,开放的书籍,为开放的世界

208.1 实施 Web 服务器

[编辑 | 编辑源代码]

详细目标 (208.1)

[编辑 | 编辑源代码]

(LPIC-1 版本 4.5)


权重 4


描述: 考生应该能够安装和配置 Web 服务器。这个目标包括监控服务器负载和性能、限制客户端用户访问、配置对脚本语言的支持作为模块以及设置客户端用户身份验证。还包括配置服务器选项以限制资源的使用。考生应该能够配置 Web 服务器以使用虚拟主机并自定义文件访问。


关键知识领域

  • Apache 2.4 配置文件、术语和实用程序。
  • Apache 日志文件配置和内容。
  • 访问限制方法和文件。
  • mod_perl 和 PHP 配置。
  • 客户端用户身份验证文件和实用程序。
  • 最大请求、最小和最大服务器和客户端的配置。
  • Apache 2.4 虚拟主机实现(有和没有专用 IP 地址)。
  • 在 Apache 的配置文件中使用重定向语句来自定义文件访问。


术语和实用程序

  • 访问日志和错误日志
  • .htaccess
  • httpd.conf
  • mod_auth_basicmod_authz_hostmod_access_compat
  • htpasswd
  • AuthUserFileAuthGroupFile
  • apachectlapache2ctl
  • httpdapache2

Apache 是互联网上使用最广泛的 Web 服务器,[1] 也是开源开发成功的“典范”。虽然 Web 服务器本身并不需要特别花哨(许多编程语言都有关于如何编写 HTTP 服务器的教程),但 Apache 的“成功秘诀”在于它的灵活性和鲁棒性。Apache 可以通过各种模块轻松扩展,mod_perlmod_auth 将在本节中介绍。

安装和配置

[编辑 | 编辑源代码]

Apache HTTP 服务器在最新的版本(截至撰写本文时为 2.2)中可以从 Apache HTTP Server 网站上以源代码形式下载,也可以从您喜欢的 Linux 发行版的存储库中以预编译的二进制包形式下载。

在本节的其余部分,我们将参考 Apache 文档中的文件名。此文档通常与 Apache 二进制文件一起安装在 DocumentRoot 中。如果我们无法访问本地文档,仍然可以从 Apache 网站上获取 官方文档。我们将使用一个虚拟网络,其中包含在 VirtualBox 中的 Slackware 13.0,它是免费的(在成本方面)并且以自由的方式提供(在自由方面),具有少量限制。下面将提供针对 Debian LennyRedhat Enterprise 的克隆版 Centos 5.4 的发行版特定摘要。

如果我们想从源代码编译 Apache,我们使用通常的 configuremakemake install 步骤。有关更多详细信息,请参阅 文档 页面。

Web 服务器二进制httpd 本身通常位于 /usr/sbin/ 中。我们可以直接使用二进制文件通过命令行选项来启动和停止 Web 服务器,但更好的方法是使用控制脚本 apachectl 来与 httpd 交互。apachectl 可以以方便的方式控制 Web 服务器进程(启动和停止)并且在后台设置环境并检查配置文件。在从 Apache 1.3 过渡到 Apache 2.x 系列的早期,控制脚本被称为 apache2ctl 以区别于 Apache 1.3 脚本(那时)apachectl

不幸的是,LPI 仍然使用 apache2ctl,而 Apache 源代码生成 apachectl

[root@lpislack ~]# apachectl
Usage: /usr/sbin/httpd [-D name] [-d directory] [-f file]
                       [-C "directive"] [-c "directive"]
                       [-k start|restart|graceful|graceful-stop|stop]
                       [-v] [-V] [-h] [-l] [-L] [-t] [-S]
Options:
  -D name            : define a name for use in <IfDefine name> directives
  -d directory       : specify an alternate initial ServerRoot
  -f file            : specify an alternate ServerConfigFile
  -C "directive"     : process directive before reading config files
  -c "directive"     : process directive after reading config files
  -e level           : show startup errors of level (see LogLevel)
  -E file            : log startup errors to file
  -v                 : show version number
  -V                 : show compile settings
  -h                 : list available command line options (this page)
  -l                 : list compiled in modules
  -L                 : list available configuration directives
  -t -D DUMP_VHOSTS  : show parsed settings (currently only vhost settings)
  -S                 : a synonym for -t -D DUMP_VHOSTS
  -t -D DUMP_MODULES : show all loaded modules
  -M                 : a synonym for -t -D DUMP_MODULES
  -t                 : run syntax check for config files

嗯,这看起来不对,因为如果 apachectl 遇到它不理解的参数,它会直接将这些参数传递给 httpd。而没有参数是这样的参数,所以 apachectl 在没有参数的情况下调用 httpd

apachectl 可以 startstoprestart Web 服务器,但更有用的是 gracefullgracefull-stop,它们在不停止当前打开的连接的情况下重启/停止 Web 服务器。configtesthttpd -t 相同,用于测试 apache 配置文件。选项 statusfullstatus 需要 mod_status 模块才能显示有关我们的 http 服务器的许多有用的状态信息。

Apache 实例的日志位于 /var/log/httpd/ 中。两个最重要的日志文件是 access_log,它记录对 Web 服务器的所有访问,以及 error_log,它只记录错误。像 AwstatsWebalizer 这样的工具使用 access_log 来生成它们的报告。

access_log 的片段显示(取自 Debian Lenny 机器 lpidebian)IP 192.162.10.21 访问网站上的 /,这是 Web 服务器的“欢迎”页面(稍后会详细介绍),然后尝试 GET /favicon.ico 以及 /login.html,这两者都导致“404”,这意味着“文件不存在”。

192.168.10.21 - - [02/Jun/2009:17:06:01 -0400] "GET / HTTP/1.1" 200 56 "-" "Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.10) Gecko/2009042315 Firefox/3.0.10"
192.168.10.21 - - [02/Jun/2009:17:17:12 -0400] "GET /favicon.ico HTTP/1.1" 404 300 "-" "Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.10) Gecko/2009042315 Firefox/3.0.10"
192.168.10.21 - - [05/Jun/2009:16:41:39 -0400] "GET / HTTP/1.1" 200 56 "-" "Mozilla/5.0 (compatible; Konqueror/3.5; Linux 2.6.27.7-smp) KHTML/3.5.10 (like Gecko)"
192.168.10.21 - - [05/Jun/2009:16:41:39 -0400] "GET /favicon.ico HTTP/1.1" 404 300 "-" "Mozilla/5.0 (compatible; Konqueror/3.5; Linux 2.6.27.7-smp) KHTML/3.5.10 (like Gecko)"
192.168.10.21 - - [05/Jun/2009:16:41:50 -0400] "GET /login.html HTTP/1.1" 404 299 "-" "Mozilla/5.0 (compatible; Konqueror/3.5; Linux 2.6.27.7-smp) KHTML/3.5.10 (like Gecko)"

error_log 中的这个片段以更详细的方式显示了相同的错误

[Fri Jun 05 13:41:10 2009] [notice] mod_python: using mutex_directory /tmp
[Fri Jun 05 13:41:11 2009] [notice] Apache/2.2.9 (Debian) PHP/5.2.6-1+lenny3 with Suhosin-Patch mod_python/3.3.1 Python/2.5.2 mod_perl/2.0.4 Perl/v5.10.0 configured -- resuming normal operations
[Fri Jun 05 16:41:39 2009] [error] [client 192.168.10.21] File does not exist: /var/www/favicon.ico
[Fri Jun 05 16:41:50 2009] [error] [client 192.168.10.21] File does not exist: /var/www/login.html

Apache 的配置在 /etc/httpd/httpd.conf 中进行。这个冗长但经过良好文档化的配置文件在某种程度上类似于 HTML 页面。要删除所有注释,您可以轻松地使用 grep

root@lpislack:~# grep -v ^# /etc/httpd/httpd.conf | grep -v ^$ | grep -v "^    #"
ServerRoot "/usr"
Listen 80
LoadModule auth_basic_module lib/httpd/modules/mod_auth_basic.so
LoadModule auth_digest_module lib/httpd/modules/mod_auth_digest.so
...
LoadModule log_config_module lib/httpd/modules/mod_log_config.so
LoadModule userdir_module lib/httpd/modules/mod_userdir.so
LoadModule alias_module lib/httpd/modules/mod_alias.so
LoadModule rewrite_module lib/httpd/modules/mod_rewrite.so
User apache
Group apache
ServerAdmin [email protected]
DocumentRoot "/srv/httpd/htdocs"
<Directory />
    Options FollowSymLinks
    AllowOverride None
    Order deny,allow
    Deny from all
</Directory>
<Directory "/srv/httpd/htdocs">
    Options Indexes FollowSymLinks
    AllowOverride None
    Order allow,deny
    Allow from all
</Directory>
DirectoryIndex index.html
ErrorLog "/var/log/httpd/error_log"
LogLevel warn
LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
CustomLog "/var/log/httpd/access_log" common
ScriptAlias /cgi-bin/ "/srv/httpd/cgi-bin/"
<Directory "/srv/httpd/cgi-bin">
    AllowOverride None
    Options None
    Order allow,deny
    Allow from all
</Directory>
DefaultType text/plain
TypesConfig /etc/httpd/mime.types
root@lpislack:~#

这个稍微简化的 httpd.conf 是从 Slackware 13.0 系统(lpislack)中获取的。在谈论 httpd.conf 时,有两个术语需要了解:“指令”和“容器”。“指令”是配置选项(及其值)本身,而“容器”是目录或文件集合。容器内的任何指令仅在该容器内有效,容器外的指令对整个站点具有全局影响。另一方面,有一些指令仅在容器内有效。

ServerRoot "/usr"
这是一个棘手的问题。所有相对路径都从这里开始,绝对路径如其名称所示是绝对的。
Listen 80
httpd 监听传入连接请求的 TCP 端口。如果我们的机器有多个网络地址,我们也可以在这里将 httpd 绑定到一个(或多个)IP 地址/端口组合。
LoadModule auth_basic_module lib/httpd/modules/mod_auth_basic.so
加载模块 auth_basic_module,它位于相对于 ServerRootlib/httpd/modules/mod_auth_basic.so 中,因此该模块的完整路径是 /usr/lib/httpd/modules/mod_auth_basic.so
User apache
httpd 运行的用户帐户。这最好是一个受限帐户。一个(第一个)httpd 进程必须以 root 身份运行,如果它想要获取端口 80。
Group apache
httpd 运行的用户组。
ServerAdmin [email protected]
管理员的电子邮件地址,负责运行httpd。当出现错误时,此地址会显示出来。
DocumentRoot "/srv/httpd/htdocs"
这是硬盘上实际 HTML 文档所在的目录!
<Directory /> ... </Directory>
这是一个容器对象。里面的所有指令仅对目录“/及其所有子目录有效。
Options FollowSymLinks
潜在的安全风险!做它的名字所暗示的事情。
AllowOverride None
您可以使用.htaccess文件覆盖大多数指令。这是一个安全风险,并且此指令禁止使用.htascess
Order deny,allow
控制对文件和目录的访问。首先查看不允许谁,然后查看允许谁。默认情况下是最后一个匹配的控制,如果没有匹配或两者匹配,则使用默认值(=最后一个)!
Deny from all
拒绝所有主机访问此容器中的所有文件。
<Directory "/srv/httpd/htdocs"> ... </Directory>
ServerRoot目录的容器。请注意Order allow,denyAllow from all指令。在这里,我们希望所有主机都可以访问。
DirectoryIndex index.html
当 Web 浏览器访问目录而不是特定 HTML 页面时,将向客户端呈现具有此名称的文件。
如果此目录中不存在index.html,则会显示目录本身的内容。Options Indexes允许这样做,而Options -Indexes会生成错误消息,而不是列出目录内容。
ErrorLog "/var/log/httpd/error_log"
设置错误消息的日志文件。
LogLevel warn
设置错误消息的详细程度。
LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
设置自定义日志文件(通常是access_log)中条目的格式。
CustomLog "/var/log/httpd/access_log" common
设置自定义日志文件的名称和位置。
ScriptAlias /cgi-bin/ "/srv/httpd/cgi-bin/"
CGI 脚本的目录。
DefaultType text/plain
如果 HTML 页面本身不包含其他信息,Apache 会将此 MIME 类型用于它提供给 Web 浏览器的 HTML 页面。
TypesConfig /etc/httpd/mime.types
用于不同类型文件名类型的 MIME 类型列表。

访问限制方法和文件

[edit | edit source]

可以根据机器的IP 或网络(主机名、域名、IP 地址或网络)或用户名和密码来限制对 Web 服务器上的文件和目录的访问。虽然可以通过此方法限制访问,但双向传输的所有内容仍然没有加密!为了保护通信并确保 Web 服务器的身份,将在本书的下一章中使用 SSL/TLS 协议。

容器

[edit | edit source]

Apache Web 服务器的行为可以在 Apache 配置文件(或.htaccess文件)中针对每个目录(<Directory>容器)、每个文件(<File>容器)或每个 URL(<Location>容器)进行微调。<Directory>(或<Location>)容器中的指令对目录本身及其所有子目录有效。大多数这些指令可以被外部配置文件覆盖,通常是.htaccess。出于安全和理智的原因,强烈建议不要这样做。AllowOverride的一些可能的指令是

None
不允许使用外部配置更改(最安全)
All
所有指令都可以更改(最不安全)
Limit
允许一些更改(根本不安全)
AuthConfig
主要可以更改与身份验证相关的指令
Options
主要可以覆盖Options指令

机器限制

[edit | edit source]

Order设置访问限制的顺序,其中最后一个匹配规则获胜。如果两个规则都不匹配或都匹配,最后一个规则也是默认规则。可能的Allow/Deny限制是主机名(host.domain.example)、域名(domain2.example)、ip(192.168.10.3)和网络(192.168.10 192.168.10.0/24)。

<Directory "/srv/httpd/htdocs">
    Options Indexes FollowSymLinks
    AllowOverride None
    Order allow,deny
    Allow from all
    Deny from example.com
</Directory>

允许来自任何地方的所有访问,但拒绝example.com域名。

基于用户的限制

[edit | edit source]

基于用户的访问限制在不同的级别上是不安全的

  • 密码未加密(危险:窥探)
  • 所有内容上传和下载都是明文(危险:窥探)
  • 无法保证服务器的身份(危险:欺诈/钓鱼)

Apache 灵活性的一个重要部分是它能够与不同的后端进行用户身份验证,最简单的是纯文本文件,这对于较少的用户来说是可以的,但不能扩展到超过(大约)150 人。

用户名、密码和组存储在文本文件中,通常称为.htpasswd.htgroup。这些名称在httpd.conf.htaccess中由指令AuthUserFileAuthGroupFile定义。这两个指令都是mod_auth模块的一部分。我们使用htpasswd实用程序创建/更改用户名和密码。-c选项会创建一个新的密码文件,如果这样的文件已经存在,它将被销毁,不会发出任何警告!htpasswd需要两个参数:密码和用户名。

root@lpislack# htpasswd -c /etc/httpd/htpasswd newuser
...

还有一件需要牢记的重要事项是,密码文件和组文件唯一安全的位置是DocumentRoot之外,在该位置,这些文件不会被未经授权的访问者意外地或恶意地下载。

回到现实,用.htaccess文件覆盖httpd.conf指令,并将.htpasswd.htgroup放在文档目录中,这通常是在网站管理员没有完全访问 Apache 配置权限的情况下进行的,例如在共享托管环境中。为了保护这些文件,可以在httpd.conf中指定的<Files>容器中限制对它们的访问

<FilesMatch "^\.ht">
    Order allow,deny
    Deny from all
    Satisfy All
</FilesMatch>

示例 1

[edit | edit source]

此示例显示了首选但遗憾的是并非始终可行的配置。受限制的目录是/srv/httpd/htdocs/private1,可以通过我的 Web 浏览器在http://lpislack.vbox.privat/private1/访问。

httpd.conf:

<Directory "/srv/httpd/htdocs/private1">
    AuthType Basic
    AuthName "Private1! Restricted Access!"
    require valid-user
    AuthUserFile /etc/httpd/htpasswd
</Directory>

在修改配置文件后,我们可能应该重新启动httpd服务器进程。

root@lpislack:/etc/httpd# /etc/rc.d/rc.httpd restart

创建密码文件htaccess

root@lpislack:/etc/httpd# htpasswd -c /etc/httpd/htpasswd firstuser
New password:
Re-type new password:
Adding password for user firstuser
root@lpislack:/etc/httpd# cat htpasswd
firstuser:2km7TAXpj3scw
root@lpislack:/etc/httpd#

此文件仅对授权(root!)用户可用。(顺便说一下,密码是tee2Seih。)

受密码保护的页面/srv/httpd/htdocs/private1/index.html源代码

root@lpislack:/srv/www/htdocs/private1# cat index.html
<html><body><h1>This is private!</h1></body></html>

示例 2

[edit | edit source]

此示例显示了常用的配置。它不是最好的,但有时是唯一可能的设置。如果我们可以将密码文件定位到DocumentRoot之外,我们可以做得好得多(安全得多)。这里受限制的目录是/srv/httpd/htdocs/private2,可以通过 Web 浏览器在http://lpislack.vbox.privat/private2/访问。

httpd.conf的唯一更改是允许AllowOverride。实际上,如果我们可以更改httpd.conf,我们一开始就可以做正确的事情(参见示例 1)。

<Directory "/srv/httpd/htdocs/private2">
    AllowOverride AuthConfig
</Directory>

设置外部配置文件.htaccess/srv/httpd/htdocs/private2/

    AuthType Basic
    AuthName "Private2! Restricted Access!"
    require valid-user
    AuthUserFile /srv/httpd/htdocs/private2/.htpasswd

重新启动httpd

root@lpislack:/etc/httpd# /etc/rc.d/rc.httpd restart

使用用户seconduser创建密码文件,密码为uu2yo1Wo

root@lpislack:/etc/httpd# htpasswd -c /srv/www/htdocs/private2/.htpasswd seconduser
New password:
Re-type new password:
Adding password for user seconduser
root@lpislack:/etc/httpd# cat /srv/www/htdocs/private2/.htpasswd
seconduser:2l.jKENGUwyQ6

模块和 CGI

[edit | edit source]

灵活性和易于扩展性是 Apache 成功的重要原因之一。它们部分是通过 CGI(=通用网关接口)概念和用模块扩展已编译的 Apache 实例的能力来实现的。CGI 程序(通常称为“CGI 脚本”)是可执行程序,可以用任何语言编写,无论是 bash、pearl、php、basic、汇编语言还是 ada。它们在服务器上运行,这会消耗服务器的硬件资源(RAM 和 CPU 时间),但不会影响客户端。他接收到的内容看起来像是任何静态HTML 页面,尽管 HTML 页面是通过 CGI 程序动态创建的。httpd接收 CGI 程序的输出,并将其未经更改和未经检查地提供给客户端 Web 浏览器。(例如,HTTP 标头必须由 CGI 程序来制作)。CGI 程序还可以接收用户输入(通过 PUT 或 GET 请求)。

示例

[edit | edit source]

bash脚本以难看的闪烁字母输出“不要在家尝试”,并将/etc/passwd的内容打印出来,以显示 CGI 编程有多危险!

#!/bin/sh
echo "Content-type: text/html"
echo ""
echo "<html>"
echo "<body>"
echo "<blink>DON'T TRY THIS AT HOME!</blink>"
cat /etc/passwd
echo "</body>"
echo "<html>"

模块

[edit | edit source]

另一方面,模块可以扩展httpd的功能,提供不是 Apache 主要源代码一部分的功能。(一些模块可以直接编译到httpd中。)可以使用httpd.conf中的简单更改来打开和关闭模块(例如出于安全原因)。大多数模块需要在httpd.conf中添加额外的配置指令,通常是通过导入配置文件来实现。

出于安全原因,我们只启用网站实际需要的模块。

一个非常有用的例子是mod_php。如果 PHP 代码被执行为一个简单的 CGI 脚本,每个脚本都会启动 PHP 解析引擎,生成 HTML 文本,然后关闭 PHP 解析引擎。

mod_php 将 PHP 引擎作为 Apache 进程的模块启动,PHP 引擎将被持久化到多个请求中。这极大地减少了使用 PHP 创建动态网站的开销。作为额外的奖励,我们可以在 HTTP 源代码中直接使用 PHP 代码。此代码也在服务器端运行,然后在将完整的 HTML 页面发送到客户端之前由其输出替换。如果我们使用数据库,如果我们使用mod_php,此连接也可以持久化。

PHP 语言本身由php.ini配置,位于/etc/httpd/,但此文件通常不需要更改。

要在 Slackware 13.0 上启用mod_php,我们只需要取消注释该行

Include /etc/httpd/mod_php.conf

/etc/httpd/httpd.conf中。这将直接将此已设置的配置包含到我们的httpd.conf中。

mod_php.conf:

LoadModule php5_module lib/httpd/modules/libphp5.so
AddType application/x-httpd-php .php

我们现在将AddType application/x-httpd-php更改为

AddType application/x-httpd-php .php .html .htm

在 HTML 文档中使用 PHP 代码。这可能很方便,但会显着增加高流量网站的工作量,因为每个请求的 HTML 页面都会被 PHP 解释器处理。我们还可以做的一件事是使生活更轻松,那就是将index.php添加到DirectoryIndex指令中。

现在我们重新启动httpd

要检查它是否有效,我们在DocumentRoot下创建testforphp.php

<html>
<head>
<title>Status for PHP</title>
</head>
<body>
<?php
phpinfo();
?>
</body>
</html>

现在删除此文件(或至少拒绝读取权限),因为这会将我们的整个 Web 服务器配置广播到整个互联网,世界上每个讨厌鬼都离我们只有几毫秒的距离。(尝试在 Google 中搜索intitle:phpinfo "PHP Version"...)

虽然 Slackware 13.0 附带perl作为可安装软件包,但/srv/www/cgi-bin中的最小测试 CGI 脚本printenv需要一些帮助。首先,我们需要通过以下方式将其标记为可执行文件:

root@lpislack:/srv/www/htdocs# chmod a+x ../cgi-bin/printenv

然后将第一行 "#!/usr/local/bin/perl" 更改为 "#!/usr/bin/perl"。现在我们可以使用 Web 浏览器导航到 http://lpislack.vbox.privat/cgi-bin/printenv 并查看它是否有效。

DOCUMENT_ROOT="/srv/httpd/htdocs"
GATEWAY_INTERFACE="CGI/1.1"
HTTP_ACCEPT="text/html, application/xml;q=0.9, application/xhtml+xml, image/png, image/jpeg, image/gif, image/x-xbitmap, */*;q=0.1"
HTTP_ACCEPT_CHARSET="iso-8859-1, utf-8, utf-16, *;q=0.1"
HTTP_ACCEPT_ENCODING="deflate, gzip, x-gzip, identity, *;q=0"
HTTP_ACCEPT_LANGUAGE="de-DE,de;q=0.9,en;q=0.8"
HTTP_CACHE_CONTROL="no-cache"
HTTP_CONNECTION="Keep-Alive, TE"
HTTP_HOST="lpislack.vbox.privat"
HTTP_TE="deflate, gzip, chunked, identity, trailers"
HTTP_USER_AGENT="Opera/9.80 (X11; Linux i686; U; de) Presto/2.2.15 Version/10.10"
PATH="/bin:/usr/bin:/sbin:/usr/sbin"
QUERY_STRING=""
REMOTE_ADDR="192.168.10.21"
REMOTE_PORT="40206"
REQUEST_METHOD="GET"
REQUEST_URI="/cgi-bin/printenv"
SCRIPT_FILENAME="/srv/httpd/cgi-bin/printenv"
SCRIPT_NAME="/cgi-bin/printenv"
SERVER_ADDR="172.25.28.4"
SERVER_ADMIN="[email protected]"
SERVER_NAME="lpislack.vbox.privat"
SERVER_PORT="80"
SERVER_PROTOCOL="HTTP/1.1"
SERVER_SIGNATURE=""
SERVER_SOFTWARE="Apache/2.2.14 (Unix) DAV/2 PHP/5.2.12"
UNIQUE_ID="S3ibiawZHAQAAAq2Hf0AAAAD"

我们目前不使用mod_perl,而是像运行任何其他可执行文件一样运行用 Perl 编写的 CGI 脚本。

所以mod_perl(来自 http://perl.apache.org)对 Perl 语言做了mod_php对 PHP 所做的同样的事情:它将本机语言支持直接添加到 Apache Web 服务器中,从而减少负载并加快响应时间。

遗憾的是,Slackware 13.0 没有预先构建的mod_perl软件包,但 http://slackbuilds.orghttp://slackbuilds.org/repository/13.0/network/mod_perl/ 为所有能够阅读说明的人提供了一个经过验证的构建脚本。(作为旁注,SlackBuilds 是从源代码构建 Slackware 软件包的首选方法。)

这种情况展示了模块的使用:Apache 中未包含的功能可以通过外部模块添加,而无需重新编译 Apache。如果 Apache 存在 bug 修复,并且我们需要升级,mod_perl仍然可以作为模块正常工作。如果mod_perl编译到 Apache 中,我们需要获取源代码,将其适合我们的设置,编译并安装它。每次更新都需要经历相同的过程,才能继续使用 Perl。

构建并安装软件包后,我们只需要将mod_perl.conf包含到httpd.conf中并重新启动 Apache 服务器。

mod_perl.conf:

LoadModule perl_module lib/httpd/modules/mod_perl.so
AddHandler perl-script pl
<Files *.pl>
     # mod_perl mode
     SetHandler perl-script
     PerlResponseHandler ModPerl::Registry
     PerlOptions +ParseHeaders
     Options +ExecCGI
</Files>

Perl 文件可以存在于DocumentRoot中的任何地方,并且它们的名称必须以 ".pl" 结尾。让我们回到printenv示例。如果我们再次调用它,它将仍然作为 CGI 执行,但如果我们将它复制到DocumentRoot并将其重命名为printenv.pl,它将由mod_perl运行,正如我们在下面的输出中看到的那样,MOD_PERLMOD_PERL_API_VERSION行清楚地表明了这一点。

DOCUMENT_ROOT="/srv/httpd/htdocs"
GATEWAY_INTERFACE="CGI/1.1"
HTTP_ACCEPT="text/html, application/xml;q=0.9, application/xhtml+xml, image/png, image/jpeg, image/gif, image/x-xbitmap, */*;q=0.1"
HTTP_ACCEPT_CHARSET="iso-8859-1, utf-8, utf-16, *;q=0.1"
HTTP_ACCEPT_ENCODING="deflate, gzip, x-gzip, identity, *;q=0"
HTTP_ACCEPT_LANGUAGE="de-DE,de;q=0.9,en;q=0.8"
HTTP_CONNECTION="Keep-Alive, TE"
HTTP_HOST="lpislack.vbox.privat"
HTTP_TE="deflate, gzip, chunked, identity, trailers"
HTTP_USER_AGENT="Opera/9.80 (X11; Linux i686; U; de) Presto/2.2.15 Version/10.10"
MOD_PERL="mod_perl/2.0.4"
MOD_PERL_API_VERSION="2"
PATH="/bin:/usr/bin:/sbin:/usr/sbin"
QUERY_STRING=""
REMOTE_ADDR="192.168.10.21"
REMOTE_PORT="45519"
REQUEST_METHOD="GET"
REQUEST_URI="/printenv.pl"
SCRIPT_FILENAME="/srv/httpd/htdocs/printenv.pl"
SCRIPT_NAME="/printenv.pl"
SERVER_ADDR="172.25.28.4"
SERVER_ADMIN="[email protected]"
SERVER_NAME="lpislack.vbox.privat"
SERVER_PORT="80"
SERVER_PROTOCOL="HTTP/1.1"
SERVER_SIGNATURE=""
SERVER_SOFTWARE="Apache/2.2.14 (Unix) DAV/2 PHP/5.2.12 mod_perl/2.0.4 Perl/v5.10.0"
UNIQUE_ID="S3i3VqwZHAQAAAxfFDUAAAAA"

限制资源使用

[编辑 | 编辑源代码]

Apache 能够为非常繁忙的网站提供服务。在高负载下提供快速响应时间的一种机制是让等待的进程随时准备投入使用。因此,与大多数其他程序不同,Apache 在启动时会生成多个进程。进程数量会根据连接数量进行调整,根据需要创建和销毁子进程。

一个控制进程监听新请求,通常在 TCP 端口 80 上,而每个客户端都连接到自己的子进程,该子进程在整个连接的生命周期内为请求提供服务。StartServers确定 Apache 启动时要开始的进程数量。但这意义不大,因为MinSpareServers设置了等待为新连接提供服务的空闲 Apache 进程的最小数量。如果剩下的空闲服务器少于此数量,它们将以每秒一个的速度创建。如果还不够,进程创建的速度会每秒加倍,直到每秒 32 个新进程。如果这仍然不够,我们肯定还有其他问题。另一方面,如果空闲服务器多于MaxSpareServers,则会逐一关闭不需要的进程。

MaxClients限制了同时运行的服务器进程的绝对数量,以及同时客户端连接的最大数量。256 的最大数量是在编译时设置的硬性限制。如果连接请求多于 Apache 进程来处理它们,请求将首先移至一个待处理队列,只有当这个待处理队列也填满时,请求才会被拒绝。

Apache(子)进程的生命周期可以通过他将服务连接的绝对数量来限制,如MaximumRequests定义的那样。这可以缓解在不太稳定的平台上出现内存泄漏时发生的问题,或者由有 bug 的模块或编写糟糕的 CGI 引起的故障。如果设置为0,子进程可以无限期地存在,只要它们没有因为空闲服务器过多而终止。

Redhat/CentOS

[编辑 | 编辑源代码]

安装

# yum install httpd

Web 服务器二进制文件名为httpd。控制脚本名为apachectl。访问和错误日志文件位于/var/log/httpd/,名为access_logerror_log

安装

# aptitude install apache2

Web 服务器二进制文件名为apache2。控制脚本名为apache2ctl,它不是另一个名称的apachectl。访问和错误日志文件位于/var/log/apache2/,名为access.logerror.log。(注意“.”而不是“_”。)

参考资料

[编辑 | 编辑源代码]
  1. "关于 Web 服务器使用情况的 Netcraft 报告". 检索于 2009-12-27.
华夏公益教科书