The Apache suEXEC feature provides security when executing CGI scripts by running them with the permissions of the user who owns them. By default on Ubuntu systems, suEXEC is compiled with /var/www
as the document root (AP_DOC_ROOT
), which may not match your server setup if you're using home directories.
Since suEXEC is compiled into Apache, changing the document root requires recompilation. Here's the complete process:
# Install required build dependencies
sudo apt-get install apache2-dev apache2-suexec-custom
# Download Apache source matching your version
sudo apt-get source apache2
# Configure with new document root
cd apache2-2.4.*
./configure --with-suexec-docroot=/home \
--with-suexec-userdir=public_html \
--with-suexec-logfile=/var/log/apache2/suexec.log \
--with-suexec-uidmin=100 \
--with-suexec-gidmin=100
# Build the suexec binary
make suexec
# Back up and replace existing suexec
sudo mv /usr/lib/apache2/suexec /usr/lib/apache2/suexec.bak
sudo cp support/suexec /usr/lib/apache2/
sudo chown root:root /usr/lib/apache2/suexec
sudo chmod 4755 /usr/lib/apache2/suexec
After rebuilding, verify the changes took effect:
sudo /usr/lib/apache2/suexec -V
You should now see:
-D AP_DOC_ROOT="/home"
-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"
For user directories to work properly, ensure your Apache configuration includes:
<VirtualHost *:80>
ServerName example.com
DocumentRoot /home/user/public_html
<Directory /home/user/public_html>
Options +ExecCGI
AddHandler fcgid-script .fcgi .cgi
FCGIWrapper /home/user/public_html/cgi-bin/php-cgi .php
Require all granted
</Directory>
SuexecUserGroup user user
</VirtualHost>
Create a test CGI script to verify permissions:
#!/bin/sh
echo "Content-type: text/plain"
echo ""
echo "Hello World! Running as $(whoami)"
Save this as /home/user/public_html/cgi-bin/test.cgi
and make it executable:
chmod +x /home/user/public_html/cgi-bin/test.cgi
When you install suexec via apache2-suexec
package on Ubuntu, it's compiled with default paths that might not match your server setup. The critical parameter here is AP_DOC_ROOT
, which defines the base directory where suexec will allow script execution.
# Current default configuration
-D AP_DOC_ROOT="/var/www"
-D AP_HTTPD_USER="www-data"
-D AP_USERDIR_SUFFIX="public_html"
Unlike regular Apache directives, suexec security parameters are compiled into the binary. This means you can't simply edit a config file - you need to:
- Modify the source configuration
- Recompile suexec
- Replace the existing binary
First, install required development tools:
sudo apt-get update
sudo apt-get install apache2-dev dpkg-dev debhelper
Get the source package:
apt-get source apache2-suexec
cd apache2-suexec-*
Edit the configuration file. Look for suexec.h
or similar:
nano debian/suexec.h
Modify the document root definition:
#define AP_DOC_ROOT "/home"
Build the modified package:
dpkg-buildpackage -rfakeroot -b
Install the new package:
cd ..
sudo dpkg -i apache2-suexec-custom*.deb
After installation, verify the changes:
sudo /usr/lib/apache2/suexec -V
Expected output should show:
-D AP_DOC_ROOT="/home"
Create a test script in a user's public_html:
# /home/testuser/public_html/test.cgi
#!/bin/sh
echo "Content-type: text/plain"
echo ""
echo "Suexec test successful"
Set proper permissions:
chmod 755 /home/testuser/public_html/test.cgi
chown -R testuser:testuser /home/testuser/public_html
Update your virtual host configuration:
<VirtualHost *:80>
ServerName example.com
SuexecUserGroup testuser testuser
DocumentRoot /home/testuser/public_html
<Directory /home/testuser/public_html>
Options +ExecCGI
SetHandler cgi-script
Require all granted
</Directory>
</VirtualHost>
Permission issues: Ensure:
sudo chown -R www-data:www-data /home
sudo find /home -type d -exec chmod 711 {} \;
SELinux contexts: On RHEL/CentOS:
chcon -R -t httpd_sys_content_t /home
Log debugging: Check suexec log:
tail -f /var/log/apache2/suexec.log