What our modifications add?
The normal crond adds decent security by running all scripts with user privileges but this doesn't protect world writable directories and files. Also, world readable files are open to all users, so you can't protect one user's data from leaking to other users on the machine.
We worked to solve these issues and add a separation between users.
So what we did was to add chroot support to our crond. What this means is that a user can see only its own files and the programs from the BaseOS. The user is insulated from everyone else on the machine.
More about the chroot structure and mechanism can be found here.
Every time a user runs a script on the server, its script can use as much resources as its parent process can, this is simply how processes work on Linux. But Linux gives us a way of controlling the resource allocation of each process, the parent process only has to set a new limit before starting the new process. So, after the successful implementation of those limits in SuExec, we decided to implement them in crond as well.
We have currently implemented the following resource limits:
- CPU time limitations (RLIMIT_CPU)
- Maximum memory allocation by a process (RLIMIT_AS)
- Maximum size of files that a process may create (RLIMIT_FSIZE)
- Maximum number of files that a process may open (RLIMIT_NOFILE)
- Maximum number of processes that a user may have in any single time on the system (RLIMIT_NPROC)
If you want more information about these limits please refer to the getrlimit man page on your Linux machine:
In Linux it is possible to collect resource statistics from each child process. We decided to use this functionality to collect CPU usage statistics from all processes started by crond.
Before every execution our modified crond logs it and the cpustats daemon logs the resources used by the process. This way we have information about every process executed by crond.
Via The 1H Web Interface
The crond limits configuration is available in the 1H Local Interface -> Settings -> Hive Configuration.
You can adjust the global limits for the server via this interface. If you need to have limits alter per user those changes must be made manually in the limits configuration file as explained below.
Our crond offers configuration for the limits it imposes for every process. You can either change the global values or on a per-user basis.
The configuration file is /usr/local/apache/conf/rlimit-config and it is used by both SuExec and crond.
Its syntax is very simple:
username:memlimit:cpulimit:numproc:filesize:ofiles username - the username for which these limits will apply memlimit - RLIMIT_AS cpulimit - RLIMIT_CPU numporoc - RLIMIT_NPROC filesize - RLIMIT_FSIZE ofiles - RLIMIT_NOFILE
Here is an exemplary custom limits entry for user myuser:
So processes of user myuser will have the following limitations:
- Maximum 50MB of memory
- Maximum of 120 CPU ticks (do not mistake a CPU tick with an actual second, it is not)
- Maximum of 20 simultaneous processes at any given time
- The biggest file it can create or read will be 200MB
- The maximum number of files it can open simultaneously will be 40
If a username is not found in the rlimit-config, the Default limits are applied to its processes.
You can change the default limits by using a magic username in the rlimit-config. If you have a line with username 00 in the configuration file, those limits will be used instead of the default if a username is not found in the file.
How to exclude users from the chroot/global limits?
We know that some users need access to resources and programs that are not available in the chrooted environment. That is why we developed our custom crond in such a way that you can exclude users from the default configuration. The first step is to create the following folder:
By default the folder doesn't exist and you can use the mkdir command to create it:
Exclude an account from the chrooted environment
To exclude a certain user from the chrooted environment you just have to access the cron.exclude folder and create the following empty file:
Please note that you should replace the "USER" string with the actual username that you want to be excluded. You can use the touch command to create the file:
In the above mentioned example the "myacct" user has been excluded from the chrooted environment. There is no need to restart the cron daemon for the changes to take effect.
Exclude an account from global limits
To exclude a certain user from the global limits you need to create the following file:
Of course, you have to replace the "USER" string with the actual username that you want to be excluded. You can use the touch command to create the file: