CageFS

CageFS is a virtualized file system and a set of tools to contain each user in its own 'cage'. Each customer will have its own fully functional CageFS, with all the system files, tools, etc.

The benefits of CageFS are:

  • Only safe binaries are available to user
  • User will not see any other users, and would have no way to detect presence of other users & their user names on the server
  • User will not be able to see server configuration files, such as Apache config files.
  • User's will have limited view of /proc file system, and will not be able to see other users' processes

At the same time, user's environment will be fully functional, and user should not feel in any way restricted. No adjustments to user's scripts are needed. CageFS will cage any scripts execution done via:

  • Apache (suexec, suPHP, mod_fcgid, mod_fastcgi)
  • LiteSpeed Web Server
  • Cron Jobs
  • SSH
  • Any other PAM enabled service

Note

mod_php is not supported, MPM ITK requires a custom patch

Note

CageFS is not supported for H-Sphere.

Installation

Minimum Requirements:

  • kernel: CL6 with lve1.2.17.1 or later, CL7.
  • 7GB of disk space.

Depending on your setup, and number of users, you might also need:

  • Up to 8MB per customer in /var directory (to store custom /etc directory)
  • 5GB to 20GB in /usr/share directory (to store safe skeleton of a filesystem)

Warning

If at any time you decide to uninstall CageFS, please make sure you follow uninstall instructions

To install CageFS:

$ yum install cagefs
$ /usr/sbin/cagefsctl --init

That last command will create skeleton directory that might be around 7GB in size. If you don't have enough disk space in /usr/share, use following commands to have cagefs-skeleton being placed in a different location:

$ mkdir /home/cagefs-skeleton
$ ln -s /home/cagefs-skeleton /usr/share/cagefs-skeleton

WARNING

If you are placing skeleton in /home directory on cPanel servers, you must configure the following option in cPanel WHM: WHM -> Server Configuration -> Basic cPanel/WHM Setup -> Basic Config -> Additional home directories
Change the value to blank (not default Home ). Without changing this option, cPanel will create new accounts in incorrect places.

CageFS will automatically detect and configure all necessary files for:

  • cPanel
  • Plesk
  • DirectAdmin
  • ISPmanager
  • Interworx
  • MySQL
  • PostgreSQL
  • LiteSpeed

Web interface to manage CageFS is available for cPanel, Plesk 10+, DirectAdmin, ISPmanager & Interworx. Command line tool would need to be used for other control panels.

Once you initialized the template you can start enabling users. By default CageFS is disabled for all users.

Starting from cagefs-6.1-27 fs.proc_can_see_other_uid will be migrated (one time) from /etc/sysctl.conf into /etc/sysctl.d/90-cloudlinux.conf . If this variable is not set in either file, it will default to 0.

It is strongly advised against setting this variable in 90-cloudlinux.conf. Define it in /etc/sysctl.conf or in some other config file with an index number greater than 90-cloudlinux.conf, e.g. /etc/sysctl.d/95-custom.conf.

You can find more information on fs.proc_can_see_other_uid automatic migration in Kernel Config Variables .

Unistalling CageFS

To uninstall CageFS, start by disabling and removing all directories:

$ /usr/sbin/cagefsctl --remove-all

That command will: disable CageFS for all customers, unmount CageFS for all users, removes /usr/share/cagefs-skeleton & /var/cagefs directories. It will not remove /etc/cagefs directory.

Remove CageFS RPM:

$ yum remove cagefs

Managing Users

CageFS provides for two modes of operations:

  1. Enabled for all, except those that are disabled.
  2. Disabled for all, except those that are enabled.

Mode #1 is convenient for production operation, where you want all new users to automatically be added to CageFS. Mode #2 is convenient while you test CageFS, as it allows you to enable it on one by one for your customers.

To start using CageFS you have to select one of the mode of operations:

$ /usr/sbin/cagefsctl --enable-all
or
$ /usr/sbin/cagefsctl --disable-all
or
$ /usr/sbin/cagefsctl --toggle-mode
That will switch the operation mode, preserving current disabled/enabled users.

To enable individual user do:

$ /usr/sbin/cagefsctl --enable [username]
To disable individual user:
$ /usr/sbin/cagefsctl --disable [username]
To list all enabled users:
$ /usr/sbin/cagefsctl --list-enabled
To list all disabled users:
$ /usr/sbin/cagefsctl --list-disabled
To see current mode of operation:
$ /usr/sbin/cagefsctl --display-user-mode

Command-line Tools

cagefsctl is used to manage CageFS. It allows initializing and updating CageFS, as well as enabling/disabling CageFS for individual users.

Use the following syntax to manage CageFS: /usr/sbin/cagefsctl [OPTIONS]

Options:

-i --init initialize CageFS (create CageFS if it does not exist)
-r --reinit reinitialize CageFS (make backup and recreate CageFS)
-u --update update files in CageFS (add new and modified files to CageFS, remove unneeded files)
-f --force recreate CageFS (do not make backup, overwrite existing files)
-d --dont-clean do not delete any files from skeleton (use with --update option)
-k --hardlink use hardlinks if possible
--create-mp Creates /etc/cagefs/cagefs.mp file
--mount-skel mount CageFS skeleton directory
--unmount-skel unmount CageFS skeleton directory
--remove-all disable CageFS, remove templates and /var/cagefs directory
--sanity-check perform basic self-diagnistics of common cagefs-related issues (mostly useful for support)
--addrpm add rpm-packages in CageFS (run cagefsctl --update in order to apply changes)
--delrpm remove rpm-packages from CageFS (run cagefsctl --update in order to apply changes)
--list-rpm list rpm-packages that are installed in CageFS
-e --enter enter into user's CageFS as root
--update-list update specified files only (paths are read from stdin)
--update-etc update /etc directory of all or specified users
--set-update-period set min period of update of CageFS in days (default = 1 day)
--force-update force update of CageFS (ignore period of update)
--force-update-etc force update of /etc directories for users in CageFS
--reconfigure-cagefs configure CageFS integration with other software (control panels, database servers, etc)

Use the following syntax to manage users:
/usr/sbin/cagefsctl [OPTIONS] username [more usernames]

Options:

-m --remount remount specified user(s)
-M --remount-all remount CageFS skeleton directory and all users (use this each time you have changed cagefs.mp file
-w --unmount unmount specified user(s)
____ --unmount-dir unmount specified dir for all users
-W --unmount-all unmount CageFS skeleton directory and all users
-l --list list users that entered in CageFS
--list-logged-in list users that entered in CageFS via SSH
--enable enable CageFS for the user
--disable disable CageFS for the user
--enable-all enable all users, except specified in /etc/cagefs/users.disabled
--disable-all disable all users, except specified in /etc/cagefs/users.enabled
--display-user-mode display the current mode ( "Enable All" or "Disable All" )
--toggle-mode toggle mode saving current lists of users (lists of enabled and disabled users remain unchanged)
--list-enabled list enabled users
--list-disabled list disabled users
--user-status print status of specified user (enabled or disabled)
--getprefix display prefix for user

PHP Selector related options:

--setup-cl-selector setup PHP Selector or register new alt-php versions
--remove-cls-selector unregister alt-php versions, switch users to default php version when needed
--rebuild-alt-php-ini rebuild alt_php.ini file for specified users (or all users if none specified)
--validate-alt-php-ini same as --rebuild-alt-php-ini but also validates alt_php.ini options
--cl-selector-reset-versions reset php version for specifed users to default (or all users if none specified)
--cl-selector-reset-modules reset php modules (extensions) for specific users to defaults (or all users if none specified)
--create-virt-mp create virtual mount points for the user
--create-virt-mp-all create virtual mount points for all users
--remount-virtmp create virtual mount points and remount user
--apply-global-php-ini use with 0, 1 or 2 arguments from the list: error_log, date.timezone without arguments applies all global php options including the two above

Common options:

___ --disable-cagefs disable CageFS
--cagefs-status print CageFS status: ( enabled or disabled )
--set-min-uid Set min UID
--get-min-uid Display current MIN_UID setting
--print-suids Print list of SUID and SGID programs in skeleton
--do-not-ask assume "yes" in all queries (should be the first option in command)
--clean-var-cagefs clean /var/cagefs directory (remove data of non-existent users)
--set-tmpwatch set tmpwatch command and parameters (save to /etc/cagefs/cagefs.ini file)
--tmpwatch execute tmpwatch (remove outdated files in tmp directories in CageFS for all users)
--toggle-plugin disable/enable CageFS plugin
-v --verbose verbose output
--wait-lock wait for end of execution of other cagefsctl processes (when needed) before execution of the command
-h --help this message

Running Command Inside CageFS

[lve-wrappers 0.6-1+]

Sometimes you will need to execute a command as user inside CageFS.

If a user has shell enabled - you can simply use:

$ /bin/su - $USERNAME  -c "_command_"
Yet, if a user have they shell disabled, it wouldn't work. To solve this issue, we have added command:
$ /sbin/cagefs_enter_user $USERNAME "_command_"

If you disable CageFS for a user, then cagefs_enter will be executed without proxyexec .

You can forcibly disable cagefs_enter start via proxyexec for all users (regardless if CageFS is enabled or disabled) by specifying the parameter cagefs_enter_proxied=0 in /etc/sysconfig/cloudlinux .

/bin/cagefs_enter.proxied can be executed instead of /bin/cagefs_enter to enter CageFS without proxyexec . Note that starting cagefs_enter via proxyexec is necessary to enable sending local notification messages to users with enabled CageFS. cagefs_enter is executed via proxyexec by default.

Sanity Check

[ CageFS 6.0-34+]

CageFS --sanity-check utility allows to check CageFS configuration consistency, so that an administrator can save the time investigating issues with CageFS and ensure that custom configuration is correct.

To start, run the command:

cagefsctl --sanity-check
At the moment 7 types of check are implemented:
  1. Check cagefs mount points exists - reads cagefs.mp file and verifies if the directories specified in it really exist on the disk. To learn more, visit Mount points and Split by username

  2. Check cagefs users.enabled is a directory - ensures that if /etc/cagefs/users.enabled exists, then it is a directory, not a file (if it is recognized as a file, then it would cause a breakdown).

  3. Check cagefs users.disabled is a directory - ensures that if /etc/cagefs/users.disabled exists, then it is a directory, not a file (if it is recognized as a file, then it would cause a breakdown).

  4. Check cagefs disable.etcfs exists - checks if /etc/cagefs/etc.safe/disable.etcfs exists.

  5. Check cagefs users can enter cagefs - chooses two users in the system with enabled CageFS (the first and the second ones in the unsorted list) and tries to log in to CageFS under their credentials and see what happens. It runs su -l "$USER" -s /bin/bash -c "whoami" and compares the output with the $USER and su command retcode estimation.

Note

If a login fails, it can be due to various reasons, that can only be determined in manual mode. The checker only gives the output of the command.

  1. Check cagefs proxy commands configs are parsable - tries to load /etc/cagefs/*.proxy.commands files and parse them to check the syntax. In case of any parsing error the test will fail. To learn more, visit Executing by proxy .

  2. Check cagefs virt.mp files syntax - reads all /var/cagefs///virt.mp files (if any) and checks their syntax validity. At the moment there are only two checks of the syntax: the file is not empty if it exists, and the file is not starting with the sub directory definitions (with @). To learn more, visit Per-user virtual mount points

  3. Check MultiPHP system default PHP version – checks that MultiPHP system default PHP version is NOT Alt-PHP. That means PHP Selector should work properly. If MultiPHP system default PHP version is Alt-PHP, PHP Selector does not work and should be disabled. To learn more on how to disable PHP Selector, visit cPanel LVE Manager

Possible results of the checks:

  • OK - the check succeeded.

  • FAILED - the check revealed a problem.

  • SKIPPED - the check was skipped as it made no sense in such environment (e.g. wrong control panel) or can not be performed for some reason (e.g no users with enabled CageFS found). The actual result does not mean that a problem exists and can be considered as positive.

  • INTERNAL_TEST_ERROR - the check failed because of a problem inside the checker itself. Must be reported to the developers.

In case if at least one of the checks resulted neither OK nor SKIPPED then the checker will end with ret code >0.

CageFS Quirks

Due to the nature of CageFS, some options will not work as before or will require some changes:

  • lastlog will not work ( /var/log/lastlog ).
  • PHP will load php.ini from /usr/selector/php.ini. That file is actually a link to the real php.ini file from your system. So the same php.ini will be loaded in the end.
  • You have to run cagefsctl --update any time you have modified php.ini, or you want to get new/updated software inside CageFS.
  • CageFS installation changes jailshell to regular bash on cPanel - read why .

Configuration

File System Templates

CageFS creates a filesystem template in /usr/share/cagefs-skeleton directory. CageFS template will be mounted for each customer.  The template is created by running:

# /usr/sbin/cagefsctl --init

To update the template, you should run:

$ /usr/sbin/cagefsctl --update

The behavior of the commands (and the files copied into /usr/share/cagefs-skeleton directory) depends on the configuration files in /etc/cagefs/conf.d
You can add additional files, users, groups and devices into CageFS template by adding .cfg file, and running:

$ /usr/sbin/cagefsctl --update

To delete files from CageFS template, remove corresponding .cfg file, and run:

$ /usr/sbin/cagefsctl --update

Here is an example openssh-clients.cfg file:

[openssh-clients]

comment=OpenSSH Clients

paths=/etc/ssh/ssh_config, /bin/hostname, /usr/bin/scp, /usr/bin/sftp, /usr/bin/slogin, /usr/bin/ssh, /usr/bin/ssh-add, /usr/bin/ssh-agent, /usr/bin/ssh-copy-id, /usr/bin/.ssh.hmac, /usr/bin/ssh-keyscan, /usr/libexec/openssh/sftp-server, /etc/environment, /etc/security/pam_env.conf

devices=/dev/ptmx

Example mail.cfg file:

[mail]

comment=Mail tools

paths=/bin/mail, /etc/aliases.db, /etc/mail, /etc/mailcap, /etc/mail.rc, /etc/mime.types, /etc/pam.d/smtp.sendmail, /etc/rc.d/init.d/sendmail, /etc/smrsh, /etc/sysconfig/sendmail, /usr/bin/hoststat, /usr/bin/Mail, /usr/bin/mailq.sendmail, /usr/bin/makemap, /usr/bin/newaliases.sendmail, /usr/bin/purgestat, /usr/bin/rmail.sendmail, /usr/lib64/sasl2/Sendmail.conf, /usr/lib/mail.help, /usr/lib/mail.tildehelp, /usr/lib/sendmail.sendmail, /usr/sbin/mailstats, /usr/sbin/makemap, /usr/sbin/praliases, /usr/sbin/sendmail.sendmail, /usr/sbin/smrsh, /var/log/mail, /var/spool/clientmqueue, /var/spool/mqueue

users=smmsp

groups=smmsp

There is an easy way to add/delete files from particular RPMs into CageFS. That can be done by using --addrpm and --delrpm options in cagefsctl . Like:

$ cagefsctl --addrpm ffmpeg
$ cagefsctl --update

Note

ffmpeg RPM should be installed on the system already.

Excluding Files

To exclude files and directories from CageFS, edit file:
/etc/cagefs/custom.black.list
And add files or directories in there, one per line.

Please do not edit /etc/cagefs/black.list file because it is replaced during the update of CageFS package.

Excluding Users

To exclude users from CageFS, create a file (any name would work) inside /etc/cagefs/exclude folder, and list users that you would like to exclude from CageFS in that file.

Mount Points

CageFS creates individual namespace for each user, making it impossible for users to see each other's files and creating high level of isolation. The way namespace is organized:

  1. /usr/share/cagefs-skeleton with safe files is created
  2. Any directory from the server that needs to be shared across all users is mounted into /usr/share/cagefs-skeleton (a list of such directories is defined in /etc/cagefs/cagefs.mp)
  3. /var/cagefs/[prefix]/username directory for each user. Prefix is defined as last two digits of user id. User id is taken from /etc/passwd file.
  4. Separate /etc directory is created and populated for each user inside /var/cagefs/[prefix]/username
  5. /tmp directory is mounted for each user separately into ~username/.cagefs-tmp directory
  6. Additional custom directories can be mounted for each user by defining them in /etc/cagefs/cagefs.mp
  7. You can define custom directories per user using virt.mp files [CageFS 5.1 and higher]

To define individual custom directories in /etc/cagefs/cagefs.mp following format is used:

@/full/path/to/directory,permission notation

This is useful when you need to give each user its own copy of a particular system directory, like:

@/var/run/screen,777

Such entry would create separate /var/run/screen for each user, with permissions set to 777

To modify mount points, edit /etc/cagefs/cagefs.mp. Here is an example of cagefs.mp:

/var/lib/mysql
/var/lib/dav
/var/www/cgi-bin
/var/spool
/dev/pts
/usr/local/apache/domlogs
/proc
/opt
@/var/spool/cron,700
@/var/run/screen,777

If you want to change mount points, make sure you re-initialize mount points for all customers:

$ cagefsctl --remount-all
This command will kill all current processes and reset mount points.

Per user virtual mount points

[CageFS 5.1 and higher]

  • Please, see Split by username feature, as it might be simpler to implement in some cases.

Starting with CageFS 5.1 you can specify additional directories to be mounted inside user's CageFS. This can be specified for each user. To specify virtual mount points for a user, create a file:

/var/cagefs/[prefix]/[user]/virt.mp

Inside that file, you can specify mount points in the following format:

virtdir1,mask
@subdir1,mask
@subdir2,mask
virdir2,mask
@subdir3,mask
@subdir4,mask
>virtdir3,mask
@subdir5,mask
@subdir6,mask
# comments
  • mask is always optional, if missing 0755 is used
  • Create virtual directory subdir/virtdir , mount it to:
    • skeleton jaildir/virtdir
    • inside virtual directory, create directories subdir1, subdir2
    • mount virtdir1/subdir1 to subdir/virtdir/subdir1
    • if virtdir is started with >, create directory subdir/virtdir , but don't mount it into jaildir . This is needed for cases when virtdir is inside home base dir.
  • if file /var/cagefs/[prefix]/[user]/virt.mp is missing -- no virt directories are loaded for that user.

Note that CageFS will automatically create those files for Plesk 10 & higher.

For example if we have Plesk 11.5 with two users cltest1, and cltest2:

cltest1 uid 10000 has domains: cltest1.com, cltest1-addon.com and sub1.cltest1.com
cltest2 uid 10001 has domains: cltest2.com, cltest2-addon.com

In such case we would have file /var/cagefs/00/cltest1/virt.mp :

>/var/www/vhosts/system,0755
@cltest1-addon.com,0755
@cltest1.com,0755
@sub1.cltest1.com,0755

and file: /var/cagefs/01/cltest2/virt.mp:

>/var/www/vhosts/system
@cltest2-addon.com
@cltest2.com

Split by Username

[CageFS 5.3.1+]

Sometimes you might need to make sure that directory containing all users would show up as containing just that user inside CageFS. For example, if you have directory structure like:

/home/httpd/fcgi-bin/user1
/home/httpd/fcgi-bin/user2

Then we can add the following line to /etc/cagefs/cagefs.mp file:

%/home/httpd/fcgi-bin

and execute:

cagefsctl --remount-all

After that each subdirectory of /home/httpd/fcgi-bin will be mounted for appropriate user in CageFS: /home/httpd/fcgi-bin/user1 will be mounted for user1 and /home/httpd/fcgi-bin/user2 will be mounted for user2 .

Mounting user’s home directory inside CageFS

CageFS 6.1-1 (and later) has improved mounting user’s home directory that is applied for users with home directories like /home/user or /homeN/user (where N = 0,1,..9).

In such case, earlier versions of CageFS always mount user’s home directory to /home/user and create symlink /homeN -> /home when needed, so user’s home directory can be accessed both via /home/user and /homeN/user . This quirk leads to some rare incompatibilities between CageFS and other software (for example OpenCart), because real path of user’s home directory in CageFS and in real file system can differ.

New CageFS mounts user’s home directory in a way that its real path in CageFS is always the same as in real file system. Additionally, CageFS searches for symlinks like /homeX -> /homeY and /homeX/user -> /homeY/user in real system and creates such symlinks in user’s CageFS when found.

This new mounting mode is enabled by default. You can switch to old mounting mode by executing the following commands:

# touch /etc/cagefs/disable.home.dirs.search
# cagefsctl --force-update
# cagefsctl --remount-all

Note

New mounting mode will be disabled automatically when "mounting base home directory" mode is enabled (mount_basedir=1 setting in /etc/cagefs/cagefs.base.home.dirs file).

Base Home Directory

If you have a custom setup where home directories are in a special format, like: /home/$USERNAME/data , you can specify it using regular expressions. This is needed by CageFS to create safe home space for end user, where no other users are visible.

We will create empty: /var/cagefs/[prefix]/$USERNAME/home , and then mount /home/$USERNAME in that directory

To do that, create a file: /etc/cagefs/cagefs.base.home.dirs

With content like:

^/home/
^/var/www/users/

If there is no such file, the home directory without last component will be considered as a base dir, like with /home/$USERNAME we would create /var/cagefs/[prefix]/$USERNAME/home , and then mount /home/$USERNAME in there

With /home/$USERNAME/data as a home dir, we would assume that /home/$USERNAME is the base directory, and we would create /var/cagefs/[prefix]/$USERNAME/home/$USERNAME/data and then we would mount /home/$USERNAME/data -- which would cause each user to see empty base directories for other users, exposing user names.

Sharing home directory structure among users

When you want to share directory structure among multiple users, you can add following line at the top of the /etc/cagefs/cagefs.base.home.dirs file. This is useful on the systems that support sites with multiple users, with different home directories inside the main 'site' directory.

mount_basedir=1

For example:

user1 has home directory /var/www/vhosts/sitename.com/web_users/user1 user2 has home directory /var/www/vhosts/sitename.com/web_users/user2 site admin has home directory /var/www/vhosts/sitename.com

So, content of /etc/cagefs/cagefs.base.home.dirs should be the following:

mount_basedir=1
^/var/www/vhosts/[^/]+

Directory structure in /var/www/vhosts/sitename.com will be mounted in CageFS for appropriate users.
Each user will have access to whole directory structure in /var/www/vhosts/sitename.com (according to their permissions).

Note

You should execute cagefsctl --remount-all in order to apply changes to CageFS (i.e. remount home directories).

PostgreSQL support

CloudLinux 7:

CageFS works with any PostgreSQL version installed from CloudLinux or CentOS repositories. PostgreSQL packages for CloudLinux 7 come from the upstream (CentOS) unmodified. PostgreSQL’s socket is located in /var/run/postgresql directory. This directory is mounted to CageFS by default (in cagefs-5.5-6.34 or later).

When PostgreSQL has been installed after CageFS install, please add line:

/var/run/postgresql

/etc/cagefs/cagefs.mp file and then execute:

cagefsctl --remount-all 

The steps above are enough to configure CageFS to work with PostgreSQL.

CloudLinux 6:

CageFS provides separate /tmp directory for each end user. Yet, PostgreSQL keeps its Unix domain socket inside server's main /tmp directory. In addition to that, the location is hard coded inside PostgreSQL libraries.

To resolve the issue, CloudLinux provides a version of PostgreSQL with modified start up script that can store PostgreSQL's socket in /var/run/postgres. The script automatically creates link from /tmp to that socket to prevent PostgreSQL dependent applications from breaking.

In addition to that, CageFS knows how to correctly link this socket inside end user's /tmp directory.

To enable PostgreSQL support in CageFS:

  1. Make sure you have updated to latest version of PostgreSQL.

  2. Edit file /etc/sysconfig/postgres, and uncomment SOCK_DIR line.

  3. Update CageFS configuration by running:

cagefsctl  --reconfigure-cagefs
  1. Restart PostgreSQL by running:
$ service postgresql restart 

If you are using cPanel, you would also need to modify file: /etc/cron.daily/tmpwatch

And update line:

flags=-umc 

to:

flags=-umcl

to prevent symlink from being removed.

PAM Configuration

CageFS depends on pam_lve module tor PAM enabled services. When installed, the module is automatically installed for following services:

  • sshd
  • crond
  • su

The following line is added to corresponding file in /etc/pam.d/:

session    required     pam_lve.so      100     1

Where 100 stands for minimum UID to put into CageFS & LVE , and 1 stands for CageFS enabled.

Executing By Proxy

Some software has to run outside CageFS to be able to complete its job. This includes such programs as passwd, sendmail , etc.

CloudLinux uses proxyexec technology to accomplish this goal. You can define any program to run outside CageFS, by specifying it in /etc/cagefs/custom.proxy.commands file. Do not edit existing /etc/cagefs/proxy.commands as it will be overwritten with next CageFS update.

Once program is defined, run this command to populate the skeleton:

$ cagefsctl --update

All the cPanel scripts located in /usr/local/cpanel/cgi-sys/ that user might need to execute should be added to proxy.commands .

Users with duplicate UIDs

The syntax of /etc/cagefs/*.proxy.commands files is as follows:
ALIAS:wrapper_name=username:path_to_executable

Mandatory parameters are ALIAS and path_to_executable .

  • ALIAS - any name which is unique within all /etc/cagefs/*.proxy.commands files;

  • wrapper_name - the name of wrapper file, which is used as a replacement for executable file path_to_executable inside CageFS . Wrapper files are located in /usr/share/cagefs/safeprograms . If wrapper name is not specified, then default wrapper /usr/share/cagefs/safeprograms/cagefs.proxy.program is used. Also, a reserved word noproceed can be used, it will intend that wrapper is not in use (installed before) - applied for the commands with several ALIAS , as in the example below.

  • username - the name of a user on whose behalf path_to_executable will run in the real system. If username is not specified, then path_to_executable will run on behalf the same user that is inside CageFS.

  • path_to_executable - the path to executable file which will run via proxyexec .

Example of a simple command executed via proxyexec :

SENDMAIL=/usr/sbin/sendmail

Example of crontab command execution with custom wrapper under root (privilege escalation). The command uses two ALIAS , that is why in the second line noproceed is specified instead of wrapper name.

CRONTAB_LIST:cagefs.proxy.crontab=root:/usr/bin/crontab
CRONTAB_SAVE:noproceed=root:/usr/bin/crontab

Sometimes hosters may have users with non unique UIDs . Thus, proxyexec may traverse users directory to find a specific one. That behavior turns into inappropriate if users directory is not cached locally (for example LDAP is in use).

To turn this feature off:

touch /etc/cagefs/proxy.disable.duid

Or to activate it back:

rm /etc/cagefs/proxy.disable.duid

Custom /etc files per customer

[4.0-5 and later]

To create a custom file in /etc directory for end user, create a directory:
/etc/cagefs/custom.etc/[username]

Put all custom files, and sub-directories into that direcotry.

For example, if you want to create custom /etc/hosts file for USER1 , create a directory:
/etc/cagefs/custom.etc/USER1

Inside that directory, create a hosts file, with the content for that user.

After that execute:

$ cagefsctl --update-etc USER1

If you are making changes for multiple users, you can run:

$ cagefsctl --update-etc

To remove a custom file, remove it from /etc/cagefs/custom.etc/[USER] directory, and re-run:

$ cagefsctl --update-etc

Moving cagefs-skeleton directory

Sometimes you might need to move cagefs-skeleton from /usr/share to another partition.

There are two ways:

  1. If /usr/share/cagefs-skeleton is not created yet ( cagefsctl --init wasn't executed), then execute:
$ mkdir /home/cagefs-skeleton 
$ ln -s /home/cagefs-skeleton /usr/share/cagefs-skeleton 
$ cagefsctl --init
  1. If /usr/share/cagefs-skeleton already exists:
$ cagefsctl --disable-cagefs 
$ cagefsctl --unmount-all
# To ensure that the following command prints empty output: 
$ cat /proc/mounts | grep cagefs 
# if you see any cagefs entries, execute "cagefsctl --unmount-all" again.
$ mv /usr/share/cagefs-skeleton /home/cagefs-skeleton 
$ ln -s /home/cagefs-skeleton /usr/share/cagefs-skeleton
$ cagefsctl --enable-cagefs

On cPanel servers, if you place skeleton into /home directory, then you should configure the following option:

In cPanel WHM choose Server Configuration and go to Basic cPanel/WHM Setup , then in Basic Config change Additional home directories default value to blank (not "home" ).

Note

If this option is not set, then cPanel will create new accounts in incorrect places.

Moving /var/cagefs directory

To move /var/cagefs to another location:

$ cagefsctl --disable-cagefs
$ cagefsctl --unmount-all

Verify that /var/cagefs.bak directory does not exist (if it exists - change name "cagefs.bak" to something else)

$ cp -rp /var/cagefs /new/path/cagefs
$ mv /var/cagefs /var/cagefs.bak
$ ln -s /new/path/cagefs /var/cagefs
$ cagefsctl --enable-cagefs
$ cagefsctl --remount-all

Verify that the following command gives empty output:

$ cat /proc/mounts | grep cagefs.bak

Then you can safely remove /var/cagefs.bak:

$ rm -rf /var/cagefs.bak

TMP Directories

CageFS makes sure that each user has his own /tmp directory, and that directory is the part of end-user's quota.

The actual location of the directory is $USER_HOME/.cagefs/tmp

Once a day, using cron job, CageFS will clean up user's /tmp directory from all the files that haven't been accessed during 30 days.

This can be changed by running:

$ cagefsctl --set-tmpwatch='/usr/sbin/tmpwatch -umclq 720'

Where 720 is the number of hours that the file had to be inaccessible to be removed.

By default this is done at 03:37 AM, but you can also force the clean up outdated files that match 'chosen period' of all user's /tmp directories without waiting for a job to be launched by cronjob . Just run:

$ cagefsctl --tmpwatch

The following path will be cleaned as well:

/var/cache/php-eaccelerator (actual location $USER_HOME/.cagefs/var/cache/php-eaccelerator )

You can configure tmpwatch to clean custom directories inside CageFS .

Create /etc/cagefs/cagefs.ini configuration file and specify tmpwatch_dirs directive as follows:

tmpwatch_dirs=/dir1,/dir2

After that directories /dir1 and /dir2 inside CageFS  will be cleaned automatically.

Note that actual location of those directories in real file system is $USER_HOME/.cagefs/dir1 and $USER_HOME/.cagefs/dir2 .

Cleanup PHP sessions

For cPanel servers, CageFS version 6.0-42 or higher performs cleaning of PHP sessions based on session.gc_maxlifetime and session.save_path directives specified in proper php.ini files.

session.gc_maxlifetime directive default value is 1440 seconds. Those session files will be deleted, that were created or had metadata (ctime) changes more time ago than it is specified in session.gc_maxlifetime .

For Alt-PHP versions session.save_path value is normally /tmp .

Note

For new installations of Alt-PHP packages, session.save_path will be changed from /tmp to /opt/alt/phpNN/var/lib/php/session, where NN corresponds to Alt-PHP version.

This applies to the following Alt-PHP versions (or later):

  • alt-php44-4.4.9-71;
  • alt-php51-5.1.6-81;
  • alt-php52-5.2.17-107;
  • alt-php53-5.3.29-59;
  • alt-php54-5.4.45-42;
  • alt-php55-5.5.38-24;
  • alt-php56-5.6.31-7;
  • alt-php70-7.0.23-5;
  • alt-php71-7.1.9-5;
  • alt-php72-7.2.0-0.rc.2.2.

When using EasyApache 3, session.save_path value is normally /var/cpanel/php/sessions/ea3 or /tmp . Seettings for EasyApache 3 are usualy taken from the file /usr/local/lib/php.ini .

When using EasyApache 4, session.save_path value is normally /var/cpanel/php/sessions/ea-phpXX , where XX corresponds to PHP version.

Cleaning is started by cron /etc/cron.d/cpanel_php_sessions_cron , which starts the script /usr/share/cagefs/clean_user_php_sessions twice within one hour.

The settings for ea-php are located in /opt/cpanel/ea-phpXX/root/etc/php.d/local.ini or in /opt/cpanel/ea-phpXX/root/etc/php.ini , where XX corresponds to the PHP version.

The settings for alt-php are located in /opt/alt/phpXX/etc/php.ini files, where XX corresponds to PHP version.

The cleaning script cleans php sessions for all PHP versions ( ea-php and alt-php ) regardless of whether a version is used or selected via MultiPHP Manager or PHP Selector . When different session.gc_maxlifetime values are specified for the same session.save_path (for different php versions), the cleaning script will use the least value for cleaning session.save_path . So, it is recommended to specify different session.save_path for each PHP version.

Users can define custom value of session.gc_maxlifetime via PHP Selector in order to configure PHP's garbage collector, but that will not affect the script for cleaning PHP sessions. The script cleans PHP sessions based on global values of session.gc_maxlifetime and session.save_path directives taken from files mentioned above. Settings in custom users’ php.ini files are ignored.

Cleanup PHP session files in Plesk

For Plesk servers, CageFS version 6.0-52 or higher is provided with a special cron job for removing obsolete PHP session files. Cleanup script runs once an hour (similar to how it is done in Plesk).

Each time the script runs, it performs the cleanup of the paths:

  1. set by session.save_path directive in /opt/alt/phpXX/etc/php.ini files. If session.save_path is missing, then /tmp is used. Session files lifetime is set by session.gc_maxlifetime directive. If it is not found, then 1440 seconds value is used (24 minutes, as in Plesk). Lifetime set in the file is only taken into consideration if it is longer than 1440 seconds, otherwise 1440 seconds is used. All the installed Alt-PHP versions are processed.

  2. /var/lib/php/session . Files lifetime is only defined by Plesk script /usr/lib64/plesk-9.0/maxlifetime . If the script is missing or returns errors, then this directory is not processed.

The following features are applied during the cleanup:

  • all the users with UID higher than specified in /etc/login.defs are processed. Each user is processed independently from one another.
  • only directories inside CageFS are being cleaned. The paths of the same name in the physical  file system are not processed.
  • in all the detected directories, all the files with the names that correspond to sess_ search mask are removed, the rest of the files are ignored.
  • the files older than specified lifetime are removed.
  • all non-fatal errors (lack of rights, missing directory) are ignored and do not affect the further work of the script.

Disable PHP sessions cleanup on cPanel and Plesk

Here is a possible workaround for PHP session expiration problem (session lives longer than it is possible in a control panel). To use your own custom PHP sessions cleanup scripts - you can turn off built-in sessions cleanup implementation in the following way: add clean_user_php_sessions=false line to /etc/sysconfig/cloudlinux .

Syslog

By default, /dev/log should be available inside end user's CageFS . This is needed so that user's cronjobs and other things that user dev/log would get recorded in the system log files.

This is controlled using file /etc/rsyslog.d/schroot.conf with the following content:

$AddUnixListenSocket /usr/share/cagefs-skeleton/dev/log

To remove presence of dev/log inside CageFS, remove that file, and restart rsyslog service.

Excluding mount points

How to exclude mounts from namespaces for all LVEs

By default, all mounts from the real file system is inherited by namespaces of all LVEs . So, destroying all LVEs may be required in order to unmount some mount in real file system completely. Otherwise, mount point remains busy after unmounting it in the real file system because this mount exists in namespaces of LVEs .

lvectl start command saves all mounts from real file system as “default namespace” for later use in all LVEs . lve_namespaces service executes lvectl start command during startup.

In lve-utils-2.0-26 (and later) there is an ability to exclude specific mounts from namespaces for all LVEs . In order to do so, please create a file /etc/container/exclude_mounts.conf with list of mounts to exclude (one mount per line) as regular expressions, and then execute lvectl start :

# cat /etc/container/exclude_mounts.conf    
^/dir1/
^/dir2$
# lvectl start

After that, all new created LVEs will be without /dir2 mount and without mounts that start with /dir1/ (like /dir1/x , /dir1/x/y , etc). To apply changes to existing LVEs you should recreate LVEs :

# lvectl destroy all   
# lvectl apply all

Note

You should recreate all LVEs only once after creating /etc/container/exclude_mounts.conf file. After that the configuration changes will be applied to all new LVEs automatically.

Control Panel Integration

CageFS comes with a plugin for various control panels.

The plugin allows to:

  • Initialize CageFS;

  • Select mode of operation ;

  • See and modify the list of enabled/disabled users;

  • Update CageFS skeleton.

cPanel

CageFS plugin for cPanel is located in Plugins section of WHM.

It allows to initialize CageFS, select users CageFS will be enabled for, as well as update CageFS skeleton.

To enable CageFS for a proper user (users), in CageFS User Manager choose a user from the list on the right ( Disabled users) and click Toggle . The user will move to the list on the left ( Enabled users).

To disable a user (users), choose a user from the list on the left ( Enabled users) and click Disable CageFS . The user will move to the list on the right ( Disabled users).

To update CageFS skeleton, click Update CageFS Skeleton .

Plesk

CageFS comes with a plugin for Plesk 10.x. It allows initializing and updating CageFS template, as well as managing users and mode of operation for CageFS.

In modules section choose CageFS:

To enable CageFS for a proper user (users), in CageFS User Manager choose a user from the list on the right ( Disabled users) and click Toggle . The user will move to the list on the left ( Enabled users).

To disable a user (users), choose a user from the list on the left ( Enabled users) and click Disable CageFS . The user will move to the list on the right ( Disabled users).

To update CageFS skeleton, click Update CageFS Skeleton .

ISPManager

CageFS comes with plugin for ISP Manager to enable/disable CageFS on per user base. In edit user section chose Permission tab. Mark CageFS User Mode checkbox and click OK to apply.

Or you can manage global CageFS settings via CageFS menu