LFCE 53 ๐ง Apache โ Modules and .htaccess
Apache’s functionality is extended through modules, and its configuration can be extended into per-directory files called .htaccess. These are two separate mechanisms that solve different problems. A module adds capabilities to the server itself: SSL/TLS, URL rewriting, authentication, compression. A .htaccess file allows configuration directives to be applied at the directory level without editing the main server configuration. The previous chapter covered virtual hosts; this chapter covers the modules that enable features within those hosts and the .htaccess mechanism that allows per-directory overrides.
The management of modules differs significantly between Debian and RHEL. Debian uses the a2enmod and a2dismod helper scripts to manage symlinks between mods-available and mods-enabled. RHEL uses the LoadModule directive in configuration files under conf.modules.d/. The .htaccess mechanism is controlled by the AllowOverride directive, and its use has performance and security implications that the Apache documentation explicitly warns about.
Key point: Debian enables modules with a2enmod <module>; RHEL enables them by uncommenting or adding LoadModule in conf.modules.d/. The .htaccess file is only read if the <Directory> block for that path has AllowOverride set to a value other than None. The Apache documentation recommends using the main server configuration instead of .htaccess whenever possible, because .htaccess files are read on every request and can be a security risk if users are allowed to modify them.
Why modules and .htaccess require separate treatment
The module-management problem.
A module is a shared object that extends the server. mod_ssl provides HTTPS, mod_rewrite provides URL manipulation, mod_auth_basic provides password authentication. The module must be loaded before its directives are recognized. On Debian, a2enmod creates a symlink in /etc/apache2/mods-enabled/ that points to the module’s .load file in mods-available. The .load file contains the LoadModule directive, and the module is loaded when Apache starts . On RHEL, the LoadModule directive is placed in a file under /etc/httpd/conf.modules.d/, and the service must be restarted for the module to load .
The AllowOverride problem.
The .htaccess file is a per-directory configuration file. Apache looks for it in the requested directory and every parent directory up to the document root. This lookup happens on every request, even if the file does not exist. The AllowOverride directive controls which directives from the .htaccess file are honored. AllowOverride None disables .htaccess entirely. AllowOverride All permits every directive. The specific values like FileInfo, AuthConfig, and Indexes permit only the corresponding directive groups . The Apache documentation states that .htaccess should be used only when the content provider does not have access to the main server configuration, and that even then, the performance cost is significant .
The performance-cost problem.
For every request, Apache performs a filesystem lookup for .htaccess in the requested directory and all its parents. If the document root is /var/www/example and the request is for /var/www/example/subdir/file.html, Apache looks for .htaccess in /var/www/example/subdir/, /var/www/example/, and possibly higher directories depending on the AllowOverride settings. This is four additional filesystem accesses per request, even when no .htaccess file exists . For mod_rewrite rules in .htaccess, the regular expressions are recompiled on every request, whereas in the main configuration they are compiled once and cached.
a. Managing modules on Debian and RHEL
On Debian and Ubuntu, the a2enmod and a2dismod commands manage the symlinks. The module’s .load file contains the LoadModule directive, and the optional .conf file contains configuration directives that are applied when the module is enabled .
# Debian: enable the rewrite module
sudo a2enmod rewrite
# Output: Enabling module rewrite.
# To activate the new configuration, you need to run:
# systemctl restart apache2
# Disable a module
sudo a2dismod rewrite
# List enabled modules
ls /etc/apache2/mods-enabled/
The a2enmod command creates a symlink in /etc/apache2/mods-enabled/ that points to the module’s files in /etc/apache2/mods-available/. If the module has a .conf file, its directives are included in the main server context . The a2dismod command removes the symlink. The service must be restarted or reloaded for the change to take effect.
On RHEL and its derivatives, the module loading is controlled by the LoadModule directive. The module’s .so file is in /usr/lib64/httpd/modules/, and the LoadModule line is placed in a file under /etc/httpd/conf.modules.d/ .
# RHEL: search for the module in the configuration files
grep mod_ssl.so /etc/httpd/conf.modules.d/*
# If found, uncomment the LoadModule line
# LoadModule ssl_module modules/mod_ssl.so
# If not found, create a new configuration file
sudo tee /etc/httpd/conf.modules.d/30-example.conf > /dev/null <<'EOF'
LoadModule ssl_module modules/mod_ssl.so
EOF
# Restart the service
sudo systemctl restart httpd
The grep command locates the configuration file that contains the module’s LoadModule line. The line is uncommented to enable the module. If the module is not referenced in any file, a new file is created with the LoadModule directive . The service restart is required because the module is loaded at startup, not on reload.
b. Enabling .htaccess with AllowOverride
The .htaccess file is only read if the <Directory> block for the path has AllowOverride set to a value other than None. The value determines which directive groups are permitted.
<Directory /var/www/example>
Options -Indexes +FollowSymLinks
AllowOverride All
Require all granted
</Directory>
The AllowOverride All directive permits every directive in .htaccess. A more restrictive configuration permits only specific groups, such as FileInfo for mod_rewrite directives or AuthConfig for authentication directives .
<Directory /var/www/example>
AllowOverride FileInfo AuthConfig
</Directory>
The FileInfo group permits directives that control the handling of files, including mod_rewrite rules. The AuthConfig group permits authentication directives. A directive in .htaccess that is not permitted by the AllowOverride value causes an Internal Server Error when the file is requested, because Apache refuses to process the directive .
c. The .htaccess file and its use cases
A .htaccess file contains directives in the same syntax as the main configuration. It applies to the directory it is in and all subdirectories, unless overridden by another .htaccess file.
# /var/www/example/.htaccess
RewriteEngine On
RewriteRule ^old-page\.html$ /new-page.html [R=301,L]
<Files ".env">
Require all denied
</Files>
The RewriteEngine On directive enables the rewrite engine for the directory. The RewriteRule redirects requests for old-page.html to new-page.html with a permanent redirect. The <Files> block denies access to the .env file . The .htaccess file is read on every request, and the directives are applied before the request is processed.
The Apache documentation explicitly recommends against using .htaccess when the main configuration is accessible. The main configuration is parsed once at startup, the directives are compiled once, and there is no per-request filesystem lookup. The .htaccess mechanism exists for shared hosting environments where users do not have root access and cannot edit the main configuration . In a dedicated server or a virtual machine where the administrator has root access, the <Directory> block in the virtual host configuration is the correct place for these directives.
Complete Example Session
# ============================================
# PART 1: ENABLE MOD_REWRITE ON DEBIAN
# ============================================
sudo a2enmod rewrite
sudo systemctl restart apache2
# ============================================
# PART 2: ENABLE MOD_SSL ON DEBIAN
# ============================================
sudo a2enmod ssl
sudo systemctl restart apache2
# ============================================
# PART 3: VERIFY ENABLED MODULES ON DEBIAN
# ============================================
ls /etc/apache2/mods-enabled/ | grep -E "rewrite|ssl"
# Output: rewrite.load, ssl.load
# ============================================
# PART 4: ENABLE MOD_REWRITE ON RHEL
# ============================================
grep mod_rewrite.so /etc/httpd/conf.modules.d/*
# If commented, uncomment the LoadModule line
# If not present, add it to a new .conf file
sudo tee /etc/httpd/conf.modules.d/30-rewrite.conf > /dev/null <<'EOF'
LoadModule rewrite_module modules/mod_rewrite.so
EOF
sudo systemctl restart httpd
# ============================================
# PART 5: CONFIGURE AllowOverride
# ============================================
# In the <Directory> block for the site:
# AllowOverride FileInfo AuthConfig
# Validate and reload
sudo apache2ctl configtest
sudo systemctl reload apache2
# ============================================
# PART 6: CREATE THE .htaccess FILE
# ============================================
sudo tee /var/www/example/.htaccess > /dev/null <<'EOF'
RewriteEngine On
RewriteRule ^old-page\.html$ /new-page.html [R=301,L]
<Files ".env">
Require all denied
</Files>
EOF
# ============================================
# PART 7: CREATE THE TARGET FILE
# ============================================
echo "<h1>New Page</h1>" | sudo tee /var/www/example/new-page.html
sudo chown www-data:www-data /var/www/example/.htaccess /var/www/example/new-page.html
# ============================================
# PART 8: TEST THE REWRITE
# ============================================
curl -I http://localhost/old-page.html
# Output: HTTP/1.1 301 Moved Permanently
# Location: http://localhost/new-page.html
# ============================================
# PART 9: TEST THE FILE DENIAL
# ============================================
curl -I http://localhost/.env
# Output: HTTP/1.1 403 Forbidden
# ============================================
# PART 10: VERIFY THE MODULES ARE LOADED
# ============================================
sudo apache2ctl -M | grep -E "rewrite|ssl"
# Output: rewrite_module (shared)
# ssl_module (shared)
The ten parts demonstrate the complete module and .htaccess workflow: enabling modules on Debian, verifying the enablement, enabling a module on RHEL, configuring AllowOverride, creating the .htaccess file, testing the rewrite, testing the file denial, and verifying the loaded modules. The critical distinction is between Parts 1 and 4: Debian uses a2enmod, and RHEL uses the LoadModule directive in conf.modules.d/.
Quick Reference
Module Management
| Distribution | Enable | Disable | Configuration Location |
|---|---|---|---|
| Debian / Ubuntu | a2enmod <module> | a2dismod <module> | /etc/apache2/mods-available/ |
| RHEL / Rocky | Uncomment LoadModule | Comment LoadModule | /etc/httpd/conf.modules.d/ |
AllowOverride Values
| Value | Permits |
|---|---|
None | No .htaccess directives |
All | Every directive |
FileInfo | Rewrite, MIME, and file handling directives |
AuthConfig | Authentication directives |
Indexes | Directory indexing directives |
Common Modules
| Module | Purpose |
|---|---|
rewrite | URL rewriting and redirection |
ssl | HTTPS/TLS |
auth_basic | Password authentication |
authn_file | File-based authentication |
headers | HTTP header manipulation |
deflate | Compression |
Verification Commands
| Command | Distribution | Purpose |
|---|---|---|
a2enmod | Debian | Enable a module |
a2dismod | Debian | Disable a module |
apache2ctl -M | Debian | List loaded modules |
httpd -M | RHEL | List loaded modules |
apache2ctl configtest | Debian | Validate syntax |
httpd -t | RHEL | Validate syntax |
Best Practices
โ Do This:
# Use a2enmod on Debian
a2enmod rewrite # โ
# Use LoadModule in conf.modules.d on RHEL
LoadModule rewrite_module modules/mod_rewrite.so # โ
# Set AllowOverride to the minimum required
AllowOverride FileInfo # โ
# Use the main configuration instead of .htaccess when possible
<Directory> block in the virtual host # โ
# Deny access to sensitive files in .htaccess or <Directory>
<Files ".env"> Require all denied </Files> # โ
# Verify loaded modules
apache2ctl -M | grep rewrite # โ
โ Don’t Do This:
# Use a2enmod on RHEL
a2enmod rewrite # Command not found # โ
# Set AllowOverride All without understanding the risk
AllowOverride All # Any .htaccess directive is permitted # โ
# Use .htaccess on a dedicated server with root access
# The main configuration is more efficient # โ
# Forget to restart after enabling a module on RHEL
# The module is not loaded until the service restarts # โ
# Use .htaccess for authentication when the main config is accessible
# It is slower and less secure # โ
Common Pitfalls
| Pitfall | Why It Happens | Fix |
|---|---|---|
| Module directives not recognized | Module not loaded | a2enmod on Debian; LoadModule on RHEL |
.htaccess ignored | AllowOverride None | Set to All or the specific group |
| 500 Internal Server Error | Directive in .htaccess not permitted by AllowOverride | Adjust AllowOverride or move the directive |
| Performance degradation | .htaccess enabled and read on every request | Use the main configuration instead |
| Module not loaded after enablement on RHEL | Service not restarted | systemctl restart httpd |
a2enmod not found on RHEL | Debian-specific script | Use LoadModule in conf.modules.d/ |
Real-World Examples
1. Enable rewrite on Debian
sudo a2enmod rewrite
2. Disable a module on Debian
sudo a2dismod rewrite
3. Enable a module on RHEL
sudo tee /etc/httpd/conf.modules.d/30-rewrite.conf <<'EOF'
LoadModule rewrite_module modules/mod_rewrite.so
EOF
4. Set AllowOverride
AllowOverride FileInfo AuthConfig
5. Disable .htaccess
AllowOverride None
6. .htaccess rewrite rule
RewriteEngine On
RewriteRule ^old\.html$ /new.html [R=301,L]
7. .htaccess file denial
<Files ".env">
Require all denied
</Files>
8. List loaded modules
apache2ctl -M # Debian
httpd -M # RHEL
9. Validate configuration
apache2ctl configtest # Debian
httpd -t # RHEL
10. Check .htaccess override
# In the <Directory> block, verify AllowOverride is not None
Visual
Module Management: Debian vs RHEL
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ DEBIAN USES a2enmod; RHEL USES LoadModule โ
โ โ
โ Debian: โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ a2enmod rewrite โ โ
โ โ โ creates symlink in /etc/apache2/mods-enabled/ โ โ
โ โ โ points to /etc/apache2/mods-available/rewrite.load โ โ
โ โ โ the .load file contains LoadModule โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ
โ RHEL: โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ LoadModule rewrite_module modules/mod_rewrite.so โ โ
โ โ โ placed in /etc/httpd/conf.modules.d/30-rewrite.confโ โ
โ โ โ service restart loads the module โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
AllowOverride Controls .htaccess
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ THE <Directory> BLOCK DETERMINES WHAT .htaccess CAN DO โ
โ โ
โ <Directory /var/www/example> โ
โ AllowOverride FileInfo AuthConfig โ
โ </Directory> โ
โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ .htaccess in /var/www/example/ โ โ
โ โ โ โ
โ โ RewriteEngine On โ FileInfo group; permitted โ โ
โ โ AuthType Basic โ AuthConfig group; permittedโ โ
โ โ โ โ
โ โ Options Indexes โ Options group; NOT permittedโ โ
โ โ โ 500 Internal Server Error โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ
โ AllowOverride None disables .htaccess entirely. โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
The .htaccess Performance Cost
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ .htaccess IS READ ON EVERY REQUEST โ
โ โ
โ Request: /var/www/example/subdir/file.html โ
โ โ โ
โ โผ โ
โ Apache looks for .htaccess in: โ
โ โโโ /var/www/example/subdir/.htaccess โ
โ โโโ /var/www/example/.htaccess โ
โ โโโ (and higher, depending on AllowOverride) โ
โ โ
โ Filesystem accesses: 4 per request, even if no file exists โ
โ โ
โ Main configuration: parsed once at startup, no per-request โ
โ lookup. This is why the main configuration is preferred. โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Summary
| Item | Value |
|---|---|
| Debian module enable | a2enmod <module> |
| Debian module disable | a2dismod <module> |
| Debian module directory | /etc/apache2/mods-available/ |
| RHEL module enable | Uncomment LoadModule in conf.modules.d/ |
| RHEL module disable | Comment LoadModule |
| RHEL module directory | /usr/lib64/httpd/modules/ |
.htaccess control | AllowOverride |
AllowOverride None | Disables .htaccess |
AllowOverride All | Permits all directives |
AllowOverride FileInfo | Permits rewrite and file directives |
.htaccess cost | Filesystem lookup per request |
| Recommendation | Use main configuration when possible |
Key takeaways:
- Debian and RHEL manage modules differently. Debian uses
a2enmodto create symlinks inmods-enabled. RHEL uses theLoadModuledirective in files underconf.modules.d/. The module must be loaded before its directives are recognized . AllowOverridecontrols.htaccess.Nonedisables the file entirely.Allpermits every directive. The specific values likeFileInfoandAuthConfigpermit only the corresponding directive groups ..htaccesshas a performance cost. Apache looks for the file in the requested directory and all its parents on every request. The main configuration is parsed once and does not incur this cost .- The main configuration is preferred. The Apache documentation recommends using the
<Directory>block in the virtual host configuration instead of.htaccesswhen the administrator has root access. The.htaccessmechanism exists for shared hosting environments where users cannot edit the main configuration . - A directive not permitted by
AllowOverridecauses a 500 error. The.htaccessfile is read, but the directive is rejected, and Apache returns an Internal Server Error instead of ignoring the directive . - Verify loaded modules with
-M. Theapache2ctl -Mcommand on Debian andhttpd -Mon RHEL list the modules that are currently loaded. This is the definitive confirmation that a module is active.
Remember: Modules extend the server’s capabilities, and .htaccess extends the configuration to the directory level. Debian manages modules with a2enmod; RHEL uses LoadModule in conf.modules.d/. The AllowOverride directive determines what .htaccess can do, and it should be set to the minimum required. The main configuration is preferred whenever the administrator has root access, because it is parsed once and does not incur the per-request filesystem lookup that .htaccess requires. Enable the module, configure the override, validate with configtest, and verify with -M.
Stop using slow, ad-bloated tool sites! ๐คฎ
๐ Search “KandZ Tools” on Google to use many professional utilities for free.
KandZ.me is the ultimate minimalist hub for:
โ
Finance (Mortgage, Interest, Inflation)
โ
Tech (Base64, JSON, Dev Suite, IP)
โ
Health (BMI, BMR, TDEE)
โ
Productivity (Timer, Workspace, QR)
โก๏ธ Fast & Private
๐ No data leaves your device
๐ 100% Free
๐ Use it now: https://tools.kandz.me
๐ Bookmark itโyouโll need it later!