APACHE 網頁伺服器
我們最常使用的網路應用莫過於網頁伺服器了, 這裡我們將介紹如何安裝一個功能完整的網頁伺服器。讀完本章後,您可以了解下列網頁伺服器的管理項目:
13.1 概論
Apache 是 UNIX 系統中普遍使用的網頁伺服器軟體。根據 Netcraft 的統計 (http://news.netcraft.com/archives/web_server_survey.html),目前網際網路中,有超過百分之六十的伺服器是使用 Apache 來提供網頁瀏覽的服務。Apache 可以說是目前世界上使用人數最多的網頁伺服器軟體,它不僅可以在 FreeBSD、UNIX、Linux 中運行,也可以安裝在 Windows 作業系統中。
Apache 和 FreeBSD 一樣,在軟體版本上也有多個分支,目前較穩定的版本有 1.3.33 及 2.0.x。Apache 1.3 系列開發已久,已經十分穩定了,不會再有重大的修改。而 Apache 2 系列是一個開發較活躍的版本,它和 1.3 最大的不同在於多執行緒 (multithreaded) 的支援。筆者建議您使用 Apache 2.2 來做為您的網頁伺服器。
Apache 之所以風行的原因,除了免費、歷史悠久、穩定外,它提供了彈性化的介面,可以讓我們依需求加入各種模組,以提供更強大的功能。例如,我們可以在網頁伺服器上加入 PHP,以支援更多的網頁應用。PHP 是一個用來寫網頁程式的軟體,就像 ASP、JAVA servlet、CGI 等等有類似的用途,我們可以使用 PHP 建立留言版、電子相簿、購物車等應用。PHP 十分容易學習,程式碼也很簡潔,速度更是沒話說。如果你有些微的程式語言基礎,不出二個禮拜,你就能對 PHP 有十足的認識,並且可以自己寫出留言版、權限控制等簡單的程式。
如果要使用 PHP,那你一定也要使用一套資料庫系統做為程式後端的資料儲存。在眾多免費的資料庫軟體中,最有名的應該是 MySQL 和 PostgreSQL 了。不論是 MySQL 或 PostgreSQL,它們的功能及速度都令人讚賞。使用 PHP 加上資料庫軟體,你可以製作出網頁的各式資料庫,如會員管理、產品資料庫等等。總之,我十分建議使用 Apache+PHP+資料庫的組合,就算目前不會用到,不久的將來也會使用它們的功能。全部一股腦的裝起來,省得日後麻煩。
13.2 安裝及設定 Apache
13.2.1使用 ports 安裝
使用 FreeBSD port 安裝 Apache 十分容易,我們只要使用下列指令即可完成安裝:
# cd /usr/ports/www/apache22 # make install clean
我們已經完成了最基本的 Apache 伺服器安裝,如果您不需要支援 PHP 及資料庫,可以跳過下列步驟。
安裝 PHP
# cd /usr/ports/lang/php5 # make install clean
執行了上述指令後,會出現一個視窗讓您選擇進階設定,我們將使用 Apache module 而不使用 CGI 模式。如下圖所示:
圖 13-1
接下來我們必須安裝一些常用的 PHP 模組,請執行下列指令:
# cd /usr/ports/lang/php5-extensions # make install clean
執行了 make install 後,會出現一個選單,除了預設的項目外,我們必須再選擇下列幾個常用的項目:CTYPE、EXIF、GD、ICONV、IMAP、PCRE、SESSION、ZLIB。這些項目非常常用,尤其是 SESSION。
安裝完 PHP 後,我們將下來要安裝資料庫,您可以選擇安裝 MySQL 或 PostgreSQL,或者乾脆二者都安裝,以利日後使用不同的資料庫應用。
安裝 MySQL
# cd /usr/ports/databases/mysql50-server # make WITH_CHARSET=big5 WITH_XCHARSET=all install clean # cd /usr/ports/databases/php5-mysql # make install clean
安裝 PostgreSQL
# cd /usr/ports/databases/postgresql82-server # make install clean # cd /usr/ports/databases/php5-pgsql # make install clean
安裝了 MySQL 及 PostgreSQL 後,必須再進行資料庫的細部設定。相關的資料庫詳細設定說明,請參考「資料庫系統」一章的說明。
13.2.2 Apache 基本設定
安裝完 Apache 後,我們必須先進行一些基本設定才可以開始使用。本節中,我們先介紹較常使用的設定項目,讓您可以快速的設定好網頁伺服器,而更詳細的 Apache 設定將於下一小節中說明。Apache 的設定檔位於 /usr/local/etc/apache22/httpd.conf,請使用文章編輯軟體打開 httpd.conf。
我們按照設定項目在 httpd.conf 中出現的順序說明每一個項目,您可以使用搜尋的方式查找每一個項目的關鍵字,以進行設定。
ServerAdmin 設定管理者郵件
設定您的信箱,這個信箱位址當網頁出現錯誤訊息時將出現在該頁面上。以下範例為預設值:
ServerAdmin you@example.com |
ServerName 設定主機名稱及埠號
ServerName 可以讓您設定您的主機名稱,如果您沒有主機名稱,可以設定為您機器所使用的 IP。ServerName 會被用來重新轉向網址,例如,當您輸入一個網址 「http://www.example.com/dir」時,Apache 會參考您在 ServerName 中的設定,將 www.example.com 改成 ServerName,並在您所輸入的網址後加上一個斜線「/」以連到 dir 目錄中,也就是將網址轉向到「http://www.example.com/dir/」。如果您的網址設定不正確,則使用者可能會連到一個不存在的位址。
所以,如果您沒有主機名稱,可以將這個值設定為 IP,讓網址轉向後還是可以連到正確的地方。在 ServerName 的設定中,我們也指定了 HTTP 的連接埠 80。
如果您的伺服器是位於 NAT 後面,使用 NAT 做 Port Forwarding,建議不要設定這個項目,改將下一個設定選項 UseCanonicalName 設為 On,才不會在轉向網址時導到錯誤的位置。
ServerName www.example.com:80 |
DocumentRoot 設定網頁根目錄
DocumentRoot 可以讓我們指定網頁根目錄的位置,也就是我們存放網頁的目錄。
DocumentRoot "/usr/local/www/data" |
設定好 DocumentRoot 後,我們必須要再設定該目錄的權限。在 DocumentRoot 之後,有下列區段:
<Directory "/usr/local/www"> Options Indexes FollowSymLinks AllowOverride None Order allow,deny Allow from all </Directory> |
您必須將 <Directory "/usr/local/www"> 也改成您的網頁根目錄位置。
DirectoryIndex 指定預設網頁檔名
當使用者使用網址「http://www.example.com/dir」連到一個目錄中時,如果沒有指定網頁,Apache 會去查找 DirectoryIndex 中所設定的網頁在不在,如果存在則秀出預設的網頁。
預設的網頁只有二個,我們可以再加上 index.htm、index.php 等常用的網頁:
DirectoryIndex index.php index.htm index.html index.html.var |
加入 PHP 支援
如果您要使用 PHP,則必須在 httpd.conf 中加入 PHP 的支援,請在 httpd.conf 檔案最後加入下列內容:
AddType application/x-httpd-php .php AddType application/x-httpd-php-source .phps |
上述設定完成後,您就可以存檔離開。
接下來,我們必在修改 /etc/rc.conf ,並加入下列設定以在開機時啟動 Apache:
apache22_enable="YES" |
最後,我們就可以使用下列指令以啟動 Apache 了:
# /usr/local/etc/rc.d/apache22 start
如果您要停止 Apache,可以使用下列指令:
# /usr/local/etc/rc.d/apache2 stop
我們可以在網頁根目錄中新增一個檔案來測試 PHP 是否有正常運作,請使用文書編輯軟體開一個新檔 test.php,並加入下列內容:
<? phpinfo(); ?> |
接下來您就可以連到該網頁 http://192.168.0.1/test.php (請將 192.168.0.1 改成您的主機 IP) 看看是否可以使用 PHP。如果有支援 PHP,則會顯示 PHP 組態,如果沒有,則只會出現上述檔案內容。
13.3 http.conf 說明
/usr/local/etc/apache2/httpd.conf 是 Apache 的主要設定檔。檔案中有 # 為開頭者是註解,用以說明設定的情形及方式,如果一行的開頭有 # 的話,該行對 Apache 就不會產生作用。
我們按照 httpd.conf 中各選項出現的順序說明幾個重要的項目,比較不可能更動的項目我們就不在此說明。這些細部 Apache 的設定看起來有點無趣,但不看過一遍不知道有什麼是我們可以調整的項目。建議您先大略瀏覽過即可,日後有調整的需要時,再回過頭來參考即可。
ServerRoot 設定 Apache 執行的根目錄
ServerRoot 用以設定 Apache 的根目錄位置,記錄檔、設定檔的相對目錄位置。
ServerRoot "/usr/local" |
必須注意的是,如果您的此目錄設定為 NFS 或是其它以網路掛入的檔案系統中,請先閱讀 http://httpd.apache.org/docs-2.0/mod/mpm_common.html#lockfile 關於 LockFile 的說明,以避免一些不必須的問題發生。另外,請勿在 ServerRoot 的路徑名稱最後面加入 "/" 符號。
LockFile 設定 lock 檔的位置
LockFile 通常只有在您的網頁資料使用 NFS 掛入時才會需要設定,否則使用預設值即可。如果您有設定 LockFile,LockFile 必須設定在非網路掛入的檔案系統中。
<IfModule !mpm_winnt.c> <IfModule !mpm_netware.c> #LockFile /var/log/accept.lock </IfModule> </IfModule> |
我們看到 LockFile 這個項目被 <IfModule !mpm_winnt.c> </IfModule> 包起來,這表示當沒有使用 winnt 模組時這個設定才會生效。在下列其它設定中,我們會看到有其它的選項也是以 <IfModule> </IfModule> 包起來,意思是一樣的。
PidFile 設定 httpd.pid 位置
Apache 在啟動時,會將自己的 process id 寫入 PidFile 中。
<IfModule !mpm_netware.c> PidFile /var/run/httpd.pid </IfModule> |
Timeout 設定連線逾時
Timeout 設定了等待 Client 端回應的時間,以秒為單位。如果 Client 端在指定的時間內沒有傳送任何資料,即切斷連線。
Timeout 300 |
KeepAlive 是否使用保持連線
設定是否使用保持連線的功能 (Presistent Connections)。當 KeepAlive 設為 On 時,一個已經建立的連線會用來處理多個 HTTP 的請求,也就是一個連線會用來傳送多個檔案,以避免每一個請求都要重新建立新的連線而降低效能。您可以將 KeepAlive 設為 Off 以關閉保持連線的功能。
KeepAlive On |
MaxKeepAliveRequests 最多有幾個保持連線
設定最多可以有幾個 KeepAlive 的連線。您可以將這個項目設為 0 表示無限制。當有太多的保持連線時,會造成系統資源佔用太多。但如果是一個忙錄的伺服器,建議您提高限制,以增加執行效率。
MaxKeepAliveRequests 100 |
KeepAliveTimeout 保持連線的逾時時間
同一個 Client 的「保持連線」功能,在多少秒後沒有連線的請求即為連線逾時。如果二次請求的時間超過這個設定值,連線就會中斷。
KeepAliveTimeout 15 |
prefork MPM 控制 process 數量
您會看到有很多個 StartServers、MinSpareServers、MaxClients 等設定,每個設定都使用 <IfModule> </IfModule> 包起來。這是因為不同的平台會使用不同的模組,而設定就會依平台而有所不同。在 FreeBSD 中,我們使用的是 perfork 這個模組,因此,我們只要設定這個模組中的值即可。
在這個群組中,各個項目所代表的意義如下:
<IfModule prefork.c> StartServers 5 MinSpareServers 5 MaxSpareServers 10 MaxClients 150 MaxRequestsPerChild 0 </IfModule> |
Listen 設定接受連線的 IP 及埠號
設定 Apache 所要使用的連接埠號。預設的 HTTP 連接埠為 80,我們使用預設值即可,所以我們使用預設值即可。如果您希望 Apache 只接受連到某一個 IP 的連線 (當您同一台主機有多個 IP 時),可以設定只監聽某一個 IP、埠號的連線。
例如,我們可以設定只接受客戶端連到 192.168.0.1 的連接埠 8000,則可以設定為 192.168.0.1:8000。
Listen 80 |
LoadModule 動態載入的模組
Apache Dynamic Shared Object (DSO) 允許我們在啟動 Apache 時動態載入模組,例如載入認證模組、PHP 模組等。在這個區段中,您可以看到 Apache 載入了很多模組。我們之後在設定虛擬主機、目錄模限控制時,都必須檢查 Apache 是否有載入我們想要的模組。這個部份的設定只要保持預設值即可。
LoadModule access_module libexec/apache2/mod_access.so LoadModule auth_module libexec/apache2/mod_auth.so LoadModule auth_anon_module libexec/apache2/mod_auth_anon.so LoadModule auth_dbm_module libexec/apache2/mod_auth_dbm.so ... 略 ... |
ExtendedStatus 顯示詳細狀態資訊
Apache 有一個 CGI 可以顯示 Apache 伺服器的狀態資訊 (server-status),當 ExtendedStatus 打開後,會顯示更多資訊。我們會在本章下一小節中說明如何使用這些資訊。
#ExtendedStatus On |
首先,請開啟你的 httpd.conf,然後找到以下兩行、並去除前面的註解符號:
#LoadModule info_module modules/mod_info.so
#LoadModule status_module modules/mod_status.so
接著,請找以下這段,並且同樣的去除註解符號:
#<Location /server-info>
# SetHandler server-info
# Order deny,allow
# Deny from all
# Allow from [你的網域]
#</Location>
[你的網域] 代表你自己的網域,請依照實際狀況來設定就對了。
再來請找以下這段,一樣去除註解、[你的網域] 一樣也是根據實際情況來設定:
#<Location /server-status>
# SetHandler server-status
# Order deny,allow
# Deny from all
# Allow from [你的網域]
#</Location>
最後請找這一行,並去除註解符號:
#ExtendedStatus On
存檔後就大功告成了!請記得重新啟動伺服器,然後就可以看成果囉!
沒有做其他更改的話,預設的網址應該是這樣:
User Group 設定執行時的使用者及群組
系統要使用什麼使用者名稱及群組執行 Apache。使用 FreeBSD ports 安裝後,預設的使用者及群組為 www。
User www Group www |
ServerAdmin 設定郵件
設定您的 Email。這個 Email 會顯示在一些由 Apache 所產生的頁面中。例如,當使用者連到一個不存在的網頁、或是網頁發生錯誤時,Apache 會秀出您所設定的 Email。
ServerAdmin you@example.com |
ServerName 設定主機名稱
ServerName 可以讓您設定您的主機名稱,如果您沒有主機名稱,可以設定為您機器所使用的 IP。ServerName 會被用來重新轉向網址,例如,當您輸入一個網址 「http://www.example.com/dir」時,Apache 會參考您在 ServerName 中的設定,將 www.example.com 改成 ServerName,並在您所輸入的網址後加上一個斜線「/」以連到 dir 目錄中,也就是將網址轉向到「http://www.example.com/dir/」。如果您的網址設定不正確,則使用者可能會連到一個不存在的位址。
所以,如果您沒有主機名稱,可以將這個值設定為 IP,讓網址轉向後還是可以連到正確的地方。在 ServerName 的設定中,我們也指定了 HTTP 的連接埠 80。
如果您的伺服器是位於 NAT 後面,使用 NAT 做 Port Forwarding,建議不要設定這個項目,改將下一個設定選項 UseCanonicalName 設為 On,才不會在轉向網址時導到錯誤的位置。
ServerName www.example.com:80 |
DocumentRoot 設定網頁根目錄
DocumentRoot 可以讓我們指定網頁根目錄的位置,也就是我們存放網頁的目錄。除非您有使用 symbolic links 或是 aliases,否則所有的網頁都會放在這個目錄中。
DocumentRoot "/usr/local/www/data" |
<Directory> 設定目錄權限
接下來的幾個區段中,您會看到 <Directory> </Directory> 的設定。這個設定是用來指定某個目錄的存取權限,例如是否允許執行 CGI、是否要列出該目錄下的所有檔案等等。
我們以之前所設定的網頁根目錄「DocumentRoot」為例,當您修改了網頁根目錄後,您也必須將這個區段中的 <Directory "/usr/local/www"> 改成您的網頁目錄。由於 Apache 將一般的網頁和 CGI 分別放在不同的目錄,所以您的 DocumentRoot 設定和這裡的設定稍有不同。但您可以將 <Directory> 及 DocumentRoot 都改成 /home/www。
<Directory "/usr/local/www"> # # Possible values for the Options directive are "None", "All", # or any combination of: # Indexes Includes FollowSymLinks SymLinksifOwnerMatch ExecCGI MultiViews # # Note that "MultiViews" must be named *explicitly* --- "Options All" # doesn't give it to you. # # The Options directive is both complicated and important. Please see # http://httpd.apache.org/docs-2.0/mod/core.html#options # for more information. # Options Indexes FollowSymLinks # # AllowOverride controls what directives may be placed in .htaccess files. # It can be "All", "None", or any combination of the keywords: # Options FileInfo AuthConfig Limit # AllowOverride None # # Controls who can get stuff from this server. # Order allow,deny Allow from all </Directory> |
我們後續再來說明一下 <Directory> </Directory> 這個區段中每個項目的用途。
Options 設定目錄可以使用的功能
我們在 <Directory> </Directory> 中指定了要設定哪一個目錄後,可以再使用 Option 來設定該目錄可以使用哪些功能。以下為功能的列表及說明:
當我們對目錄設定 Option 的項目後,它的子目錄也會繼承該目錄的設定值。如果我們同時設定一個目錄及其子目錄的 Option 的設,會以最接近的目錄設定為主。例如,我們為 /home/www 及 /home/www/photo 設定權限如下:
<Directory /home/www> Options Indexes FollowSymLinks </Directory> <Directory /home/www/photo> Options Includes </Directory> |
我們設定了 /home/www 可以使用 Indexes 及 FollowSymLinks,但 /home/www/photo 只能使用 Includes。雖然 /home/www/photo 是 /home/www 的子目錄,但是其目錄的設定只會以自己的 Options 為主,也就是不具有 Indexes 及FollowSymLinks,只有 Includes 的權限。
如果您希望子目錄可以繼承上一層的設定,可以使用 + 及 - 的符號表示。例如:
<Directory /home/www> Options Indexes FollowSymLinks </Directory> <Directory /home/www/photo> Options +Includes -Indexes </Directory> |
我們在 /home/www/photo 的 Option 中使用了 + 及 -,所以它會繼承 /home/www 的設定,但是加上 Includes 的功能,並取消 Indexes,所以最後 /home/www/photo 的權限就是 Includes 及 FollowSymLinks。
AllowOverride 設定 .htaccess 中可以使用的項目
Apache 允許使用者對於目錄中使用 .htaccess 檔來控制權限,例如使用密碼保護、設定權限等。我們會在下一章中說明如何使用 .htaccess 來做密碼保護。
您可以將 AllowOverride 設成 All 或 None 來表示允許或不允許。或者,您也可以指定只允許下列某幾個功能:
Order 設定 Allow 及 Deny 的順序
我們可以在目錄中設定允許 (Allow) 及拒絕 (Deny) 的規則先後順序,當二者抵觸時,以後者為主。以下列範例為例,我們先設定了 Order 為 Deny, Allow,再設定拒絕所有連線,但只允許 192.168.0.2 來存取 /home/www/mp3。
<Directory /home/www/mp3> Order Deny,Allow Deny from all Allow from 192.168.0.2 </Directory> |
UserDir 設定使用者個人網頁
在 mod_userdir 區段中,包含了使用者個人網頁的設定。使用者可以使用 http://www.example.com/~username 連到個人網頁。預設的設定是每個使用者都可以在自己的家目錄中建立一個名為 putblic_html 的目錄,該目錄就使用者的個人網頁目錄。UserDir 這個項目即定義了使用者個人網頁的路徑名稱。如果您覺得這個名稱太長,更改它的設定,但記得要修改 <Directory> 中的相對設定。
如果您不想讓使用者有個人網頁,可以將這個區段前面使用 # 註解起來。
<IfModule mod_userdir.c> UserDir public_html UserDir disabled root toor daemon ..... pop www nobody mailnull smmsp # # Control access to UserDir directories. The following is an example # for a site where these directories are restricted to read-only. # <Directory /home/*/public_html> AllowOverride FileInfo AuthConfig Limit Indexes Options MultiViews Indexes SymLinksIfOwnerMatch IncludesNoExec <Limit GET POST OPTIONS PROPFIND> Order allow,deny Allow from all </Limit> <LimitExcept GET POST OPTIONS PROPFIND> Order deny,allow Deny from all </LimitExcept> </Directory> </IfModule> |
DirectoryIndex 設定預設網頁檔名
當使用者使用網址「http://www.example.com/dir」連到一個目錄中時,如果沒有指定網頁,Apache 會去查找 DirectoryIndex 中所設定的網頁在不在,如果存在則秀出預設的網頁。
預設的網頁只有二個,我們可以再加上 index.htm、index.php 等常用的網頁:
DirectoryIndex index.php index.htm index.html index.html.var |
HostnameLookups 設定將客戶端 IP 轉為 hostname
是否要在 Apache 的記錄檔中將 Client 的 IP 轉成 hostname。由於將 IP 轉成 hostname 需要一點時間,將這個功能設為 On 會造成連線的效率變慢很多。
HostnameLookups Off |
ErrorLog 指定錯誤記錄檔位置
設定 Apache 錯誤訊息的記錄檔位置。
ErrorLog /var/log/httpd-error.log |
CustomLog 指定連線記錄檔位置
設定 Apache 連線記錄檔的位置。
CustomLog /var/log/httpd-access.log combined |
Alias 設定別名
我們可以為一個目錄或連線的 URI 設定別名,以簡化目錄名稱。例如,您可以將 /home/alex/mp3/ 取一個別名為 /mp3/,讓使用者在連線到 http://www.example.com/mp3/ 時,指向 /home/alex/mp3/。
Alias /mp3/ /home/alex/mp3/ |
別名可以設定很多個,您可以依需求簡化連結的位置。設定的別名目錄不一定要是 DocumentRoot 的子目錄,我們可以指定網頁根目錄以外的目錄。
|
AliasMatch 使用常規表示的別名
除了一般的別名外,我們還可以使用常規表示來設定別名。例如,我們要設定所有要使用 *.php 的檔案都連到 /usr/local/php 目錄中,則可以使用:
AliasMatch ^(.+\.php)$ /usr/local/php$1 |
ScriptAlias 設定 CGI 目錄
ScriptAlias 可以讓我們設定 CGI 的所在目錄,它的功用其實看 Alias 差不多。下面的範例就是當使用者要連到 http://www.example.com/cgi-bin/ 時,我們將 cgi-bin 指向 /usr/local/www/cgi-bin/ 目錄中。
ScriptAlias /cgi-bin/ "/usr/local/www/cgi-bin/" |
ErrorDocument 指定錯誤訊息頁面
當使用者連到一個不存在的網頁,或是網頁發生錯誤時,Apache 預設會幫我們產生一個錯誤訊息的網頁。我們可以修改這個設定,以秀出我們自己設定的頁面。例如,當您連到 YAHOO! 時,如果網頁不存在,它的頁面中還是秀出一些 YAHOO 自己的資訊。
在 ErrorDocument 之後,首先要加的是錯誤代碼。錯誤代碼 404 在 HTTP 協定中表示找不到頁面。在下列設定中,我們設定當找不到頁面時,就秀出 /missing.html。/missing.html 的「/」指的並非系統的根目錄,而是您網頁的根目錄。
ErrorDocument 404 /missing.html |
|
13.4 PHP 進階設定
php.ini 是 PHP 的設定檔,若您使用 ports 安裝,則你必須將設定檔範例 /usr/local/etc/php.ini-dist 複製成 /usr/local/etc/php.ini。我們可以經由修改 php.ini 來調整 PHP 的功能。
在 php.ini 中,開頭為 ";" 的項目為註解、以 [ ] 包起來的是區段的名稱,二種都不會代表任何意義。在修改完 php.ini 後,我們必須也要重跑 Apache 才可以有作用。
以下就讓我們針對最常調整的幾個項目做說明。
max_execution_time
這個選項設定了 PHP scripts 最長的執行時間,如果您的 PHP 程式需要執行很長的時間,則可以將它延長。預設的最長執行時間是 30 秒。
max_execution_time = 30 |
memory_limit
設定每一個 scripts 所能耗用的記憶體大小,預設是 8 MB。
memory_limit = 8M |
error_reporting
預設的錯誤回報內容為何。這個選項設定了 PHP scripts 在發生何種錯誤時要回報訊息。預設是除了 NOTICE 及 STRICT 的錯誤以外都回報。這個選項的設定使用了 bit operation,在 php.ini 運算表示式可以使用「|」表示 bit OR、「&」表示 AND、「~」表示 NOT。以下列範例而言,就是 E_ALL AND (NOT E_NOTICE) AND (NOT E_STRICT)。
error_reporting = E_ALL & ~E_NOTICE & ~E_STRICT |
error_log
我們可以將錯誤訊息記錄在檔案中,或是使用 syslog 將錯誤記錄在 /var/log/messages 中。以下的範例即是使用 syslog。
error_log = syslog |
register_globals
PHP 自從 4.1.0 開始,支援一種比較安全的變數傳遞方式。原本我們在寫 PHP 程式時,從表單以 POST 方式傳入 PHP 程式時,PHP 可以直接拿來使用。例如,有一個表單是下面這個樣子:
<form action=test.php method=post> <input type=text name=username size="20"> <input type=button value=送出 name=b1> </form> |
當上述的 HTML 按了送出之後,在 test.php 這個程式就會有一個變數名為 $username,其值是我們所填入的名稱。
但是使用者也可以直接在網址列輸入 http://url/test.php?username=myname 來設定 $username 這個變數的值為 myname。
這會有什麼問題呢?讓我們以 PHP 4.1.0 release note 所提出的例子來說明。假設我們有一個程式如下:
<?php if (authenticate_user()) { $authenticated = true; } ... ?> |
使用者可以經由網址列輸入一個變數 $authenticated=true,這樣一來,不管是否通過 authenticate_user() 的檢查,$authenticated 永遠都是 true。
所以在 4.1.0 之後,有一個新的方式可以讓我們使用,就是將傳進來的變數全部都存在陣列中。以第一個例子而言,我們以 POST 的方式從表單傳來變數 $username,新的取得變數方式是:$_POST["username"],也就是說所有以 POST 傳遞過來的變數全部存在 $_POST 這個陣列中。詳細說明請參考 http://www.php.net/release_4_1_0.php 。
在 4.2.0 之前,新舊二種方式都可以使用,但是在 4.2.0 之後,Default 只能使用新的方式來傳遞變數。所以如果你安裝的了新 PHP 而發現無法使用舊的 PHP 程式,別驚訝。
如果您還是要以舊的方式來傳遞變數,請修改 php.ini,將原本的 register_globals = Off 改成下列這個樣子,並移除開頭的註解符號 ";":
; register_globals = Off register_globals = On |
post_max_size
當使用者從網頁中使用 HTML FORM 以 POST method 送出資料時,最大的資料上限為何。預設值是 8 MB。
error_log = syslog |
file_uploads
是否允許使用者以 HTTP 上傳檔案。預設為 On。
file_uploads = On |
upload_max_filesize
當使用者從網頁中使用 PHP 上傳檔案時,檔案最大的大小為何。預設是 2 MB。
upload_max_filesize = 2M |
13.5 Apache 伺服器狀態與管理
身為系統管理者,必須時常查看系統狀態,檢查、注意主機是否有異常的情形發生。Apache 提供了詳細的系統記錄檔,我們可以經由這些檔案了解伺服器、網頁是否有異常的情形。另外,Apache 也提供了一些工具,可以讓我們了解伺服器的運作情形。
13.5.1 Apache 狀態資訊
在安裝完 Apache 後,如果您所管理的是一個大型的網頁伺服器,您一定會需要了解伺服器的系統負荷是否足以處理龐大的網路流量。Apache 內建了 server-status 及 server-info 二種觀看伺服器資訊的方法。
server-status 伺服器狀態資訊
server-status 可以讓我們了解 Apache 目前運作的情形,包括佔用的系統資源、目前連線數量等。在使用 server-status 之前,我們必須先修改 httpd.conf,以打開此功能。
首先,請先修改 httpd.conf,打開下列這一行:
# Real-time info on requests and configuration Include etc/apache22/extra/httpd-info.conf |
接著,修改 /usr/local/etc/apache22/extra/httpd-info.conf:
# # Get information about the requests being processed by the server # and the configuration of the server. # # Required modules: mod_status (for the server-status handler), # mod_info (for the server-info handler) # # Allow server status reports generated by mod_status, # with the URL of http://servername/server-status # Change the ".example.com" to match your domain to enable. <Location /server-status> SetHandler server-status Order deny,allow Deny from all Allow from .example.com </Location> # # ExtendedStatus controls whether Apache will generate "full" status # information (ExtendedStatus On) or just basic information (ExtendedStatus # Off) when the "server-status" handler is called. The default is Off. # ExtendedStatus On |
我們將 ExtendedStatus 設為 On,以顯示詳細的伺服器狀態。接著在 server-status 區段中,我們設定了 Deny、Allow,以限制只有從某個地方連線進來的使用者可以查看伺服器狀態。在上述的範例中,我們限制只有從 192.168.0.x 的使用者才可以看到 server-status。
修改完 httpd.conf 後,我們必須使用下列指令重新啟動 Apache:
# /usr/local/etc/rc.d/apache22 restart
接下來,我們就可以使用瀏覽器連到 http://192.168.0.1/server-status。請將 192.168.0.1 改成您的主機 IP。連到 server-status 後,您可以看到下列畫面:
圖 13-2
server-status 的輸出中每個欄位所代表的意義如下:
欄位 | 說明 |
Server Version | Apache 伺服器的版本。 |
Server Built | Apache 伺服器編譯安裝的時間。 |
Current Time | 目前的系統時間。 |
Restart Time | Apache 重新啟動的時間。 |
Parent Server Generation | Apache 父程序 (parent process) 的世代編號,就是 httpd 接收到 SIGHUP 而重新啟動的次數。 |
Server uptime | Apache 啟動後到現在經過的時間。 |
Total accesses | 到目前為此 Apache 接收的連線數量及傳輸的資料量。 |
CPU Usage | 目前 CPU 的使用情形。 |
_SWSS.... | 所有 Apache process 目前的狀態。每一個字元表示一個程序,最多可以顯示 256 個程序的狀態。 |
Scoreboard Key | 上述狀態的說明。以下為每一個字元符號所表示的意義:
|
Srv | 本程序與其父程序的世代編號。 |
PID | 本程序的 process id。 |
Acc | 分別表示本次連線、本程序所處理的存取次數。 |
M | 該程序目前的狀態。 |
CPU | 該程序所耗用的 CPU 資源。 |
SS | 距離上次處理要求的時間。 |
Req | 最後一次處理要求所耗費的時間,以千分之一秒為單位。 |
Conn | 本次連線所傳送的資料量。 |
Child | 由該子程序所傳送的資料量。 |
Slot | 由該 Slot 所傳送的資料量。 |
Client | 客戶端的位址。 |
VHost | 屬於哪一個虛擬主機或本主機的 IP。 |
Request | 連線所提出的要求資訊。 |
我們在查看 server-status 時,可以在輸入的網址中加上參數 refresh 來讓網頁自動更新。例如,您可以輸入 http://192.168.0.1/server-status?refresh=5,讓網頁每 5 秒鐘自動重新載入。
server-info 伺服器組態資訊
server-info 和 server-status 的設定類似,我們可以經由 server-info 知道 Apache 的組態資訊,包括版本、載入的模組等。
同樣的,在使用 server-info 之前,我們必須先修改 httpd.conf,以打開此功能。
# Real-time info on requests and configuration Include etc/apache22/extra/httpd-info.conf |
接著,修改 /usr/local/etc/apache22/extra/httpd-info.conf:
... # # ExtendedStatus controls whether Apache will generate "full" status # information (ExtendedStatus On) or just basic information (ExtendedStatus # Off) when the "server-status" handler is called. The default is Off. # ExtendedStatus On # # Allow remote server configuration reports, with the URL of # http://servername/server-info (requires that mod_info.c be loaded). # Change the ".example.com" to match your domain to enable. # <Location /server-info> SetHandler server-info Order deny,allow Deny from all Allow from 192.168.0. </Location> ... |
我們找到 server-info 的區段,並移除開頭的 #。在 server-info 區段中,我們一樣設定了 Deny、Allow,以限制只有從某個地方連線進來的使用者可以查看伺服器組態設定。
修改完 httpd.conf 後,我們必須使用下列指令重新啟動 Apache 才可以使用:
# /usr/local/etc/rc.d/apache22 restart
最後您就可以使用 http://192.168.0.1/server-info 連到 Apache 的伺服器組態資訊頁面:
圖 13-3
在 server-info 中,我們可以看到最上方是 Apache 所有己載入的模組資訊,接著是 Apache 主要的設定狀態,而最下方是目前 Apache 設定檔和預設值不同的地方。在本頁面的其它部份為每一個已載入的模組狀態供您參考。
13.5.2 效能測試
Apache 提供了一個測試 Apache 效能的工具 - ab。你可以使用 ab 針對某個 URL 來模擬出連續的連線請求 (不限本地主機),並設定同時間要模擬多少連線。
以下為 ab 這個指令比較常用的參數說明:
參數 | 說明 |
-n requests | 要做多少次連線請求,requests 為次數。 |
-c concurrency | 同時有多少個連線,concurrency 為個數。 |
-t timelimit | 最多等待回應的秒數。 |
-p postfile | 要以 POST 方法連線所欲送出的參數檔案。postfile 為存放參數的檔案名稱。 |
例如,我要對自己的機器中的 index.php 作測試,模擬 1000 次請求,每次最多同時 20 個連線,只要在命令列執行指令:
# /usr/local/sbin/ab -n 1000 -c 20 http://127.0.0.1/index.php
等了幾秒之後出現:
This is ApacheBench, Version 2.0.40-dev <$Revision: 1.146 $> apache-2.0 Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/ Copyright 2006 The Apache Software Foundation, http://www.apache.org/ Benchmarking 127.0.0.1 (be patient) Completed 100 requests Completed 200 requests Completed 300 requests Completed 400 requests Completed 500 requests Completed 600 requests Completed 700 requests Completed 800 requests Completed 900 requests Finished 1000 requests Server Software: Apache/2.2.4 Server Hostname: 127.0.0.1 Server Port: 80 Document Path: /index.php Document Length: 9764 bytes Concurrency Level: 20 Time taken for tests: 4.534259 seconds Complete requests: 1000 Failed requests: 0 Write errors: 0 Total transferred: 10189000 bytes HTML transferred: 9764000 bytes Requests per second: 220.54 [#/sec] (mean) Time per request: 90.685 [ms] (mean) Time per request: 4.534 [ms] (mean, across all concurrent requests) Transfer rate: 2194.40 [Kbytes/sec] received Connection Times (ms) min mean[+/-sd] median max Connect: 0 1 1.3 2 9 Processing: 9 85 15.9 83 221 Waiting: 8 59 22.2 62 181 Total: 10 87 16.0 85 221 Percentage of the requests served within a certain time (ms) 50% 85 66% 87 75% 89 80% 91 90% 100 95% 115 98% 135 99% 154 100% 221 (longest request) |
您可以增加最多同時連線數目及連線次數,操看看你機器的上限在哪裡。
還有更多的參數,詳細用法請 man ab。
13.5.3 維護伺服器記錄檔
查看伺服器記錄檔可以讓我們了解伺服器的運作情形。Apache 預設會有二個記錄檔,一個是所有連線的記錄,預設的名稱是 /var/log/httpd-access.log;另一個是連線錯誤記錄檔,預設的位置是 /var/log/httpd-error.log。記錄檔的位置及檔名是由 httpd.conf 決定,如果您修改過記錄檔的設定,則路徑可能就不太一定。以下為 httpd.conf 關於記錄檔的設定:
... ErrorLog /var/log/httpd-error.log ... LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined LogFormat "%h %l %u %t \"%r\" %>s %b" common LogFormat "%{Referer}i -> %U" referer LogFormat "%{User-agent}i" agent ... CustomLog /var/log/httpd-access.log combined ... |
我們來看一下 httpd-access.log 的內容:
圖 13-4
我們截取一條記錄加以說明。第一行開頭的部份是客戶端的 IP,接下來是連線的時間、所查看的網頁、及所使用的作業系統、瀏覽器等。在存取記錄中要顯示什麼資訊是由 httpd.conf 中的 LogFormat 所控制。因為我們設定了 CustomLog 所使用的格式是 combined,而 combined 在 LogFormat 中的設定就是顯示上述格式。LogFormat 的格式中,每一個欄位使用都可以用 %X 表示,例如 %h 表示客戶端的 IP。
基本上我們比較少直接查看 access log,我們會使用一些外掛軟體來析記錄檔。例如,統計每個網頁的使用量、哪一個網頁最常被存取、每天有多少連線等等。下一章中,我們會介紹如何安裝使用網頁分析軟體。
我們可能比較常看的是錯誤記錄檔。經由查看錯誤記錄檔,我們可以知道網頁中沒有有連結是壞的、使用者有沒有嘗試連到一個不存在的網頁。我們選三條錯誤記錄來說明:
[Fri Dec 10 19:45:45 2004] [error] [client 163.30.0.2] File does not exist: /home/www/style.css [Fri Dec 10 20:55:44 2004] [error] [client 220.165.54.39] request failed: URI too long [Fri Dec 10 20:56:09 2004] [error] [client 220.165.54.39] File does not exist: /home/www/c/winnt/system32/cmd.exe |
第一個錯誤記錄是有人要存取 style.css,但卻找不到該檔案,這可能是我們網頁的 HTML 中有錯誤的連結。第二、三條記錄看來應該是 Windows 的病毒,它試著去存取 system32/cmd.exe,想要找 Windows 網頁伺服器的漏洞。您可以在錯誤記錄檔中看到很多這種病毒的訊息,很慶幸我們是使用 FreeBSD + Apache,不需要擔心病毒的入侵。
隨著使用人數的增加,網站的 log 檔可能會越來越大,我們可以使用 FreeBSD 的 newsyslog 來把舊的 log 備份起來。在 newsyslog 中,我們可以指定要備份多少個 log 檔,超過之後會自動刪除最舊的檔案。
首先編輯 /etc/newsyslog.conf 加入下列二行:
/var/log/httpd-access.log 644 7 * $W0D1 J /var/run/httpd.pid /var/log/httpd-error.log 644 7 * $W0D2 J /var/run/httpd.pid |
以上二行的意義是將 /var/log/httpd-access.log 這個檔案做備份,備份後的檔案名稱像這樣 httpd-access.log.0.bz2 。備份後該檔案的權限是 644,最大的數字到 7,也就是最多八個檔案,不限制檔案多大時要備份,選在每週日半夜 1 點時備份,並將該檔以 bzip2 壓縮。在備份完後,要將 /var/run/httpd.pid 所記錄的 Process ID 重新啟動。