To configure TLS on a Linux server, install a certificate (e.g., Let’s Encrypt via Certbot), enable HTTPS in your web server (Nginx or Apache), enforce TLS 1.3 with modern ciphers, set HSTS and OCSP stapling, redirect HTTP to HTTPS, open port 443, test with SSL Labs, and automate renewals.
Transport Layer Security (TLS) encrypts data between your server and users’ browsers, securing logins, payments, and APIs while boosting SEO. In this step-by-step guide, you’ll learn how to configure TLS on Linux servers the right way—covering Let’s Encrypt, Nginx/Apache configs, TLS 1.3 hardening, HSTS, OCSP stapling, testing, and automation.
What You’ll Learn (Beginner-Friendly Overview)
This guide is built from real-world hosting experience and SERP research. We’ll use Certbot to issue certificates, then configure secure TLS for Nginx or Apache, enforce HTTPS, and harden your setup for an A+ on SSL Labs. You’ll also get troubleshooting tips, automation, and security best practices for 2026 and beyond.
Prerequisites and Checklist
- A registered domain pointing to your server’s public IP (A/AAAA record).
- Root or sudo access to a Linux server (Ubuntu/Debian/RHEL/AlmaLinux/Rocky).
- Open ports: 80 (HTTP) and 443 (HTTPS) in your firewall/cloud security group.
- Updated packages and accurate system time (NTP enabled).
- A backup of current web server configs.
Step 1: Update Server and Open Firewall
Keep your system patched and ensure traffic to 80/443 is allowed. Examples for Ubuntu/Debian and RHEL family:
# Ubuntu/Debian
sudo apt update && sudo apt -y upgrade
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable # if not already enabled
# RHEL/AlmaLinux/Rocky
sudo dnf -y update
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
sudo firewall-cmd --reload
Step 2: Install Certbot (Let’s Encrypt)
Let’s Encrypt provides free, trusted TLS certificates. The recommended install method is via Snap (where available), which keeps Certbot updated. If Snap isn’t an option, use your distro’s package manager.
Install Certbot via Snap (Ubuntu/Debian)
sudo apt -y update
sudo apt -y install snapd
sudo snap install core && sudo snap refresh core
sudo snap install --classic certbot
sudo ln -s /snap/bin/certbot /usr/bin/certbot
Install Certbot on RHEL/AlmaLinux/Rocky (Snap or DNF)
# Using snapd
sudo dnf -y install epel-release
sudo dnf -y install snapd
sudo systemctl enable --now snapd.socket
sudo ln -s /var/lib/snapd/snap /snap
sudo snap install core && sudo snap refresh core
sudo snap install --classic certbot
sudo ln -s /snap/bin/certbot /usr/bin/certbot
# or, if you prefer repo packages (may lag behind):
sudo dnf -y install certbot
Step 3: Issue a TLS Certificate
Certbot can configure your web server automatically (plugins) or just obtain a cert (standalone/webroot). Use DNS records that already point to your server and ensure port 80 is reachable for HTTP validation.
Automatic for Nginx
sudo certbot --nginx -d example.com -d www.example.com
Certbot will update Nginx to serve HTTPS and create a renewal task.
Automatic for Apache
sudo certbot --apache -d example.com -d www.example.com
It will enable SSL, update the virtual host, and configure redirects if you choose.
Optional: Use ECDSA Keys (Faster, Modern)
# Issue ECDSA certificate (recommended in 2026)
sudo certbot --nginx -d example.com --key-type ecdsa --elliptic-curve secp384r1
Cert files are stored under /etc/letsencrypt/live/your-domain/ as fullchain.pem and privkey.pem.
Step 4: Configure TLS on Nginx (Secure Defaults)
Nginx offers excellent TLS performance. Here’s a hardened server block for TLS 1.2/1.3 with modern ciphers, OCSP stapling, HSTS, and redirects. Replace example.com and certificate paths accordingly.
# /etc/nginx/sites-available/example.com.conf
server {
listen 80;
listen [::]:80;
server_name example.com www.example.com;
return 301 https://example.com$request_uri;
}
server {
listen 443 ssl http2; # Enable HTTP/2
listen [::]:443 ssl http2;
server_name example.com www.example.com;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
ssl_trusted_certificate /etc/letsencrypt/live/example.com/chain.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers off;
# Modern cipher suites for TLS 1.2 (TLS 1.3 ciphers are implicit)
ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:
ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:
ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305';
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:50m; # ~400k sessions
ssl_session_tickets off;
# OCSP stapling
ssl_stapling on;
ssl_stapling_verify on;
resolver 1.1.1.1 1.0.0.1 valid=300s;
resolver_timeout 5s;
# Enable HSTS AFTER you confirm HTTPS works across your site/subdomains
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
# Security headers (baseline)
add_header X-Content-Type-Options nosniff;
add_header X-Frame-Options SAMEORIGIN;
add_header Referrer-Policy no-referrer-when-downgrade;
root /var/www/example.com/public;
index index.html index.htm index.php;
location / {
try_files $uri $uri/ =404;
}
}
Test and reload Nginx:
sudo nginx -t && sudo systemctl reload nginx
Step 5: Configure TLS on Apache (Secure Defaults)
Apache’s mod_ssl and HTTP/2 (via mod_http2) provide robust TLS. Enable necessary modules and use a hardened virtual host.
# Enable modules (Ubuntu/Debian)
sudo a2enmod ssl headers http2 rewrite
sudo systemctl reload apache2
# Virtual host: /etc/apache2/sites-available/example.com.conf
<VirtualHost *:80>
ServerName example.com
ServerAlias www.example.com
Redirect permanent / https://example.com/
</VirtualHost>
<IfModule mod_ssl.c>
<VirtualHost *:443>
ServerName example.com
ServerAlias www.example.com
Protocols h2 http/1.1
SSLEngine on
SSLCertificateFile /etc/letsencrypt/live/example.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/example.com/privkey.pem
SSLCACertificateFile /etc/letsencrypt/live/example.com/chain.pem
SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1
SSLHonorCipherOrder off
SSLCipherSuite ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:\
ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:\
ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305
# OCSP stapling
SSLUseStapling on
SSLStaplingCache "shmcb:/var/run/ocsp(128000)"
# HSTS (enable after confirming HTTPS everywhere)
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
Header always set X-Content-Type-Options "nosniff"
Header always set X-Frame-Options "SAMEORIGIN"
Header always set Referrer-Policy "no-referrer-when-downgrade"
DocumentRoot /var/www/example.com/public
<Directory /var/www/example.com/public>
AllowOverride All
Require all granted
</Directory>
</VirtualHost>
</IfModule>
# Enable and reload
sudo a2ensite example.com.conf
sudo systemctl reload apache2
Step 6: Auto-Renew TLS Certificates
Certbot installs a systemd timer or cron job automatically. Verify and test renewal:
sudo systemctl list-timers | grep certbot
sudo certbot renew --dry-run
Step 7: Test, Validate, and Troubleshoot
Validate your configuration locally and externally. Aim for an A+ on SSL Labs and ensure TLS 1.3 works.
# Check TLS 1.3 connectivity
openssl s_client -connect example.com:443 -tls1_3 -servername example.com < /dev/null
# Fetch HTTPS headers
curl -I https://example.com
# Enumerate ciphers (requires nmap scripts)
nmap --script ssl-enum-ciphers -p 443 example.com
- Use SSL Labs (Qualys) to audit protocol support, ciphers, and chain.
- If Certbot fails HTTP challenge, confirm DNS is correct and port 80 is open.
- For OCSP stapling errors, ensure resolver lines are present and server has outbound DNS access.
- On SELinux systems, verify contexts for cert files or use restorecon on paths.
Hardening Best Practices for 2026
- Prefer TLS 1.3. Keep TLS 1.2 for compatibility; disable 1.0/1.1 entirely.
- Use ECDSA certificates (secp384r1) where supported for stronger, faster handshakes.
- Enable HTTP/2; consider HTTP/3 (QUIC) if your stack supports it for latency gains.
- Implement HSTS after verifying HTTPS across your entire site and subdomains.
- Turn on OCSP stapling to reduce validation latency and improve trust signals.
- Rotate keys/certs if compromised; monitor logs for handshake or certificate errors.
- Keep OpenSSL, Nginx/Apache, and Certbot up to date to patch vulnerabilities.
Optional: HTTP/3 (QUIC) Quick Start on Nginx
Nginx 1.25+ supports HTTP/3. This uses TLS 1.3 over QUIC (UDP) for faster page loads on modern browsers. You’ll also need UDP/443 open.
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
listen 443 quic reuseport; # HTTP/3
listen [::]:443 quic reuseport;
add_header Alt-Svc 'h3=":443"; ma=2592000, h3-29=":443"; ma=2592000' always;
add_header QUIC-Status $quic always;
# ... (rest same as TLS config above)
}
Note: 0-RTT in TLS 1.3 can improve performance but has replay risks. Enable only if you understand your application’s idempotency.
Common Mistakes and How to Fix Them
- Broken redirect loops: Ensure only one canonical redirect (www → non-www or vice versa) and avoid mixed rules in app/server.
- Mixed content warnings: Update hard-coded http:// assets to https:// or use relative URLs.
- Incorrect certificate chain: Always serve fullchain.pem and configure ssl_trusted_certificate/SSLCACertificateFile.
- Weak ciphers enabled: Use Mozilla SSL Guidelines to generate up-to-date cipher lists.
- Firewall blocking validation: Keep port 80 open during initial issuance and renewals (unless using DNS challenge).
Performance Tips
- Enable session resumption and disable session tickets unless you properly manage ticket keys.
- Offload compression to the app layer (gzip/brotli) while keeping TLS CPU overhead low.
- Co-locate OCSP and DNS resolvers near your server to minimize handshake latency.
- Use ECDSA certificates and HTTP/2 multiplexing to reduce connection overhead.
Managed Option: Let YouStable Handle It
If you’d rather not tinker with TLS, YouStable’s managed WordPress hosting and VPS include free Let’s Encrypt SSL, pre-hardened TLS 1.3 settings, HTTP/2/3 support, automatic renewals, and 24/7 monitoring. It’s a safe shortcut to strong security and faster page loads without manual configuration.
FAQs: Configure TLS on Linux Server
What’s the difference between SSL and TLS?
SSL is the older protocol; TLS is its modern, secure successor. Today, “SSL certificate” usually means a TLS certificate. Always use TLS 1.2 or TLS 1.3—older protocols are deprecated for security reasons.
How do I get an A+ on SSL Labs?
Disable TLS 1.0/1.1, prefer TLS 1.3, use modern ciphers, enable HSTS and OCSP stapling, serve the correct certificate chain, and keep Nginx/Apache/OpenSSL updated. Test regularly and follow Mozilla’s SSL configuration guidelines.
Is ECDSA better than RSA for TLS?
For most modern clients, ECDSA offers faster handshakes and smaller keys at strong security levels. Many sites deploy ECDSA-only or dual-stack (ECDSA primary with RSA fallback). Let’s Encrypt supports ECDSA via Certbot’s –key-type ecdsa option.
Can I enable HTTP/3 with TLS 1.3?
Yes. HTTP/3 runs over QUIC and requires TLS 1.3. On Nginx 1.25+ or recent Apache builds with QUIC support, enable HTTP/3, open UDP/443, and advertise Alt-Svc headers. Validate with browser dev tools and online tests.
How do I renew Let’s Encrypt certificates automatically?
Certbot installs a systemd timer or cron job by default. Confirm with systemctl list-timers and test using certbot renew –dry-run. Ensure port 80 or your chosen validation method (like DNS) remains available at renewal time.
Final Thoughts
Configuring TLS on a Linux server is straightforward: issue a certificate, harden your Nginx/Apache settings, enforce HTTPS, and automate renewals. By following the steps above, you’ll deliver fast, secure connections that satisfy users, pass compliance checks, and improve SEO in 2026 and beyond.