Ahosting Logo
Knowledge Base

Understanding TLS Versions and Cipher Suites

What to accept and what to refuseAccept· TLS 1.3, faster and with the weak options removed· TLS 1.2, still needed by some clientsRefuse· TLS 1.0 and 1.1, long deprecated· SSL 3 and earlier· cipher suites without forward secrecyThe header to be careful withHSTS is not a cipher setting and cannot be withdrawn once a browser has it. Set a short lifetimefirst.

Having a valid certificate is not the same as having a good HTTPS configuration. The protocol versions and ciphers your server accepts decide whether the connection is actually secure, and whether older visitors can connect at all.

Most of this is set once and left alone, which makes the defaults worth checking.

Which versions to accept

TLS 1.2 and TLS 1.3. Those two, and nothing else.

TLS 1.3 is faster; it establishes a connection in fewer round trips, and removes the weak options entirely, so there is nothing to misconfigure.

TLS 1.2 remains necessary for older clients and is secure when configured sensibly.

TLS 1.0 and 1.1 are obsolete. They are disabled by every major browser, so leaving them enabled on your server does not help anyone connect. It only widens what you accept. SSL 3.0 and earlier have been broken for years.

The compatibility question

Turning off old versions is usually described as a compatibility risk. In practice the affected clients are ones that cannot use your site anyway.

Browsers that only speak TLS 1.0 will refuse the connection regardless of your server, because the browser dropped support. The genuine casualties are old devices, embedded systems and legacy applications calling your API.

So check your logs before deciding. If nothing is negotiating TLS 1.0, disabling it costs nothing at all.

Ciphers, briefly

A cipher suite is the set of algorithms used for a connection. Your server offers a list, the client picks from it.

You do not need to understand each one. You need three properties.

Forward secrecy, so that a key compromised later cannot decrypt traffic captured earlier. This means ECDHE key exchange.

Authenticated encryption, AES-GCM or ChaCha20-Poly1305.

Nothing obsolete: no RC4, no 3DES, no DES, no export ciphers, no anything with MD5.

Use a published configuration

The practical advice, and better than assembling your own list.

Mozilla publishes maintained TLS configurations in three levels, modern, intermediate and old, with ready-made settings for each web server. Intermediate is right for almost every public website.

Using one means your configuration is reviewed by people who follow this closely, and it is updated when something is deprecated. A hand-written cipher string from a blog post ages badly and nothing tells you when.

HSTS, carefully

HTTP Strict Transport Security tells browsers to use HTTPS for your domain and never fall back:

Strict-Transport-Security: max-age=31536000; includeSubDomains

It removes the brief unencrypted request that a redirect involves, which is a real improvement.

It is also difficult to undo. Once a browser has the header, it refuses plain HTTP for your domain for the stated period regardless of what you do afterwards, and the only way to shorten it is to serve a lower value to every visitor who already received the long one.

So: start with a short max-age (a few hundred seconds) confirm everything works, then raise it. And add includeSubDomains only when you are certain every subdomain has a certificate, because it applies to all of them including ones you forgot. Forcing HTTPS walks through the redirect it builds on.

The preload list goes further and is genuinely hard to leave. Do not add your domain to it until HTTPS has been working for months.

OCSP stapling

Clients check whether a certificate has been revoked, and by default that means contacting the authority, adding latency and telling the authority who is visiting your site.

Stapling has your server fetch that response periodically and include it in the handshake. Faster for visitors and more private.

It is a single directive on most servers and worth enabling. Check it is actually working afterwards, because a misconfigured stapling setup fails silently back to the slower path.

Testing your configuration

Online SSL analysers grade a configuration and list exactly what is wrong: protocol versions, cipher order, chain problems, missing headers.

Run one after any change. The report is specific enough to act on directly, and it tests as a real client rather than as your browser, which has cached things that hide problems. Understanding the certificate chain walks through the one it most often catches.

From the command line, check which versions your server accepts:

openssl s_client -connect example.com:443 -tls1_1

A refused connection there is the correct result.

Do not chase the grade

An analyser's score is a useful check and a poor goal.

Pushing to the highest grade usually means restricting to a narrow set of modern clients, which is right for an internal API and wrong for a public shop that would rather take the order.

Intermediate configuration, TLS 1.2 and 1.3, a complete chain, and a certificate that renews reliably. That covers everything that actually protects visitors, and a certificate that quietly failed to renew undoes all of it, which is where the attention belongs. Managing AutoSSL goes into the failures that appear only in a log.

An API client failing where a browser succeeds is more often a trust-list problem than a protocol one. There is more on separating them in How to Fix Certificate Errors in Scripts and API Clients.

Confirm what the server actually negotiates

Configuration states what is permitted. What matters is what a client and the server settle on, and that is testable.

echo | openssl s_client -connect example.com:443 2>/dev/null | grep -E 'Protocol|Cipher'
for v in tls1 tls1_1 tls1_2 tls1_3; do
  printf '%-8s %s\n' "$v" "$(echo | openssl s_client -connect example.com:443 -$v 2>&1 | grep -c 'Cipher is')"
done

The loop shows which versions are accepted. Older versions answering means they are still enabled, whatever the intended configuration says.

Test after any panel update as well. Configuration written by hand is occasionally replaced during an update, and the setting reverts without anybody being told.

Know which clients you would exclude

Disabling older protocol versions is correct and it has a measurable cost that should be measured rather than assumed.

awk -F'"' '{print $6}' ~/logs/example.com | sort | uniq -c | sort -rn | head -15

Read which clients actually visit. On a consumer site the old ones are a negligible share; on a site with business customers running managed devices, or one with an application integration, the picture can be different.

The integrations are the ones that break silently. A payment callback or a supplier's system connecting with an old configuration fails without any visitor noticing, and the report arrives days later as a business problem.

Keep the configuration in one place

Settings applied per site drift apart, and an estate ends up with several different configurations nobody can summarise.

grep -rn 'SSLProtocol\|ssl_protocols' /etc/apache2/ /etc/nginx/ 2>/dev/null | head

Set it once at the server level and let sites inherit. Where a site genuinely needs something different, that exception should be visible rather than being one file among many.

Review it annually rather than when something prompts you. Recommendations change, and a configuration that was current three years ago is the one most likely to be flagged by whatever check a customer runs. SSL troubleshooting covers what the checks report.