Alright, let’s get straight to it. You’re running a modern web stack on Linux. You’ve been diligent, you’ve secured your URL endpoints, and you’re serving traffic over HTTPS using TLS 1.2. That’s a solid baseline. But in the world of infrastructure, standing still is moving backward. TLS 1.3 has been the standard for a while now, and it’s not just an incremental update; it’s a significant leap forward in both security and performance.
The good news? If you’re on a current platform like Rocky Linux 9.6, you’re already 90% of the way there. The underlying components are in place. This guide is the final 10%—a no-nonsense, command-line focused walkthrough to get you from TLS 1.2 to the faster, more secure TLS 1.3, complete with the validation steps and pro-tips to make it production-ready.
Prerequisites Check: Ensure that your OS is updated to the latest and we’re Good to Go
Before we touch any configuration files, let’s confirm your environment is ready. Enabling TLS 1.3 depends on two critical pieces of software: your web server (Nginx) and the underlying cryptography library (OpenSSL).
- Nginx: You need version 1.13.0 or newer.
- OpenSSL: You need version 1.1.1 or newer.
Rocky Linux 9.6 and its siblings in the RHEL 9 family ship with versions far newer than these minimums. Let’s verify it. SSH into your server and run this command:
nginx -V
The output will be verbose, but you’re looking for two lines. You’ll see something like this (your versions may differ slightly):
nginx version: nginx/1.26.x
built with OpenSSL 3.2.x ...
With Nginx and OpenSSL versions well above the minimum, we’re cleared for takeoff.
The Upgrade: Configuring Nginx for TLS 1.3
This is where the rubber meets the road. The process involves a single, targeted change to your Nginx configuration.
Step 1: Locate Your Nginx Server Block
Your SSL configuration is defined within a server block in your Nginx files. If you have a simple setup, this might be in /etc/nginx/nginx.conf. However, the best practice is to have separate configuration files for each site in /etc/nginx/conf.d/.
Find the relevant file for the site you want to upgrade. It will contain the listen 443 ssl; directive and your ssl_certificate paths.
Step 2: Modify the ssl_protocols Directive
Inside your server block, find the line that begins with ssl_protocols. To enable TLS 1.3 while maintaining compatibility for clients that haven’t caught up, modify this line to include TLSv1.3. The best practice is to support both 1.2 and 1.3.
# BEFORE
# ssl_protocols TLSv1.2;
# AFTER: Add TLSv1.3
ssl_protocols TLSv1.2 TLSv1.3;
It is critical that this directive is inside every server block where you want TLS 1.3 enabled. Settings are not always inherited from a global http block as you might expect.
Validation and Deployment: Trust, but Verify
A configuration change isn’t complete until it’s verified. This two-step process ensures you don’t break your site and that the change actually worked.
Step 1: Test and Reload Nginx
Never apply a new configuration blind. First, run the built-in Nginx test to check for syntax errors:
sudo nginx -t
If all is well, you’ll see a success message. Now, gracefully reload Nginx to apply the changes without dropping connections:
sudo systemctl reload nginx
Step 2: Verify TLS 1.3 is Active
Your server is reloaded, but how do you know TLS 1.3 is active? You must verify it with an external tool.
- Quick Command-Line Check: For a fast check from your terminal, use
curl:curl -I -v --tlsv1.3 --tls-max 1.3 https://your-domain.comLook for output confirming a successful connection using TLSv1.3.
- The Gold Standard: The most comprehensive way to verify your setup is with the Qualys SSL Labs SSL Server Test. Navigate to their website, enter your domain name, and run a scan. In the “Configuration” section of the report, you will see a heading for “Protocols.” If your setup was successful, you will see a definitive “Yes” next to TLS 1.3.
Advanced Hardening: Pro-Tips for Production
You’ve enabled a modern protocol. Now, let’s enforce its use and add other layers of security that a production environment demands.
Pro-Tip 1: Implement HSTS (HTTP Strict Transport Security)
HSTS is a header your server sends to tell browsers that they should only communicate with your site using HTTPS. This prevents downgrade attacks. Add this header to your Nginx server block:
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;
max-age=63072000: Tells the browser to cache this rule for two years.includeSubDomains: Applies the rule to all subdomains. Use with caution.preload: Allows you to submit your site to a list built into browsers, ensuring they never connect via HTTP.
Pro-Tip 2: Enable OCSP Stapling
Online Certificate Status Protocol (OCSP) Stapling improves performance and privacy by allowing your server to fetch the revocation status of its own certificate and “staple” it to the TLS handshake. This saves the client from having to make a separate request to the Certificate Authority.
Enable it by adding these lines to your server block:
# OCSP Stapling
ssl_stapling on;
ssl_stapling_verify on;
ssl_trusted_certificate /etc/letsencrypt/live/your-domain.com/fullchain.pem; # Use your fullchain certificate
resolver 8.8.8.8 1.1.1.1 valid=300s; # Use public resolvers
Pro-Tip 3: Modernize Your Cipher Suites
While TLS 1.3 has its own small set of mandatory, highly secure cipher suites, you can still define the ciphers for TLS 1.2. The ssl_prefer_server_ciphers directive should be set to off for TLS 1.3, which is the default in modern Nginx versions, allowing the client’s more modern cipher preferences to be honored. However, you should still define a strong cipher list for TLS 1.2.
Here is a modern configuration snippet combining these tips:
server {
listen 443 ssl http2;
server_name your-domain.com;
# SSL Config
ssl_certificate /path/to/fullchain.pem;
ssl_certificate_key /path/to/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers off;
# HSTS Header
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;
# OCSP Stapling
ssl_stapling on;
ssl_stapling_verify on;
ssl_trusted_certificate /path/to/fullchain.pem;
# ... other configurations ...
}
TL;DR
- Enable TLS 1.3 by adding it to the
ssl_protocolsdirective in your Nginx server block:ssl_protocols TLSv1.2 TLSv1.3;. Rocky Linux 9.6 ships with the required Nginx and OpenSSL versions. - Always validate your configuration before and after applying it. Use
sudo nginx -tto check syntax, and then use an external tool like the Qualys SSL Labs test to confirm TLS 1.3 is active on your live domain. - Go beyond the basic setup by implementing advanced hardening. Add the
Strict-Transport-Security(HSTS) header and enable OCSP Stapling to build a truly robust and secure configuration.
Conclusion
Upgrading to TLS 1.3 on a modern stack like Nginx on Rocky Linux 9 is refreshingly simple. The core task is a one-line change. However, as a senior engineer, your job doesn’t end there. The real “super hack” is in the full workflow: making the change, rigorously validating it from an external perspective, and then hardening the configuration with production-grade features like HSTS and OCSP Stapling. By following these steps, you’ve done more than just flip a switch; you’ve demonstrably improved your site’s security posture and performance, confirming your stack is compliant with the latest standards.