您现在的位置是:网站首页> 编程资料编程资料

Linux下PHP+Apache的26个必知的安全设置_PHP编程_

2023-05-25 475人已围观

简介 Linux下PHP+Apache的26个必知的安全设置_PHP编程_

PHP是一种开源服务器端脚本语言,应用很广泛。Apache web服务器提供了这种便利:通过HTTP或HTTPS协议,访问文件和内容。配置不当的服务器端脚本语言会带来各种各样的问题。所以,使用php时要小心。以下是Linux下PHP+Apache的26个PHP程序员必知的安全方面的设置

为PHP安全提示而提供的示例环境

文件根目录(DocumentRoot):/var/www/html

默认的Web服务器:Apache(可以使用Lighttpd或Nginx来取代Apache)

默认的PHP配置文件:/etc/php.ini

默认的PHP加载模块配置目录:/etc/php.d/

我们的示例php安全配置文件:/etc/php.d/security.ini(需要使用文本编辑器来创建该文件)

操作系统:RHEL/CentOS/FedoraLinux(相关指令应该与Debian/Ubuntu等其他任何Linux发行版或者OpenBSD/FreeBSD/HP-UX等其他类似Unix的操作系统兼容)。

默认的php服务器TCP/UDP端口:无

为本文所列的大多数操作编写代码时,假定它们将由运行bash外壳程序或其他任何现代外壳程序的根用户来执行:

 $ php -v

示例输出:

 PHP 5.3.3 (cli) (built: Oct 24 2011 08:35:41) Copyright (c) 1997-2010 The PHP Group Zend Engine v2.3.0, Copyright (c) 1998-2010 Zend Technologies

出于演示的用途,我会使用以下操作系统:

 $cat/etc/redhat-release

示例输出:

 Red HatEnterprise Linux Server release 6.1 (Santiago)

第1个设置项:了解你的对手

基于PHP的应用程序面临不同类型的攻击。我注意到了几种不同类型的攻击:

XSS:跨站脚本是Web PHP应用程序中的一种安全漏洞,攻击者可以利用该漏洞来窃取用户的信息。你可以配置Apache,编写更安全的PHP脚本(验证所有的用户输入),以避免XSS攻击。

SQL注入攻击:这是PHP应用程序的数据库层中的安全漏洞。用户输入不正确地过滤时,应用程序就能执行任何SQL语句。你可以配置Apache,编写安全代码(验证和转换所有的用户输入),以避免SQL注入攻击。PHP中的一个常见做法是,在发送SQL查询之前,使用名为mysql_real_escape_string()的函数,转换参数。

文件上传:它让访客可以将文件放在(将文件上传到)你的服务器上。这会带来众多安全问题,比如删除你的文件、删除数据库、获取用户详细资料,不一而足。你可以使用php来禁用文件上传,或编写安全代码(比如验证用户输入,只允许PNG或GIF等图像文件类型)。

添加本地和远程文件:攻击者可以从远程服务器打开文件,执行任何PHP代码。这让他们得以上传文件、删除文件和安装后门。可以配置php以禁用远程文件执行功能。

eval() :将字符串作为PHP代码来进行评估。攻击者常常利用该函数来隐藏其在服务器本身上面的代码和工具。你可以配置PHP,禁用eval()。

sea-surf攻击(跨站请求伪造,CSRF):这种攻击迫使最终用户针对目前已验证其身份的Web应用程序执行有害的操作。如果是平常的用户,得逞的CSRF攻击会危及最终用户的数据和操作。但如果被盯上的最终用户使用管理员帐户,这会危及整个Web应用程序。

第2个设置项:查找内置的PHP模块

想查看一组编译进去的PHP模块,请输入以下命令:

 # php -m

我建议你使用模块数量减少的PHP,以增强性能和安全。比如说,你可以通过删除(移除)配置文件或者更名(或移动)一个名为/etc/php.d/sqlite3.ini的文件来禁用sqlite3模块,操作如下:

 #rm/etc/php.d/sqlite3.ini

或者

 #mv/etc/php.d/sqlite3.ini /etc/php.d/sqlite3.disable

其他编译进去的模块只能通过重新安装精简配置的PHP来移除。可以从php.net下载php源代码,然后按以下方法编译它,支持GD、fastcgi和mysql:

 ./configure --with-libdir=lib64 --with-gd --with-mysql --prefix=/usr --exec-prefix=/usr --bindir=/usr/bin --sbindir=/usr/sbin --sysconfdir=/etc --datadir=/usr/share --includedir=/usr/include --libexecdir=/usr/libexec --localstatedir=/var --sharedstatedir=/usr/com --mandir=/usr/share/man--infodir=/usr/share/info--cache-file=../config.cache --with-config-file-path=/etc --with-config-file-scan-dir=/etc/php.d --enable-fastcgi --enable-force-cgi-redirect

参阅如何编译php,并重新安装到类似Unix的操作系统上(http://www.php.net/manual/en/install.unix.php),以了解更多信息。

第3个设置项:限制PHP信息泄露

要限制PHP信息泄露,就要禁用expose_php。编辑/etc/php.d/secutity.ini,执行以下指令:

expose_php=Off

启用后,expose_php向外界报告PHP安装在服务器上,这包括HTTP头里面的PHP版本(如X-Powered-By: PHP/5.3.3)。PHP标识的全局唯一标识符(GUID,见示例http://www.php.net/?=PHPE9568F34-D428-11d2-A769-00AA001ACF42)也显示出来,因而将它们添加到支持PHP的网站的URL后面,就会显示相应标识。expose_php启用后,你可以使用以下命令,查看PHP版本:

 $curl-I //www.jb51.net

示例输出:

 HTTP/1.1 200 OK X-Powered-By: PHP/5.3.3 Content-type: text/html; charset=UTF-8 Vary:accept-Encoding, Cookie X-Vary-Options: Accept-Encoding;list-contains=gzip,Cookie;string-contains=wikiToken;string-contains=wikiLoggedOut;string-contains=wiki_session last-Modified: Thu, 03 Nov 2011 22:32:55 GMT ...

我还建议,你应在httpd.conf中执行ServerTokens和ServerSignature命令,隐藏Apache版本及其他信息(http://www.cyberciti.biz/faq/rhel-centos-hide-httpd-version/)。

第4个设置项:尽量减少可装入的PHP模块(动态加载模块)

PHP支持“动态加载模块”(Dynamic Extensions)。默认情况下,RHEL装入/etc/php.d/目录里面的所有加载模块。要启用或禁用某一个模块,只要在/etc/php.d/目录中找到配置文件、为模块名称添加注释。你还可以更名或删除模块配置文件。想获得最佳的PHP性能和安全,你应该只启用Web应用程序需要的加载模块。比如说,要禁用gd加载模块,输入以下命令:

 #cd/etc/php.d/ # mv gd.{ini,disable} # /sbin/servicehttpd restart

要启用名为gd的php模块,请输入:

 # mv gd.{disable,ini} # /sbin/service httpd restart

第5个设置项:将所有PHP错误记入日志

别让PHP错误信息暴露在网站的所有访客面前。编辑/etc/php.d/security.ini,执行以下指令:

display_errors=Off

确保你将所有PHP错误记入到日志文件中(http://www.cyberciti.biz/tips/php-howto-turn-on-error-log-file.html):

log_errors=On

error_log=/var/log/httpd/php_scripts_error.log

第6个设置项:不允许上传文件

出于安全原因,编辑/etc/php.d/security.ini,执行以下命令:

file_uploads=Off

如果使用你应用程序的用户需要上传文件,只要设置upload_max_filesize(http://www.cyberciti.biz/faq/linux-unix-apache-increase-php-upload-limit/),即可启用该功能,该设置限制了PHP允许通过上传的文件的最大值:

file_uploads=On

用户通过PHP上传的文件最大1MB

upload_max_filesize=1M

第7个设置项:关闭远程代码执行

如果启用,allow_url_fopen允许PHP的文件函数——如file_get_contents()、include语句和require语句——可以从远程地方(如ftp或网站)获取数据。

allow_url_fopen选项允许PHP的文件函数——如file_get_contents()、include语句和require语句——可以使用FTP或HTTP协议,从远程地方获取数据。

编程员们常常忘了这一点,将用户提供的数据传送给这些函数时,没有进行适当的输入过滤,因而给代码注入安全漏洞留下了隐患。基于PHP的Web应用程序中存在的众多代码注入安全漏洞是由启用allow_url_fopen和糟糕的输入过滤共同引起的。编辑/etc/php.d/security.ini,执行以下指令:

allow_url_fopen=Off

出于安全原因,我还建议禁用allow_url_include:

allow_url_include=Off

第8个设置项:启用SQL安全模式

编辑/etc/php.d/security.ini,执行以下指令:

sql.safe_mode=On

如果启用,mysql_connect()和mysql_pconnect()就忽视传送给它们的任何变量。请注意:你可能得对自己的代码作一些更改。sql.safe_mode启用后,第三方开源应用程序(如WorkdPress)及其他应用程序可能根本运行不了。我还建议你针对所有安装的php 5.3.x关闭magic_quotes_gpc(http://php.net/manual/en/security.magicquotes.php),因为它的过滤并不有效、不是很可靠。mysql_escape_string()和自定义过滤函数能起到更好的作用(向Eric Hansen致谢,https://www.facebook.com/EricHansen.SFU):

magic_quotes_gpc=Off

第9个设置项:控制POST请求的大小

作为请求的一部分,客户机(浏览器或用户)需要将数据发送到Apache Web服务器时,比如上传文件或提交填好的表单时,就要用到HTTP POST请求方法。攻击者可能会企图发送过大的POST请求,大量消耗你的系统资源。你可以限制PHP将处理的POST请求的最大大小。编辑/etc/php.d/security.ini,执行以下命令:

post_max_size=1K

1K设置了php应用程序允许的POST请求数据的最大大小。该设置还影响文件上传。要上传大容量文件,这个值必须大于upload_max_filesize。我还建议你限制使用Apache Web服务器的可用方法。编辑httpd.conf,执行针对文件根目录/var/www/html的以下指令:

 Order allow,deny ## 可在此添加配置的其余部分... ##

第10个设置项:资源控制(拒绝服务控制)

你可以设置每个php脚本的最长执行时间,以秒为单位。另一个建议的选项是设置每个脚本可能用于解析请求数据的最长时间,以及脚本可能耗用的最大内存数量。编辑/etc/php.d/security.ini,执行以下命令:

设置,以秒为单位

max_execution_time = 30

max_input_time = 30

memory_limit = 40M

第11个设置项:为PHP安装Suhosin高级保护系统

来自Suhosin项目网页(http://www.hardened-php.net/suhosin/):

Suhosin是一款高级的保护系统,面向安装的PHP。它旨在保护服务器和用户,远离PHP应用程序和PHP核心中的已知缺陷和未知缺陷。Suhosin分两个独立部分,可以单独使用,也可以组合使用。第一个部分是针对PHP核心的小补丁,实施了几个低级防护措施,以防范缓冲器溢出或格式字符串安全漏洞;第二个部分是功能强大的PHP加载模块,实施了其他所有的保护措施。

看看如何在Linux操作系统下安装和配置suhosin(http://www.cyberciti.biz/faq/rhel-linux-install-suhosin-php-protection/)。

第12个设置项:禁用危险的PHP函数

PHP有许多函数,如果使用不当,它们可以用来闯入你的服务器。你可以使用disable_functions命令,在/etc/php.d/security.ini中禁用一系列函数:

 disable_functions=exec,passthru,shell_exec,system,proc_open,popen,curl_exec,curl_multi_exec,parse_ini_file,show_source 

第13个设置项:PHP Fastcgi/CGI - cgi.force_redirect命令

PHP可与FastCGI协同工作。 Fascgi减少了Web服务器占用的内存资源,但是仍为你提供了整个PHP语言具有的速度和功能。你可以配置Apache2+PHP+FastCGI或cgi,如这里描述的那样。配置命令cgi.force_redirect可以防止任何人使用http://www.cyberciti.biz/cgi-bin/php/hackerdir/backdoor.php这样的地址,直接调用PHP。出于安全原因,应启用cgi.force_redirect。编辑/etc/php.d/security.ini,执行以下命令:

出于安全原因,在典型的*Apache+PHP-CGI/FastCGI*环境中,启用cgi.force_redirect

cgi.force_redirect=On

第14个设置项:PHP用户和用户组ID

mod_fastcgi是面向Apache Web服务器的cgi模块。它可以连接至外部的FASTCGI服务器。你要确保PHP以非根目录用户的身份来运行。如果PHP以根目录或100以下UID的身份来运行,它可以访问及/或处理系统文件。你必须使用Apache的suEXEC或mod_suPHP,以非特权用户的身份来执行PHP CGI。suEXEC功能让Apache用户们能够以有别于调用Web服务器的用户ID的用户ID来运行CGI程序。在该示例中,我的php-cgi以phpcgi用户的身份来运行,Apache以apache用户的身份来运行:

 #psaux |grepphp-cgi

示例输出:

 phpcgi 6012 0.0 0.4 225036 60140 ? S Nov22 0:12 /usr/bin/php-cgi phpcgi 6054 0.0 0.5 229928 62820 ? S Nov22 0:11 /usr/bin/php-cgi phpcgi 6055 0.1 0.4 224944 53260 ? S Nov22 0:18 /usr/bin/php-cgi phpcgi 6085 0.0 0.4 224680 56948 ? S Nov22 0:11 /usr/bin/php-cgi phpcgi 6103 0.0 0.4 224564 57956 ? S Nov22 0:11 /usr/bin/php-cgi phpcgi 6815 0.4 0.5 228556 61220 ? S 00:52 0:19 /usr/bin/php-cgi phpcgi 6821 0.3 0.5 228008 61252 ? S 00:55 0:12 /usr/bin/php-cgi phpcgi 6823 0.3 0.4 225536 58536 ? S 00:57 0:13 /usr/bin/php-cgi

你可以使用spawn-fcgi等工具,以phpcgi用户的身份(先要为系统添加phpcgi用户)来创建远程和本地FastCGI进程:

 # spawn-fcgi -a 127.0.0.1 -p 9000 -u phpcgi -g phpcgi -f /usr/bin/php-cgi

现在,你可以配置Apache、Lighttpd和Nginx web服务器了,使用在127.0.0.1ip地址处端口9000上运行的php FastCGI。

第15个设置项:限制PHP对文件系统的访问

open_basedir命令设置了允许PHP使用fopen()和其他函数来访问哪些目录的文件。如果文件在open_basdir定义的路径外面,PHP就拒绝打开该文件。你无法使用符号链接作为变通办法。比如说,只允许访问/var/www/html目录、不允许访问/var/www、/tmp或/etc目录:

限制PHP进程访问/var/www/html/等专门指定的目录外面的文件

; Limits the PHP process from accessing files outside; of specifically designated directories suchas/var/www/html/open_basedir="/var/www/html/"; ------------------------------------; Multipledirsexample; open_basedir="/home/httpd/vhost/cyberciti.biz/html/:/home/httpd/vhost/nixcraft.com/html/:/home/httpd/vhost/theos.in/html/"; ------------------------------------

第16个设置项:会话路径

PHP中的会话支持包括在随后的访问中保留某些数据的一种方法。这让你能够开发更加定制的应用程序,并加大网站的吸引力。该路径在/etc/php.ini文件中定义,与某一个会话有关的所有数据都将存放在session.save_path选项指定的目录下的文件中。在RHEL/CentOS/Fedor

-六神源码网