当编写Unix守护程序时,一种经典的安全预防措施是让它们放弃所有不需要的特权;否则,拥有不需要的特权容易招致不必要的麻烦。在代码(或PHP本身)中含有漏洞的情况下,通过确保一个守护程序以最小权限用户身份运行,往往能够使损失减到最小。
一种实现此目的的方法是,以非特权用户身份执行该守护程序。然而,如果程序需要在一开始就打开非特权用户无权打开的资源(例如日志文件,数据文件,套接字,等等)的话,这通常是不够的。
如果你以根用户身份运行,那么你能够借助于posix_setuid()和posiz_setgid()函数来放弃你的特权。下面的示例把当前运行程序的特权改变为用户nobody所拥有的那些权限:
就象chroot()一样,任何在放弃特权之前被打开的特权资源都会保持为打开,但是不能创建新的资源。$pw=posix_getpwnam('nobody'); posix_setuid($pw['uid']); posix_setgid($pw['gid']);
三. 保证排它性
你可能经常想实现:一个脚本在任何时刻仅运行一个实例。为了保护脚本,这是特别重要的,因为在后台运行容易导致偶然情况下调用多个实例。
保证这种排它性的标准技术是,通过使用flock()来让脚本锁定一个特定的文件(经常是一个加锁文件,并且被排它式使用)。如果锁定失败,该脚本应该输出一个错误并退出。下面是一个示例:
注意,有关锁机制的讨论涉及较多内容,在此不多加解释。$fp=fopen("/tmp/.lockfile","a"); if(!$fp || !flock($fp, LOCK_EX | LOCK_NB)) { fputs(STDERR, "Failed to acquire lock\n"); exit; } /*成功锁定以安全地执行工作*/