4

I'm hosting multiple sites from one server where each site has it's own user and www directory in their home dir. Currently our web server runs as user nobody(99). We're noticing that to run several popular scripts and engines, they require write access to their own files.

As the home directory is owned by the user, not nobody(99), what is the best policy or change in hosting configuration that would:

  • ...make it so that all the various engines and platforms work?
  • ...still allow us to work with files and edit them without having to diddle with permissions as root?
  • Doesn't require me to massage permissions and/or ownership with every file change.

Thanks for the advice!

5 Answers 5

1

You should consider extended ACLs. Supported on FreeBSD and linux, the setfacl command allows you to define more than 1 user/group that has access to each file/directory. You can then give the nobody user/group the 'execute' permission of /home /home/user. then read and write on only the document root of the sites where they require it.

Failing this, you can just change the group of each users' home directory to nobody and use permissions of 710 on /home/username and then chown user:nobody and chmod 770 on the document root.

Remember that the 'nobody' user will require the 'execute' permission on every directory between / and the document root (either view a specific permission or the 'other' field), and then read (and optionally write) on the document root. You can disallow all other users to have read or execute on the users directory or the document root directory. It is not uncommon to see /home where noone other than root has read access, and all users only have execute. then they can get to /home/username but they cannot get a list of what other users exist on the server

0
chown -R :nobody root_of_all_sites
chmod g+rw -R root_of_all_sites

basically you make the sites group writable and you assign nobody group to read and write to it. you may need to set this periodically (if the users upload new files or have a different mechanism for it - umask etc.)

1
  • Not a very elegant solution... Seems a bit of a kludge. I've done this before and it would be impractical considering every time a user makes a change, the files have to be massaged back in place. Jan 9, 2011 at 5:10
0

Do the users of these multiple sites trust each other? If so, it's pretty easy for users to deal with this themselves. All the user should need to do is make the appropriate directory world-accessible/writable with

chmod o+wx dir
chmod o+w dir/files_webserver_should_edit*

If the user wants to be sure to have access to the files created in that directory, the user could also run

chmod g+s dir

so that the files created by the webserver are owned by nobody but are in the user's group (though the PHP script will need to be sure to create files with group access). o+s would make files owned by the user, but that might deny the webserver access to files it created if the file's permissions aren't right. If some files are not supposed to be writable by the webserver, you can go a step further and

chmod o+t dir
chmod g-w dir/files_not_to_be_altered*

If a user has write access to a directory but not to a file in that directory, they can delete the file from the directory and create a new one that they DO have write access to. The sticky bit (o+t) prevents a user from removing a file they don't own from a directory. With these combined, a PHP script can create new files and update and delete the files they create (since they will be owned by "nobody") but can't edit "files_not_to_be_altered" and can't erase them since they're owned by "user").

This gives the user control over which directories are actually writable by the webserver, and doesn't require root access since it isn't changing ownership.

If the users don't trust each other, then you'll need a little root intervention. Each website's directory structure will need to be tweaked once to convert its ownership:
Note: these instructions assume that nobody's group is also nobody, but some systems use nogroup

chown -R user:nobody /some/website
chmod -R g+rX,o-rwx /some/website

(capital X adds x access to directories)

This will make the directory tree accessable to user and nobody and remove everyone else's access. Users can proceed from there on their own, granting g+w access where they please, however they will have to use u+s instead of g+s to ensure they have access to the files created by the webserver. o+t will work as intended.

As an aside, you may have other servers using nobody/nogroup... to minimize alternate attack methods (an exploit in some other service running as nobody giving an attacker the ability to write in these websites) most systems have a dedicated webserver user/group that only the webserver runs as.

3
  • Isn't there a way to have apache/php run as the user of the home dir? Jan 9, 2011 at 5:11
  • @Omega: oh... well, in that case suPHP will run PHP scripts as the owner of the script. Note that this will give the scripts the same permission as the user, which may lead to trouble with insecure scripts since they'll be able to write all over everything. suPHP uses php-cgi, and you can find out more at suphp.org
    – DerfK
    Jan 9, 2011 at 15:04
  • Any performance concerns with suPHP? Was trying to avoid running CGI PHP... Feb 10, 2011 at 14:44
0

Probably the easiest way to do this is to use mpm-itk - it'll require that you switch mpms, and does incur a performance hit. However, this will let you configure a different user for Apache to use per VirtualHost, and will require no other configuration changes. I've tried it out, and it's quite easy to use, and the performance hit isn't horrible. YMMV of course...

1
  • Not sure I like being forced to use one mpm over others... Feb 10, 2011 at 14:43
0

For best performance, you should run the PHP scripts as a separate user and chown the files so that the Apache user only has read-access to them.

Easiest is to use SuPHP: http://www.suphp.org/

Another option is to run PHP in CGI mode and make sure Apache is configured to exec() each CGI under its own userid. Instructions here:

http://php.net/manual/en/security.cgi-bin.php

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .