Apache suExec

suExec lets you execute CGI processes as a separate user than the webserver, usually unprivileged.


SuExec is very strict on security. When compiling Apache, you need to set the SuExec parameters that will be used.

You can display the SuExec compile-time variables:

/usr/lib/apache2/suexec -V

As a reference, here are the settings for an Ubuntu 13.04 install:

 -D AP_DOC_ROOT="/var/www"
 -D AP_GID_MIN=100
 -D AP_HTTPD_USER="www-data"
 -D AP_LOG_EXEC="/var/log/apache2/suexec.log"
 -D AP_SAFE_PATH="/usr/local/bin:/usr/bin:/bin"
 -D AP_UID_MIN=100
 -D AP_USERDIR_SUFFIX="public_html"

Also, one from Gentoo with Apache 2.2.29:

 -D AP_DOC_ROOT="/var/www"
 -D AP_GID_MIN=100
 -D AP_HTTPD_USER="apache"
 -D AP_LOG_EXEC="/var/log/apache2/suexec_log"
 -D AP_SAFE_PATH="/usr/local/bin:/usr/bin:/bin"
 -D AP_UID_MIN=1000
 -D AP_USERDIR_SUFFIX="public_html"

The commands executed by SuExec must have a parent directory of DOC_ROOT. They do not immediately need to be in that directory, just below it. So, /var/www/cgi-bin would be fine.

GID_MIN and UID_MIN are minimum values, to prevent users with low-level privileges from executing scripts.

HTTPD_USER is the user that Apache drops to after starting the program as root.

These are all configured when installing Apache.

Build-time Gotcha

When compiling Apache, if you change the SuExec configuration variables, do a full make clean on the directory, or the new compile will still use the old variables.

Apache Configuration

The only directive that needs to be set inside the Apache config is SuexecUserGroup. It can be set either globally or per-virtualhost.

SuexecUserGroup www www


Here is an example of the configuration options on OSX.

./configure \
        --enable-suexec \
        --with-suexec-docroot=/var/www \
        --with-suexec-bin=/usr/local/apache2/bin/suexec \
        --with-suexec-caller=daemon \
        --with-suexec-uidmin=500 \
        --with-suexec-logfile=/usr/local/apache2/logs/suexec_log \
        --with-suexec-gidmin=20 \
        --with-suexec-userdir=Sites \

And the result of suexec -V:

 -D AP_DOC_ROOT="/private/var/www"
 -D AP_HTTPD_USER="daemon"
 -D AP_LOG_EXEC="/usr/local/apache2/logs/suexec_log"
 -D AP_SAFE_PATH="/usr/local/bin:/usr/bin:/bin"
 -D AP_UID_MIN=500

Again, note that HTTPD_USER is daemon, or the user that Apache runs as. The GID_MIN and UID_MIN are set for the minimum uids of the user running the executables.

Related config:

SuexecUserGroup steve staff


  • SUEXEC_SAFEPATH: Default PATH for suexec (default: /usr/local/bin:/usr/bin:/bin)
  • SUEXEC_LOGFILE: Path to the suexec logfile (default: /var/log/apache2/suexec_log)
  • SUEXEC_CALLER: Name of the user Apache is running as (default: apache)
  • SUEXEC_DOCROOT: Directory in which suexec will run scripts (default: /var/www)
  • SUEXEC_MINUID: Minimum UID, which is allowed to run scripts via suexec (default: 1000)
  • SUEXEC_MINGID: Minimum GID, which is allowed to run scripts via suexec (default: 100)
  • SUEXEC_USERDIR: User subdirectories (like /home/user/html) (default: public_html)
  • SUEXEC_UMASK: Umask for the suexec process (default: 077)