Isolating Apache virtualhosts from the rest of the system
I am setting up a web server that will host a number of different web sites as Apache VirtualHosts, each of these will have the possibility to run scripts (primarily PHP, possiblu others).
My question is how I isolate each of these VirtualHosts from eachother and from the rest of the system? I don't want e.g. website X to read the configuration of website Y or any of the server's "private" files.
At the moment I have set up the VirtualHosts with FastCGI, PHP and SUExec as described here (http://x10hosting.com/forums/vps-tutorials/148894-debian-apache-2-2-fastcgi-php-5-suexec-easy-way.html), but the SUExec only prevents users from editing/executing files other than their own - the users can still read sensitive information such as config files.
I have thought about removing the UNIX global read permission for all files on the server, as this would fix the above problem, but I'm not sure if I can safely do this without disrupting the server function.
I also looked into using chroot, but it seems that this can only be done on a per-server basis, and not on a per-virtual-host basis.
I'm looking for any suggestions that will isolate my VirtualHosts from the rest of the system.
PS I'm running Ubuntu 12.04 server
My ANSWER: I ended with almost following my current configuration, but doing a chroot jail for all the virtual hosts, e.g. having the chroot jail in /var/www
and then have all the users' data in subfolders each with group/others r/w/x permissions disabled. This option was desirable especially because it is all possible without any modifications to source code.
I selected @Chris' answer, because it was thoroughly written and also considered FTP and SELinux
This can be done by enabling the mod_users module in Apache.
You will need to setup UserDir in your apache configuration. I suggest you do this in a separate config file and include it. Wrap the include in
<IfModule mod_users.c>
Include conf/extra/userdir.conf
</IfModule>
I can give you the entire tutorial but this should get you started for configuring Apache: http://www.techytalk.info/enable-userdir-apache-module-ubuntu-debian-based-linux-distributions/
Hint if you are running SELinux (and you should) you would have to give Apache read access to the user homes. You can do this by setting:
sudo setsebool -P httpd_enable_homedirs=On
It also needs file permissions to the user dirs public_html directory and r-x permissions on the parent directories up to root.
Obviously you need to setup chroot for the users for example in vsftpd. Install:
apt-get vsftpd
To configure chrooting open /etc/vsftpd/vsftpd.conf with vi or nano. Find and uncomment or add: chroot_local_user=yes
You can get the same behavior for sftp which I recommend over FTP, open /etc/ssh/sshd_config and add a Match block and this line:
Subsystem sftp internal-sftp
Match Group web_users
ChrootDirectory %h
ForceCommand internal-sftp
AllowTcpForwarding no
Match
This will chroot any user in the web_users group. Also you would need to deny access to the shell by setting it to /sbin/nologin:
useradd -G "web_users" -s /sbin/nologin new_user
If this is to be a public production server, I also strongly suggest you apply some hardening on the OS, OpenSSH, Apache, PHP, vsftpd and apply some strict iptables and TCP wrappers. I recommend you leave SELinux in place too.
I suggest to take a look at suphp
or PHP-FPM.
It will basically enable the PHP interpreter to 'su' to some specific user configured for that VirtualHost. That will allow you to utilize general file system permissions to isolate every single VirtualHost.
I would recommend FPM for performance considerations. From the homepage this is what is of most interest to you:
Also of interest are the per-pool user and group options, which allow you to run that specific fpm pool under the given uid and gid; goodbye suphp!
Look into chroot
.
Some starting points:
Apache chrooting made simple
Chroot environment for Apache (Debian)
Apache Chroot Jail: Virtual Hosting