I recently encountered a baffling situation where my .htaccess rules were being completely ignored on a Fedora 13 LAMP server. Despite having AllowOverride All
properly configured in my VirtualHost, directives like these had no effect:
RewriteEngine on
RewriteBase /
RewriteRule ^.*$ index.php
Even extreme test cases like completely blocking access didn't work:
order deny,allow
deny from all
My virtual host configuration in /etc/httpd/conf.d/virtual.conf
appeared correct:
<VirtualHost *>
ServerName ourwebsite.com
DocumentRoot /var/www/html/ourwebsite.com/docroot
<Directory "/var/www/html/ourwebsite.com/docroot">
Options FollowSymLinks
AllowOverride All
Order allow,deny
Allow from all
</Directory>
</VirtualHost>
After extensive testing, I discovered the root cause in Apache's main configuration. The default <Directory />
directive was overriding my VirtualHost settings:
<Directory />
Options FollowSymLinks
AllowOverride None # This was the culprit!
</Directory>
Changing this to AllowOverride All
immediately made my .htaccess rules work. This reveals an important lesson about Apache's configuration hierarchy.
Apache processes directory directives in a specific order:
- Main server config (httpd.conf)
- VirtualHost directives
- .htaccess files
The most restrictive setting takes precedence. In my case, the global AllowOverride None
was more restrictive than the VirtualHost's AllowOverride All
.
For most production environments, I recommend this approach:
<Directory />
Options FollowSymLinks
AllowOverride None
Require all denied
</Directory>
<Directory /var/www/html>
Options Indexes FollowSymLinks
AllowOverride All
Require all granted
</Directory>
This provides security while still allowing .htaccess overrides in your web directories.
If you're experiencing similar problems, try these debugging steps:
# Check if mod_rewrite is loaded
apachectl -M | grep rewrite
# Test your configuration syntax
apachectl configtest
# Verify which directives are being processed
tail -f /var/log/httpd/error_log
Remember that file permissions also matter - ensure your .htaccess file is readable by the Apache user.
For performance-critical environments, consider moving your rules directly into the VirtualHost configuration:
<VirtualHost *>
ServerName ourwebsite.com
DocumentRoot /var/www/html/ourwebsite.com/docroot
<Directory "/var/www/html/ourwebsite.com/docroot">
RewriteEngine On
RewriteRule ^.*$ index.php [L]
</Directory>
</VirtualHost>
This eliminates .htaccess parsing overhead while maintaining the same functionality.
The scenario where .htaccess
files are completely ignored despite having proper AllowOverride All
directives in VirtualHost configurations is more common than many developers realize. This issue typically manifests when:
- Rewrite rules don't execute
- Access control directives have no effect
- Custom error documents fail to work
The root cause often lies in Apache's configuration hierarchy. The key discovery was:
<Directory />
Options FollowSymLinks
AllowOverride None
</Directory>
This default configuration in httpd.conf
takes precedence over VirtualHost-specific settings, effectively disabling .htaccess
processing globally.
To properly fix this, we need to modify both the global and VirtualHost configurations:
# In httpd.conf or apache2.conf
<Directory />
Options FollowSymLinks
AllowOverride None
Require all denied
</Directory>
# Then in your VirtualHost configuration
<VirtualHost *:80>
ServerName ourwebsite.com
DocumentRoot /var/www/html/ourwebsite.com/docroot
<Directory "/var/www/html/ourwebsite.com/docroot">
Options FollowSymLinks
AllowOverride All
# For Apache 2.4+
Require all granted
# For Apache 2.2
Order allow,deny
Allow from all
</Directory>
</VirtualHost>
After making changes:
- Restart Apache:
sudo systemctl restart httpd
- Check syntax:
apachectl configtest
- Verify using this test
.htaccess
:
# Force 403 Forbidden for testing
Order deny,allow
Deny from all
For systems where modifying the root Directory directive isn't possible:
# Option 1: Move directives to main config
<Directory "/var/www/html/ourwebsite.com/docroot">
RewriteEngine On
RewriteRule ^.*$ index.php [L]
</Directory>
# Option 2: Use LocationMatch
<LocationMatch "^/.*">
# Your rules here
</LocationMatch>
Ensure these modules are enabled:
mod_rewrite
mod_authz_host
mod_alias
Enable with: sudo a2enmod rewrite
If problems persist, check:
# View applied configuration
apachectl -S
# Check enabled modules
apachectl -M
# Verify directory permissions
namei -l /var/www/html/ourwebsite.com/docroot/.htaccess