← Recipes

阅读中文版本

Harden TLS Cipher Suites

Restrict a server to modern TLS versions and strong ciphers, then verify with a scanner and client handshake tests.

~30 mintlssecurityhardening

Task

Configure a server to offer only TLS 1.2 and 1.3 with strong cipher suites.

When to use this

A scanner reports legacy protocol support, exposing clients to downgrade attacks and weak cipher negotiation.

Prerequisites

  • Control over the TLS terminator
  • openssl for handshake tests
  • A scanner such as testssl.sh

Steps

1. Set modern protocols and cipher lists.

ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305';
ssl_prefer_server_ciphers on;

Expected output: Only TLS 1.2 and 1.3 with forward-secret AEAD suites are offered.

2. Verify the negotiated protocol and cipher.

openssl s_client -connect app.example.com:443 -tls1_1 </dev/null 2>&1 | grep -i 'no protocols\|alert'
openssl s_client -connect app.example.com:443 -tls1_3 </dev/null 2>&1 | grep -i 'Protocol\|Cipher'

Expected output: Legacy TLS is refused while TLS 1.3 negotiates a strong AEAD suite.

Troubleshooting

Problem

Legacy clients break

Solution

Document the client matrix and provide a separate endpoint only if a compliance reason exists.

Problem

Cipher list rejected

Solution

Check the terminator syntax; some expect OpenSSL names, others IANA names.

Limitations

  • Breaking legacy clients is a compatibility decision.
  • Does not cover certificate or key strength.
  • Cipher preference interacts with HTTP/2 requirements.

What this recipe does

Configure a server to offer only TLS 1.2 and 1.3 with strong cipher suites.

A scanner reports legacy protocol support, exposing clients to downgrade attacks and weak cipher negotiation.

Prerequisites

  • Control over the TLS terminator
  • openssl for handshake tests
  • A scanner such as testssl.sh

Procedure

  1. Set modern protocols and cipher lists.
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305';
ssl_prefer_server_ciphers on;

Expected result: Only TLS 1.2 and 1.3 with forward-secret AEAD suites are offered.

  1. Verify the negotiated protocol and cipher.
openssl s_client -connect app.example.com:443 -tls1_1 </dev/null 2>&1 | grep -i 'no protocols\|alert'
openssl s_client -connect app.example.com:443 -tls1_3 </dev/null 2>&1 | grep -i 'Protocol\|Cipher'

Expected result: Legacy TLS is refused while TLS 1.3 negotiates a strong AEAD suite.

How to confirm it worked

Run the commands above and confirm every expected result in order. If a step does not produce the stated output, use the troubleshooting notes before continuing. A passing run shows the scanner reports no legacy protocol support and modern clients negotiate strong AEAD suites.

Troubleshooting

Legacy clients break — Document the client matrix and provide a separate endpoint only if a compliance reason exists.

Cipher list rejected — Check the terminator syntax; some expect OpenSSL names, others IANA names.

Limitations

  • Breaking legacy clients is a compatibility decision.
  • Does not cover certificate or key strength.
  • Cipher preference interacts with HTTP/2 requirements.