Decoding Nginx’s ssl_ciphers Directive: Understanding HIGH:!aNULL:!MD5 for Secure TLS Configuration


5 views

The ssl_ciphers HIGH:!aNULL:!MD5; directive in Nginx controls which cryptographic algorithms are permitted for TLS/SSL connections. Let's examine each component:

# Basic structure
ssl_ciphers [cipher_suite_specification];

The HIGH keyword represents a predefined group of ciphers considered secure by current standards. This includes:

  • AES256-SHA256
  • AES128-SHA256
  • ECDHE-RSA-AES256-GCM-SHA384
  • ECDHE-ECDSA-AES256-GCM-SHA384

The exclamation mark (!) indicates exclusion:

!aNULL - Disables anonymous Diffie-Hellman ciphers (security risk)
!MD5   - Bans ciphers using MD5 hashing (considered cryptographically weak)

While HIGH:!aNULL:!MD5 works, here's a more contemporary approach:

ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:
ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:
ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256';

Use OpenSSL to test your cipher suite:

openssl s_client -connect yourdomain.com:443 -cipher 'HIGH:!aNULL:!MD5'

Complete secure configuration example:

ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;
ssl_session_timeout 1d;
ssl_session_cache shared:MozSSL:10m;
ssl_session_tickets off;
ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384';

The ssl_ciphers directive in Nginx configuration is crucial for specifying the encryption algorithms used in TLS/SSL communication. It determines which cryptographic protocols are available for securing connections between clients and your server.

The configuration line:

ssl_ciphers HIGH:!aNULL:!MD5;

consists of several important components:

The HIGH profile includes ciphers that are considered strong and secure by current standards, typically those with key lengths of 128 bits or more. This includes:

  • AES (128/256-bit) with SHA hash functions
  • Camellia (128/256-bit)
  • 3DES (though less recommended today)

The !aNULL and !MD5 components are exclusion modifiers:

  • !aNULL explicitly disables cipher suites that provide no authentication
  • !MD5 removes cipher suites that use the MD5 hash algorithm, which is considered cryptographically broken

For better security in current environments, consider using:

ssl_ciphers 'TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384';

To test your SSL configuration, you can use OpenSSL:

openssl ciphers -v 'HIGH:!aNULL:!MD5'

This will output the list of enabled ciphers according to your specification.

When selecting ciphers, consider:

  • Modern CPUs handle AES-GCM efficiently
  • ChaCha20-Poly1305 performs well on mobile devices
  • ECDHE provides forward secrecy

Always:

  • Disable SSLv2 and SSLv3 (ssl_protocols TLSv1.2 TLSv1.3;)
  • Prioritize AEAD cipher suites
  • Enable OCSP Stapling
  • Use strong DH parameters
# Example complete SSL configuration
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_ecdh_curve secp384r1;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
ssl_session_tickets off;