Many Apache administrators on CentOS encounter this frustrating scenario: while the main DocumentRoot (/var/www/html
) serves content perfectly, any attempt to access subdirectories (localhost/test
) results in a 403 Forbidden error. Let's thoroughly examine the complete solution set.
Before diving into Apache configurations, verify these essential server-level permissions:
# Check directory ownership
ls -ld /var/www/html/test
# Verify Apache user has execute permission on parent directories
namei -l /var/www/html/test
The default configuration often needs these critical adjustments:
<Directory "/var/www/html">
Options Indexes FollowSymLinks
AllowOverride All
Require all granted
# For Apache 2.2 compatibility:
# Order allow,deny
# Allow from all
</Directory>
On CentOS, SELinux often blocks access. Check and modify context:
# View current context
ls -Z /var/www/html
# Apply proper context
chcon -R -t httpd_sys_content_t /var/www/html/test
semanage fcontext -a -t httpd_sys_content_t "/var/www/html/test(/.*)?"
Here's a working configuration that addresses all potential issues:
# In /etc/httpd/conf/httpd.conf or separate vhost file
<VirtualHost *:80>
DocumentRoot "/var/www/html"
ServerName localhost
<Directory "/var/www/html">
Options Indexes FollowSymLinks
AllowOverride All
Require all granted
</Directory>
# Specific subdirectory permissions
<Directory "/var/www/html/test">
Options +Indexes
Require all granted
</Directory>
</VirtualHost>
# Then run these commands:
chmod 755 /var/www/html
chown -R apache:apache /var/www/html/test
restorecon -Rv /var/www/html
systemctl restart httpd
- Verify parent directory execute permissions (chmod 755)
- Check for correct ownership (apache:apache or www-data:www-data)
- Confirm SELinux isn't blocking access (audit2allow if needed)
- Ensure no conflicting .htaccess files exist
- Check error logs:
tail -f /var/log/httpd/error_log
When working with Apache on CentOS, you might encounter a frustrating 403 Forbidden error when trying to access subdirectories under your DocumentRoot (/var/www/html in this case). While the root directory loads fine, attempting to access localhost/test fails with permission issues. Let's break down why this happens and how to properly configure Apache.
The original configuration shows two main Directory blocks:
<Directory />
Options FollowSymLinks
AllowOverride None
</Directory>
<Directory "/var/www/html">
Options Indexes FollowSymLinks
AllowOverride None
Order allow,deny
Allow from all
</Directory>
While this configuration allows access to the root directory, it doesn't properly handle subdirectories. The key issues are:
- Missing "ExecCGI" option if you need CGI scripts
- Potential SELinux context problems on CentOS
- Incorrect filesystem permissions
Here's a comprehensive configuration that solves the subdirectory access problem:
# Main configuration for /var/www/html
<Directory "/var/www/html">
Options Indexes FollowSymLinks
AllowOverride All
Require all granted
# Set default directory permissions
<IfModule mod_access_compat.c>
Order allow,deny
Allow from all
</IfModule>
</Directory>
# Additional security for system directories
<Directory />
Options FollowSymLinks
AllowOverride None
Require all denied
</Directory>
On CentOS/RHEL systems, you should also verify:
# Check SELinux context
ls -Z /var/www/html
# If context is wrong, fix it with:
chcon -R -t httpd_sys_content_t /var/www/html
# Verify directory permissions
chmod -R 755 /var/www/html
chown -R apache:apache /var/www/html
After making changes, always:
- Check syntax:
apachectl configtest
- Restart Apache:
systemctl restart httpd
- Check error logs:
tail -f /var/log/httpd/error_log
If you need directory-specific rules, enable .htaccess:
<Directory "/var/www/html/test">
AllowOverride All
Options +Indexes
Require all granted
</Directory>
Then create /var/www/html/test/.htaccess with:
Options +Indexes
DirectoryIndex index.php index.html