How to Configure Secure TLS Settings in Apache on RHEL 9 | CentOS Stream 9

Secure Apache TLS configuration on RHEL 9 | CentOS Stream 9

Secure your Apache web server on RHEL 9 or CentOS Stream 9 with a hardened TLS configuration. Learn how to enable TLS 1.2/1.3, enforce strong ciphers, configure HSTS, and test your setup.

Table of Contents

🔈Introduction

Transport Layer Security (TLS) is the backbone of modern web encryption, ensuring data transmitted between clients and servers remains secure. While enabling TLS on Apache is straightforward, misconfigurations can expose your environment to vulnerabilities such as weak ciphers, insecure protocols, or downgrade attacks.

In this guide, we’ll walk through how to configure a secure TLS setup in Apache on RHEL 9 or CentOS Stream 9. By the end, you’ll have a hardened Apache TLS configuration that balances security and compatibility.


🛡️ Why Secure TLS Configuration Matters

TLS doesn’t just encrypt traffic—it also authenticates the server and protects against interception and tampering. However, the default Apache configuration is not hardened and may include weak ciphers or protocols (like TLS 1.0/1.1) that are vulnerable to modern attacks.

A properly configured TLS environment provides:

  • Confidentiality – Prevents eavesdropping on sensitive data.
  • Integrity – Ensures data is not tampered with in transit.
  • Authentication – Confirms the identity of the server.
  • Future-proofing – Mitigates risks from known vulnerabilities like BEAST, POODLE, and SWEET32.

🔄 Step 1: Install and Enable Apache with SSL/TLS Support

If Apache and SSL modules aren’t installed yet, begin with:

				
					sudo dnf install httpd mod_ssl -y
				
			
				
					sudo systemctl enable --now httpd
				
			

The mod_ssl package provides the TLS module and the default configuration file located at:

				
					less /etc/httpd/conf.d/ssl.conf
				
			

🔄 Step 2: Obtain a TLS Certificate

For production deployments, it’s best to use a trusted certificate authority (CA). You can obtain free certificates from Let’s Encrypt using Certbot:

				
					sudo dnf install certbot python3-certbot-apache -y
				
			
				
					sudo certbot --apache -d example.com -d www.example.com
				
			

This automatically configures Apache with Let’s Encrypt TLS certificates. For internal testing, you can create a self-signed certificate:

				
					sudo openssl req -x509 -nodes -days 365 \
  -newkey rsa:4096 \
  -keyout /etc/pki/tls/private/example.key \
  -out /etc/pki/tls/certs/example.crt
				
			

Update ssl.conf with the correct paths:

				
					SSLCertificateFile /etc/pki/tls/certs/example.crt
SSLCertificateKeyFile /etc/pki/tls/private/example.key
				
			

🔄 Step 3: Disable Insecure TLS Protocols

Older protocols like TLS 1.0 and TLS 1.1 should be disabled due to vulnerabilities. Only TLS 1.2 and TLS 1.3 should remain enabled. In /etc/httpd/conf.d/ssl.conf, modify:

				
					SSLProtocol -all +TLSv1.2 +TLSv1.3
				
			

This ensures clients must negotiate either TLS 1.2 or TLS 1.3.

🔄 Step 4: Use Strong Cipher Suites

Cipher suites determine the encryption algorithms used in the TLS handshake. Weak ciphers like 3DES and RC4 must be disabled. Add the following to ssl.conf:

				
					SSLCipherSuite TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384
SSLHonorCipherOrder on
				
			
  • TLS 1.3 ciphers are automatically chosen by the protocol and don’t need manual configuration.
  • For TLS 1.2, we explicitly set only strong AEAD (Authenticated Encryption with Associated Data) ciphers.

🔄 Step 5: Enable Forward Secrecy

Forward Secrecy (FS) ensures that even if your private key is compromised, past sessions remain secure. This is achieved by prioritizing Elliptic Curve Diffie-Hellman (ECDHE) ciphers. The cipher suite configuration above already enforces FS by using ECDHE-based ciphers.

🔄 Step 6: Configure HTTP Strict Transport Security (HSTS)

HSTS tells browsers to only connect using HTTPS, protecting against downgrade attacks. Add the following header to your Apache configuration (inside the <VirtualHost *:443> block):

				
					Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"
				
			

This enforces HTTPS for one year across your domain and subdomains.

🔄 Step 7: Optimize SSL Session Settings

To reduce handshake overhead and prevent resource exhaustion attacks:

				
					SSLSessionCache shmcb:/run/httpd/sslcache(512000)
SSLSessionCacheTimeout 300
				
			

This caches TLS sessions for 5 minutes, reducing renegotiation load.

🔄 Step 8: Restart Apache and Verify

Restart Apache to apply changes:

				
					sudo systemctl restart httpd
				
			

🔄 Step 9: Test Your Apache TLS Configuration

Local Testing

Use openssl s_client to test supported protocols:

				
					openssl s_client -connect example.com:443 -tls1_2
				
			
				
					openssl s_client -connect example.com:443 -tls1_3
				
			

▶️ Remote Testing

Use nmap to list supported ciphers:

				
					nmap --script ssl-enum-ciphers -p 443 example.com
				
			

▶️ Online Testing

Run a test at Qualys SSL Labs for a comprehensive security grade.


🖥️ Apache Secure TLS Configuration Example

Here’s a simplified secure TLS configuration for Apache:

				
					<VirtualHost *:443>
    ServerName example.com
    DocumentRoot /var/www/html

    SSLEngine on
    SSLCertificateFile /etc/letsencrypt/live/example.com/fullchain.pem
    SSLCertificateKeyFile /etc/letsencrypt/live/example.com/privkey.pem

    SSLProtocol -all +TLSv1.2 +TLSv1.3
    SSLCipherSuite TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384
    SSLHonorCipherOrder on

    SSLSessionCache shmcb:/run/httpd/sslcache(512000)
    SSLSessionCacheTimeout 300

    Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"
</VirtualHost>
				
			

🔐 Key TLS Hardening Directives in Apache

DirectiveRecommended SettingPurpose
SSLProtocol-all +TLSv1.2 +TLSv1.3Disable old protocols
SSLCipherSuiteStrong AEAD ciphersPrevent weak encryption
SSLHonorCipherOrderonEnforce server preference
SSLSessionCacheEnabled with timeoutImprove performance
Strict-Transport-Security1 year + subdomainsEnforce HTTPS

🧰 Troubleshooting Common TLS Issues

ProblemPossible CauseFix
Clients cannot connectTLS 1.0/1.1 only supportedEnable TLS 1.2/1.3
Old browsers breakNo fallback ciphersAdd ECDHE-RSA-AES128-GCM-SHA256
SSL Labs grade BMissing HSTS or weak ciphersEnable HSTS + strong ciphers
Apache won’t restartTypo in ssl.confRun apachectl configtest

🏁 Conclusion

A hardened TLS configuration in Apache ensures your RHEL 9 or CentOS Stream 9 server is resilient against common SSL/TLS vulnerabilities. By carefully selecting protocols, enforcing strong ciphers, enabling forward secrecy, and implementing HSTS, you can deliver a secure browsing experience for your users.

Regularly audit your configuration using tools like OpenSSL, nmap, or SSL Labs to keep up with evolving security best practices.

Did you find this article helpful? Your feedback is invaluable to us! Feel free to share this post with those who may benefit, and let us know your thoughts in the comments section below.


👉 Related Posts

Leave a Reply

Your email address will not be published. Required fields are marked *