跳轉至內容

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 webadmin@your.site
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 webadmin@your.site
管理員的電子郵件地址,負責執行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="you@example.com"
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="webadmin@lpislack.vbox.privat"
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.
華夏公益教科書