摘要:在本文中,讓我們共同探討基於PHP語言構建一個基本的服務器端監視引擎的諸多技巧及注意事項,並給出完整的源碼實現。
一. 更改工作目錄的問題
當你編寫一個監視程序時,讓它設置自己的工作目錄通常更好些。這樣以來,如果你使用一個相對路徑讀寫文件,那麼,它會根據情況自動處理用戶期望存放文件的位置。總是限制程序中使用的路徑盡管是一種良好的實踐;但是,卻失去了應有的靈活性。因此,改變你的工作目錄的最安全的方法是,既使用chdir()也使用chroot()。
chroot()可用於PHP的CLI和CGI版本中,但是卻要求程序以根權限運行。chroot()實際上把當前進程的路徑從根目錄改變到指定的目錄。這使得當前進程只能執行存在於該目錄下的文件。經常情況下,chroot()由服務器作為一個"安全設備"使用以確保惡意代碼不會修改一個特定的目錄之外的文件。請牢記,盡管chroot()能夠阻止你訪問你的新目錄之外的任何文件,但是,任何當前打開的文件資源仍然能夠被存取。例如,下列代碼能夠打開一個日志文件,調用chroot()並切換到一個數據目錄;然後,仍然能夠成功地登錄並進而打開文件資源:
<?php
$logfile = fopen("/var/log/chroot.log", "w");
chroot("/Users/george");
fputs($logfile, "Hello From Inside The Chroot ");
?>
如果一個應用程序不能使用chroot(),那麼你可以調用chdir()來設置工作目錄。例如,當代碼需要加載特定的代碼(這些代碼能夠在系統的任何地方被定位時),這是很有用的。注意,chdir()沒有提供安全機制來防止打開未授權的文件。
二. 放棄特權
當編寫Unix守護程序時,一種經典的安全預防措施是讓它們放棄所有不需要的特權;否則,擁有不需要的特權容易招致不必要的麻煩。在代碼(或PHP本身)中含有漏洞的情況下,通過確保一個守護程序以最小權限用戶身份運行,往往能夠使損失減到最小。
一種實現此目的的方法是,以非特權用戶身份執行該守護程序。然而,如果程序需要在一開始就打開非特權用戶無權打開的資源(例如日志文件,數據文件,套接字,等等)的話,這通常是不夠的。
如果你以根用戶身份運行,那麼你能夠借助於posix_setuid()和posiz_setgid()函數來放棄你的特權。下面的示例把當前運行程序的特權改變為用戶nobody所擁有的那些權限:
$pw=posix_getpwnam('nobody');