Table of Contents

Setup and work with CloudLinux CageFS

Preamble

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

CloudLinux CageFS

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.

1. Installation

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.

2. Configure the CageFS template/skeleton and keep it up to date

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

3. Working with CageFS

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

Enable CageFS in LiteSpeed Web Server(LSWS)

Since version 4.1.12, LSWS has supported CageFS. Once enabled, the user's virtual host will be chrooted/jailed in CageFS.

1. Enable CageFS in LSWS

To enable in LSWS, go to Configuration > Server > General > CloudLinux and set CloudLinux to CageFS or CageFS without suEXEC.

2. Add a LSWS mount point

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 

3. Update CageFS

# /usr/sbin/cagefsctl --remount-all
# /usr/sbin/cagefsctl --update

NOTE: If the update mentions needing to force update, force the update.

4. Enable CageFS for a test user

# /usr/sbin/cagefsctl --enable username

5. Verify CageFS setup

5.1 The user only sees their own information in their shell

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.

5.2 But the user can also see files with a mount point in the skeleton

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 [~]# 

5.3 Once CageFS is enabled for a LSWS user, their virtual host is also jailed

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

6. Changes in files mounted to the skeleton are seen by the jailed user without a remount

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 [~]#