In this article, we show how to install CageFS (a Cloudlinux feature) and enable it with LiteSpeed Web Server.
Detailed installation instructions for CageFS can be found at http://docs.cloudlinux.com/index.html?cagefs_installation.html
CageFS, previously known as SecureLVE, is a security extension of CloudLinux. It creates a virtualized file system and set of tools for each end user. This makes sure that each user can see only their own files and tools. The separation is preserved for shell scripts, CGI scripts, and cronjobs as well.
To install CageFS, run:
# yum install cagefs # /usr/sbin/cagefsctl --init
* This last command initializes a CageFS template (aka a skeleton). This skeleton directory can be around 7GB in size. If there is not enough disk space for this skeleton in /usr/share, use the following commands before initializing to have cagefs-skeleton placed in a different location:
# mkdir /home/cagefs-skeleton # ln -s /home/cagefs-skeleton /usr/share/cagefs-skeleton
Note: On cPanel servers, if you will be placing the skeleton into the /home directory, you must turn off the home directory matching value (cPanel WHM → Server Configuration → Basic cPanel/WHM Setup → Basic Config → Additional home directories…) Change the value to blank (not the default “home”) to turn it off. If you do not change this option, cPanel will create new accounts in incorrect places.
Once you have initialized the template you can start enabling users. By default, CageFS is disabled for all users.
In CageFS, each jailed user can only see system directories and system information that has been mounted in the skeleton. (They can also see their own non-system files.) You can configure which directories are mounted in the skeleton by editing the /etc/cagefs/cagefs.mp file. Use the following command to create this file:
# /usr/sbin/cagefsctl --create-mp
A guided to editing this file can be found at http://docs.cloudlinux.com/index.html?mount_points.html. If you make updates to the system in the future, you can update what's mounted in the skeleton by running:
# /usr/sbin/cagefsctl --create-mp # /usr/sbin/cagefsctl --remount-all # /usr/sbin/cagefsctl --update
To enable CageFS for a user:
# /usr/sbin/cagefsctl --enable <username>
To enable CageFS for all users:
# /usr/sbin/cagefsctl --enable-all
To disable CageFS for a user:
# /usr/sbin/cagefs --disable <username>
cagefsctl options
-i | --init : initialize CageFS (creates CageFS if it does not exist) -r | --reinit : reinitialize CageFS (makes a backup and recreates CageFS) -u | --update : update CageFS files (adds new and modified files to CageFS, removes unneeded files) --update-etc : update /etc template only -f | --force : recreate CageFS (does not make backup, overwrites existing files) -d | --dont-clean : do not delete any files from skeleton (use with --update option) -k | --hardlink : use hardlinks if possible --create-mp : create /etc/cagefs/cagefs.mp file (the mount point configuration file) --mount-skel : mount CageFS skeleton directory and start cagefs-fuse service (if not started) --unmount-skel: unmount CageFS skeleton directory and stop cagefs-fuse service (if started) --remove-all : disable CageFS, remove templates and /var/cagefs directory
Since version 4.1.12, LSWS has supported CageFS. Once enabled, the user's virtual host will be chrooted/jailed in CageFS.
To enable in LSWS, go to Configuration > Server > General > CloudLinux and set CloudLinux to CageFS
or CageFS without suEXEC
.
A LSWS mount point will be included in the skeleton automatically if LSWS is installed prior to CageFS.
If LSWS gets installed after CageFS, run following command to get LSWS added to the skeleton:
# /usr/sbin/cagefsctl --create-mp
# /usr/sbin/cagefsctl --remount-all # /usr/sbin/cagefsctl --update
NOTE: If the update mentions needing to force update, force the update.
# /usr/sbin/cagefsctl --enable username
root@cptest [~]# su - username test1@cptest [~]# cat /etc/passwd smmsp:x:51:51::/var/spool/mqueue:/sbin/nologin root:x:0:0:root:/root:/bin/bash test1:x:502:500::/home/username:/bin/bash
In this test, note that the output of the cat command yields no information for other users.
test1@cptest [~]# ls -l /usr/local/lsws/fcgi-bin/ total 175216 drwxr-xr-x 2 root root 4096 Mar 18 12:31 ./ drwxr-xr-x 15 root root 4096 Mar 31 05:07 ../ -r-xr-xr-x 1 root root 3773 Mar 26 14:37 RackRunner.rb* -r-xr-xr-x 1 root root 4714 Mar 26 14:37 RailsRunner.rb* -r-xr-xr-x 1 root root 1095 Mar 26 14:37 RailsRunner.rb.2.3* -rw-r--r-- 1 root root 632 Mar 15 14:39 error_log -r-xr-xr-x 1 root root 3342 Jan 7 20:43 lsperld.fpl* -r-xr-xr-x 1 root root 2280672 Jan 7 20:43 lsphp* -rwxr-xr-x 1 root root 22214525 Jan 9 22:07 lsphp-5.3.20* -rwxr-xr-x 1 root root 22214525 Jan 8 14:37 lsphp-5.3.20.bak* -rwxr-xr-x 1 root root 26077761 Feb 28 19:46 lsphp-5.3.22* -rwxr-xr-x 1 root root 26080599 Mar 12 17:49 lsphp-5.3.22-6.2* -rwxr-xr-x 1 root root 22213832 Feb 27 18:59 lsphp-5.3.22.bak* -rwxr-xr-x 1 root root 29145362 Mar 18 12:31 lsphp-5.4.12* -rwxr-xr-x 1 root root 29145362 Mar 14 12:47 lsphp-5.4.12.bak* lrwxrwxrwx 1 root root 7 Jan 7 20:43 lsphp4 -> ./lsphp* lrwxrwxrwx 1 root root 12 Mar 18 12:31 lsphp5 -> lsphp-5.4.12* test1@cptest [~]#
Create a test file under the document root as follows:
test1@cptest [~]# vi test.php <?php $passwd=`cat /etc/passwd`; echo "<pre>$passwd</pre>", "\n"; ?>
Pointing the browser to http://test1.example.com/test.php
should show the following: (Only the user's own /etc/passwd
is visible to the jailed vhost.)
smmsp:x:51:51::/var/spool/mqueue:/sbin/nologin root:x:0:0:root:/root:/bin/bash test1:x:502:500::/home/test1:/bin/bash
We are going to compile a new PHP to test this. First we compile the PHP (e.g. 5.4.14) in the LSWS WebAdmin console as normal. When we are done we can see the new PHP at the bottom of our output below:
root@cptest [~]# ls -l /usr/local/lsws/fcgi-bin/ total 203684 drwxr-xr-x 2 root root 4096 May 8 16:29 ./ drwxr-xr-x 15 root root 4096 Mar 31 05:07 ../ -r-xr-xr-x 1 root root 3773 Mar 26 14:37 RackRunner.rb* -r-xr-xr-x 1 root root 4714 Mar 26 14:37 RailsRunner.rb* -r-xr-xr-x 1 root root 1095 Mar 26 14:37 RailsRunner.rb.2.3* -rw-r--r-- 1 root root 632 Mar 15 14:39 error_log -r-xr-xr-x 1 root root 3342 Jan 7 20:43 lsperld.fpl* -r-xr-xr-x 1 root root 2280672 Jan 7 20:43 lsphp* -rwxr-xr-x 1 root root 22214525 Jan 9 22:07 lsphp-5.3.20* -rwxr-xr-x 1 root root 22214525 Jan 8 14:37 lsphp-5.3.20.bak* -rwxr-xr-x 1 root root 26077761 Feb 28 19:46 lsphp-5.3.22* -rwxr-xr-x 1 root root 26080599 Mar 12 17:49 lsphp-5.3.22-6.2* -rwxr-xr-x 1 root root 22213832 Feb 27 18:59 lsphp-5.3.22.bak* -rwxr-xr-x 1 root root 29145362 Mar 18 12:31 lsphp-5.4.12* -rwxr-xr-x 1 root root 29145362 Mar 14 12:47 lsphp-5.4.12.bak* -rwxr-xr-x 1 root root 29147575 May 8 16:29 lsphp-5.4.14* lrwxrwxrwx 1 root root 7 Jan 7 20:43 lsphp4 -> ./lsphp* lrwxrwxrwx 1 root root 12 May 8 16:29 lsphp5 -> lsphp-5.4.14* root@cptest [~]#
If we then switch to user “test1” we can still see this new PHP without having to remount anything:
[root@cptest ~]# su - test1 test1@cptest [~]# ls -l /usr/local/lsws/fcgi-bin/ total 203684 drwxr-xr-x 2 root root 4096 May 8 16:29 ./ drwxr-xr-x 15 root root 4096 Mar 31 05:07 ../ -r-xr-xr-x 1 root root 3773 Mar 26 14:37 RackRunner.rb* -r-xr-xr-x 1 root root 4714 Mar 26 14:37 RailsRunner.rb* -r-xr-xr-x 1 root root 1095 Mar 26 14:37 RailsRunner.rb.2.3* -rw-r--r-- 1 root root 632 Mar 15 14:39 error_log -r-xr-xr-x 1 root root 3342 Jan 7 20:43 lsperld.fpl* -r-xr-xr-x 1 root root 2280672 Jan 7 20:43 lsphp* -rwxr-xr-x 1 root root 22214525 Jan 9 22:07 lsphp-5.3.20* -rwxr-xr-x 1 root root 22214525 Jan 8 14:37 lsphp-5.3.20.bak* -rwxr-xr-x 1 root root 26077761 Feb 28 19:46 lsphp-5.3.22* -rwxr-xr-x 1 root root 26080599 Mar 12 17:49 lsphp-5.3.22-6.2* -rwxr-xr-x 1 root root 22213832 Feb 27 18:59 lsphp-5.3.22.bak* -rwxr-xr-x 1 root root 29145362 Mar 18 12:31 lsphp-5.4.12* -rwxr-xr-x 1 root root 29145362 Mar 14 12:47 lsphp-5.4.12.bak* -rwxr-xr-x 1 root root 29147575 May 8 16:29 lsphp-5.4.14* lrwxrwxrwx 1 root root 7 Jan 7 20:43 lsphp4 -> ./lsphp* lrwxrwxrwx 1 root root 12 May 8 16:29 lsphp5 -> lsphp-5.4.14* test1@cptest [~]#