Quick answer
TLS (Transport Layer Security) is the protocol that encrypts traffic between a client and a server and lets the client verify it is talking to the right server. It is what puts the S in HTTPS. SSL was its predecessor and every version of it is now broken and deprecated — but the name stuck, so "SSL certificate" almost always means a TLS certificate. TLS provides three things: confidentiality so nobody in between can read the traffic, integrity so nobody can alter it undetected, and authentication so you know the server is genuine.
01SSL or TLS?
SSL 2.0 and 3.0 were Netscape's original protocols. TLS 1.0 succeeded SSL 3.0 in 1999, and the versions in use today are TLS 1.2 and TLS 1.3. Every older version has been formally retired: RFC 6176 prohibited SSL 2.0 in 2011, RFC 7568 did the same for SSL 3.0 in 2015, and RFC 8996 deprecated TLS 1.0 and 1.1 in 2021 with the words "MUST NOT be used".
The industry never updated its vocabulary, so "SSL certificate", "SSL termination" and "SSL/TLS" all persist. They refer to TLS. If a product genuinely offers SSL 3.0, that is a warning sign rather than a feature.
| Version | Year | Status |
|---|---|---|
| SSL 2.0 / 3.0 | 1995 / 1996 | Prohibited (RFC 6176, RFC 7568), disabled everywhere |
| TLS 1.0 / 1.1 | 1999 / 2006 | Deprecated in 2021 (RFC 8996), should be off |
| TLS 1.2 | 2008 | Widely used, secure when configured well |
| TLS 1.3 | 2018 | Current, one round trip, fewer ways to misconfigure |
02What the handshake does
Before any data moves, client and server negotiate. The client announces which TLS versions and cipher suites it supports; the server picks from that list, presents its certificate, and the two derive a shared secret that only they know.
The clever part is that the shared secret is derived rather than transmitted. With modern key exchange, someone recording the whole conversation still cannot decrypt it later even if the server's private key is stolen afterwards — a property called forward secrecy. TLS 1.3 made it mandatory by removing static RSA and Diffie-Hellman key exchange altogether.
TLS 1.3 also cut the full handshake from the two round trips of TLS 1.2 to one. It adds an optional 0-RTT mode for resumed connections that sends data immediately, at a price the specification spells out: that early data is not forward secret and can be replayed, so it should only carry requests that are safe to repeat.
Because the ClientHello is sent before any keys exist, its contents are visible to the network: the server name requested and the versions, cipher suites and extensions offered. Different TLS libraries produce recognisably different ClientHellos, which is the basis of TLS fingerprinting.
client → ClientHello versions, cipher suites, key share
server → ServerHello chosen suite, key share
Certificate proof of identity
Finished handshake authenticated
client → Finished encrypted from here on
one round trip, then application data flows encrypted03What a certificate actually proves
A certificate binds a public key to a domain name, signed by a certificate authority your browser already trusts. When the server presents it, the browser checks the signature chain, that the name matches, and that it has not expired or been revoked.
It is worth being precise about what that proves: control of the domain at the time of issue. Nothing more. A valid certificate does not mean the site is honest, safe or run by a real company — a phishing site can obtain one in minutes.
Certificates are also getting shorter-lived. Under CA/Browser Forum ballot SC-081, publicly trusted TLS certificates issued from 15 March 2026 may be valid for at most 200 days, falling to 100 days from 15 March 2027 and 47 days from 15 March 2029. Manual renewal stops being realistic well before the last step.
Publicly trusted certificates are recorded in public, append-only Certificate Transparency logs; Chrome and Safari require proof of logging. That is good for catching mis-issued certificates and bad for anyone hoping a hostname stays secret: a certificate for origin.example.com announces that the name exists, one of the leaks covered in hiding your origin IP.
04TLS termination and re-encryption
When a reverse proxy or CDN sits in front of your server, it usually terminates TLS: the encrypted connection ends there, the request is inspected, and a second connection is made to your origin. This is what makes a WAF possible at all — you cannot inspect what you cannot read.
The second leg should also be encrypted. If a provider terminates TLS at the edge and then talks to your origin in plain text, everything between them and you is readable by anyone on that path. Full end-to-end encryption should be the default, not an upgrade.
- Edge termination — required for caching, inspection and compression
- Re-encryption to the origin — should always be on
- Automatic certificate issuance and renewal, so nothing expires silently
- Certificates issued through DNS validation (the ACME dns-01 challenge in RFC 8555), so the origin never has to be publicly reachable for issuance
05Configuring it well
The settings below cover most of what matters on an origin server. The snippet is nginx; every web server has the same choices under different names. Set the protocol list explicitly rather than relying on defaults, which have changed between versions.
- Disable everything below TLS 1.2 — TLS 1.0 and 1.1 are deprecated
- Prefer TLS 1.3 where clients support it
- Enable HSTS (RFC 6797), one of the HTTP security headers, so browsers refuse to fall back to plain HTTP — and know that it also removes the option to click through a certificate warning, so a lapsed certificate becomes a hard outage
- Automate renewal; a certificate nobody remembered is one of the most avoidable outages there is
- Serve the full chain, leaf first and intermediates after it in the same file — a missing intermediate breaks some clients and not others, which is a miserable bug to chase
# Port 80 only redirects; nothing is served in plain text
server {
listen 80;
listen [::]:80;
server_name example.com www.example.com;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
listen [::]:443 ssl;
server_name example.com www.example.com;
# leaf certificate first, then the intermediates, in one file
ssl_certificate /etc/ssl/example.com/fullchain.pem;
ssl_certificate_key /etc/ssl/example.com/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_session_cache shared:TLS:10m;
# one year; add includeSubDomains only once every subdomain has HTTPS
add_header Strict-Transport-Security "max-age=31536000" always;
root /var/www/example.com;
}06Checking a server from the command line
The SSL/TLS checker shows expiry, chain and negotiated version for any public hostname, and the security headers checker confirms whether HSTS is actually being sent. From a terminal, OpenSSL answers the same questions and also works on servers that are not public yet.
# certificate subject, issuer, expiry and the names it covers
openssl s_client -connect example.com:443 -servername example.com </dev/null 2>/dev/null \
| openssl x509 -noout -subject -issuer -enddate -ext subjectAltName
# chain, hostname and negotiated version: look for "Verify return code: 0 (ok)"
openssl s_client -connect example.com:443 -servername example.com \
-verify_hostname example.com </dev/null 2>&1 \
| grep -E '^New,|Verify return code'
# TLS 1.1 must be refused; SECLEVEL=0 lets the client at least offer it
openssl s_client -connect example.com:443 -servername example.com -tls1_1 \
-cipher 'DEFAULT:@SECLEVEL=0' </dev/null
# will the certificate still verify 30 days from now?
openssl s_client -connect example.com:443 -servername example.com \
-attime $(date -d '+30 days' +%s) </dev/null 2>&1 | grep 'Verify return code'07Common TLS errors and what they mean
Browsers and OpenSSL name the same failures differently. The browser codes below are Chromium's; the OpenSSL messages are what the commands above print. The NET::ERR_CERT codes behind a "Your connection is not private" warning, including the visitor-side causes, are mapped one by one in your connection is not private.
| Browser error | OpenSSL says | Usual cause and fix |
|---|---|---|
| NET::ERR_CERT_DATE_INVALID | certificate has expired | An expired certificate, or a client whose clock is wrong. Renew and automate; check the device's time |
| NET::ERR_CERT_COMMON_NAME_INVALID | hostname mismatch | The certificate does not list the name requested, often www versus the bare domain. Add the name to the certificate |
| NET::ERR_CERT_AUTHORITY_INVALID | unable to verify the first certificate, or self-signed certificate | A missing intermediate on a client that cannot fetch it, or a self-signed certificate. Serve the full chain from a public CA |
| ERR_SSL_VERSION_OR_CIPHER_MISMATCH | alert protocol version | Client and server share no version or cipher suite. Enable TLS 1.2 and 1.3 with current suites; other handshake failures are covered in the ERR_SSL_PROTOCOL_ERROR guide |
| ERR_TOO_MANY_REDIRECTS | Not a TLS error | A proxy talks plain HTTP to an origin that redirects to HTTPS, in a loop. Encrypt the proxy-to-origin leg; the ERR_TOO_MANY_REDIRECTS guide shows how to trace the loop |
Questions
Frequently asked questions
Sources
Sources and verification
nginx snippet checked with nginx -t (nginx 1.22.1) and served locally with a test CA, intermediate and leaf certificate. The OpenSSL 3.0.22 commands were run against it: the full chain verified, TLS 1.1 was refused with a protocol-version alert, TLS 1.2 and 1.3 negotiated, and a leaf-only chain, a self-signed certificate, a wrong hostname and a future -attime produced the OpenSSL messages listed. The HSTS header and port-80 redirect were confirmed with curl 7.88.1. Debian 12, October 2026.
- 01RFC 8446: The Transport Layer Security (TLS) Protocol Version 1.3 · IETF
- 02RFC 5246: The TLS Protocol Version 1.2 · IETF
- 03RFC 8996: Deprecating TLS 1.0 and TLS 1.1 · IETF
- 04RFC 7568: Deprecating Secure Sockets Layer Version 3.0 · IETF
- 05RFC 6176: Prohibiting Secure Sockets Layer (SSL) Version 2.0 · IETF
- 06Transport Layer Security: protocol history · Wikipedia
- 07RFC 6797: HTTP Strict Transport Security (HSTS) · IETF
- 08RFC 8555: Automatic Certificate Management Environment (ACME) · IETF
- 09Ballot SC-081v3: schedule of reducing validity and data reuse periods · CA/Browser Forum
- 10TLS Baseline Requirements (relevant dates: 200, 100 and 47 days) · CA/Browser Forum
- 11How Certificate Transparency works · certificate.transparency.dev
- 12An Update on the Lock Icon · Chromium Blog
- 13Module ngx_http_ssl_module (ssl_certificate chain order) · nginx.org
- 14net_error_list.h (certificate and TLS error codes) · Chromium source
Last updated