Linux下的Apache和PHP安全设置简要
chengkinhung
|
1#
chengkinhung 发表于 2007-12-23 12:22
Linux下的Apache和PHP安全设置简要
说明: LAMP系统以安全和高效而闻名,但缺省的安装配置依然有部分权限设置过于宽松,导致
系统存在安全隐患, 尤其是对于提供支持PHP功能的虚拟域名空间租用服务的系统,就一定要 加强相关的安全设置. 本文原来是工作过程中的笔记,主要是针对RedHat Linux版本的设置特点,所介绍的配置选项 部分是从Google上寻找,部分是我的经验心得,均在CentOS4.4中调试通过. 讀者如有兴趣,请 参考使用; 若有更好更全面的见解,也欢迎不吝赐教(chengkinhung@gmail.com); PHP安全设置的参考资料: (網主Stefan Esser原是teso成员,是目前搞php安全最牛的人之一) http://www.hardened-php.net/hardening_patch.14.html ################################################################################ 請注意: 本文所描述的选项配置只涉及两个文件: php.ini和httpd.conf; 參考網址: http://us2.php.net/configuration.changes 對于提供公共網絡服務的ISP,基于安全性理由,建議apache和php都使用最小權限的公用设置. 針對特定用戶所提出的涉及安全性能的特殊要求, 可以在不改变全局性的共用设置的情況下, 通過利用Apache Virtualhost的PHP扩展功能來實現. 只需在相應用戶的Virtualhost的設置 段落中插入php_value,php_admin_value或php_admin_flag指令,就可以使該用戶具有與全局 設置不同的權限和行為. 針對Apache的特定虛擬用戶進行單獨配置的相关语法如下: php_admin_value name 1|0|string (value控制具体的参数) php_admin_flag name on|off (flag控制on或off,適用于Apache2.20版本) 請注意: 上述針對虛擬用戶的設置命令,可以直接設置在<VirtualHost>單元里面,或者設置在 相應用戶的<Directory>單元里面. 例如,要将ernest这个用户的register_globals功能打开,并且将upload_max_filesize调高到 5M,同時關閉safe_mode,但又不影响其他用户,就可以在该用户的VirtualHost里面加如下幾行: <VirtualHost 222.222.222.222> php_value upload_max_filesize 5M php_value register_globals 1 php_value safe_mode 0 php_flag safe_mode Off php_admin_value safe_mode 0 #(for Apache2.20) php_admin_flag safe_mode Off #(for Apache2.20) </VirtualHost> 在php.ini配置文件中的大部分功能,均可以用这种方式来调整,调整后应重新启动apache,然后 就可以在phpinfo中看到中间栏的Local Value同右边栏位的Master Value是不同值. 請注意: 有些参数值的设定方法跟它们在php.ini配置文件中的设置方法可能不一样,例如 上面的"register_globals 1", 原来在php.ini中应是"register_globals On". ################################################################################ ================================================================================ (1) safe_mode: 以安全模式运行PHP; -------------------------------------------------------------------------------- 在php.ini文件中使用如下選項(這是影響全局的設置): safe_mode = On (使用安全模式) safe_mode = Off (关闭安全模式) PHP的安全模式是為了試圖解決共享伺服器(shared-server)的安全問題而專門設立的. 然而 從結構上看, 試圖在PHP層面上解決這個問題其實是不合理的, 只是考慮到修改WEB伺服器層 和操作系統層都顯得非常的不現實, 因此許多使用者,特別是提供公共網絡服務的ISP供應商, 大多都在其服務器中要求以安全模式來运行PHP,用以防止合法用戶的跨站讀取或越權操作等 危險行為, 以及將非授權用戶的惡意行為所造成的影響降到最低范圍. 參考網址: http://hk2.php.net/features.safe-mode 在Apache的httpd.conf中VirtualHost的相应设置方法(這是針對特定用戶的設置): php_admin_flag safe_mode On (使用安全模式) php_admin_flag safe_mode Off (关闭安全模式) 或者: php_admin_value safe_mode 1 (使用安全模式) php_admin_value safe_mode 0 (关闭安全模式) 嚴重警告: 如果在全局性設置中已經啟用了safe_mode的功能,但又在特別的用戶虛擬空間中 關閉該用戶的safe_mode的功能,這就等于給予了該用戶特殊的權限,允許他不須受safe_mode 的限制而自由地使用系統的服務,也就是說所有原來被全局性的safe_mode功能所禁止的行為, 例如跨站讀取或越權操作等都可以被該用戶執行, 這就好像在原本安全設防的金庫中打開了 一個可供該用戶自由進出的洞,因此任何使用該用戶空間的應用都不再被全局性的safe_mode 保護所限制,當然這就意味著整個系統的安全性都可能會受到該用戶空間的影響,包括可能因 該空間應用的漏洞而導致整個系統被入侵等等. 所以,這樣的針對特定用戶的特殊設置,應當 作為一種特許授權的方式來考慮, 并有必要建立有效的監控機制以防止該用戶濫用系統資源, 否則, 一旦該用戶變得不再可信任或他的網站程序存在漏洞, 那么您的整體系統所受的影響 就會同完全沒有啟用safe_mode一模一樣. ================================================================================ ================================================================================ (2) safe_mode_include_dir: 无需UID/GID检查的目录 -------------------------------------------------------------------------------- 當您按照前面(1)所述之設置啟用PHP的安全模式之后,PHP的腳本在運行時就會對所有被操作 的目錄以及文件進行針對UID/GID的匹配性檢查: 即檢查被操作目錄或文件的UID或GID,是否 同當前PHP腳本文件的UID或GID一樣. 然而, 如果您的系統允許用戶的PHP腳本訪問公共路徑的話(例如很多較舊的Forum或Gallery 程序都會直接引用系統文件來擴展當時PHP還未能支持的功能), 那么這種設置就會造成麻煩. 而使用safe_mode_include_dir設置可以指定某些目錄, 當PHP腳本操作這些目录及其子目录 時(該目录必须在include_path中或者用完整路径来包含), 則允許越过UID/GID检查,即不對 該目錄進行UID/GID匹配性檢查. 从PHP4.2.0开始, 這個指令已經可以接受同include_path指令类似的风格, 即用分号隔开的 多個路径, 而以前則只能指定單一个目录. 同open_basedir一樣, 它所指定的路徑实际上也 是一个字符串的前缀限制,而非針對該目录名稱空間的操作. 例如如果指定: “safe_mode_include_dir = /dir/incl”, 那么所有的PHP腳本都将允许任意 访问 “/dir/include”和“/dir/incls” 路徑(如果它们存在的話). 因此, 如果您希望将访问 控制在一个指定的目录里面, 就必須在上述設置的指定路徑的结尾加上一个斜线, 例如: “safe_mode_include_dir = /dir/incl/” 請注意: VirtualHost会自动继承php.ini中的safe_mode_include_dir设置. ================================================================================ ================================================================================ (3) open_basedir: 将用户可操作的文件限制在某目录下; -------------------------------------------------------------------------------- 如下是php.ini中的原文說明以及默認配置: ; open_basedir, if set, limits all file operations to the defined directory ; and below. This directive makes most sense if used in a per-directory or ; per-virtualhost web server configuration file. This directive is ; *NOT* affected by whether Safe Mode is turned On or Off. open_basedir = . open_basedir可将用户访问文件的活动范围限制在指定的区域,通常是其家目录的路径,也 可用符号"."来代表当前目录。注意用open_basedir指定的限制实际上是前缀,而不是目录名。 举例来说: 若"open_basedir = /dir/user", 那么目录 "/dir/user" 和 "/dir/user1"都是 可以访问的。所以如果要将访问限制在仅为指定的目录,请用斜线结束路径名。例如设置成: "open_basedir = /dir/user/" open_basedir也可以同时设置多个目录, 在Windows中用分号分隔目录,在任何其它系统中用 冒号分隔目录。當其作用于Apache模块时,父目录中的open_basedir路径自动被继承。 有三种方法可以在Apache中为指定的用户做独立的设置: (a) 在Apache的httpd.conf中Directory的相应设置方法: <Directory /usr/local/apache/htdocs> php_admin_value open_basedir /usr/local/apache/htdocs/ #设置多个目录可以参考如下: php_admin_value open_basedir /usr/local/apache/htdocs/:/tmp/ </Directory> (b) 在Apache的httpd.conf中VirtualHost的相应设置方法: php_admin_value open_basedir /usr/local/apache/htdocs/ #设置多个目录可以参考如下: php_admin_value open_basedir /var/www/html/:/var/tmp/ (c) 因为VirtualHost中設置了open_basedir之后, 這個虛擬用戶就不会再自动继承php.ini 中的open_basedir設置值了,这就难以达到灵活的配置措施, 所以建议您不要在VirtualHost 中设置此项限制. 例如,可以在php.ini中设置open_basedir = .:/tmp/, 這個設置表示允许 访问当前目录(即PHP腳本文件所在之目錄)和/tmp/目录. 请注意: 若在php.ini所設置的上传文件临时目錄為/tmp/, 那么设置open_basedir時就必須 包含/tmp/,否則會導致上傳失敗. 新版php則会提示"open_basedir restriction in effect" 警告信息, 但move_uploaded_file()函数仍然可以成功取出/tmp/目录下的上传文件,不知道 这是漏洞还是新功能. ================================================================================ |