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;