Apache HTTP Server (httpd) is the most historically significant web server in the history of the internet, powering billions of websites since 1995. On RHEL 9, Apache is available as httpd from the AppStream repository and integrates with SELinux, firewalld, and systemd. Apache’s module architecture makes it highly extensible: mod_rewrite for URL manipulation, mod_ssl for HTTPS, mod_proxy for reverse proxying, and hundreds of community modules. While Nginx has overtaken Apache in raw concurrency benchmarks, Apache’s .htaccess support, built-in CGI handling, and mature module ecosystem make it the preferred choice for many PHP applications and shared hosting environments. This guide covers installing Apache on RHEL 9, configuring the firewall and SELinux, creating a virtual host, and verifying the installation.
Prerequisites
- RHEL 9 server with root or sudo access
- Ports 80 and 443 accessible on the network
Step 1 — Install Apache
dnf install -y httpd httpd-tools mod_ssl
# Verify the installed version
httpd -v
Step 2 — Start and Enable Apache
systemctl enable --now httpd
systemctl status httpd
Step 3 — Open Firewall Ports
firewall-cmd --permanent --add-service=http
firewall-cmd --permanent --add-service=https
firewall-cmd --reload
firewall-cmd --list-services
Step 4 — Understand the Apache Directory Structure on RHEL 9
/etc/httpd/conf/httpd.conf— main configuration file/etc/httpd/conf.d/— drop-in virtual host and module configs/etc/httpd/conf.modules.d/— module loading directives/var/www/html/— default document root/var/log/httpd/access_log— access log/var/log/httpd/error_log— error log
Step 5 — Configure the Main httpd.conf
vi /etc/httpd/conf/httpd.conf
Key directives to review and set:
ServerAdmin [email protected]
ServerName server.example.com:80
# Hide Apache version from error pages and Server header
ServerTokens Prod
ServerSignature Off
# Deny access to filesystem root by default
AllowOverride None
Require all denied
# Allow access to web root
Options Indexes FollowSymLinks
AllowOverride All # Required for .htaccess to work
Require all granted
# Log format
LogFormat "%h %l %u %t "%r" %>s %b "%{Referer}i" "%{User-Agent}i"" combined
CustomLog /var/log/httpd/access_log combined
ErrorLog /var/log/httpd/error_log
LogLevel warn
# Test configuration
apachectl configtest
# Reload to apply
systemctl reload httpd
Step 6 — Create a Virtual Host
# Create document root
mkdir -p /var/www/example.com/html
# Set ownership
chown -R apache:apache /var/www/example.com/
# Create test page
echo 'example.com running on RHEL 9 with Apache
' > /var/www/example.com/html/index.html
# Set SELinux context
semanage fcontext -a -t httpd_sys_content_t '/var/www/example.com(/.*)?'
restorecon -Rv /var/www/example.com/
vi /etc/httpd/conf.d/example.com.conf
ServerName example.com
ServerAlias www.example.com
DocumentRoot /var/www/example.com/html
ServerAdmin [email protected]
Options -Indexes +FollowSymLinks
AllowOverride All
Require all granted
CustomLog /var/log/httpd/example.com.access_log combined
ErrorLog /var/log/httpd/example.com.error_log
apachectl configtest
systemctl reload httpd
Step 7 — SELinux Considerations
# Allow Apache to make network connections (needed for mod_proxy)
setsebool -P httpd_can_network_connect 1
# Allow Apache to connect to databases
setsebool -P httpd_can_network_connect_db 1
# Allow Apache to read user home directories
setsebool -P httpd_read_user_content 1
# Diagnose SELinux denials
ausearch -c httpd -m avc --start today | audit2allow -a
Step 8 — Enable Useful Apache Modules
# Check which modules are enabled
httpd -M
# The following modules are included in the base httpd package:
# mod_rewrite — URL rewriting (required for WordPress, Laravel, etc.)
# mod_ssl — SSL/TLS support
# mod_proxy — Reverse proxy and load balancing
# mod_headers — Add/modify HTTP response headers
# Example: enable mod_rewrite (usually already enabled on RHEL 9)
grep -r 'mod_rewrite' /etc/httpd/conf.modules.d/
Step 9 — Useful Apache Commands
# Test configuration
apachectl configtest
# Graceful restart (finish existing connections before reload)
apachectl graceful
# Full restart
systemctl restart httpd
# Show current status and worker stats
apachectl status
# Show compiled-in modules and config flags
httpd -V
Verification Checklist
systemctl is-active httpd
curl -si http://localhost | head -5
curl -I http://example.com 2>/dev/null | head -5
firewall-cmd --list-services | grep http
Conclusion
Apache HTTP Server is installed and serving virtual hosts on your RHEL 9 server with SELinux enforcing, firewalld open on ports 80 and 443, and a clean /etc/httpd/conf.d/ configuration. The ServerTokens Prod and ServerSignature Off directives hide version information from potential attackers.
Next steps: How to Configure Apache Virtual Hosts on RHEL 9, How to Secure Apache with Let’s Encrypt on RHEL 9, and How to Configure Apache mod_proxy as a Reverse Proxy on RHEL 9.