DEV Community

Cover image for TLS Is Easy to Enable and Hard to Get Right
Mike Pultz
Mike Pultz

Posted on

TLS Is Easy to Enable and Hard to Get Right

Enabling TLS is a solved problem. Get a certificate from Let's Encrypt, point your server at it, done. What's not solved is the configuration that comes after: cipher suites, protocol versions, session settings, OCSP stapling. The decisions that determine whether your TLS implementation is actually secure, or just technically present.

The problem is that a misconfigured TLS setup looks identical to a correct one. Both show the padlock. Both say HTTPS. The difference only surfaces when someone runs a scan, or when an auditor asks why you're still accepting TLS 1.1, or when a CVE lands and you're not sure if you're exposed.

Why it's hard

Every application handles TLS differently. The correct cipher string for Nginx is not the correct cipher string for Postfix. PostgreSQL's ssl_min_protocol_version setting doesn't exist in MySQL, which uses tls_version instead. RabbitMQ uses an Erlang term file. IIS uses registry keys. Kafka uses Java KeyStore files and properties that differ between brokers and clients.

The underlying security requirements are identical across all of them: TLS 1.2 minimum, ECDHE for key exchange, AEAD for encryption. But applying those requirements to a specific piece of software means learning its configuration model, finding documentation that reflects current best practices, and figuring out which version introduced the settings you need.

Most developers aren't TLS specialists. They're configuring TLS for a database or a message broker or a mail server that happens to be one component of a larger system, and they need a correct answer quickly, not a cryptography education.

The documentation gap

Vendor documentation tends toward completeness, not correctness. A reference page will show every available TLS option without telling you which combinations are safe. Example configurations show what's possible, not what's recommended. Defaults often favor compatibility over security, which in this context means accepting protocol versions that RFC 8996 deprecated in 2021 and cipher suites that haven't been recommended since before that.

AI assistants have the same problem at higher velocity: their training data includes every TLS guide ever written, including the outdated ones, and they'll confidently reproduce decade-old cipher strings without flagging that they've been superseded.

The result is that the most natural paths to a TLS configuration produce configs that work but may not be secure.

What GoodTLS does

GoodTLS is a configuration reference for 48 applications across 8 categories: web servers, databases, message brokers, mail servers, DNS resolvers, VPN software, and more. Each guide gives you the specific configuration for that application, based on current standards, with no deprecated options and no hedging.

The cipher suites are the same across every OpenSSL-based application on the site:

ECDHE-ECDSA-AES256-GCM-SHA384
ECDHE-RSA-AES256-GCM-SHA384
ECDHE-ECDSA-AES128-GCM-SHA256
ECDHE-RSA-AES128-GCM-SHA256
ECDHE-ECDSA-CHACHA20-POLY1305
ECDHE-RSA-CHACHA20-POLY1305
Enter fullscreen mode Exit fullscreen mode

Every suite uses ECDHE for forward secrecy. Every suite uses AEAD encryption. None use CBC mode. None use static RSA key exchange. The list is the same whether you're configuring Nginx, HAProxy, Postfix, or OpenVPN, because the security requirements are the same.

TLS 1.2 minimum, TLS 1.3 alongside it, everywhere. No exceptions for "legacy compatibility." There is no legacy client that justifies enabling a protocol deprecated three years ago.

Consistency across your stack

A typical production environment has TLS configured in a lot of places: web server at the edge, database, cache, message broker, mail server. Each configured at different times, by different people, from different sources. The result is usually a patchwork: Nginx hardened because someone ran an SSL Labs scan, PostgreSQL running with defaults, Redis with a cipher string from five years ago.

GoodTLS covers all of them from the same standard. If you use it as the reference for your stack, you get consistent security posture across every application, not because the syntax is the same, but because the underlying decisions are.

The attacks it prevents

These aren't hypothetical. The recommendations map directly to real vulnerabilities.

Excluding CBC ciphers eliminates the Lucky13 attack surface. Excluding 3DES closes Sweet32. Requiring ECDHE key exchange prevents ROBOT. Disabling TLS 1.0 and 1.1 rules out BEAST and POODLE. Excluding EXPORT ciphers removes FREAK and LOGJAM. Each item in the cipher list has a reason; each exclusion has a CVE behind it.

The goal is a configuration where the answer to "are you vulnerable to X" is no by construction, because the class of cipher or protocol that enables X isn't present.

Who it's for

Developers who need to configure TLS for an application they don't work with every day. Security engineers auditing configurations against a known baseline. Organizations writing internal TLS standards who want something they can link to.

goodtls.com — free, no account required.

Top comments (0)