分类:安全

非常全面的关于 php 安全配置的文章  有空把他翻译成中文 先收藏

 

PHP is an open-source server-side scripting language and it is a widely used. The Apache web server provides access to files and content via the HTTP OR HTTPS protocol. A misconfigured server-side scripting language can create all sorts of problems. So, PHP should be used with caution. Here are twenty-five php security best practices for sysadmins for configuring PHP securely.

[2]

Our Sample Setup For PHP Security Tips

  • DocumentRoot: /var/www/html
  • Default Web server: Apache ( you can use Lighttpd or Nginx instead of Apache)
  • Default PHP configuration file: /etc/php.ini
  • Default PHP extensions config directory: /etc/php.d/
  • Our sample php security config file: /etc/php.d/security.ini (you need to create this file using a text editor)
  • Operating systems: RHEL / CentOS / Fedora Linux (the instructions should work with any other Linux distributions such as Debian / Ubuntu or other Unix like operating systems such as OpenBSD/FreeBSD/HP-UX).
  • Default php server TCP/UDP ports: none
[3]

Most of the actions listed in this post are written with the assumption that they will be executed by the root user running the bash or any other modern shell:
$ php -v
Sample outputs:

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

For demonstration purpose I’m going to use the following operating system:
$ cat /etc/redhat-release
Sample outputs:

Red Hat Enterprise Linux Server release 6.1 (Santiago)

#1: Know Your Enemy

PHP based apps can face the different types of attacks. I have noticed the different types of attacks:

  1. XSS [4] – Cross-site scripting is a vulnerability in php web applications, which attackers may exploit to steal users’ information. You can configure Apache and write more secure PHP scripts (validating all user input) to avoid xss attacks.
  2. SQL injection [5] – It is a vulnerability in the database layer of an php application. When user input is incorrectly filtered any SQL statements can be executed by the application. You can configure Apache and write secure code (validating and escaping all user input) to avoid SQL injection attacks. A common practice in PHP is to escape parameters using the function called mysql_real_escape_string() before sending the SQL query.
    Spoofing
  3. File uploads – It allows your visitor to place files (upload files) on your server. This can result into various security problems such as delete your files, delete database, get user details and much more. You can disable file uploads using php or write secure code (like validating user input and only allow image file type such as png or gif).
  4. Including local and remote files – An attacker can open files from remote server and execute any PHP code. This allows them to upload file, delete file and install backdoors. You can configure php to disable remote file execution.
  5. eval() [6] – Evaluate a string as PHP code. This is often used by an attacker to hide their code and tools on the server itself. You can configure php to disable eval().
  6. Sea-surf Attack [7] (Cross-site request forgery – CSRF) – This attack forces an end user to execute unwanted actions on a web application in which he/she is currently authenticated. A successful CSRF exploit can compromise end user data and operation in case of normal user. If the targeted end user is the administrator account, this can compromise the entire web application.

#2: Find Built-in PHP Modules

To see the set of compiled-in PHP modules type the following command:
# php -m
Sample outputs:

[PHP Modules]
apc
bcmath
bz2
calendar
Core
ctype
curl
date
dom
ereg
exif
fileinfo
filter
ftp
gd
gettext
gmp
hash
iconv
imap
json
libxml
mbstring
memcache
mysql
mysqli
openssl
pcntl
pcre
PDO
pdo_mysql
pdo_sqlite
Phar
readline
Reflection
session
shmop
SimpleXML
sockets
SPL
sqlite3
standard
suhosin
tokenizer
wddx
xml
xmlreader
xmlrpc
xmlwriter
xsl
zip
zlib
[Zend Modules]
Suhosin

I recommends that you use PHP with a reduced modules for performance and security. For example, you can disable sqlite3 module by deleting (removing) configuration file [8], OR renaming (moving) a file [9] called /etc/php.d/sqlite3.ini as follows:
# rm [8] /etc/php.d/sqlite3.ini
OR
# mv [9] /etc/php.d/sqlite3.ini /etc/php.d/sqlite3.disable
Other compiled-in modules can only be removed by reinstallating PHP with a reduced configuration. You can download php source code from php.net and compile it as follows with GD, fastcgi, and MySQL support:

./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

See how to compile and reinstall php on Unix like operating system [10] for more information.

#3: Restrict PHP Information Leakage

To restrict PHP information leakage disable expose_php. Edit /etc/php.d/secutity.ini and set the following directive:

expose_php=Off

When enabled, expose_php reports to the world that PHP is installed on the server, which includes the PHP version within the HTTP header (e.g., X-Powered-By: PHP/5.3.3). The PHP logo guids (see example [11]) are also exposed, thus appending them to the URL of a PHP enabled site will display the appropriate logo. When expose_php enabled you can see php version using the following command:
$ curl -I http://www.cyberciti.biz/index.php
Sample outputs:

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
...

I also recommend that you setup the ServerTokens and ServerSignature directives in httpd.conf to hide Apache version [12] and other information.

#4: Minimize Loadable PHP Modules (Dynamic Extensions)

PHP supports “Dynamic Extensions”. By default, RHEL loads all the extension modules found in /etc/php.d/ directory. To enable or disable a particular module, just find the configuration file in /etc/php.d/ directory and comment the module name. You can also rename or delete module configuration file. For best PHP performance and security, you should only enable the extensions your webapps requires. For example, to disable gd extension, type the following commands:
# cd /etc/php.d/
# mv gd.{ini,disable}
# /sbin/service httpd restart [13]

To enable php module called gd, enter:
# mv gd.{disable,ini}
# /sbin/service httpd restart [14]

#5: Log All PHP Errors

Do not expose PHP error messages to all site visitors. Edit /etc/php.d/security.ini and set the following directive:

display_errors=Off

Make sure you log all php errors to a log file [15]:

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

#6: Disallow Uploading Files

Edit /etc/php.d/security.ini and set the following directive to disable file uploads for security reasons:

file_uploads=Off

If users of your application need to upload files, turn this feature on by setting upload_max_filesize limits the maximum size of files [16] that PHP will accept through uploads:

file_uploads=On
# user can only upload upto 1MB via php
upload_max_filesize=1M

#7: Turn Off Remote Code Execution

If enabled, allow_url_fopen allows PHP’s file functions — such as file_get_contents() and the include and require statements — can retrieve data from remote locations, like an FTP or web site.

The allow_url_fopen [17] option allows PHP’s file functions – such as file_get_contents() and the include and require statements – can retrieve data from remote locations using ftp or http protocols. Programmers frequently forget this and don’t do proper input filtering when passing user-provided data to these functions, opening them up to code injection vulnerabilities [18]. A large number of code injection vulnerabilities reported in PHP-based web applications are caused by the combination of enabling allow_url_fopen and bad input filtering. Edit /etc/php.d/security.ini and set the following directive:

allow_url_fopen=Off

I also recommend to disable allow_url_include for security reasons:

allow_url_include=Off

#8: Enable SQL Safe Mode

Edit /etc/php.d/security.ini and set the following directive:

sql.safe_mode=On

If turned [19] On, mysql_connect() and mysql_pconnect() ignore any arguments passed to them. Please note that you may have to make some changes to your code. Third party and open source application such as WordPress, and others may not work at all when sql.safe_mode enabled. I also recommend that you turn off magic_quotes_gpc [20] for all php 5.3.x installations as the filtering by it is ineffective and not very robust. mysql_escape_string() and custom filtering functions serve a better purpose (hat tip to Eric Hansen [21]):

magic_quotes_gpc=Off

#9: Control POST Size

The HTTP POST request method is used when the client (browser or user) needs to send data to the Apache web server as part of the request, such as when uploading a file or submitting a completed form. Attackers may attempt to send oversized POST requests to eat your system resources. You can limit the maximum size POST request that PHP will process. Edit /etc/php.d/security.ini and set the following directive:

; Set a realistic value here
post_max_size=1K

The 1K sets max size of post data allowed by php apps. This setting also affects file upload. To upload large files, this value must be larger than upload_max_filesize. I also suggest that you limit available methods using Apache web server. Edit, httpd.conf and set the following directive for DocumentRoot /var/www/html:

 
<Directory /var/www/html>
    <LimitExcept GET POST>
        Order allow,deny
    </LimitExcept>
## Add rest of the config goes here... ##
</Directory>

#10: Resource Control (DoS Control)

You can set maximum execution time of each php script [17], in seconds. Another recommend option is to set maximum amount of time each script may spend parsing request data, and maximum amount of memory a script may consume. Edit /etc/php.d/security.ini and set the following directives:

# set in seconds
max_execution_time =  30
max_input_time = 30
memory_limit = 40M

#11: Install Suhosin Advanced Protection System for PHP

From the project page [22]:

Suhosin is an advanced protection system for PHP installations. It was designed to protect servers and users from known and unknown flaws in PHP applications and the PHP core. Suhosin comes in two independent parts, that can be used separately or in combination. The first part is a small patch against the PHP core, that implements a few low-level protections against bufferoverflows or format string vulnerabilities and the second part is a powerful PHP extension that implements all the other protections.

See how to install and configure suhosin [23] under Linux operating systems.

#12 Disabling Dangerous PHP Functions

PHP has a lot of functions which can be used to crack your server if not used properly. You can set list of functions in /etc/php.d/security.ini using disable_functions directive [24]:

 
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 Directive

PHP work with FastCGI. Fascgi reduces the memory footprint of your web server, but still gives you the speed and power of the entire PHP language. You can configure Apache2+PHP+FastCGI [25] or cgi as described here [25]. The configuration directive cgi.force_redirect prevents anyone from calling PHP directly with a URL like http://www.cyberciti.biz/cgi-bin/php/hackerdir/backdoor.php. Turn on cgi.force_redirect for security reasons. Edit /etc/php.d/security.ini and set the following directive:

; Enable cgi.force_redirect for security reasons in a typical *Apache+PHP-CGI/FastCGI* setup
cgi.force_redirect=On

#14 PHP User and Group ID

mod_fastcgi is a cgi-module for Apache web server. It can connect to an external FASTCGI server. You need to make sure php run as non-root user. If PHP executes as a root or UID under 100, it may access and/or manipulate system files. You must execute PHP CGIs as a non-privileged user using Apache’s suEXEC [26] or mod_suPHP [27]. The suEXEC feature provides Apache users the ability to run CGI programs under user IDs different from the user ID of the calling web server. In this example, my php-cgi is running as phpcgi user and apache is running as apache user:
# ps aux | grep php-cgi
Sample outputs:

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

You can use tool such as spawn-fcgi [28] to spawn remote and local FastCGI processes as phpcgi user (first, add phpcgi user to the system [29]):
# spawn-fcgi -a 127.0.0.1 -p 9000 -u phpcgi -g phpcgi -f /usr/bin/php-cgi
Now, you can configure Apache [30], Lighttpd [31], and Nginx [32] web server to use external php FastCGI running on port 9000 at 127.0.0.1 IP address.

#15 Limit PHP Access To File System

The open_basedir directive set the directories from which PHP is allowed to access files using functions like fopen(), and others. If a file is outside of the paths defined by open_basdir, PHP will refuse to open it. You cannot use a symbolic link as a workaround. For example only allow access to /var/www/html directory and not to /var/www, or /tmp or /etc directories:

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

#16 Session Path

Session support [33] in PHP consists of a way to preserve certain data across subsequent accesses. This enables you to build more customized applications and increase the appeal of your web site. This path is defined in /etc/php.ini file and all data related to a particular session will be stored in a file in the directory specified by the session.save_path option. The default is as follows under RHEL/CentOS/Fedora Linux:

session.save_path="/var/lib/php/session"
; Set the temporary directory used for storing files when doing file upload
upload_tmp_dir="/var/lib/php/session"

Make sure path is outside /var/www/html and not readable or writeable by any other system users:
# ls -Z /var/lib/php/
Sample outputs:

drwxrwx---. root apache system_u:object_r:httpd_var_run_t:s0 session

Note: The -Z option to the ls command [34] display SELinux security context such as file mode, user, group, security context and file name.

#17 Keep PHP, Software, And OS Up to Date

Applying security patches is an important part of maintaining Linux, Apache, PHP, and MySQL server. All php security update should be reviewed and applied as soon as possible using any one of the following tool (if you’re installing PHP via a package manager):
# yum update [35]
OR
# apt-get update && apt-get upgrade [36]
You can configure Red hat / CentOS / Fedora Linux to send yum package update notification via email [37]. Another option is to apply all security updates [38] via a cron job [39]. Under Debian / Ubuntu Linux you can use apticron to send security [40] notifications.

Note: Check php.net [41] for the most recent release for source code installations.

#18: Restrict File and Directory Access

Make sure you run Apache as a non-root user such as Apache or www. All files and directory should be owned by non-root user (or apache user) under /var/www/html:
# chown -R apache:apache /var/www/html/ [42]
/var/www/html/ is a subdirectory and DocumentRoot which is modifiable by other users since root never executes any files out of there, and shouldn’t be creating files in there.

Make sure file permissions are set to 0444 (read-only) under /var/www/html/:
# chmod -R 0444 /var/www/html/
Make sure all directories permissions are set to 0445 under /var/www/html/:
# find /var/www/html/ -type d -print0 | xargs -0 -I {} chmod 0445 {} [43]

A Note About Setting Up Correct File Permissions

The chown and chmod command make sures that under no circumstances DocumentRoot or files contained in DocumentRoot are writable by the Web server user apache. Please note that you need to set permissions that makes the most sense for the development model of your website, so feel free to adjust the chown and chmod command as per your requirements. In this example, the Apache server run as apache user. This is configured with the User and Group directives in your httpd.conf file. The apache user needs to have read access to everything under DocumentRoot but should not have write access to anything.

Make sure httpd.conf has the following directives for restrictive configuration:

 
<Directory / >
    Options None
    AllowOverride None
    Order allow,deny
</Directory>

You should only grant write access when required. Some web applications such as wordpress and others may need a caching directory. You can grant a write access to caching directory using the following commands:
# chmod a+w /var/www/html/blog/wp-content/cache
### block access to all ###
# echo 'deny from all' > /var/www/html/blog/wp-content/cache/.htaccess

#19: Write Protect Apache, PHP, and, MySQL Configuration Files

Use the chattr command [44] to write protect configuration files:
# chattr +i /etc/php.ini
# chattr +i /etc/php.d/*
# chattr +i /etc/my.ini
# chattr +i /etc/httpd/conf/httpd.conf
# chattr +i /etc/

The chattr command can write protect your php file or files in /var/www/html directory too:
# chattr +i /var/www/html/file1.php
# chattr +i /var/www/html/

#20: Use Linux Security Extensions (such as SELinux)

Linux comes with various security patches which can be used to guard against misconfigured or compromised server programs. If possible use SELinux [45] and other Linux security extensions [46] to enforce limitations on network and other programs. For example, SELinux provides a variety of security policies for Linux kernel and Apache web server. To list all Apache SELinux protection variables, enter:
# getsebool -a | grep httpd
Sample outputs:

allow_httpd_anon_write --> off
allow_httpd_mod_auth_ntlm_winbind --> off
allow_httpd_mod_auth_pam --> off
allow_httpd_sys_script_anon_write --> off
httpd_builtin_scripting --> on
httpd_can_check_spam --> off
httpd_can_network_connect --> off
httpd_can_network_connect_cobbler --> off
httpd_can_network_connect_db --> off
httpd_can_network_memcache --> off
httpd_can_network_relay --> off
httpd_can_sendmail --> off
httpd_dbus_avahi --> on
httpd_enable_cgi --> on
httpd_enable_ftp_server --> off
httpd_enable_homedirs --> off
httpd_execmem --> off
httpd_read_user_content --> off
httpd_setrlimit --> off
httpd_ssi_exec --> off
httpd_tmp_exec --> off
httpd_tty_comm --> on
httpd_unified --> on
httpd_use_cifs --> off
httpd_use_gpg --> off
httpd_use_nfs --> off

To disable Apache cgi support, enter:
# setsebool -P httpd_enable_cgi off
See Red Hat SELinux guide [47] for more information.

#21 Install Mod_security

ModSecurity is an open source intrusion detection and prevention engine for web applications. You can easily install mod_security under Linux and protect apache and php [48] based apps from xss and various other attacks:

 
## A few Examples ##
# Do not allow to open files in /etc/
SecFilter /etc/

# Stop SQL injection
SecFilter "delete[[:space:]]+from"
SecFilter "select.+from"

#22 Run Apache / PHP In a Chroot Jail If Possible

Putting PHP and/or Apache in a chroot jail minimizes the damage done by a potential break-in by isolating the web server to a small section of the filesystem. You can use traditional chroot kind of setup with Apache [49]. However, I recommend FreeBSD jails [50], XEN virtulization [51], KVM virtulization [52], or OpenVZ virtualization [53] which uses the concept of containers.

#23 Use Firewall To Restrict Outgoing Connections

The attacker will download file locally on your web-server using tools such as wget. Use iptables to block outgoing connections from apache user. The ipt_owner module attempts to match various characteristics of the packet creator, for locally generated packets. It is only valid in the OUTPUT chain. In this example, allow vivek user to connect outside using port 80 (useful for RHN or centos repo access):

 
/sbin/iptables -A OUTPUT -o eth0 -m owner --uid-owner vivek -p tcp --dport 80 -m state --state NEW,ESTABLISHED  -j ACCEPT

Here is another example that blocks all outgoing connections from apache user except to our own smtp server, and spam validation API service:

 
# ....
/sbin/iptables --new-chain apache_user
/sbin/iptables --append OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
/sbin/iptables --append OUTPUT -m owner --uid-owner apache -j apache_user
# allow apache user to connec to our smtp server
/sbin/iptables --append apache_user -p tcp --syn -d 192.168.1.100 --dport 25 -j RETURN
# Allow apache user to connec to api server for spam validation
/sbin/iptables --append apache_user -p tcp --syn -d  66.135.58.62 --dport 80 -j RETURN
/sbin/iptables --append apache_user -p tcp --syn -d  66.135.58.61 --dport 80 -j RETURN
/sbin/iptables --append apache_user -p tcp --syn -d  72.233.69.89 --dport 80 -j RETURN
/sbin/iptables --append apache_user -p tcp --syn -d  72.233.69.88 --dport 80 -j RETURN
#########################
## Add more rules here ##
#########################
# No editing below
# Drop everything for apache outgoing connection
/sbin/iptables --append apache_user -j REJECT

#24 Watch Your Logs & Auditing

Check the apache log file [54]:
# tail -f /var/log/httpd/error_log
# grep 'login.php' /var/log/httpd/error_log
# egrep -i "denied|error|warn" /var/log/httpd/error_log

Check the php log file [55]:
# tail -f /var/log/httpd/php_scripts_error.log
# grep "...etc/passwd" /var/log/httpd/php_scripts_error.log

Log files will give you some understanding of what attacks is thrown against the server and allow you to check if the necessary level of security is present or not. The auditd service is provided for system auditing. Turn it on to audit SELinux events [56], authetication events, file modifications, account modification and so on. I also recommend using standard “Linux System Monitoring Tools [57]” for monitoring your web-server.

#25 Run Service Per System or VM Instance

For large installations it is recommended that you run, database, static, and dynamic content from different servers.

///////////////
/ ISP/Router /
//////////////
  \
   |
   Firewall
     \
      |
     +------------+
     | LB01       |
     +------------+                 +--------------------------+
                  |                 | static.lan.cyberciti.biz |
		  +-----------------+--------------------------+
                                    | phpcgi1.lan.cyberciti.biz|
                                    +--------------------------+
                                    | phpcgi2.lan.cyberciti.biz|
                                    +--------------------------+
                                    | mysql1.lan.cyberciti.biz |
                                    +--------------------------+
                                    | mcache1.lan.cyberciti.biz|
                                    +--------------------------+

(Fig.01: Running Services On Separate Servers)

Run different network services on separate servers or VM instances. This limits the number of other services that can be compromised. For example, if an attacker able to successfully exploit a software such as Apache flow, he / she will get an access to entire server including other services running on the same server (such as MySQL, e-mail server and so on). But, in the above example content are served as follows:

  1. static.lan.cyberciti.biz – Use lighttpd or nginx server for static assets such as js/css/images.
  2. phpcgi1.lan.cyberciti.biz and phpcgi2.lan.cyberciti.biz – Apache web-server with php used for generating dynamic content.
  3. mysql1.lan.cyberciti.biz – MySQL database server.
  4. mcache1.lan.cyberciti.biz – Memcached server is very fast caching system for MySQL. It uses libevent or epoll (Linux runtime) to scale to any number of open connections and uses non-blocking network I/O.
  5. LB01 – A nginx web and reverse proxy server in front of Apache Web servers. All connections coming from the Internet addressed to one of the Web servers are routed through the nginx proxy server, which may either deal with the request itself or pass the request wholly or partially to the main web servers. LB01 provides simple load-balancing.

#26 Additional Tools

From the project page [58]:

PHPIDS (PHP-Intrusion Detection System) is a simple to use, well structured, fast and state-of-the-art security layer for your PHP based web application. The IDS neither strips, sanitizes nor filters any malicious input, it simply recognizes when an attacker tries to break your site and reacts in exactly the way you want it to.

You can use PHPIDS to detect malicious users, and log any attacks detected for later review. Please note that I’ve personally not used this tool.

From the project page [59]:

PhpSecInfo provides an equivalent to the phpinfo() function that reports security information about the PHP environment, and offers suggestions for improvement. It is not a replacement for secure development techniques, and does not do any kind of code or app auditing, but can be a useful tool in a multilayered security approach.

Security Information About PHP Application [60]Fig.02: Security Information About PHP Application

See Linux security hardening tips [61] which can reduce available vectors of attack on the system.

A Note About PHP Backdoors

You may come across php scripts or so called common backdoors such as c99, c99madshell, r57 and so on. A backdoor php script is nothing but a hidden script for bypassing all authentication and access your server on demand. It is installed by an attackers to access your server while attempting to remain undetected. Typically a PHP (or any other CGI script) script by mistake allows inclusion of code exploiting vulnerabilities in the web browser. An attacker can use such exploiting vulnerabilities to upload backdoor shells which can give him or her a number of capabilities such as:

  • Download files
  • Upload files
  • Install rootkits
  • Set a spam mail servers / relay server
  • Set a proxy server to hide tracks
  • Take control of server
  • Take control of database server
  • Steal all information
  • Delete all information and database
  • Open TCP / UDP ports and much more

Tip: How Do I Search PHP Backdoors?

Use Unix / Linux grep command [62] to search c99 or r57 shell:
# grep -iR 'c99' /var/www/html/
# grep -iR 'r57' /var/www/html/
# find /var/www/html/ -name \*.php -type f -print0 | xargs -0 grep c99
# grep -RPn "(passthru|shell_exec|system|base64_decode|fopen|fclose|eval)" /var/www/html/

Conclusion

Your PHP based server is now properly harden and ready to show dynamic webpages. However, vulnerabilities are caused mostly by not following best practice programming rules. You should be consulted further resources for your web applications security needs especially php programming which is beyond the scope of sys admin work.

References:

  1. PHP security [63] – from the official php project.
  2. PHP security guide [64] – from the PHP security consortium project.
  3. Apache suseexec [65] – documentation from the Apache project.
  4. Apache 2.2 [66] – security tips from the Apache project.
  5. The Open Web Application Security Project [67] – Common types of application security attacks.

Recommended readings:

  1. PHP Security Guide [68]: This guide aims to familiarise you with some of the basic concepts of online security and teach you how to write more secure PHP scripts. It’s aimed squarely at beginners, but I hope that it still has something to offer more advanced users.
  2. Essential PHP Security [69] (kindle [70] edition): A book about web application security written specifically for PHP developers. It covers 30 of the most common and dangerous exploits as well as simple and effective safeguards that protect your PHP applications.
  3. SQL Injection Attacks and Defense [71] This book covers sql injection and web-related attacks. It explains SQL injection. How to find, confirm, and automate SQL injection discovery. It has tips and tricks for finding SQL injection within the code. You can create exploits using SQL injection and design to avoid the dangers of these attacks.

Please add your favorite php security tool or tip in the comments.

Updated for accuracy!

Important Message from nixCraft:

4000+ howtos and counting! Want to read more Linux / UNIX howtos, tips and tricks? We request you to sign up for the following to ensure that you make the most from our guides / howtos:

  1. RSS feed for nixCraft – Get intimated about our new howtos / faqs as soon as it is released.
  2. Daily email newsletter or weekly newsletter – Get intimated about our new howtos / faqs as soon as it is released via email.

We will NEVER rent, sell, or give away your e-mail address to anyone for any reason.

Article printed from nixCraft: http://www.cyberciti.biz/

URL to article: http://www.cyberciti.biz/tips/php-security-best-practices-tutorial.html

#!/bin/sh
BADIPS=$(netstat -an | grep -i ':80'|grep 'EST' | awk '{print $5}' | cut -d: -f1 | sort | uniq -c | awk '{if($1 > 50) {print $2}}')
for i in $BADIPS
do
echo $i
echo $i >> /tmp/banip
/sbin/iptables -A INPUT -p tcp -j DROP -s $i
done

HttpLimitZoneModule  配置说明

This module makes it possible to limit the number of simultaneous connections for the assigned session or as a special case, from one address.

Example configuration

http {
  limit_zone   one  $binary_remote_addr  10m;
 
  server {
    location /download/ {
      limit_conn   one  1;
    }
  }
}

HttpLimitReqModule  配置说明

This module allows you to limit the number of requests for a given session, or as a special case, with one address.

Restriction done using leaky bucket.

Example Configuration

http {
    limit_req_zone  $binary_remote_addr  zone=one:10m   rate=1r/s;

    ...

    server {

        ...

        location /search/ {
            limit_req   zone=one  burst=5;
        }

1、 mod_evasive 介绍;

mod_evasive 是Apache(httpd)服务器的防DDOS的一个模块。对于WEB服务器来说,是目前比较好的一个防护DDOS攻击的扩展模块。虽然并不能完全防御 DDOS攻击,但在一定条件下,还是起到缓服Apache(httpd)服务器的压力。如果配合iptables、硬件防火墙等防火墙设备配合使用,可能 有更好的效果。可惜LinuxSir.Org 并没有硬件防火墙,所以是否这种组合效果有更好的效果,我没办法验证。

mod_evasive 的官方地址: http://www.zdziarski.com/projects/mod_evasive


2、 mod_evasive 的安装和配置;


2.1 mod_evasive 的下载地址;

mod_evasive_1.10.1.tar.gz


2.2 mod_evasive 的安装;

安装 mod_evasive 之前,你要用安装Apache(httpd)服务器软件包,还要安装httpd-devel或 apache-dev。在Slackware 12.0中,安装httpd软件即可;

 

#tar zxvf mod_evasive_1.10.1.tar.gz
#cd mod_evasive
#/usr/sbin/apxs -i -a -c mod_evasive20.c

注:apxs 用于编译模块工具;如果是用系统自带的软件包,一般位于/usr/sbin目录。如果您是自己编译安装Apache(httpd)的,你应该自己来指定路径;

我们然后修改/etc/ld.so.conf 文件,把编译出来的动态模块的所在位置指定在 ld.so.conf中;比如我用的是Aapche 2.x ,编译完成后,模块mod_evasive20.so 安装到了 /usr/lib/httpd/modules 目录中;那我们就要把 这个目录写入到ld.so.conf中。

#echo "/usr/lib/httpd/modules" >> /etc/ld.so.conf
#ldconfig

注: 具体要与你的系统环境为准,不要照搬照抄,如果你对Linux不太熟的话;


2.3 mod_evasive 的配置;

在编译安装完成后,会自动插入一行到Apache 配置文件中,对于Apache 2.x 版本中,应该在其配置文件中有类似下面的一行;

LoadModule evasive20_module   lib/httpd/modules/mod_evasive20.so

对于Apache 1.x来说,也应该差不多,大体只是路径不同罢了;

然后我们再修改 Apache 的配置文件,配置文件名为httpd.conf;

 

在Apache v2.x加入;

<IfModule mod_evasive20.c>
DOSHashTableSize    3097
DOSPageCount        2
DOSSiteCount        50
DOSPageInterval     1
DOSSiteInterval     1
DOSBlockingPeriod   10
</IfModule>

 

相关参数
DOSHashTableSize 3097:定义哈希表大小。
DOSSiteCount 50:允许客户机的最大并发连接。
DOSPageCount 2:允许客户机访问同一页的间隔。
DOSPageInterval 1:网页访问计数器间隔。
DOSSiteInterval 1:全站访问计数器间隔。
DOSSiteInterval 60:加入黑名单后拒绝访问时间。
DOSEmailNotify [email protected]:有IP加入黑名单后通知管理员。
DOSSystemCommand “sudo iptables -A INPUT -s %s -j DROP”:IP加入黑名单后执行的系统命令。
DOSLogDir “/tmp”:锁定机制临时目录。
DOSWhiteList 127.0.0.1:防范白名单,不阻止白名单IP。

如果您不知道把这些插入到哪,用下面的办法做也是可以的;

在/etc目录中创建一个文件,比如mod_evasive.conf;

#touch /etc/mod_evasive.conf

然后把根据自己的Apache版本来加入相应的内容;

接着我们再修改 httpd.conf ,在最后一行加入

Include /etc/mod_evasive.conf

修改完成后,我们要重启Apache服务器;

比如在Slackware 12.0中,Apache 2.x的重启,我们要用到

#/etc/rc.d/rc.httpd restart

在Redhat、Fededora、Debian、Ubuntu、CentOS中的Apache,可以用;

#/etc/init.d/httpd restart

#/etc/init.d/apache restart

大体上差不多是这样的……


2.4 对mod_evasive测试验证 ;

防DDOS的模块做好后,我们可以要验证,可以用Apache 自带的ab工具,系统默认安装在/usr/sbin目录中;比如;

#/usr/sbin/ab -n 1000 -c 50 http://www.google.com:80/

注:上面的例子的意思是,如果您的服务器是google的WEB服务器,我们要发送数据请求包,总共1000个,每次并发50个;

另外一个测试工具就是mod_evasive的解压包的目录中,有个test.pl ,你可以修改IP地址,然后用

#perl test.pl

是不是有效果,请根据 ab工具或 测试脚本出来的结果来查看;

因为我们编译mod_evasive时,用的是默认配置,所以日志被存放在/tmp目录中。如果有DDOS攻击,会在/tmp产生日志。日志的文件是以 dos-开头的;


3、mod_evasive 的高级配置;

如果想更改一些适合自己的参数,有些必要的参数,并不是通过配置文件修改就一下起作用的,我们要修改源码包中的 mod_evasive.c(Apache 1.x用之) 或 mod_evasive20.c (Apache 2.x用之);

#define DEFAULT_HASH_TBL_SIZE   3097ul  // Default hash table size
#define DEFAULT_PAGE_COUNT      2       // Default maximum page hit count per interval
#define DEFAULT_SITE_COUNT      50      // Default maximum site hit count per interval
#define DEFAULT_PAGE_INTERVAL   1       // Default 1 Second page interval
#define DEFAULT_SITE_INTERVAL   1       // Default 1 Second site interval
#define DEFAULT_BLOCKING_PERIOD 10      // Default for Detected IPs; blocked for 10 seconds
#define DEFAULT_LOG_DIR         "/tmp"  // Default temp directory

比如我们改改其中的数字,根据英文很容易理解。比如修改日志存放目录,就把/tmp改成别的目录。如果您不知道放在哪好,还是用默认的吧;

如果您在这里更改了参数,不要忘记修改Apache 配置文件中关于mod_evasive 的参数;

如果您想加入一些其它的参数,请查阅源码包中的README,里面有详细说明,大多来说没太大的必要……

这个文件相当重要,如果您想更改某些设置,就要修改这个文件……


4、关于本文;

mod_evasive 还是有点用的,安装也不费力气。如果你需要的时候,会想到这个模块的 …… mod_evasive 是否有更高级的用法,也不是在这篇文章里能说的清楚的。如果不懂怎么办?请查看源码包中的README。

本文权当做软件说明 ……

北南 记之

From LinuxSir.Org


5、参考文档;

参考 mod_evasive 源码包中的README ……

1. 禁用危险函数

vi /etc/php.ini
disable_functions = proc_open,phpinfo,show_source,system,shell_exec,passthru,exec,popen

2. 限制php活动范围

open_basedir = /tmp/:/raid0/www/html/

(D)DoS Deflate 一个轻量级帮助你抵挡DDOS攻击的BASH 脚本.

It utilizes the command below to create a list of IP addresses connected to the server, along with their total number of connections. It is one of the simplest and easiest to install solutions at the software level.

netstat -ntu | awk '{print $5}' | cut -d: -f1 | sort | uniq -c | sort -n

IP addresses with over a pre-configured number of connections are automatically blocked in the server’s firewall, which can be direct iptables or Advanced Policy Firewall (APF). (We highly recommend that you use APF on your server in general, but deflate will work without it.)

Notable Features

  • It is possible to whitelist IP addresses, via /usr/local/ddos/ignore.ip.list.
  • Simple configuration file: /usr/local/ddos/ddos.conf
  • IP addresses are automatically unblocked after a preconfigured time limit (default: 600 seconds)
  • The script can run at a chosen frequency via the configuration file (default: 1 minute)
  • You can receive email alerts when IP addresses are blocked.

Installation

wget http://www.inetbase.com/scripts/ddos/install.sh
chmod 0700 install.sh
./install.sh

Uninstallation

wget http://www.inetbase.com/scripts/ddos/uninstall.ddos
chmod 0700 uninstall.ddos
./uninstall.ddos

Questions?

Although most things are explained on this page, if you have any further questions, you may contact the original developer of the script, Zaf.

mysql安全设置及性能优化配置全攻略,注意在不熟悉的情况下更改设置前最好进行备份,以免出错。

1、修改root用户的的口令

缺省情况下MySQL没有设置密码,我们可以用三种方法设置密码头:

*  用mysqladmin命令来改root用户口令
# mysqladmin -uroot password ecan5com //设置MySQL管理操作用户root的密码为52netseek

*  用set password修改口令:
mysql> set password for [email protected]=password(‘ecan5com’);

*  直接修改user表的root用户口令
mysql> use mysql;
mysql> update user set password=password(‘ecan5com’) where user=’root’;
mysql> flush privileges;

2、删除默认的数据库和用户

我们的数据库是在本地,并且也只需要本地的php脚本对mysql进行读取,所以很多用户不需要。m
ysql初始化后会自动生成空用户和test库,这会对数据库构成威胁,我们全部删除。
我们使用mysql客户端程序连接到本地的mysql服务器后出现如下提示:
mysql> drop database test;
mysql> use mysql;
mysql> delete from db;
mysql> delete from user where not(host=”localhost” and user=”root”);
mysql> flush privileges;

3、 改变默认mysql管理员的名称 //仅为建议

根据个人习惯,因为默认的mysql的管理员名称是root,所以如果能够修改的话,
能够防止一些脚本小子对系统的穷举。我们可以直接修改数据库,把root用户改为”admin”
mysql> use mysql;
mysql> update user set user=”admin” where user=”root”;
mysql> flush privileges;

4、提高本地安全性

提高本地安全性,主要是防止mysql对本地文件的存取,比如黑客通过mysql把/etc/passwd获取了,会对系统构成威胁。
mysql对本地文件的存取是通过SQL语句来实现,主要是通过Load DATA LOCAL INFILE来实现,我们能够通过禁用该功能来
防止黑客通过SQL注射等获取系统核心文件。 禁用该功能必须在 my.cnf 的[mysqld]部分加上一个参数:
set-variable=local-infile=0

5、禁止远程连接mysql

因为我们的mysql只需要本地的php脚本进行连接,所以我们无需开socket进行监听,那么我们完全可以关闭监听的功能。
有两个方法实现:
* 配置my.cnf文件,在[mysqld]部分添加 skip-networking 参数
* mysqld服务器中参数中添加 –skip-networking 启动参数来使mysql不监听任何TCP/IP连接,增加安全性。如果要进行mysql的管理的话,可以在服务器本地安装一个phpMyadmin来进行管理。

6、控制数据库访问权限

对于使用php脚本来进行交互,最好建立一个用户只针对某个库有 update、select、delete、insert、drop table、create table等权限,这样就很好避免了数据库用户名和密码被黑客查看后最小损失。
比如下面我们创建一个数据库为db1,同时建立一个用户test1能够访问该数据库。
mysql> create database db1;
mysql> grant select,insert,update,delete,create,drop privileges on db1.* to [email protected] identified by ‘admindb’;
以上SQL是创建一个数据库db1,同时增加了一个test1用户,口令是admindb,但是它只能从本地连接mysql,对db1库有select,insert,update,delete,create,drop操作权限。

7、限制一般用户浏览其他用户数据库

如果有多个数据库,每个数据库有一个用户,那么必须限制用户浏览其他数据库内容,可以在启动MySQL服务器时加–skip-show-database 启动参数就能够达到目的。

忘记mysql密码的解决办法
如果不慎忘记了MySQL的root密码,我们可以在启动MySQL服务器时加上参数 –skip-grant-tables来跳过授权表的验证 (./safe_mysqld –skip-grant-tables &),这样我们就可以直接登陆MySQL服务器,然后再修改root用户的口令,重启MySQL就可以用新口令登陆了。

8、数据库文件的安全

我们默认的mysql是安装在/usr/local/mysql目录下的,那么对应的数据库文件就是在/usr/local/mysql/var目录下,那么我们要保证该目录不能让未经授权的用户访问后把数据库打包拷贝走了,所以要限制对该目录的访问。
我们修改该目录的所属用户和组是mysql,同时改变访问权限:
# chown -R mysql.mysql /usr/local/mysql/var
# chmod -R go-rwx /usr/local/mysql/var

9、删除历史记录

执行以上的命令会被shell记录在历史文件里,比如bash会写入用户目录的.bash_history文件,如果这些文件不慎被读,
那么数据库的密码就会泄漏。用户登陆数据库后执行的SQL命令也会被MySQL记录在用户目录的.mysql_history文件里。
如果数据库用户用SQL语句修改了数据库密码,也会因.mysql_history文件而泄漏。所以我们在shell登陆及备份的时候
不要在-p后直接加密码,而是在提示后再输入数据库密码。 另外这两个文件我们也应该不让它记录我们的操作,以防万一。
# rm .bash_history .mysql_history
# ln -s /dev/null .bash_history
# ln -s /dev/null .mysql_history

10、其他

另外还可以考虑使用chroot等方式来控制mysql的运行目录,更好的控制权限,具体可以参考相关文章。
my.cnf的调试参数

11、快速修复MySQL数据库

修复数据库
# mysqlcheck -A -o -r -p
修复指定的数据库
# mysqlcheck  -o -r Database_NAME -p

12、跟据内存的大小选择MySQL的负载,选择相应的文件名复制到/etc/my.cnf

如果是RPM包安装:/usr/share/doc/mysql-XXX/目录下有
如果是源代码编译安装:support-files/目录下有.
cp /usr/local/share/mysql-***/my-large.cnf /etc/my.cnf
my-small.cnf # > my-medium.cnf # 32M – 64M
my-large.cnf # memory = 512M
my-huge.cnf # 1G-2G
my-innodb-heavy-4G.cnf # 4GB

阅读了本文,你是否对mysql安全设置及性能优化配置有了更好的认识,如果你觉的本文不错!请分享到您的空间与微博,让更多好友分享及下次需要查看的时候能快速找到本文!