On Github jvehent / pragmatic-ssl-tls
by Julien Vehent / @jvehent
OpSec assists Mozillians in defining and operating security controls to ensure that data at Mozilla is protected consistently across the organization.
We want GOOD HTTPS Everywhere!
Bad SSL/TLS default settings. Good conf takes time. Mozilla guidelines: Server Side TLS
$ ./cipherscan mozilla.org prio ciphersuite protocols pfs_keysize 1 DHE-RSA-AES128-SHA SSLv3,TLSv1,TLSv1.1,TLSv1.2 DH,1024bits 2 DHE-RSA-AES256-SHA SSLv3,TLSv1,TLSv1.1,TLSv1.2 DH,1024bits 3 AES128-SHA SSLv3,TLSv1,TLSv1.1,TLSv1.2 4 AES256-SHA SSLv3,TLSv1,TLSv1.1,TLSv1.2 5 DES-CBC3-SHA SSLv3,TLSv1,TLSv1.1,TLSv1.2 Certificate: trusted, 2048 bit, sha1WithRSAEncryption signature TLS ticket lifetime hint: None OCSP stapling: supported Server side cipher ordering
We are all Gentlemen... and we wear bow ties!
+---------------------+ | APPLICATION |7 +---------------------+ | PRESENTATION |6 +---------------------+ | SESSION |5 +---------------------+ | TRANSPORT |4 +---------------------+ | NETWORK |3 +---------------------+ | DATA LINK |2 +---------------------+ | PHYSICAL |1 +---------------------+
The primary goal of the SSL protocol is to provide privacy and reliability between two communicating applications.
Very very smart cryptographers and developers!
+---------------------+ | APPLICATION |7 +---------------------+ | PRESENTATION |6 +---------------------+ +----------------------+ | SESSION |5 |SSL Handshake Protocol| +---------------------+ <============={+----------------------+ | TRANSPORT |4 |SSL Record Protocol | +---------------------+ +----------------------+ | NETWORK |3 +---------------------+ | DATA LINK |2 +---------------------+ | PHYSICAL |1 +---------------------+
+----------------+ +----------------+ | |- CLIENT HELLO- - - - - - - - - - ->|1 | | |<- - - - - - - - - - - SERVER HELLO |2 | | |<- - - - - - - - - - - CERTIFICATE -|3 | | C |<- - - - - - - CERTIFICATE REQUEST -|4 | | L |<- - - - - - - SERVER KEY EXCHANGE -|5 S | | I |<- - - - - - - - SERVER HELLO DONE -|6 E | | E |- CERTIFICATE - - - - - - - - - - ->|7 R | | N |- CLIENT KEY EXCHANGE - - - - - - ->|8 V | | T |- CERTIFICATE VERIFY- - - - - - - ->|9 E | | |- CHANGE CIPHER SPEC- - - - - - - ->|10 R | | |- CLIENT FINISHED - - - - - - - - ->|11 | | |<- - - - - - - --CHANGE CIPHER SPEC-|12 | | |<- - - - - - - - - SERVER FINISHED -|13 | | |<- - - - - ENCRYPTED DATA - - - - ->|14 | +----------------+ +----------------+
... and I'm not getting anywhere close certificates and the CA model!
We must use SSL/TLS. And we must do it right.
Starring:
By default, a server will use the first cipher a client proposes (if it supports it). Clients can be opinionated, most browsers are. This is called "client side ordering".
$ ./cipherscan example.net prio ciphersuite protocols pfs_keysize 1 DHE-RSA-AES256-SHA SSLv3,TLSv1 DH,1024bits 2 AES256-SHA SSLv3,TLSv1 3 DHE-RSA-AES128-SHA SSLv3,TLSv1 DH,1024bits 4 AES128-SHA SSLv3,TLSv1 5 RC4-SHA SSLv3,TLSv1 6 RC4-MD5 SSLv3,TLSv1 Certificate: UNTRUSTED, 2048 bit, sha1WithRSAEncryption signature TLS ticket lifetime hint: None OCSP stapling: not supported Client side cipher ordering
$ openssl s_client -connect example.net:443 -cipher 'AES256-SHA:RC4-SHA' [...] SSL-Session: Protocol : TLSv1 Cipher : AES256-SHA
$ openssl s_client -connect example.net:443 -cipher 'RC4-SHA:AES256-SHA' [...] SSL-Session: Protocol : TLSv1 Cipher : RC4-SHA
$ openssl s_client -connect google.com:443 -cipher 'AES128-SHA:RC4-SHA' [...] SSL-Session: Protocol : TLSv1.2 Cipher : AES128-SHA
$ openssl s_client -connect google.com:443 -cipher 'RC4-SHA:AES128-SHA' [...] SSL-Session: Protocol : TLSv1.2 Cipher : AES128-SHA
RFC 5246 (TLS 1.2), section 7.4.1.2. Client Hello
The cipher suite list, passed from the client to the server in the ClientHello message, contains the combinations of cryptographic algorithms supported by the client in order of the client's preference (favorite choice first). Each cipher suite defines a key exchange algorithm, a bulk encryption algorithm (including secret key length), a MAC algorithm, and a PRF. The server will select a cipher suite or, if no acceptable choices are presented, return a handshake failure alert and close the connection. If the list contains cipher suites the server does not recognize, support, or wish to use, the server MUST ignore those cipher suites, and process the remaining ones as usual.
ssl_prefer_server_ciphers on;
SSLHonorCipherOrder on
{ "Policies":[ { { "Name":"Server-Defined-Cipher-Order", "Value":true } } ] }
1) security 2) performance 3) compatibility
ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384 :ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256: kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA: ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384: ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA: DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA: AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA :AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH: !EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA
It's long, but finely tuned for performance and security.
Copy from https://wiki.mozilla.org/Security/Server_Side_TLS$ ./cipherscan jve.linuxwall.info prio ciphersuite protocols pfs_keysize 1 ECDHE-RSA-AES128-GCM-SHA256 TLSv1.2 ECDH,P-256,256bits 2 ECDHE-RSA-AES256-GCM-SHA384 TLSv1.2 ECDH,P-256,256bits 3 DHE-RSA-AES128-GCM-SHA256 TLSv1.2 DH,2048bits 4 DHE-RSA-AES256-GCM-SHA384 TLSv1.2 DH,2048bits 5 ECDHE-RSA-AES128-SHA256 TLSv1.2 ECDH,P-256,256bits 6 ECDHE-RSA-AES128-SHA TLSv1,TLSv1.1,TLSv1.2 ECDH,P-256,256bits 7 ECDHE-RSA-AES256-SHA384 TLSv1.2 ECDH,P-256,256bits 8 ECDHE-RSA-AES256-SHA TLSv1,TLSv1.1,TLSv1.2 ECDH,P-256,256bits 9 DHE-RSA-AES128-SHA256 TLSv1.2 DH,2048bits 10 DHE-RSA-AES128-SHA TLSv1,TLSv1.1,TLSv1.2 DH,2048bits 11 DHE-RSA-AES256-SHA256 TLSv1.2 DH,2048bits 12 DHE-RSA-AES256-SHA TLSv1,TLSv1.1,TLSv1.2 DH,2048bits 13 AES128-GCM-SHA256 TLSv1.2 14 AES256-GCM-SHA384 TLSv1.2
15 AES128-SHA256 TLSv1.2 16 AES256-SHA256 TLSv1.2 17 AES128-SHA TLSv1,TLSv1.1,TLSv1.2 18 AES256-SHA TLSv1,TLSv1.1,TLSv1.2 19 DHE-RSA-CAMELLIA256-SHA TLSv1,TLSv1.1,TLSv1.2 DH,2048bits 20 CAMELLIA256-SHA TLSv1,TLSv1.1,TLSv1.2 21 DHE-RSA-CAMELLIA128-SHA TLSv1,TLSv1.1,TLSv1.2 DH,2048bits 22 CAMELLIA128-SHA TLSv1,TLSv1.1,TLSv1.2 23 DES-CBC3-SHA TLSv1,TLSv1.1,TLSv1.2 Certificate: trusted, 2048 bit, sha256WithRSAEncryption signature TLS ticket lifetime hint: 300 OCSP stapling: supported Server side cipher ordering
Problem: one private key decrypts all session secrets, and thus all data, from past and future connections.
Server picks a prime p=23, a generator g=5 and a secret a=6 Server calculates A = g^a mod p = 5^6 mod 23 = 8 Server sends p, g and A to Client ----> Client picks a secret b=15 Client calculates B = g^b mod p = 5^15 mod 23 = 19 <---- Client sends B to Server Server calculates session secret s = B^a mod p = 19^6 mod 23 = 2 Client calculates session secret s = A^b mod p = 8^15 mod 23 = 2 ~ Server and Client both use session secret s = 2 ~
The session secret "s" is never sent over the wire and is specific to one session.
$ ./cipherscan accounts.firefox.com prio ciphersuite protocols pfs_keysize 1 ECDHE-RSA-AES128-GCM-SHA256 TLSv1.2 ECDH,P-256,256bits 2 ECDHE-RSA-AES128-SHA256 TLSv1.2 ECDH,P-256,256bits 3 ECDHE-RSA-AES128-SHA TLSv1,TLSv1.1,TLSv1.2 ECDH,P-256,256bits 4 DHE-RSA-AES128-SHA TLSv1,TLSv1.1,TLSv1.2 DH,1024bits [...]
Two modes:
CBC: standard, but vulnerable to many attacks.AES128-SHA, DHE-RSA-AES128-SHA, ECDHE-RSA-AES128-SHA,... GCM: safer and faster, but rarely implemented yetAES128-GCM-SHA256, DHE-RSA-AES128-GCM-SHA256, ECDHE-RSA-AES128-GCM-SHA256, ...Use AES-NI when available!
type 8192 bytes ----------------+----------- aes-128-gcm 1218628.27k aes-128-cbc 624443.39k camellia-128-cbc 160815.26k
On the choice between AES256 and AES128: I would never consider using AES256, just like I don’t wear a helmet when I sit inside my car. It’s too much bother for the epsilon improvement in security. Vincent Rijmen, AES co-author, Dec2013
Handling certificates revocation is hard.
CRL became too big to download in browsers OCSP is unreliable and slows down connections$ openssl s_client -connect mozilla.org:443 -status [...] OCSP Response Data: OCSP Response Status: successful (0x0) Response Type: Basic OCSP Response Version: 1 (0x0) Responder Id: 4C58CB25F0414F52F428C881439BA6A8A0E692E5 Produced At: Nov 15 09:58:00 2014 GMT Responses: Certificate ID: Hash Algorithm: sha1 Issuer Name Hash: B8A299F09D061DD5C1588F76CC89FF57092B94DD Issuer Key Hash: 4C58CB25F0414F52F428C881439BA6A8A0E692E5 Serial Number: 04E4EB1E7F8C5109DBBF0C1C7F411691 Cert Status: good This Update: Nov 15 09:58:00 2014 GMT Next Update: Nov 22 10:13:00 2014 GMT
Apache
# in global conf SSLStaplingCache shmcb:/var/run/ocsp(128000) <virtualhost> SSLUseStapling on SSLStaplingResponderTimeout 5 SSLStaplingReturnResponderErrors off </virtualhost>
Nginx
server { ssl_stapling on; ssl_stapling_verify on; ssl_trusted_certificate /path/to/root_CA_cert_plus_intermediates; resolver 127.0.0.1; }
Negotiating session secrets is expensive.Need to allows a client & server to reuse a session secret.
Session ID: server caches the session locally, gives an ID to the client, client sends ID with new connections. Session Ticker: server encrypts session data with local key, hands it to client for resubmission, doesn't keep local cache.Both method depend on server security. Compromise the cache or the ticket key == gain access to all session secrets.
# nginx ssl_session_timeout 5m; ssl_session_cache shared:SSL:5m;
# apache SSLSessionCache shmcb:/path/to/ssl_gcache_data(5120000)Restart servers regularly to flush old sessions
$ sudo service (nginx|apache2) graceful
Extension of Cipherscan to facilitates configuration evaluation.
$ ./cipherscan mozilla.org ...... Target: mozilla.org:443 prio ciphersuite protocols pfs_keysize 1 DHE-RSA-AES128-SHA SSLv3,TLSv1,TLSv1.1,TLSv1.2 DH,1024bits 2 DHE-RSA-AES256-SHA SSLv3,TLSv1,TLSv1.1,TLSv1.2 DH,1024bits 3 AES128-SHA SSLv3,TLSv1,TLSv1.1,TLSv1.2 4 AES256-SHA SSLv3,TLSv1,TLSv1.1,TLSv1.2 5 DES-CBC3-SHA SSLv3,TLSv1,TLSv1.1,TLSv1.2 Certificate: trusted, 2048 bit, sha1WithRSAEncryption signature TLS ticket lifetime hint: None OCSP stapling: supported Server side cipher ordering
$ ./analyze.py -t mozilla.org mozilla.org:443 has old ssl/tls Changes needed to match the intermediate level: * disable SSLv3 * consider using a SHA-256 certificate * consider using DHE of at least 2048bits and ECC of at least 256bits Changes needed to match the modern level: * remove cipher AES128-SHA * remove cipher AES256-SHA * remove cipher DES-CBC3-SHA * disable TLSv1 * disable SSLv3 * use a SHA-256 certificate * use DHE of at least 2048bits and ECC of at least 256bits
use flag -l to evaluate against a specific level