Take the 2-minute tour ×
Server Fault is a question and answer site for system and network administrators. It's 100% free, no registration required.

We have a company server with a variety of websites. They are maintained by different people from within our company. All websites are public. The server access is limited to our company only. This is NOT a shared hosting environment.

We are looking into securing the server, currently analyzing the risk related to permissions of files. We feel the highest risk is when files are uploaded and then opened/executed by the public. This should not happen, but an error in a script might allow people to do so (there are image uploaders, file uploaders, etc). Uploader scripts use PHP.

So the question is: what is the best way of setting / organizing permissions of files and processes? There seem to be several options to run PHP (and Apache), and setting the permissions. What should we take into consideration? Any tips?

We are considering mod_php and FastCGI, but perhaps given our situation other solutions are preferred?

share|improve this question

5 Answers 5

up vote 3 down vote accepted

I would highly recommend running suPHP. Using suPHP, each website could be compartmentalized to its own username instead of running as the general Apache user. This would mean that if someone would happen to "Hack" into the server due to an insecure script on the server; they would be limited only to that site and not the whole server. The exception is that if there is a root exploit they could gain access to the whole server... but at least suPHP will help to security each individual site.

Once you have Apache/PHP on different users the read/write permissions of the files on the server become important. You could also utilize permissions more fully from an organizational standpoint, allowing users to update files on their website and not just any.

share|improve this answer
    
From what I read suPHP is the way to go then! I will install this and see how it performs - especially its impact on server performance will be monitored by make sure this is not an issue. –  user60129 Jan 4 '11 at 14:08

Two more options with varying security:

  • suexec on apache. Apache may eat memory. (and doesn't work with fcgi I belive)

  • virtual appliances, one for each site. This solution offers of course the biggest freedom regarding php-versions etc. (me running openvz with great success.)

regards, /t

share|improve this answer
    
suexec does work with fastcgi in apache 2 when configured correctly. –  iainlbc Jan 3 '11 at 20:36
  • Uploads are stored in /var/tmp by default, so mount it as +noexec +nosuid and configure your Apache VirtualHost's with php_flag engine 0 (ref: PHP manual) for the directories which will contain uploaded files (if you must accept file uploads - otherwise, set file_uploads 0 in your php.ini)

  • Set allow_url_fopen 0 in php.ini (just in case one of your coders gets the bright idea to include URL's) and consider Suhosin if you have any questionable coders on staff

share|improve this answer
    
Thanks for these pointers, I will implement those. –  user60129 Jan 4 '11 at 13:51

In terms of mod_php/fastcgi I prefer php-fpm's implementation of FastCGI which is now included in PHP (since 5.33). PHP-FPM gives each "pool" (website) its own processes (dynamic or static) which it serves the php from. each vhost within apache/nginx connects to its own php-fpm pool on a specific port (ie. 9000). This is essentially accomplishing the same thing as suExec in that each php process/request is "Exec"uted as it's own user (you specify user:group for each pool, which should be chrooted/jailed).

This also gives more granular control of memory usage and separates the processing of static files/images and dynamic content (php.) Because of this separation apache does not load PHP into its processes when serving static content. When using mod_php, every request from a user is going to require a ~40MB process even if its a static request (30 of it being php). At least this is my understanding...please correct me if I am wrong.

You can setup one pool (www.domain1.com) to have 5 static PHP processes to handle requests, and another pool (www.domain2.com) to have 10 processes minimum and 30 maximum.

http://php-fpm.org/about/

share|improve this answer
    
This also does look interesting. Any idea how much of a performance hit the server will take with some 30-40 sites running (in total about 10,000 visitors on all websites per day)? –  user60129 Jan 4 '11 at 14:12
    
Unfortunately I haven't used it in a high load environment (yet). Its definitely worth asking the PHP-FPM mailing list though: highload-php-en@googlegroups.com –  iainlbc Jan 25 '11 at 2:25

Damn right this should not happen - and if you're the admin for the site it's your fault it has happened

We are considering mod_php and FastCGI,

This is nothing to do with the problems you are currently having nor how you go about making the system secure.

First thing you need is a permissions model and processes to support the deployment of code to the server in a controlled way.

One approach would be to set up a group for each project which excludes the webserver uid, then deploying all files as rw-rw-r for the user and the development group - webserver relies on 'other' permissions to read files. Set up all directories with the group sticky bit set.

Each project should be in it's own subdir within the document root, and each project should have an upload dir writeable by the webserver uid outside the document root, and at least one dedicated (per group) include dir outside the document root (for preference each should be on its own vhost). Access should be restricted by open_basedir

Publish a coding standard which should specify that permissions cannot be manipulated from the standard settings - and tweak your IDS to pick up on any PHP files added or permissions changed.

But there are other models.

The important thing is that:

  • The webserver should never be able to write to files accessible directly via the webserver.

  • If user-uploaded content is to be accessible, it should be thouroughly sanitized on upload, and access mediated by a controller script.

  • in the event that malicious code is deployed on the server it should be strictly limited in the amount of damage it can do

  • it should be possible to detect when code changes are made on the system

  • Your permissions model should prevent one project from interfering with the behaviour of another project (e.g. suppose you had a common 'include' dir - even if the different projects could not amend other's files, they could mask out behaviours by using the same filename elsewhere on the include path - or worse create errors by using the same function or class name twice).

share|improve this answer
    
Thanks for these suggestions. However, please note that nothing has gone wrong at this moment. We are just taking preventive measures. –  user60129 Jan 4 '11 at 14:07

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.