Thursday, July 28, 2011

Security precautions before you start using PHP on your Apache server, step by step

SkyHi @ Thursday, July 28, 2011

Introduction - what is PHP?

PHP is a server side scripting language. You can embed PHP code in your web pages along with HTML. When your server receives a request for a page, it first gives the page to the PHP handler program. The PHP handler outputs HTML code as-is, but when it encounters PHP commands, it executes them. Any HTML generated by the PHP commands is also output. The end result is a web page with content that has been customized on the server before being sent to whoever requested it.
PHP has capabilities that make it a potential security risk:
  • It can receive and process data from the "outside world"
  • It can be programmed to actively fetch data from anywhere on the internet
  • It is able to read and write files on the server
If you have a website, you can expect to be under constant attack from robots attempting to a) "send in" malicious data and scripts from the outside world, b) trick your server into fetching malicious scripts and running them, c) read and write files on your server. Their goal is to take control of your site and use it for their own purposes. 
This article gives configuration settings for PHP and rules for PHP coding that are effective at blocking the most common types of attacks. The configuration lines are few and the rules are simple.
There are two files where PHP configuration commands can go: php.ini or Apache .htaccess.
You should use php.ini as your first choice, if you can. You should be able to use it if:
  • You are on shared hosting at a webhost that uses suPHP or any other configuration that allows individual users to create their own php.ini files. If in doubt, ask them.
  • You are on dedicated hosting (your own rented server), or
  • You host your own website on your own server.

1a) Configure PHP settings with a php.ini file

php.ini specifies the configuration settings PHP will use when it is running on your website. It determines what things PHP scripts are allowed to do and what they are prohibited from doing. The following settings affect security.
In your public_html (the same folder where your site's main home page is), create a text file called php.ini that contains these lines. Instructions for customizing the text shown in red are farther down this page:
allow_url_fopen = Off
display_errors = Off
display_startup_errors = Off
log_errors = On
error_reporting = E_ALL
error_log = /home/yourUserID/public_html/phperr.txt
expose_php = Off
magic_quotes_gpc = On
magic_quotes_sybase = Off
register_globals = Off

Explanations:

These explanations are brief. This page of the PHP Manual has links to more.

allow_url_fopen = Off

allow_url_fopen = Off is especially important. It prevents URLs (internet addresses) from being used in PHP include() statements and in some other places. A command such as include("http://website.com/page.php") will not be allowed to execute. Only files that reside within your website can be included, and you must refer to them by their filepath names, not by their internet URLs. You won't be able to include a file from a different server, but neither will anybody else. When someone else does it maliciously by embedding the URL in an otherwise innocent-looking HTTP request and hoping that your script can be tricked into including and running their script, it's called a Remote File Inclusion (RFI) attack. Having allow_url_fopen = Off dooms all such attacks to fail.
Some webmasters think they need to have allow_url_fopen = On because their pages are already coded to use URLs to include files from their own site or from some external site. It is worth expending some effort to try to stop doing that so that you can turn allow_url_fopen off:
  1. You can include a file from your own site simply by specifying its path and filename. Here is an example how to convert a URL include to one that does not use a URL:

    Assume your current code looks like this:

    include('http://yoursite.com/page.php');

    You would convert it to this:

    include($_SERVER['DOCUMENT_ROOT'] . '/page.php');

    $_SERVER['DOCUMENT_ROOT'] is a superglobal variable calculated by the server to be the root folder of your site, the equivalent of "/", which is usually public_html. Note that it does not provide a trailing "/", so you must provide a leading "/" in '/page.php'. Now you have a reliable method to refer to any file without having to use relative paths and without using a URL unnecessarily.
     
  2. If you include static content (that doesn't change) from another of your websites, such as
    include('http://myothersite.com/includes/footer.php'),
    you can make a copy of that content in the current site and then include it locally as described above. Having duplicate copies of a few files is a small price to pay for the better security of having allow_url_fopen Off.
     
  3. If you cannot avoid it and must include content from a remote site using URLs, you'll need to set allow_url_fopen = On. You can still get some protection from RFI attacks by using .htaccess to ban incoming requests that contain potentially malicious URLs. See Section 1b) below and follow the link there.
     
  4. You can also prevent RFI, without needing special configuration settings, by writing your PHP scripts to carefully check incoming data to make sure it is not malicious. How to do that is described here

display_errors = Off
display_startup_errors = Off
log_errors = On
error_reporting = E_ALL

These specify that all errors and warnings will be logged to your error log text file. NO errors or warnings will be displayed on any web page that is sent out from your server. Errors should never be displayed publicly because they can help someone figure out how to attack your server. Remember to check your error log when you are testing new code. 

error_log = /home/yourUserID/public_html/phperr.txt

This defines the path and file to which your PHP errors and warnings are logged. Change yourUserID to the cPanel or other UserID assigned to you by your webhost. The filename can be anything you want. The path starting with /home seems to be a common one on Linux servers, but it might vary depending on your webhost. If the above doesn't work, ask them what it should be. public_html is only shown above as an example of where it fits in the path. You don't have to put your error log inside public_html. See below.
I recommend using a text file for error logging (as shown above), and not using the "system log" option that you might see mentioned. Your text file will accumulate errors indefinitely until you empty it, while the Apache system log can be flushed unpredictably.
Your error log file should be in an area of your webspace that is not publicly accessible. Any one of these methods will protect it:
  1. Put it in a folder that is not inside /public_html.
     
  2. Protect it with an .htaccess file that prohibits web access, like this:

    In cPanel > File Manager, create the folder.
    Inside the folder, create a file called .htaccess (with the leading period).
    Put this text in the file:

    order allow,deny
    deny from all

    Save the file.
    Test it by trying to go to http://yoursite.com/foldername/
    You should get a 403 Forbidden error page.
     
  3. Put it in a folder that is inside /public_html, but apply password protection to the folder. You can do this in cPanel.
With A) and B), you can only view the file with cPanel > File Manager or FTP, not by browser. With C), you can view the file in your browser by entering the password.

expose_php = Off

Not particularly important, but it doesn't hurt. The headers that accompany outgoing pages will not reveal that PHP is running or its version.

magic_quotes_gpc = On

The PHP manual recommends setting this to Off, and dealing with quotes in a secure manner on your own, but we're assuming you don't know how to do that yet, and that you also don't actually have any need yet for the situations it addresses, so for now the best setting is On.

magic_quotes_sybase = Off

Another special setting of "magic quotes". This should be Off.

register_globals = Off

register_globals = Off is especially important. You've probably seen URLs that look like this: http://site.com/index.php?something=somevalue. When register_globals is On, the variable called something is passed into your script with its value set to somevalue. When register_globals is Off, variables passed in like this are not automatically dumped into your script's variable list. This makes it harder for someone to inject their own code.

safe_mode = Off

This setting is not in the "recommended php.ini" above. I only mention it because you might run across it and wonder what it is and how it should be set. It restricts the permissions with which PHP scripts run. However, some very popular third party scripts, which you might want to use eventually, will not run properly when it is set to On. In addition, if your webhost uses suPHP, safe_mode serves no purpose. Lastly, beginning with PHP 6, safe_mode doesn't even exist. Therefore, it is best left out of your php.ini file, or, if present, set to Off.

1b) Alternative: configure PHP in .htaccess

If your webhost does not allow you to create your own php.ini, you can put configuration commands in .htaccess instead. Unfortunately, not all php.ini commands have .htaccess equivalents, but some of them do.
Put the following lines in a part of your public_html/.htaccess file that is not delimited by HTML-style tags such as the tags in the example in Section 3.1 below. The following lines have the same effects as their php.ini counterparts described in Section 1a) above, but notice that the format of the commands is different:
php_flag display_errors Off
php_flag display_startup_errors Off
php_flag log_errors On
php_flag magic_quotes_sybase Off
php_flag magic_quotes_gpc On
php_flag register_globals Off
php_value error_log /home/yourUserID/public_html/phperr.txt
php_value error_reporting 2147483647

The most important is the register_globals line.
It is very unfortunate that allow_url_fopen = Off has no .htaccess counterpart (although it will in PHP6). Because you cannot stop PHP from reading a file from a remote server, you need to make sure requests that try to do that maliciously are blocked so they cannot reach the PHP processor. A previous article has instructions how to use .htaccess to block requests that might be Remote File Inclusion attacks.
The following two also cannot be set in .htaccess, but they are unimportant:
expose_php = Off
safe_mode = Off

1c) What if the above configuration settings don't work?

If you ever write code that won't run properly with the above settings, you are leaving behind your "beginner" status and need to study PHP security more carefully before you go any further. The Security section of the PHP Manual is one reference that should be read at some point, but it isn't easy and probably isn't the best place to start. 

2) Viewing your PHP settings

Your server can give you a complete report of all your PHP settings.
  1. Create a text file with a .php extension, containing just this line:


     
  2. Upload it to your server into (preferably) a password protected folder.
  3. Open your browser and type the path into the address bar:
    http://yoursite.com/whatever/filename.php.
  4. Enter your username and password to enter the protected folder and view the result page.
  5. Save or print the result page to your local computer for reference.
  6. Delete the .php file from your server. It is not good to leave this file lying around where somebody else can run it and see how your server is configured. 

3) Modify your .htaccess file

  1. Important if you use php.ini: In your public_html/.htaccess file, add the following lines if they are not already there. Reference information for these lines is in the Apache manual section for mod_access:
# This denies all web access to your php.ini file.

order allow,deny
deny from all

  1. Required when using suPHP: If your webhost uses suPHP, you will need to enter a suPHP_ConfigPath line that tells PHP the location of your php.ini file. It will look something like this, but if this doesn't work, ask your web host what the line should be. Put this in a part of the file that is not between HTML-style tags like the tags in the paragraph above:

    suPHP_ConfigPath /home/yourUserID/public_html
     
  2. Optional: If you are adding PHP code to your existing .html files and don't want to rename them all to .php, you can instruct the server to send all .html files through the PHP processor as if they had .php extensions. To do that, add one of these lines into .htaccess, in a part of the file that is not delimited by tags. If one doesn't work, try another; experiment. 

    If you are using suPHP:
    AddHandler x-httpd-php .htm .html

    If you are not using suPHP:
    AddType application/x-httpd-php .htm .html

    Apache 2 without suPHP:
    AddHandler application/x-httpd-php .htm .html

4) One more php.ini setting, advanced...

The settings list in Section 1a) was supposed to be as simple as possible, usable by anyone, with a minimum of effort required, but there is one more php.ini setting that's worth using if you can. Here is an example of its use, with a list of some of the functions that could be disabled for increased security:
disable_functions = exec,shell_exec,passthru,system,eval,show_source,proc_open, popen,parse_ini_file,dl,(comma-separated list of function names)
This tells PHP not to allow the listed functions to be executed by any script in your site. The functions listed above are especially powerful, and many malicious scripts use them. By blocking their use, you block the scripts from causing much of their damage even if they do somehow manage to get into your site and run.
However, some of these functions are used by popular third party PHP scripts such as forums, blogs, galleries, and shopping carts, so the reason I call this an "advanced" setting is that before using this line you must search all the PHP code in your site to make sure you don't disable functions that your site requires. Nevertheless, disabling functions you don't use is worthwhile if you don't mind doing the research.
disable_functions is for php.ini only. It has no .htaccess equivalent.

5) Memorize these best coding practices

Beginner Rules:

  • Never use the PHP eval() function.
  • Never use PHP to connect to a database. (What this means is that while you are a beginner, you should not connect to a database at all, until you have studied the hazards of "SQL injection" attacks and understand how to write your code properly to guard against them.)
  • Never use the $_GET, $_POST, $_COOKIE, $_REQUEST, or $_FILES variables. These bring data into your script from the outside world. The data has the potential of being malicious.

Advanced Rule:

When the time comes that you need to break one of the Beginner Rules, first do a web search on: PHP security and spend a few days practicing proper coding techniques for the methods and functions you plan to use. 

6) Things to do

If necessary, email your web host. Ask these questions, and then modify your php.ini or .htaccess file as needed:
  1. Am I allowed to have my own php.ini file?
     
  2. I want to create an error log for PHP. Are these paths ok?

    php.ini  : error_log = /home/yourUserID/public_html/phperr.txt
    .htaccess: php_value error_log /home/yourUserID/public_html/phperr.txt

     
  3. Does my server use suPHP? If so, is this the correct line for .htaccess?

    suPHP_ConfigPath /home/yourUserID/public_html

7) You're ready to start. Good luck and have fun.

Additional security precautions for protecting your website are at
How to prevent your website from being hacked. How to repair a damaged site.

REFERENCES
http://25yearsofprogramming.com/blog/20070808.htm

How to prevent base 64 encode attack

SkyHi @ Thursday, July 28, 2011
If you look in the source code of your PHP files and see that there is a call to eval and base 64 decode that you didn't put there, then your site has been hacked. When this happens, usually there are no records of anyone FTPing or SSHing to your site, leaving you scratching your head as to how in the world this hacker got that code into your site.

How did it get there?

I'm not entirely sure of the vulnerability that lets this hack in, but I do know that after being repeatedly hit with it for several weeks, I managed to stop it entirely after I updated my PHP configuration to forbid the fopen and file_get_contents functions from opening off-site URLs.
This seems to suggest that there was code somewhere on my site that was allowing a malicious user's script to execute on my server, which was able to then write the eval base 64 decode function calls into all of my PHP files. Since I have seen this happen to Wordpress users, it looks like Wordpress has the vulnerability in it somewhere.

How do I stop it?

First, add the following lines to your php.ini file. Check with your hosting provider to find out if and how you can edit your php.ini file.
allow_url_fopen = off
allow_url_include = off
disable_functions = "apache_child_terminate, apache_setenv, define_syslog_variables, escapeshellarg, escapeshellcmd, eval, exec, fp, fput, ftp_connect, ftp_exec, ftp_get, ftp_login, ftp_nb_fput, ftp_put, ftp_raw, ftp_rawlist, highlight_file, ini_alter, ini_get_all, ini_restore, inject_code, mysql_pconnect, openlog, passthru, php_uname, phpAds_remoteInfo, phpAds_XmlRpc, phpAds_xmlrpcDecode, phpAds_xmlrpcEncode, popen, posix_getpwuid, posix_kill, posix_mkfifo, posix_setpgid, posix_setsid, posix_setuid, posix_setuid, posix_uname, proc_close, proc_get_status, proc_nice, proc_open, proc_terminate, shell_exec, syslog, system, xmlrpc_entity_decode"

Once you've done this, REMOVE ALL INSTANCES OF THE MALICIOUS CODE FROM YOUR SITE. This attack tends to add the bad code to every PHP file on your site, so you might want to run a script to remove all occurrences of it. The bad code can still work even if you add those lines to your php.ini file, so it is imperative that you get rid of all of it as soon as possible.
If you use fopen or file_get_contents on your site, they might stop working after you make this change. If your web host has the CURL module installed with PHP, then you can use that to load off-site URLs.
The above changes will disable the functions that make PHP the most vulnerable. However, if your site depends on any of them, you will have to either find a different way to do it, or to enable the functions that you need.
Above all, NEVER use a variable in a call to a function like fopen or file get contents. Look for any places in your code where a malicious user could inject malicious code. Read more about how to prevent cross-site scripting (XSS) attacks.

What does it do?

The eval base 64 decode code is actually a PHP or JavaScript function call, encoded in base 64. The eval function runs the decoded text. In this way, the hacker can run any PHP function that he or she wants to. Usually, this is used to put malware onto your site. Whenever you see Google warn you that a site has malware on it, it might be because an otherwise good site has been hit with this hack.

REFERENCES
http://www.thonky.com/how-to/prevent-base-64-decode-hack/

Disabling Dangerous PHP Functions

SkyHi @ Thursday, July 28, 2011
Have you ever wondered which PHP functions are termed to be highly dangerous in web hosting & should promptly be left disabled in the configuration ?

PHP is a powerful language which; when used in an improper way, either unknowingly; carries the potential to mess up with a web hosting server & hack/exploit user accounts further upto root level. Hackers using an insecure PHP script as an entry point to a web hosting server can start unleashing dangerous commands and take control over the complete server quickly.. Certain functions which are used in such scripts are termed to be dangerous & are turned off in the PHP configuration. Let's find out which functions are dangerous & how they are turned off..

Here's a complete list of such functions which are needed to be stopped from being executed within any website on your web hosting server:

Quote:
"apache_child_terminate, apache_setenv, define_syslog_variables, escapeshellarg, escapeshellcmd, eval, exec, fp, fput, ftp_connect, ftp_exec, ftp_get, ftp_login, ftp_nb_fput, ftp_put, ftp_raw, ftp_rawlist, highlight_file, ini_alter, ini_get_all, ini_restore, inject_code, mysql_pconnect, openlog, passthru, php_uname, phpAds_remoteInfo, phpAds_XmlRpc, phpAds_xmlrpcDecode, phpAds_xmlrpcEncode, popen, posix_getpwuid, posix_kill, posix_mkfifo, posix_setpgid, posix_setsid, posix_setuid, posix_setuid, posix_uname, proc_close, proc_get_status, proc_nice, proc_open, proc_terminate, shell_exec, syslog, system, xmlrpc_entity_decode"
Locate your php.ini and then edit:
Quote:
root@server [~]# php -i | grep php.ini
You'd get "Configuration File (php.ini) Path => /etc/php.ini" or any other different location, such as /usr/local/lib/php.ini

Now edit the file using your favourite editor :
Quote:
root@server [~]# vi /etc/php.ini
Search for the following text within that configuration file & modify disable_functions = "" to
Quote:
disable_functions = "apache_child_terminate, apache_setenv, define_syslog_variables, escapeshellarg, escapeshellcmd, eval, exec, fp, fput, ftp_connect, ftp_exec, ftp_get, ftp_login, ftp_nb_fput, ftp_put, ftp_raw, ftp_rawlist, highlight_file, ini_alter, ini_get_all, ini_restore, inject_code, mysql_pconnect, openlog, passthru, php_uname, phpAds_remoteInfo, phpAds_XmlRpc, phpAds_xmlrpcDecode, phpAds_xmlrpcEncode, popen, posix_getpwuid, posix_kill, posix_mkfifo, posix_setpgid, posix_setsid, posix_setuid, posix_setuid, posix_uname, proc_close, proc_get_status, proc_nice, proc_open, proc_terminate, shell_exec, syslog, system, xmlrpc_entity_decode"
After modifying the PHP configuration, the Apache web server needs to be restarted.. for the above done changes to take effect.

If you find any problems with your web-applications after disabling these above mentioned functions, it's recommended to recheck your code & find an alternative solution, rather than risking the complete server for a mere application..

Note that the above mentioned solution is applicable for both type of servers, Linux web hosting server & for Windows web hosting servers as well.. The PHP configuration on Windows is generally found in the C:\Windows folder.. Make sure you restart IIS web server PHP config modifications on windows servers too..

REFERENCES
http://www.eukhost.com/forums/f42/disabling-dangerous-php-functions-6020/

Suhosin" security extension for PHP

SkyHi @ Thursday, July 28, 2011
I encountered the same problem recently. The only solution I've found is to use the (very useful, in my opinion) "Suhosin" security extension for PHP, and set its suhosin.executor.func.blacklist parameter in php.ini, instead of using PHP's disable_functions directive. I have mine set to the following, which I believe covers a lot of the more "dangerous" functions but is by no means exhaustive (I also have dl() disabled with "enable_dl = Off" in php.ini):

Code:
suhosin.executor.func.blacklist = apache_note,apache_setenv,closelog,debugger_off,debugger_on,define_syslog_variables,escapeshellarg,escapeshellcmd,exec,ini_restore,openlog,passthru,pclose,pcntl_exec,popen,proc_close,proc_get_status,proc_nice,proc_open,proc_terminate,shell_exec,syslog,system,url_exec
This can then be set on a per-virtualhost or per-directory basis, which I did by logging into DA as admin, and under Custom HTTPD Configurations, adding the following to the relevant domain:

Code:
# Omit the ... section to apply settings globally in the VirtualHost. I usually copy my settings for the blacklist from php.ini, and then remove any needed functions from it when pasting here, thus permitting them.


php_admin_value suhosin.executor.func.blacklist list-of-functions-to-disable
Suhosin also provides a whitelist option, if you feel like working out which functions your PHP code uses... I know I don't.



OK i've installed as an extension, it works perfectly, now i'll try to configure some parameter to aument the quantitiy of logging.

Tnx a lot for suggestions

I've disable a lot of functions on all the directory except one, enebled those again with something like this

<Directory /usr/share/squirrelmail>
Options None
AllowOverride None
Order allow,deny
Allow from all
php_admin_value suhosin.executor.func.blacklist " "
</Directory>

In this way in the directory /usr/share/squirrelmail i can execute all the code i want even if in the php.ini i've disable a lot of function like

suhosin.executor.func.blacklist = system, exec, proc_open, proc_close, popen, passthru, shell_exec, dl, show_source, highlight_file, pcntl_exec, ......

Tnx a lot again to all has helped me solve this problem

REFERENCES
http://www.directadmin.com/forum/showthread.php?t=17076
http://www.eukhost.com/forums/f42/disabling-dangerous-php-functions-6020/

Tuesday, July 26, 2011

Understanding Linux CPU Load - when should you be worried

SkyHi @ Tuesday, July 26, 2011
You might be familiar with Linux load averages already. Load averages are the three numbers shown with the uptime and top commands - they look like this:
load average: 0.09, 0.05, 0.01
Most people have an inkling of what the load averages mean: the three numbers represent averages over progressively longer periods of time (one, five, and fifteen minute averages), and that lower numbers are better. Higher numbers represent a problem or an overloaded machine. But, what's the the threshold? What constitutes "good" and "bad" load average values? When should you be concerned over a load average value, and when should you scramble to fix it ASAP?
First, a little background on what the load average values mean. We'll start out with the simplest case: a machine with one single-core processor.

The traffic analogy

A single-core CPU is like a single lane of traffic. Imagine you are a bridge operator ... sometimes your bridge is so busy there are cars lined up to cross. You want to let folks know how traffic is moving on your bridge. A decent metric would be how many cars are waiting at a particular time. If no cars are waiting, incoming drivers know they can drive across right away. If cars are backed up, drivers know they're in for delays.
So, Bridge Operator, what numbering system are you going to use? How about:
  • 0.00 means there's no traffic on the bridge at all. In fact, between 0.00 and 1.00 means there's no backup, and an arriving car will just go right on.
  • 1.00 means the bridge is exactly at capacity. All is still good, but if traffic gets a little heavier, things are going to slow down.
  • over 1.00 means there's backup. How much? Well, 2.00 means that there are two lanes worth of cars total -- one lane's worth on the bridge, and one lane's worth waiting. 3.00 means there are three lane's worth total -- one lane's worth on the bridge, and two lanes' worth waiting. Etc.
= load of 1.00
= load of 0.50
= load of 1.70


This is basically what CPU load is. "Cars" are processes using a slice of CPU time ("crossing the bridge") or queued up to use the CPU. Unix refers to this as the run-queue length: the sum of the number of processes that are currently running plus the number that are waiting (queued) to run.
Like the bridge operator, you'd like your cars/processes to never be waiting. So, your CPU load should ideally stay below 1.00. Also like the bridge operator, you are still ok if you get some temporary spikes above 1.00 ... but when you're consistently above 1.00, you need to worry.

So you're saying the ideal load is 1.00?

Well, not exactly. The problem with a load of 1.00 is that you have no headroom. In practice, many sysadmins will draw a line at 0.70:
  • The "Need to Look into it" Rule of Thumb: 0.70 If your load average is staying above > 0.70, it's time to investigate before things get worse.
  • The "Fix this now" Rule of Thumb: 1.00. If your load average stays above 1.00, find the problem and fix it now. Otherwise, you're going to get woken up in the middle of the night, and it's not going to be fun.
  • The "Arrgh, it's 3AM WTF?" Rule of Thumb: 5.0. If your load average is above 5.00, you could be in serious trouble, your box is either hanging or slowing way down, and this will (inexplicably) happen in the worst possible time like in the middle of the night or when you're presenting at a conference. Don't let it get there.

What about Multi-processors? My load says 3.00, but things are running fine!

Got a quad-processor system? It's still healthy with a load of 3.00.
On multi-processor system, the load is relative to the number of processor cores available. The "100% utilization" mark is 1.00 on a single-core system, 2.00, on a dual-core, 4.00 on a quad-core, etc.
If we go back to the bridge analogy, the "1.00" really means "one lane's worth of traffic". On a one-lane bridge, that means it's filled up. On a two-late bridge, a load of 1.00 means its at 50% capacity -- only one lane is full, so there's another whole lane that can be filled.
= load of 2.00 on two-lane road
Same with CPUs: a load of 1.00 is 100% CPU utilization on single-core box. On a dual-core box, a load of 2.00 is 100% CPU utilization.

Multicore vs. multiprocessor

While we're on the topic, let's talk about multicore vs. multiprocessor. For performance purposes, is a machine with a single dual-core processor basically equivalent to a machine with two processors with one core each? Yes. Roughly. There are lots of subtleties here concerning amount of cache, frequency of process hand-offs between processors, etc. Despite those finer points, for the purposes of sizing up the CPU load value, the total number of cores is what matters, regardless of how many physical processors those cores are spread across.
Which leads us to a two new Rules of Thumb:
  • The "number of cores = max load" Rule of Thumb: on a multicore system, your load should not exceed the number of cores available.
  • The "cores is cores" Rule of Thumb: How the cores are spread out over CPUs doesn't matter. Two quad-cores == four dual-cores == eight single-cores. It's all eight cores for these purposes.

Bringing It Home

Let's take a look at the load averages output from uptime:
~ $ uptime
23:05 up 14 days, 6:08, 7 users, load averages: 0.65 0.42 0.36
This is on a dual-core CPU, so we've got lots of headroom. I won't even think about it until load gets and stays above 1.7 or so.
Now, what about those three numbers? 0.65 is the average over the last minute, 0.42 is the average over the last five minutes, and 0.36 is the average over the last 15 minutes. Which brings us to the question:
Which average should I be observing? One, five, or 15 minute?
For the numbers we've talked about (1.00 = fix it now, etc), you should be looking at the five or 15-minute averages. Frankly, if your box spikes above 1.0 on the one-minute average, you're still fine. It's when the 15-minute average goes north of 1.0 and stays there that you need to snap to. (obviously, as we've learned, adjust these numbers to the number of processor cores your system has).
So # of cores is important to interpreting load averages ... how do I know how many cores my system has?
cat /proc/cpuinfo to get info on each processor in your system. Note: not available on OSX, Google for alternatives. To get just a count, run it through grep and word count: grep 'model name' /proc/cpuinfo | wc -l

Monitoring Linux CPU Load with Scout

Scout provides 2 ways to modify the CPU load. Our original server load plugin and Jesse Newland's Load-Per-Processor plugin both report the CPU load and alert you when the load peaks and/or is trending in the wrong direction:
load alert

More Reading

More on Linux Performance

Monday, July 25, 2011

PHP send email from remote

SkyHi @ Monday, July 25, 2011
<?php 

<form method="post" action="http://attacker.sample.com/confirm2.php">
<input type="submit" value="go" />
<input type="hidden" name="save" value="1" />
<input type="hidden" name="applicant_first_name" value="zzzzzzz" />
</form>

Prevention:
if (!stristr ($_SERVER['HTTP_REFERER'], "local.hostname.com")) {
   exit;
}