If you run a cpanel server and provide hosting services to customers, you really need to take care that one customer should not be able to access another customer’s files. Not doing this will introduce you to a world of pain. Hackers, script kiddies and spammers are the scum of the internet and they do not care how much trouble they cause to others. Your customers may not be malicious themselves but they can also be unaware of their actions in regards to security.
With the popularity of CMS’s like WordPress, Joomla, its very easy to get a website/blog up and running in minutes. For the unaware customer, its also very easy to forget to upgrade their installations and install insecure themes and plugins. These are the main sources for hackers to gain access to their files and account on the server, and if the server is not properly secured, it only takes one customer getting his account compromised to enabling the hacker to access all other files on the server.
Fortunately there’s a way to prevent or at least make it harder for them to do that. We’ll be making use of suPHP and open_basedir.
This executes php scripts with the permissions of the script’s owner instead of the user nobody.
To enable this, apache needs to compiled with mod_suphp. This can be done via easy apache in cpanel.
– Go to Software >> EasyApache (Apache Update)
– Click on a previously saved profile and customize it, choose your apache and php version. On the next page, make sure Mod suPHP is enabled/ticked.
– Click on save and build. This should take about 5 minutes. Apache is now compiled with suPHP.
This is a PHP directive found in the php.ini file that restricts the running php script to only certain file directories specified in the directive. For cpanel users, this can be set to the /home/, /usr/local/lib, and /tmp directories. To set the open_basedir, you can do it via WHM or from the command line:
# vi /usr/local/lib/php.ini # open_basedir = "/home/:/tmp:/usr/local/lib/"
Go to Service Configuration >> PHP Configuration Editor
Check “Advanced Mode”, find the open_basedir directive and set the values
/usr/local/lib – This area stores the php.ini files and other configurations which would be needed by the running PHP script.
/tmp – This is default area where PHP stores temporary files like sessions, file uploads, etc. So the script would need access to it.
/home – This is normally where a user’s account is stored. If we want to restrict user to its own user directory (/home/username) then each user should have an independent php.ini file specifying the directory in the open_basedir directive.
Disable user’s custom php.ini
suPHP by default loads a user’s custom php.ini stored in their directory. This enables the user to override the global php.ini settings. A malicious user/script could override the global open_basedir value and the above protection will be lost. To prevent this, we have to ask suPHP to load only the main php.ini file:
Open the suPHP configuration file:
# vi /opt/suphp/etc/suphp.conf
And uncomment the following lines:
;application/x-httpd-php=/usr/local/lib/ ;application/x-httpd-php4=/usr/local/php4/lib/ ;application/x-httpd-php5=/usr/local/lib/
The above lines should read as below:
application/x-httpd-php=/usr/local/lib/ application/x-httpd-php4=/usr/local/php4/lib/ application/x-httpd-php5=/usr/local/lib/
Now, save the file and restart apache:
# service httpd restart
From what I have noticed, with the above settings, a user can still access another user’s files (/home/user2/), but since cpanel sets a 750 (No permission for others) permission on the public_html folder, it cannot access the other user’s files under public_html (where most of their files will be anyway). So, as long as users don’t change their public_html permission and store most of their files inside public_html folder, its an easier way than creating php.ini files for every single user. For me, it works, so its a decision you have to make yourself.