How to test which SSL/TLS protocols & ciphersuites are offered by a server
Environment
- some service offering SSL/TLS
Issue
-
How can we confirm what SSL or TLS protocol versions are allowed by an SSL/TLS service on a server?
-
How can we programmatically determine what SSL ciphersuites are being offered to clients of our server without looking at the server configuration?
Resolution
Two choices are detailed in this article:
See also: Securing Application 'X' with SSL/TLS in RHEL 'Y'
Option 1: Use openssl s_client to probe a target server
-
The
openssl s_clientcommand supports choosing a specific TLS protocol and disabling specific protocols-
Start by checking what client protocols are supported by the local
openssl s_clientcommand
The following example output is from a RHEL 7.2 system[user@host ~]$ openssl s_client help 2>&1 | egrep 'just.use|no_tls' -ssl2 - just use SSLv2 -ssl3 - just use SSLv3 -tls1_2 - just use TLSv1.2 -tls1_1 - just use TLSv1.1 -tls1 - just use TLSv1 -dtls1 - just use DTLSv1 -no_tls1_2/-no_tls1_1/-no_tls1/-no_ssl3/-no_ssl2 - turn off that protocol
-
Test whether a target server supports a specific protocol
The following example output shows that the target server does not support SSLv3[user@host ~]$ openssl s_client -connect localhost:443 -ssl3 <<<"" 2>/dev/null | grep -A2 ^New New, (NONE), Cipher is (NONE) Secure Renegotiation IS NOT supported Compression: NONE
The following example output shows that the target server supports TLSv1.2
[user@host ~]$ openssl s_client -connect localhost:443 -tls1_2 <<<"" 2>/dev/null | grep -A2 ^New New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES256-GCM-SHA384 Server public key is 2048 bit Secure Renegotiation IS supported
*Note that the target server in this case was "localhost"; change as necessary by specifying a DNS name or IP address* -
-
The
openssl s_clientcommand also supports choosing specific ciphers for the connection attempt-
Start by checking what client ciphersuites are supported by the local
openssl s_clientcommand
The following example output is from a RHEL 7.2 system[user@host ~]$ openssl s_client help 2>&1 | grep -A1 cipher -serverpref - Use server's cipher preferences (only SSLv2) -cipher - preferred cipher to use, use the 'openssl ciphers' command to see what is available [user@host ~]$ openssl ciphers -h usage: ciphers args -v - verbose mode, a textual listing of the SSL/TLS ciphers in OpenSSL -V - even more verbose -ssl2 - SSL2 mode -ssl3 - SSL3 mode -tls1 - TLS1 mode [user@host ~]$ openssl ciphers ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-DSS-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA256:DHE-RSA-AES256-SHA:DHE-DSS-AES256-SHA:DHE-RSA-CAMELLIA256-SHA:DHE-DSS-CAMELLIA256-SHA:ECDH-RSA-AES256-GCM-SHA384:ECDH-ECDSA-AES256-GCM-SHA384:ECDH-RSA-AES256-SHA384:ECDH-ECDSA-AES256-SHA384:ECDH-RSA-AES256-SHA:ECDH-ECDSA-AES256-SHA:AES256-GCM-SHA384:AES256-SHA256:AES256-SHA:CAMELLIA256-SHA:PSK-AES256-CBC-SHA:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:DHE-DSS-AES128-GCM-SHA256:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES128-SHA256:DHE-DSS-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA:ECDHE-RSA-DES-CBC3-SHA:ECDHE-ECDSA-DES-CBC3-SHA:DHE-RSA-SEED-SHA:DHE-DSS-SEED-SHA:DHE-RSA-CAMELLIA128-SHA:DHE-DSS-CAMELLIA128-SHA:EDH-RSA-DES-CBC3-SHA:EDH-DSS-DES-CBC3-SHA:ECDH-RSA-AES128-GCM-SHA256:ECDH-ECDSA-AES128-GCM-SHA256:ECDH-RSA-AES128-SHA256:ECDH-ECDSA-AES128-SHA256:ECDH-RSA-AES128-SHA:ECDH-ECDSA-AES128-SHA:ECDH-RSA-DES-CBC3-SHA:ECDH-ECDSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES128-SHA256:AES128-SHA:SEED-SHA:CAMELLIA128-SHA:DES-CBC3-SHA:IDEA-CBC-SHA:PSK-AES128-CBC-SHA:PSK-3DES-EDE-CBC-SHA:KRB5-IDEA-CBC-SHA:KRB5-DES-CBC3-SHA:KRB5-IDEA-CBC-MD5:KRB5-DES-CBC3-MD5:ECDHE-RSA-RC4-SHA:ECDHE-ECDSA-RC4-SHA:ECDH-RSA-RC4-SHA:ECDH-ECDSA-RC4-SHA:RC4-SHA:RC4-MD5:PSK-RC4-SHA:KRB5-RC4-SHA:KRB5-RC4-MD5 -
Test whether a target server supports a specific ciphersuite (or colon-separated list of ciphersuites)
The following example output shows requesting a very restrictive list of ciphersuites and confirms that the target server doesn't support any of them[user@host ~]$ openssl s_client -connect localhost:443 -cipher RC4-SHA:RC4-MD5:PSK-RC4-SHA <<<"" 2>/dev/null | grep -A2 ^New New, (NONE), Cipher is (NONE) Secure Renegotiation IS NOT supported Compression: NONE
*Note that many ciphersuites can be used by multiple protocols and in some cases it might be useful to combine the `-cipher CIPHERLIST` option with one of the protocol options* -
Option 2: Use open source 3rd-party cipherscan tool
Content from github.com is not included.cipherscan is a 3rd-party unsupported tool; however, it is extremely simple to use
Important note: cipherscan uses openssl to act as an SSL/TLS client, so what it sees will depend on the openssl version used.1
-
Clone the cipherscan git repository (via
git clone) or download the static zip file
Note: this does not need to be done as root
The following example shows downloading and extracting the zip file[user@host ~]$ curl -sLO https://github.com/mozilla/cipherscan/archive/master.zip [user@host ~]$ unzip -q master.zip [user@host ~]$ cd cipherscan-master/ [user@host cipherscan-master]$
-
Use the
cipherscancommand against the target (local or remote)
For advanced usage, checkcipherscan --help(e.g., using-starttlsoption for specific protocols like smtp or ftp)
The following is an example of testing against the localhost webserver running on port443[user@host cipherscan-master]$ ./cipherscan $(hostname):443 ............................................ Target: host.example.com:443 prio ciphersuite protocols pfs curves 1 ECDHE-RSA-AES256-GCM-SHA384 TLSv1.2 ECDH,P-256,256bits prime256v1,secp384r1,secp521r1 2 ECDHE-RSA-AES256-SHA384 TLSv1.2 ECDH,P-256,256bits prime256v1,secp384r1,secp521r1 3 ECDHE-RSA-AES128-GCM-SHA256 TLSv1.2 ECDH,P-256,256bits prime256v1,secp384r1,secp521r1 4 ECDHE-RSA-AES128-SHA256 TLSv1.2 ECDH,P-256,256bits prime256v1,secp384r1,secp521r1 5 ECDHE-RSA-AES256-SHA TLSv1,TLSv1.1,TLSv1.2 ECDH,P-256,256bits prime256v1,secp384r1,secp521r1 6 ECDHE-RSA-AES128-SHA TLSv1,TLSv1.1,TLSv1.2 ECDH,P-256,256bits prime256v1,secp384r1,secp521r1 7 DHE-RSA-AES256-GCM-SHA384 TLSv1.2 DH,2048bits None 8 DHE-RSA-AES256-SHA256 TLSv1.2 DH,2048bits None 9 DHE-RSA-AES128-GCM-SHA256 TLSv1.2 DH,2048bits None 10 DHE-RSA-AES128-SHA256 TLSv1.2 DH,2048bits None 11 DHE-RSA-AES256-SHA TLSv1,TLSv1.1,TLSv1.2 DH,2048bits None 12 DHE-RSA-AES128-SHA TLSv1,TLSv1.1,TLSv1.2 DH,2048bits None 13 DHE-RSA-CAMELLIA256-SHA TLSv1,TLSv1.1,TLSv1.2 DH,2048bits None 14 DHE-RSA-CAMELLIA128-SHA TLSv1,TLSv1.1,TLSv1.2 DH,2048bits None 15 AES256-GCM-SHA384 TLSv1.2 None None 16 AES256-SHA256 TLSv1.2 None None 17 AES128-GCM-SHA256 TLSv1.2 None None 18 AES128-SHA256 TLSv1.2 None None 19 AES256-SHA TLSv1,TLSv1.1,TLSv1.2 None None 20 AES128-SHA TLSv1,TLSv1.1,TLSv1.2 None None 21 CAMELLIA256-SHA TLSv1,TLSv1.1,TLSv1.2 None None 22 CAMELLIA128-SHA TLSv1,TLSv1.1,TLSv1.2 None None Certificate: untrusted, 2048 bits, sha256WithRSAEncryption signature TLS ticket lifetime hint: 300 OCSP stapling: not supported Cipher ordering: server Curves ordering: server - fallback: no Server supports secure renegotiation Server supported compression methods: NONE TLS Tolerance: yes
-
Optionally use
analyze.pyto compare target server against the TLS guidelines from Content from wiki.mozilla.org is not included.wiki.mozilla.org/Security/Server_Side_TLS
This will return recommendations to meet each configuration level
The following example shows testing this against a local webserver running on port443[user@host cipherscan-master]$ ./analyze.py -t $(hostname):443 host.example.com:443 has bad ssl/tls Things that are bad: * don't use an untrusted or self-signed certificate Changes needed to match the old level: * enable TLSv1 * enable SSLv3 * add cipher DES-CBC3-SHA * use a certificate with sha1WithRSAEncryption signature * use DHE of 1024bits and ECC of 160bits * consider enabling OCSP Stapling Changes needed to match the intermediate level: * remove cipher DHE-RSA-CAMELLIA256-SHA * remove cipher DHE-RSA-CAMELLIA128-SHA * remove cipher CAMELLIA256-SHA * remove cipher CAMELLIA128-SHA * consider enabling TLSv1 * consider enabling OCSP Stapling Changes needed to match the modern level: * remove cipher ECDHE-RSA-AES256-SHA * remove cipher ECDHE-RSA-AES128-SHA * remove cipher DHE-RSA-AES256-GCM-SHA384 * remove cipher DHE-RSA-AES256-SHA256 * remove cipher DHE-RSA-AES128-GCM-SHA256 * remove cipher DHE-RSA-AES128-SHA256 * remove cipher DHE-RSA-AES256-SHA * remove cipher DHE-RSA-AES128-SHA * remove cipher DHE-RSA-CAMELLIA256-SHA * remove cipher DHE-RSA-CAMELLIA128-SHA * remove cipher AES256-GCM-SHA384 * remove cipher AES256-SHA256 * remove cipher AES128-GCM-SHA256 * remove cipher AES128-SHA256 * remove cipher AES256-SHA * remove cipher AES128-SHA * remove cipher CAMELLIA256-SHA * remove cipher CAMELLIA128-SHA * disable TLSv1.1 * consider enabling OCSP Stapling
Note that the cipherscan tool comes with an openssl binary which requires GLIBC 2.14 (so it works on RHEL7, but not RHEL6). cipherscan also allows specifying a custom path to an openssl binary with the -o option.
This solution is part of Red Hat’s fast-track publication program, providing a huge library of solutions that Red Hat engineers have created while supporting our customers. To give you the knowledge you need the instant it becomes available, these articles may be presented in a raw and unedited form.