How to Configure Apache suEXEC Document Root from /var/www to /home on Ubuntu


10 views

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:

  1. Modify the source configuration
  2. Recompile suexec
  3. 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