Troubleshooting Apache CGI Permission Denied Errors: Fixing SELinux Restrictions

When setting up CGI scripts in Apache, one of the most frustrating errors you might encounter is:

AH01241: error spawning CGI child: exec of '/var/www/html/index.cgi' failed (Permission denied)

or:

AH01215: stderr from /var/www/html/index.cgi: (13)Permission denied: exec of '/var/www/html/index.cgi' failed

This error often indicates a permissions issue that prevents Apache from executing the CGI script. While incorrect file permissions or ownership are common culprits, SELinux (Security-Enhanced Linux) can also block execution if not configured correctly.

In this article, we’ll go through step-by-step solutions to resolve the issue and ensure smooth execution of CGI scripts under Apache while maintaining security.


1. Check File Permissions

Apache needs executable permissions on your CGI script. Run the following command:

chmod 755 /var/www/html/index.cgi

Then verify the permissions:

ls -l /var/www/html/index.cgi

The expected output should look like this:

-rwxr-xr-x 1 www-data www-data ... index.cgi

If permissions are too restrictive (e.g., chmod 644), Apache won’t be able to execute the script.


2. Check File Ownership

Ensure that the script is owned by the correct user and group. For Debian/Ubuntu, use:

chown www-data:www-data /var/www/html/index.cgi

For RHEL/CentOS, use:

chown apache:apache /var/www/html/index.cgi

Then verify ownership with:

ls -l /var/www/html/index.cgi

3. Check Directory Permissions

Apache also needs access to parent directories. Ensure the permissions are correct:

chmod 755 /var/www/html
chmod 755 /var/www

If the script is inside a cgi-bin directory:

chmod 755 /var/www/html/cgi-bin

4. Verify Apache CGI Configuration

Ensure CGI execution is enabled in Apache. Edit your Apache configuration file:

nano /etc/apache2/sites-available/000-default.conf  # Debian/Ubuntu
nano /etc/httpd/conf/httpd.conf  # RHEL/CentOS

Add or modify the following directive:

<Directory "/var/www/html">
    Options +ExecCGI
    AddHandler cgi-script .cgi
    Require all granted
</Directory>

If your script is inside cgi-bin:

ScriptAlias /cgi-bin/ "/var/www/html/cgi-bin/"
<Directory "/var/www/html/cgi-bin">
    Options +ExecCGI
    Require all granted
</Directory>

Then restart Apache:

systemctl restart apache2  # Debian/Ubuntu
systemctl restart httpd  # RHEL/CentOS

5. Troubleshooting SELinux Issues

If the above steps don’t resolve the issue, SELinux might be blocking execution. Check its status:

sestatus

If SELinux is enforcing, try allowing Apache to execute CGI scripts:

setsebool -P httpd_enable_cgi 1
setsebool -P httpd_execmem 1
restorecon -Rv /var/www/html/index.cgi

To temporarily disable SELinux for testing:

setenforce 0

If disabling SELinux resolves the issue, but you want a permanent and secure fix, modify the SELinux context:

chcon -t httpd_sys_script_exec_t /var/www/html/index.cgi

To make it persistent:

semanage fcontext -a -t httpd_sys_script_exec_t "/var/www/html/index.cgi"
restorecon -Rv /var/www/html/index.cgi

6. Check Apache Logs

If the issue persists, check Apache’s error logs for additional details:

tail -f /var/log/apache2/error.log  # Debian/Ubuntu
tail -f /var/log/httpd/error_log  # RHEL/CentOS

Look for permission-related messages and adjust settings accordingly.


7. Verify the Shebang Line

Ensure your CGI script starts with the correct interpreter line. For example:

  • Perl: #!/usr/bin/env perl
  • Python: #!/usr/bin/env python3
  • Bash: #!/bin/bash

Check if the interpreter exists and is executable:

ls -l /usr/bin/env /usr/bin/perl /usr/bin/python3 /bin/bash

If the shebang points to a non-existent or inaccessible interpreter, Apache won’t execute the script.


8. Ensure Noexec Is Not Set on Mount Points

If your web directory is mounted with the noexec flag, it will prevent execution of CGI scripts. Check by running:

mount | grep /var/www

If noexec is present, remount the filesystem with execution permissions:

mount -o remount,exec /var/www

Final Thoughts

Troubleshooting Apache CGI execution errors can be tricky, especially when SELinux is enforcing strict security policies. By following these steps, you should be able to resolve most Permission Denied (13) errors while maintaining a secure and functional server environment.

If you still encounter issues, consider checking for additional security policies or firewall rules that may be restricting Apache’s access to your scripts.

Let us know in the comments if this guide helped you, or if you have additional troubleshooting tips! 🚀

This article is inspired by real-world challenges we tackle in our projects. If you're looking for expert solutions or need a team to bring your idea to life,

Let's talk!

    Please fill your details, and we will contact you back

      Please fill your details, and we will contact you back