TLS on Linux server is the configuration and use of Transport Layer Security to encrypt and authenticate network traffic for services like HTTPS, SMTP, and APIs.
It uses digital certificates to prove identity and modern ciphers to protect data in transit, preventing interception, tampering, and impersonation while boosting compliance, performance, and user trust.
If you run websites or APIs, understanding TLS on Linux server is essential. This guide explains what TLS is, how it works, how to install and harden it on Nginx and Apache, how to test it for an A+ score, and how to automate renewals—using practical steps you can apply today.
What is TLS and How Does it Work?

TLS (Transport Layer Security) is the security layer behind HTTPS and many secure protocols. It authenticates the server with a certificate and encrypts the connection using symmetric keys negotiated during a handshake. This protects users against sniffing, MITM attacks, and session hijacking.
TLS Handshake
When a browser connects to your Linux server:
- Client says hello and offers supported TLS versions and cipher suites.
- Server replies with a certificate (proof of identity) and picks a secure cipher suite.
- Both sides securely agree on a shared session key (e.g., via ECDHE for Perfect Forward Secrecy).
- Traffic switches to fast symmetric encryption using that shared key.
TLS 1.2 vs TLS 1.3 (What to Prefer)
Use TLS 1.3 wherever possible. It’s faster (1-RTT), removes weak ciphers, and simplifies configuration. Keep TLS 1.2 enabled for compatibility with older clients but disable TLS 1.0/1.1. On modern Linux (OpenSSL 1.1.1+ or 3.0+), you get TLS 1.3 by default.
Prerequisites on a Linux Server
- OpenSSL 1.1.1 or newer (TLS 1.3 support)
- Nginx 1.17+ or Apache 2.4.37+ for HTTP/2 and modern TLS
- Public DNS A/AAAA records pointing to your server
- Firewall open on ports 80 (HTTP) and 443 (HTTPS)
Check Versions
openssl version
nginx -v # if using Nginx
apachectl -v # if using Apache (httpd on RHEL/CentOS)
Get a TLS Certificate (Free or Paid)
You can use a free Let’s Encrypt certificate (recommended for most websites) or a paid certificate from a commercial CA (useful for EV/OV requirements or private PKI policies).
Option 1: Let’s Encrypt with Certbot (Recommended)
Certbot automates certificate issuance and renewal. On Ubuntu/Debian, the Snap package is the most up-to-date method:
sudo snap install core; sudo snap refresh core
sudo snap install --classic certbot
sudo ln -s /snap/bin/certbot /usr/bin/certbot
For Nginx:-
sudo certbot --nginx -d example.com -d www.example.com
sudo certbot renew --dry-run
For Apache:-
sudo certbot --apache -d example.com -d www.example.com
sudo certbot renew --dry-run
Option 2: Paid CA (OV/EV or Custom Requirements)
Generate a key and CSR (ECDSA is modern and efficient):
# ECDSA P-256 key and CSR
openssl ecparam -genkey -name prime256v1 -out example.com.key
openssl req -new -key example.com.key -out example.com.csr -subj "/CN=example.com"
Submit the CSR to your CA. They’ll return certificate files (server cert and chain). Keep private keys secure with correct permissions (600) and root ownership.
Configure TLS on Nginx and Apache
Nginx: Secure HTTPS Example
# Redirect HTTP to HTTPS
server {
listen 80;
listen [::]:80;
server_name example.com www.example.com;
return 301 https://$host$request_uri;
}
# HTTPS server
server {
listen 443 ssl http2;
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_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers off; # TLS 1.3 ignores ciphers; keep off for speed
ssl_ciphers EECDH+AESGCM:EDH+AESGCM;
# Session settings
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:50m;
ssl_session_tickets off;
# OCSP Stapling
ssl_stapling on;
ssl_stapling_verify on;
resolver 1.1.1.1 8.8.8.8 valid=300s;
# Security headers (HSTS: enable after confirming HTTPS works sitewide)
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
root /var/www/example.com;
index index.html index.php;
# ... other app settings ...
}
Apache: Secure HTTPS Example
<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
DocumentRoot /var/www/example.com
SSLEngine on
Protocols h2 http/1.1
SSLCertificateFile /etc/letsencrypt/live/example.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/example.com/privkey.pem
SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1
SSLOpenSSLConfCmd Curves X25519:P-256
SSLOpenSSLConfCmd ServerInfo on
SSLOpenSSLConfCmd Ciphersuites TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256
SSLCipherSuite EECDH+AESGCM:EDH+AESGCM
SSLHonorCipherOrder off
# OCSP Stapling
SSLUseStapling on
SSLStaplingResponderTimeout 5
SSLStaplingReturnResponderErrors off
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
</VirtualHost>
</IfModule>
Enable required modules on Apache: ssl, headers, http2, and socache_shmcb (varies by distro).
TLS Hardening Best Practices
- Enable TLS 1.3; keep TLS 1.2 for compatibility; disable TLS 1.0/1.1.
- Prefer ECDSA certificates and ECDHE key exchange for PFS; support RSA fallback if needed.
- Disable weak ciphers (RC4, 3DES, CBC, NULL, EXPORT).
- Turn on OCSP stapling to speed up revocation checks.
- Use HSTS after verifying HTTPS works everywhere to prevent protocol downgrades.
- Enable HTTP/2 (h2) for performance; ALPN must be available (modern OpenSSL/NPN support).
- Disable session tickets or rotate keys frequently to preserve PFS.
- Set secure cookies (Secure, HttpOnly) in your app and add modern security headers where applicable.
Test and Audit Your TLS
Quick CLI Tests
# Show certificate chain and negotiated protocol/cipher
openssl s_client -connect example.com:443 -servername example.com -tls1_3
# Force TLS 1.2 test
openssl s_client -connect example.com:443 -servername example.com -tls1_2
# Enumerate ciphers (nmap)
nmap --script ssl-enum-ciphers -p 443 example.com
Online Scanners and Tooling
- SSL Labs Server Test: aim for an A+ by fixing protocol, cipher, and chain issues.
- testssl.sh: a comprehensive open-source CLI tester for Linux.
- SecurityHeaders.com: verify HSTS and other headers.
Automate Renewals and Maintenance
Let’s Encrypt certificates are valid for 90 days. Certbot installs a systemd timer or cron automatically; verify with a dry run and logs.
sudo certbot renew --dry-run
sudo journalctl -u snap.certbot.renew.service --no-pager | tail
If you manage paid certificates, set calendar reminders and deploy automation scripts to copy new certs to the right paths, reload services, and validate with health checks.
Troubleshooting Common TLS Errors
- Protocol mismatch (ERR_SSL_VERSION_OR_CIPHER_MISMATCH): old client only supports TLS 1.0/1.1; ensure TLS 1.2+ is available and confirm client compatibility.
- Incomplete chain: browsers warn “not secure.” Use fullchain.pem and include intermediate certificates.
- Hostname mismatch: certificate CN/SAN doesn’t match domain. Reissue with correct names.
- Permissions: web server can’t read key. Set chmod 600 and correct user/group.
- Time skew: invalid certificate dates if server clock is wrong. Enable NTP.
- Rate limits (Let’s Encrypt): too many requests. Use staging during tests and consolidate SANs.
Performance and Scaling with TLS
- TLS offloading/termination at a reverse proxy or load balancer (e.g., Nginx, HAProxy, AWS ALB) reduces CPU load on app servers.
- Enable HTTP/2 for multiplexing; consider HTTP/3/QUIC at the edge for latency-sensitive regions.
- Use ECDSA certificates and X25519 curves for faster handshakes on mobile.
- Consider session resumption (tickets or IDs) to cut handshake overhead; rotate ticket keys if enabled.
Compliance, Logging, and Monitoring
- Compliance: PCI DSS, HIPAA, and ISO 27001 expect strong TLS settings and regular validation.
- Logging: watch for handshake failures in Nginx/Apache error logs and monitor expiration dates.
- Inventory: track certificates, issuers, and SANs across environments; audit quarterly.
- Key management: restrict key access, back up securely, and rotate on staff or vendor changes.
Practical TLS Checklist for Linux
- Update OpenSSL, Nginx/Apache to modern versions.
- Obtain a certificate (Let’s Encrypt or CA), prefer ECDSA when possible.
- Enable TLS 1.3 and TLS 1.2; disable older protocols.
- Configure strong ciphers and PFS; disable weak suites.
- Turn on OCSP stapling and HSTS (after confirming HTTPS everywhere).
- Enable HTTP/2 and ALPN; test with SSL Labs.
- Automate renewals and reloads; monitor logs and expiry.
FAQ’s – TLS on Linux Server
Is SSL the same as TLS on Linux servers?
SSL is the older protocol; TLS is its successor. Today, people say “SSL” out of habit, but you should use TLS 1.2 and TLS 1.3. Configurations labeled “SSL” in web servers often manage TLS settings under the hood.
Do I need a paid certificate or is Let’s Encrypt enough?
For most public websites and APIs, Let’s Encrypt DV certificates are perfect and trusted by all major browsers. Choose paid OV/EV when your organization needs higher identity assurance, extended validation, or specific enterprise policies.
How do I get an A+ on SSL Labs?
Enable TLS 1.3 + 1.2, disable TLS 1.0/1.1, remove weak ciphers, use a proper chain (fullchain.pem), turn on HSTS and OCSP stapling, and prefer ECDHE with ECDSA/RSA certificates. Test iteratively with SSL Labs and testssl.sh.
What’s the difference between RSA and ECDSA certificates?
Both are secure, but ECDSA uses elliptic curves for smaller keys and faster handshakes—great for mobile and high-traffic sites. Many sites deploy dual certificates (RSA + ECDSA) to maximize compatibility with older clients.
Should I use self-signed certificates in production?
No. Browsers will warn users because the certificate isn’t issued by a trusted CA. Use Let’s Encrypt or a commercial CA for public services. Self-signed certs are fine for internal testing with trusted private PKI.