Suexec

From Wiki

Jump to: navigation, search

Contents

What is SuExec

Basics

There are three ways you can execute a script from Apache Web Server:

  1. With a built-in module like mod_php, mod_perl, mod_python, etc.
  2. By executing the script directly with mod_cgi
  3. Executing the script through mod_cgi but using a wrapper application - SuExec

So SuExec was developed to address one of the main security issues that Apache Web server had at that time - all scripts were run by the same user.

How it works?

SuExec is a Set Uid Root binary. What this means is that every time it is executed, the system runs this program with root privileges.

So SuExec does several checks before executing a script. A few of those are:

After all of these checks have finished successfully, SuExec changes its User ID (UID) from root (0) to the UID with which it has to run the script and runs it. Before the actual run of the script, SuExec logs the execution to suexec.log (if not changed during build).

What our modifications add?

Chroot

The normal suexec 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 your 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 SuExec. 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.

Limits

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, since all user scripts are executed by SuExec, we decided to implement these resource limitations in it.

We have currently implemented the following resource limits:

If you want more information about these limits please refer to the getrlimit man page on your Linux machine:

man getrlimit

Statistics

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 suexec.

So now before every execution, suexec logs it, but after that, it logs the resources used by the process. This way we have information about every process executed on the machine and we simply have to read the logs and calculate the statistics.

Configuration

Our SuExec 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

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 joyme:

joyme:50000000:120:20:200000000:40

So processes of user joyme will have the following limitations:

  1. Maximum 50MB of memory
  2. Maximum of 120 CPU ticks (do not mistake a CPU tick with an actual second, it is not)
  3. Maximum of 20 simultaneous processes at any given time
  4. The biggest file it can create or read will be 200MB
  5. 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. The default limits can be seen using suexec -V:

# /usr/local/apache/bin/suexec -V
 -D LOG_EXEC="/usr/local/apache/logs/suexec_log"
 -D DOC_ROOT="/usr/local/apache/htdocs"
 -D SAFE_PATH="/usr/bin:/bin"
 -D HTTPD_USER="nobody"
 -D UID_MIN=100
 -D GID_MIN=99
 -D SUEXEC_CHROOT, CHROOT_DIR=/var/suexec/, BASE_OS=/var/suexec/baseos, HOME_PATH=/home/
 -D SUEXEC_TRUSTED_USER=0
 -D SUEXEC_TRUSTED_GROUP=10
 -D USERDIR_SUFFIX="public_html"
 -D INCLUDEPHP
 -D INCLUDELIMITS
        LIMITS_CONF="/usr/local/apache/conf/rlimit-config"
        MAX_CPUTIME=120
        MAX_MEMLIMIT=920000000
        MAX_NUMPROC=40
        MAX_FSIZE=2000000000
        MAX_OFILE=30
 -D INCLUDESTATS
 -D HAVECGIDIR
 -D STDEXEC
 -D MOUNTCHECK
VERSION: 0.1.7

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.

CMD line test

su - nobody -s /bin/bash -c 'export PHPHANDLER="/usr/bin/php";cd /home/USER/public_html;/usr/local/apache/bin/suexec 503 500 i.php'
<?php phpinfo(); ?>


Error codes

*  Sev     Meaning
* emerg:  Failure of some basic system function
* alert:  Bug in the way Apache is communicating with suexec
* crit:   Basic information is missing, invalid, or incorrect
* error:  Script permission/configuration error
* warn:   
* notice: Some issue which the sysadmin/webmaster should be aware of
* info:   Normal activity message
* debug:  Self-explanatory
Retrieved from "http://docs.1h.com/Suexec"
Personal tools
Namespaces
Variants
Actions
Navigation
Toolbox