Confirmed users
529
edits
(Created page with "Recommended configuration for SSL/TLS Server Side") |
(First commit) |
||
Line 1: | Line 1: | ||
Recommended configuration for SSL/TLS Server | --[[User:Ulfr|Ulfr]] ([[User talk:Ulfr|talk]]) 10:12, 14 October 2013 (PDT) | ||
While SSL/TLS provides strong security, default settings must generally be avoided. In addition to known vulnerabilities in SSLv2, Beast and so on, some ciphersuites simply do not provide any security and use NULL ciphers or non-authenticated key exchanges. | |||
= General purpose ciphersuite = | |||
The general purpose ciphersuite at the time of this writing is: | |||
<blockquote> | |||
ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384: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-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:ECDHE-RSA-RC4-SHA:ECDHE-ECDSA-RC4-SHA:RC4-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!3DES:!MD5:!PSK | |||
</blockquote> | |||
If your version of OpenSSL is old, unavailable ciphers will be discarded automatically. Always use the full ciphersuite above and let OpenSSL pick the ones it supports. | |||
The ordering of a ciphersuite is very important because it decides which algorithms are going to be selected in priority. The recommendation above prioritizes algorithms that provide perfect forward secrecy. | |||
The listing below shows the list of algorithms returned by this ciphersuite. If you have to pick them manually for your application, make sure you keep this ordering. | |||
Older versions of OpenSSL may not return the full list of algorithms. AES-GCM and some ECDHE are fairly recent, and not present on most versions of OpenSSL shipped with Ubuntu or RHEL. This listing below was obtained from a freshly built OpenSSL. | |||
<pre> | |||
$ openssl version | |||
OpenSSL 1.1.0-dev xx XXX xxxx | |||
$ openssl ciphers -v 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384: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-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:ECDHE-RSA-RC4-SHA:ECDHE-ECDSA-RC4-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:RC4-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!3DES:!MD5:!PSK' |column -t | |||
ECDHE-RSA-AES128-GCM-SHA256 TLSv1.2 Kx=ECDH Au=RSA Enc=AESGCM(128) Mac=AEAD | |||
ECDHE-ECDSA-AES128-GCM-SHA256 TLSv1.2 Kx=ECDH Au=ECDSA Enc=AESGCM(128) Mac=AEAD | |||
ECDHE-RSA-AES256-GCM-SHA384 TLSv1.2 Kx=ECDH Au=RSA Enc=AESGCM(256) Mac=AEAD | |||
ECDHE-ECDSA-AES256-GCM-SHA384 TLSv1.2 Kx=ECDH Au=ECDSA Enc=AESGCM(256) Mac=AEAD | |||
DHE-DSS-AES256-GCM-SHA384 TLSv1.2 Kx=DH Au=DSS Enc=AESGCM(256) Mac=AEAD | |||
DHE-RSA-AES256-GCM-SHA384 TLSv1.2 Kx=DH Au=RSA Enc=AESGCM(256) Mac=AEAD | |||
DHE-DSS-AES128-GCM-SHA256 TLSv1.2 Kx=DH Au=DSS Enc=AESGCM(128) Mac=AEAD | |||
DHE-RSA-AES128-GCM-SHA256 TLSv1.2 Kx=DH Au=RSA Enc=AESGCM(128) Mac=AEAD | |||
ECDHE-RSA-AES128-SHA256 TLSv1.2 Kx=ECDH Au=RSA Enc=AES(128) Mac=SHA256 | |||
ECDHE-ECDSA-AES128-SHA256 TLSv1.2 Kx=ECDH Au=ECDSA Enc=AES(128) Mac=SHA256 | |||
ECDHE-RSA-AES128-SHA SSLv3 Kx=ECDH Au=RSA Enc=AES(128) Mac=SHA1 | |||
ECDHE-ECDSA-AES128-SHA SSLv3 Kx=ECDH Au=ECDSA Enc=AES(128) Mac=SHA1 | |||
ECDHE-RSA-AES256-SHA384 TLSv1.2 Kx=ECDH Au=RSA Enc=AES(256) Mac=SHA384 | |||
ECDHE-ECDSA-AES256-SHA384 TLSv1.2 Kx=ECDH Au=ECDSA Enc=AES(256) Mac=SHA384 | |||
ECDHE-RSA-AES256-SHA SSLv3 Kx=ECDH Au=RSA Enc=AES(256) Mac=SHA1 | |||
ECDHE-ECDSA-AES256-SHA SSLv3 Kx=ECDH Au=ECDSA Enc=AES(256) Mac=SHA1 | |||
DHE-RSA-AES128-SHA256 TLSv1.2 Kx=DH Au=RSA Enc=AES(128) Mac=SHA256 | |||
DHE-RSA-AES128-SHA SSLv3 Kx=DH Au=RSA Enc=AES(128) Mac=SHA1 | |||
DHE-RSA-AES256-SHA256 TLSv1.2 Kx=DH Au=RSA Enc=AES(256) Mac=SHA256 | |||
DHE-DSS-AES256-SHA SSLv3 Kx=DH Au=DSS Enc=AES(256) Mac=SHA1 | |||
ECDHE-RSA-RC4-SHA SSLv3 Kx=ECDH Au=RSA Enc=RC4(128) Mac=SHA1 | |||
ECDHE-ECDSA-RC4-SHA SSLv3 Kx=ECDH Au=ECDSA Enc=RC4(128) Mac=SHA1 | |||
AES128-GCM-SHA256 TLSv1.2 Kx=RSA Au=RSA Enc=AESGCM(128) Mac=AEAD | |||
AES256-GCM-SHA384 TLSv1.2 Kx=RSA Au=RSA Enc=AESGCM(256) Mac=AEAD | |||
RC4-SHA SSLv3 Kx=RSA Au=RSA Enc=RC4(128) Mac=SHA1 | |||
SRP-DSS-AES-256-CBC-SHA SSLv3 Kx=SRP Au=DSS Enc=AES(256) Mac=SHA1 | |||
SRP-RSA-AES-256-CBC-SHA SSLv3 Kx=SRP Au=RSA Enc=AES(256) Mac=SHA1 | |||
DH-DSS-AES256-GCM-SHA384 TLSv1.2 Kx=DH/DSS Au=DH Enc=AESGCM(256) Mac=AEAD | |||
DH-RSA-AES256-GCM-SHA384 TLSv1.2 Kx=DH/RSA Au=DH Enc=AESGCM(256) Mac=AEAD | |||
DHE-DSS-AES256-SHA256 TLSv1.2 Kx=DH Au=DSS Enc=AES(256) Mac=SHA256 | |||
DH-RSA-AES256-SHA256 TLSv1.2 Kx=DH/RSA Au=DH Enc=AES(256) Mac=SHA256 | |||
DH-DSS-AES256-SHA256 TLSv1.2 Kx=DH/DSS Au=DH Enc=AES(256) Mac=SHA256 | |||
DHE-RSA-AES256-SHA SSLv3 Kx=DH Au=RSA Enc=AES(256) Mac=SHA1 | |||
DH-RSA-AES256-SHA SSLv3 Kx=DH/RSA Au=DH Enc=AES(256) Mac=SHA1 | |||
DH-DSS-AES256-SHA SSLv3 Kx=DH/DSS Au=DH Enc=AES(256) Mac=SHA1 | |||
DHE-RSA-CAMELLIA256-SHA SSLv3 Kx=DH Au=RSA Enc=Camellia(256) Mac=SHA1 | |||
DHE-DSS-CAMELLIA256-SHA SSLv3 Kx=DH Au=DSS Enc=Camellia(256) Mac=SHA1 | |||
DH-RSA-CAMELLIA256-SHA SSLv3 Kx=DH/RSA Au=DH Enc=Camellia(256) Mac=SHA1 | |||
DH-DSS-CAMELLIA256-SHA SSLv3 Kx=DH/DSS Au=DH Enc=Camellia(256) Mac=SHA1 | |||
ECDH-RSA-AES256-GCM-SHA384 TLSv1.2 Kx=ECDH/RSA Au=ECDH Enc=AESGCM(256) Mac=AEAD | |||
ECDH-ECDSA-AES256-GCM-SHA384 TLSv1.2 Kx=ECDH/ECDSA Au=ECDH Enc=AESGCM(256) Mac=AEAD | |||
ECDH-RSA-AES256-SHA384 TLSv1.2 Kx=ECDH/RSA Au=ECDH Enc=AES(256) Mac=SHA384 | |||
ECDH-ECDSA-AES256-SHA384 TLSv1.2 Kx=ECDH/ECDSA Au=ECDH Enc=AES(256) Mac=SHA384 | |||
ECDH-RSA-AES256-SHA SSLv3 Kx=ECDH/RSA Au=ECDH Enc=AES(256) Mac=SHA1 | |||
ECDH-ECDSA-AES256-SHA SSLv3 Kx=ECDH/ECDSA Au=ECDH Enc=AES(256) Mac=SHA1 | |||
AES256-SHA256 TLSv1.2 Kx=RSA Au=RSA Enc=AES(256) Mac=SHA256 | |||
AES256-SHA SSLv3 Kx=RSA Au=RSA Enc=AES(256) Mac=SHA1 | |||
CAMELLIA256-SHA SSLv3 Kx=RSA Au=RSA Enc=Camellia(256) Mac=SHA1 | |||
SRP-DSS-AES-128-CBC-SHA SSLv3 Kx=SRP Au=DSS Enc=AES(128) Mac=SHA1 | |||
SRP-RSA-AES-128-CBC-SHA SSLv3 Kx=SRP Au=RSA Enc=AES(128) Mac=SHA1 | |||
DH-DSS-AES128-GCM-SHA256 TLSv1.2 Kx=DH/DSS Au=DH Enc=AESGCM(128) Mac=AEAD | |||
DH-RSA-AES128-GCM-SHA256 TLSv1.2 Kx=DH/RSA Au=DH Enc=AESGCM(128) Mac=AEAD | |||
DHE-DSS-AES128-SHA256 TLSv1.2 Kx=DH Au=DSS Enc=AES(128) Mac=SHA256 | |||
DH-RSA-AES128-SHA256 TLSv1.2 Kx=DH/RSA Au=DH Enc=AES(128) Mac=SHA256 | |||
DH-DSS-AES128-SHA256 TLSv1.2 Kx=DH/DSS Au=DH Enc=AES(128) Mac=SHA256 | |||
DHE-DSS-AES128-SHA SSLv3 Kx=DH Au=DSS Enc=AES(128) Mac=SHA1 | |||
DH-RSA-AES128-SHA SSLv3 Kx=DH/RSA Au=DH Enc=AES(128) Mac=SHA1 | |||
DH-DSS-AES128-SHA SSLv3 Kx=DH/DSS Au=DH Enc=AES(128) Mac=SHA1 | |||
DHE-RSA-CAMELLIA128-SHA SSLv3 Kx=DH Au=RSA Enc=Camellia(128) Mac=SHA1 | |||
DHE-DSS-CAMELLIA128-SHA SSLv3 Kx=DH Au=DSS Enc=Camellia(128) Mac=SHA1 | |||
DH-RSA-CAMELLIA128-SHA SSLv3 Kx=DH/RSA Au=DH Enc=Camellia(128) Mac=SHA1 | |||
DH-DSS-CAMELLIA128-SHA SSLv3 Kx=DH/DSS Au=DH Enc=Camellia(128) Mac=SHA1 | |||
ECDH-RSA-AES128-GCM-SHA256 TLSv1.2 Kx=ECDH/RSA Au=ECDH Enc=AESGCM(128) Mac=AEAD | |||
ECDH-ECDSA-AES128-GCM-SHA256 TLSv1.2 Kx=ECDH/ECDSA Au=ECDH Enc=AESGCM(128) Mac=AEAD | |||
ECDH-RSA-AES128-SHA256 TLSv1.2 Kx=ECDH/RSA Au=ECDH Enc=AES(128) Mac=SHA256 | |||
ECDH-ECDSA-AES128-SHA256 TLSv1.2 Kx=ECDH/ECDSA Au=ECDH Enc=AES(128) Mac=SHA256 | |||
ECDH-RSA-AES128-SHA SSLv3 Kx=ECDH/RSA Au=ECDH Enc=AES(128) Mac=SHA1 | |||
ECDH-ECDSA-AES128-SHA SSLv3 Kx=ECDH/ECDSA Au=ECDH Enc=AES(128) Mac=SHA1 | |||
AES128-SHA256 TLSv1.2 Kx=RSA Au=RSA Enc=AES(128) Mac=SHA256 | |||
AES128-SHA SSLv3 Kx=RSA Au=RSA Enc=AES(128) Mac=SHA1 | |||
CAMELLIA128-SHA SSLv3 Kx=RSA Au=RSA Enc=Camellia(128) Mac=SHA1 | |||
</pre> | |||
The ciphers are described here: http://www.openssl.org/docs/apps/ciphers.html | |||
= Prioritization logic = | |||
* ECDHE+AESGCM ciphers are selected first. These are TLS 1.2 ciphers and not widely supported at the moment. No known attack currently target these ciphers. | |||
* PFS ciphersuites are preferred, with ECDHE first, then DHE. | |||
* AES 128 is preferred to AES 256 | |||
** research shows that AES256 doesn't increase the security level significantly compared to AES128. Moreover, AES256 might be more exposed to timing attacks. Increased computational time contributes to prefer 128 bits. | |||
* AES is preferred to RC4 | |||
** Beast attacks on AES are mitigated in TLS1.1 and above, and difficult to achieve in TLS1.0. In comparison, attacks on RC4 are not mitigated and likely to become more and more dangerous. | |||
= Mandatory discards = | |||
* aNull contains non-authenticated Diffie-Hellman key exchanges, that are subject to man-in-the-middle attacks | |||
* eNull contains null-encryption ciphers (cleartext) | |||
* EXPORT are legacy weak ciphers that were marked as exportable by US law | |||
* DES and 3DES contains all legacy ciphers that used the deprecated Data Encryption Standard | |||
* SSLv2 contains all ciphers that were defined in the old version of the SSL standard, now deprecated | |||
* MD5 contains all the ciphers that use the broken message digest 5 as the hashing algorithm | |||
= Forward Secrecy = | |||
Most modern implementations of SSL stacks support some flavor of forward secrecy (at the very least DHE-RSA-AES128-SHA). The concept of forward secrecy is simple: the RSA keys from the server are used to sign a Diffie-Hellman key exchange between the client and the server. The pre-master key obtained from the Diffie-Hellman handshake is then used for encryption. Since the pre-master key is specific to a connection between a client and a server, and used only for a limited amount of time, it is called Ephemeral. | |||
With Forward Secrecy, if an attacker gets a hold of the server's private key, it will not be able to decrypt past communications. The private key was only used to sign the DH handshake, which does not reveal the pre-master key. Diffie-Hellman ensures that the pre-master keys never leave the client and the server, and cannot be intercepted by a man in the middle. | |||
Diffie-Hellman is slow. Faster implementation, such as Elliptic Curve Diffie-Hellman (ECDH) are promising but not widely supported. Therefore, forward secrecy is still considered the privilege of a few. | |||
== DHE hanshake and dhparam == | |||
When an ephemeral Diffie-Hellman cipher is used, the server and the client negociate a pre-master key using the Diffie-Hellman algorithm. This algorithm requires that the server sends the client a prime number and a generator. Neither are confidential, and are sent in clear text. However, they must be signed, such that a man in the middle cannot hijack the handshake. | |||
As an example, TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 works as follow: | |||
# Server sends Client a SERVER KEY EXCHANGE message during the SSL Handshake. The message contains: | |||
## Prime number p | |||
## Generator g | |||
## Server's Diffie-Hellman public value A =g^X mod p, where X is a private integer chosen by the server at random, and never shared with the client. | |||
## signature S of the above (plus two random values) computed using the Server's private RSA key | |||
# Client verifies the signature S | |||
# Client sends server a CLIENT KEY EXCHANGE message. The message contains: | |||
## Client's Diffie-Hellman public value B = g^Y mod p, where Y is a private integer chosen at random and never shared. | |||
# The Server and the Client can now calculate the pre-master secret using each other's public values: | |||
## server calculates PMS = B^X mod p | |||
## client calculates PMS = A^Y mod p | |||
# Client sends a CHANGE CIPHER SPEC message to the server, and both parties continue the handshake using ENCRYPTED HANDSHAKE MESSAGES | |||
The size of the prime number p constrains the size of the pre-master key PMS, because of the modulo operation. A smaller prime almost means weaker values of A and B, which could leak the secret values X and Y. Thus, the prime p should not be smaller than 2048 bits. | |||
<pre> | |||
$ openssl dhparam -rand – 2048 | |||
Generating DH parameters, 2048 bit long safe prime, generator 2 | |||
..+..+...............+ | |||
-----BEGIN DH PARAMETERS----- | |||
MBYCEQCHU6UNZoHMF6bPtj21Hn/bAgEC..... | |||
...... | |||
-----END DH PARAMETERS----- | |||
</pre> | |||
== Ciphersuite support on various systems == | |||
On a variety of ~900 systems (RHEL5 & 6, CentOS 5 & 6 and Ubuntu), the following versions of OpenSSL were found: | |||
{| class="wikitable" | |||
|- | |||
| 37 || OpenSSL 0.9.8e-fips-rhel5 01 Jul 2008 | |||
|- | |||
| 35 || OpenSSL 0.9.8k 25 Mar 2009 | |||
|- | |||
| 777 || OpenSSL 1.0.0-fips 29 Mar 2010 | |||
|- | |||
| 18 || OpenSSL 1.0.1 14 Mar 2012 | |||
|} | |||
The recommended ciphersuite was tested on each system. The list below shows the ciphersuites supported by all tested systems. However old your setup may be, it is safe to assume that the following ciphers are going to be available, in the following order: | |||
{| class="wikitable" | |||
|- | |||
! # !! Cipher !! Has Forward Secrecy !! Issues | |||
|- | |||
| 1 || RC4-SHA || No !! RC4 Warning | |||
|- | |||
| 2 || DHE-RSA-AES128-SHA || Yes || vulnerable to BEAST | |||
|- | |||
| 3 || DHE-RSA-AES256-SHA || Yes || vulnerable to BEAST | |||
|- | |||
| 4 || AES256-SHA || No || vulnerable to BEAST | |||
|- | |||
| 5 || DHE-DSS-AES128-SHA || Yes || vulnerable to BEAST | |||
|- | |||
| 6 || DHE-DSS-AES256-SHA || Yes || vulnerable to BEAST | |||
|- | |||
| 7 || AES128-SHA || No || vulnerable to BEAST | |||
= Recommended configurations = | |||
== Zeus (Riverbed Stingray) == | |||
Zeus lacks support for TLS1.2, Elliptic Curves, AES-GCM and OCSP Stapling. | |||
The recommended prioritization is below: | |||
# DHE-RSA-AES128-SHA | |||
# DHE-RSA-AES256-SHA | |||
# AES128-SHA | |||
# AES256-SHA | |||
# RC4-SHA | |||
# DES-CBC3-SHA | |||
# EDH-RSA-DES-CBC3-SHA | |||
Zeus uses RSA BSAFE crypto library. | |||
<pre> | |||
# /usr/local/zeus/zxtm/bin/zeus.zxtm -vv | grep ^Crypto | |||
Crypto library : RSA CryptoC6.4 | |||
</pre> | |||
The following ciphersuites are supported by Zeus. | |||
<pre> | |||
ssl!ssl3_ciphers | |||
This is a list (space, comma or colon separated) of SSL ciphers that will be used with performing SSL decryption or SSL encryption. The order of the supplied list determines the priority of the ciphers for SSL decryption. | |||
The default order is: | |||
SSL_RSA_WITH_RC4_128_SHA | |||
SSL_RSA_WITH_RC4_128_MD5 | |||
SSL_RSA_WITH_AES_256_CBC_SHA | |||
SSL_DHE_RSA_WITH_AES_256_CBC_SHA | |||
SSL_RSA_WITH_3DES_EDE_CBC_SHA | |||
SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA | |||
SSL_RSA_WITH_AES_128_CBC_SHA | |||
SSL_DHE_RSA_WITH_AES_128_CBC_SHA | |||
In addition, the following ciphers are supported but disabled by default: | |||
SSL_RSA_EXPORT_WITH_RC4_56_SHA | |||
SSL_RSA_EXPORT_WITH_RC4_56_MD5 | |||
SSL_RSA_WITH_DES_CBC_SHA | |||
SSL_DHE_RSA_WITH_DES_CBC_SHA | |||
SSL_RSA_EXPORT_WITH_DES_CBC_SHA | |||
SSL_RSA_EXPORT_WITH_RC4_40_MD5 | |||
SSL_RSA_EXPORT_WITH_DES40_CBC_SHA | |||
SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA | |||
SSL_RSA_WITH_NULL_SHA | |||
SSL_RSA_WITH_NULL_MD5 | |||
</pre> | |||
== Citrix Netscaler == | |||
The configuration sample below shows how a default ciphersuite object can be created and attached to a vserver. | |||
<pre> | |||
add ssl cipher MozillaDefault | |||
bind ssl cipher MozillaDefault -cipherName SSL3-RC4-SHA | |||
bind ssl cipher MozillaDefault -cipherName TLS1-DHE-DSS-AES-256-CBC-SHA | |||
bind ssl cipher MozillaDefault -cipherName TLS1-DHE-RSA-AES-256-CBC-SHA | |||
bind ssl cipher MozillaDefault -cipherName TLS1-DHE-DSS-AES-128-CBC-SHA | |||
bind ssl cipher MozillaDefault -cipherName TLS1-DHE-RSA-AES-128-CBC-SHA | |||
bind ssl cipher MozillaDefault -cipherName TLS1-AES-256-CBC-SHA | |||
bind ssl cipher MozillaDefault -cipherName TLS1-AES-128-CBC-SHA | |||
add ssl certKey <domain> -cert <cert> -key <key> | |||
add ssl certKey <intermediateCertName> -cert <intermediateCertName> | |||
link ssl certKey <domain> <intermediateCertName> | |||
set ssl vserver <domain>:https -eRSA ENABLED | |||
bind ssl vserver <domain>:https -cipherName MozillaDefault | |||
</pre> | |||
The configuration can be viewed with the following commands: | |||
<pre> | |||
> show ssl cipher MozillaDefault | |||
1) Cipher Name: SSL3-RC4-SHA | |||
Description: SSLv3 Kx=RSA Au=RSA Enc=RC4(128) Mac=SHA1 | |||
2) Cipher Name: TLS1-DHE-DSS-AES-256-CBC-SHA | |||
Description: TLSv1 Kx=DH Au=DSS Enc=AES(256) Mac=SHA1 | |||
3) Cipher Name: TLS1-DHE-RSA-AES-256-CBC-SHA | |||
Description: TLSv1 Kx=DH Au=RSA Enc=AES(256) Mac=SHA1 | |||
4) Cipher Name: TLS1-DHE-DSS-AES-128-CBC-SHA | |||
Description: TLSv1 Kx=DH Au=DSS Enc=AES(128) Mac=SHA1 | |||
5) Cipher Name: TLS1-DHE-RSA-AES-128-CBC-SHA | |||
Description: TLSv1 Kx=DH Au=RSA Enc=AES(128) Mac=SHA1 | |||
6) Cipher Name: TLS1-AES-256-CBC-SHA | |||
Description: TLSv1 Kx=RSA Au=RSA Enc=AES(256) Mac=SHA1 | |||
7) Cipher Name: TLS1-AES-128-CBC-SHA | |||
Description: TLSv1 Kx=RSA Au=RSA Enc=AES(128) Mac=SHA1 | |||
> show ssl vserver marketplace.firefox.com:https | |||
Advanced SSL configuration for VServer marketplace.firefox.com:https: | |||
DH: DISABLED | |||
Ephemeral RSA: ENABLED Refresh Count: 0 | |||
Session Reuse: ENABLED Timeout: 120 seconds | |||
Cipher Redirect: DISABLED | |||
SSLv2 Redirect: DISABLED | |||
ClearText Port: 0 | |||
Client Auth: DISABLED | |||
SSL Redirect: DISABLED | |||
Non FIPS Ciphers: DISABLED | |||
SNI: DISABLED | |||
SSLv2: DISABLED SSLv3: ENABLED TLSv1: ENABLED | |||
Push Encryption Trigger: Always | |||
Send Close-Notify: YES | |||
1) CertKey Name: marketplace.mozilla.org.san Server Certificate | |||
1) Cipher Name: MozillaDefault | |||
Description: User Created Cipher Group | |||
<pre> | |||
== Apache == | |||
Apache + mod_ssl is suitable for SSL termination. Only Apache 2.4+ & recent versions of OpenSSL support TLSv1.1 and TLSv1.2 in the SSLProtocol parameter. Also, only Apache 2.4 honors the SSLCipherSuit correctly. Make sure to test your setup before deploying. | |||
<pre> | |||
<VirtualHost *:443> | |||
... | |||
SSLEngine on | |||
SSLCertificateFile /path/to/signed_certificate | |||
SSLCertificateChainFile /path/to/intermediate_certificate | |||
SSLCertificateKeyFile /path/to/private/key | |||
SSLCACertificateFile /path/to/all_ca_certs | |||
SSLProtocol all -SSLv2 -SSLv3 | |||
SSLCipherSuite <recommended ciphersuite from top of this page> | |||
SSLHonorCipherOrder on | |||
SSLCompression off | |||
SSLUseStapling on | |||
SSLStaplingResponderTimeout 5 | |||
SSLStaplingReturnResponderErrors off | |||
SSLStaplingCache shmcb:/var/run/ocsp(128000) | |||
# Enable this if your want HSTS (recommended, but be careful) | |||
# Header add Strict-Transport-Security "max-age=15768000" | |||
... | |||
</VirtualHost> | |||
</pre> | |||
== Nginx == | |||
Nginx provides the best support of TLS at the moment. It is the only daemon that supports OCSP Stapling and custom DH parameters, in addition to TLS1.2 full support. | |||
<pre> | |||
server { | |||
listen 443; | |||
ssl on; | |||
# certs sent to the client in SERVER HELLO are concatenated in ssl_certificate | |||
ssl_certificate /path/to/signed_cert_plus_intermediates; | |||
ssl_certificate_key /path/to/private_key; | |||
# Diffie-Hellman parameter for DHE ciphersuites, recommended 2048 bits | |||
ssl_dhparam /path/to/dhparam.pem; | |||
ssl_session_timeout 5m; | |||
ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2; | |||
ssl_ciphers '<recommended ciphersuite from top of this page>'; | |||
ssl_prefer_server_ciphers on; | |||
ssl_session_cache shared:NginxCache123:50m; | |||
# Enable this if your want HSTS (recommended, but be careful) | |||
# add_header Strict-Transport-Security max-age=15768000; | |||
# OCSP Stapling --- | |||
# fetch OCSP records from URL in ssl_certificate and cache them | |||
ssl_stapling on; | |||
ssl_stapling_verify on; | |||
## verify chain of trust of OCSP response using Root CA and Intermediate certs | |||
ssl_trusted_certificate /path/to/root_CA_cert_plus_intermediates; | |||
resolver <IP DNS resolver>; | |||
.... | |||
} | |||
</pre> | |||
== Haproxy == | |||
SSL support in Haproxy is still Beta and shouldn't be used to terminate production SSL traffic. | |||
<pre> | |||
frontend ft_test | |||
mode http | |||
bind 0.0.0.0:443 ssl crt /etc/ssl/private/<concat cert + privkey> ciphers <recommended ciphersuite from top of this page> | |||
# Enable this if your want HSTS (recommended, but be careful) | |||
# rspadd Strict-Transport-Security:\ max-age=15768000 | |||
</pre> | |||
== Stud == | |||
Stud is a lightweight SSL termination proxy. It's basically a wrapper for OpenSSL. Stud is not being heavily developed, and features such as OCSP stapling are missing. But it is very lightweight and efficient, and with a recent openssl, supports all the TLS1.2 ciphersuites. | |||
<pre> | |||
# SSL x509 certificate file. REQUIRED. | |||
# List multiple certs to use SNI. Certs are used in the order they | |||
# are listed; the last cert listed will be used if none of the others match | |||
# | |||
# type: string | |||
pem-file = "<concatenate cert + privkey + dhparam>" | |||
# SSL protocol. | |||
# | |||
tls = on | |||
ssl = on | |||
# List of allowed SSL ciphers. | |||
# | |||
# Run openssl ciphers for list of available ciphers. | |||
# type: string | |||
ciphers = "<recommended ciphersuite from top of this page>" | |||
# Enforce server cipher list order | |||
# | |||
# type: boolean | |||
prefer-server-ciphers = on | |||
</pre> | |||
= CipherScan = | |||
See https://github.com/jvehent/cipherscan | |||
Cipherscan is a small Bash script that connects to a target and list the preferred Ciphers. It's an easy way to test a web server for available ciphers. | |||
The script also calculates an average handshake time in milliseconds for each cipher, but performing a given handshake X number of times. | |||
The example below shows the expected output of CipherScan with the recommended ciphersuite. | |||
<pre> | |||
$ ./CiphersScan.sh localhost:443 -v | |||
[....] | |||
prio ciphersuite avg_handshake_ms | |||
1 ECDHE-RSA-AES256-GCM-SHA384 20 | |||
2 ECDHE-RSA-AES128-GCM-SHA256 19 | |||
3 ECDHE-RSA-RC4-SHA 18 | |||
4 DHE-RSA-AES256-GCM-SHA384 22 | |||
5 DHE-RSA-AES128-GCM-SHA256 22 | |||
6 ECDHE-RSA-AES256-SHA384 19 | |||
7 ECDHE-RSA-AES256-SHA 19 | |||
8 ECDHE-RSA-AES128-SHA256 19 | |||
9 ECDHE-RSA-AES128-SHA 19 | |||
10 RC4-SHA 16 | |||
11 DHE-RSA-AES256-SHA256 22 | |||
12 DHE-RSA-AES256-SHA 22 | |||
13 DHE-RSA-CAMELLIA256-SHA 22 | |||
14 AES256-GCM-SHA384 17 | |||
15 AES256-SHA256 17 | |||
16 AES256-SHA 17 | |||
17 CAMELLIA256-SHA 17 | |||
18 DHE-RSA-AES128-SHA256 23 | |||
19 DHE-RSA-AES128-SHA 23 | |||
20 DHE-RSA-CAMELLIA128-SHA 22 | |||
21 AES128-GCM-SHA256 17 | |||
22 AES128-SHA256 17 | |||
23 AES128-SHA 17 | |||
24 CAMELLIA128-SHA 17 | |||
</pre> | |||
= SSL Labs (Qualys) = | |||
Available here: https://www.ssllabs.com/ssltest/ | |||
Test your SSL configuration against Qualys SSLLabs. The screenshot below shows the expected SSLLabs report with the recommended ciphersuite. | |||
= Appendices = | |||
== Attacks on TLS == | |||
=== BEAST CVE-2011-3389 === | |||
Beast is a vulnerability in the Initialization Vector (IV) of the CBC mode of AES, Camellia and a few other ciphers that use CBC mode. The attack allows a MITM attacker to recover plaintext values by encrypted the same message multiple times. | |||
BEAST is mitigated in TLS1.1 and above. | |||
more: https://blog.torproject.org/blog/tor-and-beast-ssl-attack | |||
=== LUCKY13 === | |||
Lucky13 is another attack on CBC mode that listen for padding checks to decrypt ciphertext. | |||
more: https://www.imperialviolet.org/2013/02/04/luckythirteen.html | |||
=== RC4 weaknesses === | |||
It has been proven that RC4 biases in the first 256 bytes of a cipherstream can be used to recover encrypted text. If the same data is encrypted a very large amount of time, then an attacker can apply statistical analysis to the results and recover the encrypted text. While hard to perform, this attack shows that it is time to push RC4 down the ciphersuite. | |||
more: http://security.stackexchange.com/questions/32497/tls-rc4-or-not-rc4 | |||
=== CRIME CVE-2012-4929 === | |||
The root cause of the problem is information leakage that occurs when data is compressed prior to encryption. If someone can repeatedly inject and mix arbitrary content with some sensitive and relatively predictable data, and observe the resulting encrypted stream, then he will be able to extract the unknown data from it. | |||
more: https://community.qualys.com/blogs/securitylabs/2012/09/14/crime-information-leakage-attack-against-ssltls | |||
=== BREACH === | |||
This is a more complex attack than CRIME, which does not require TLS-level compression (it still needs HTTP-level compression). | |||
In order to be successful, it requires to: | |||
# Be served from a server that uses HTTP-level compression | |||
# Reflect user-input in HTTP response bodies | |||
# Reflect a secret (such as a CSRF token) in HTTP response bodies | |||
more: http://breachattack.com/ | |||
== SPDY == | |||
(see also http://en.wikipedia.org/wiki/SPDY) | |||
SPDY is a protocol that incorporate TLS, which attempts to reduce latency when loading pages. It is currently not an HTTP standard (albeit it is being drafted for HTTP 2.0), but is widely supported. | |||
SPDY version 3 is vulnerable to the CRIME attack (see also http://zoompf.com/2012/09/explaining-the-crime-weakness-in-spdy-and-ssl) - this is due to the use of compression. Clients currently implement a non-standard hack in with gzip in order to circumvent the vulnerability. SPDY version 4 is planned to include a proper fix. | |||
== TLS tickets (RFC 5077) == | |||
Once a TLS handshake has been negociated between the server and the client, both may exchange a session ticket, which contains an AES-CBC 128bit key which can decrypt the session. This key is generally static and only regenerated when the web server is restarted (with recent versions of Apache, it's stored in a file and also kept upon restarts). | |||
The current work-around is to disable RFC 5077 support. | |||
more: https://media.blackhat.com/us-13/US-13-Daigniere-TLS-Secrets-Slides.pdf | |||
== Nginx configuration details == | |||
Originally published on Julien's blog at https://jve.linuxwall.info/blog/index.php?post/2013/10/12/A-grade-SSL/TLS-with-Nginx-and-StartSSL | |||
=== Building Nginx === | |||
To build Nginx from source, you will need a copy of the PCRE and OpenSSL libraries: | |||
* PCRE can be found here: ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/ | |||
* OpenSSL can be found here: http://www.openssl.org/source/ | |||
Decompress both libraries next to the Nginx source code: | |||
<pre> | |||
julien@sachiel:~/nginx_openssl$ ls | |||
build_static_nginx.sh nginx openssl-1.0.1e pcre-8.33 | |||
</pre> | |||
The script build_static_nginx.sh takes care of the rest. It should work out of the box, but you might have to edit the paths if you have different versions of the libraries. I builds a static version of OpenSSL into Nginx, so you don't have to install the openssl libs afterward. | |||
<code bash> | |||
#!/usr/bin/env bash | |||
export BPATH=$(pwd) | |||
export STATICLIBSSL="$BPATH/staticlibssl" | |||
#-- Build static openssl | |||
cd $BPATH/openssl-1.0.1e | |||
rm -rf "$STATICLIBSSL" | |||
mkdir "$STATICLIBSSL" | |||
make clean | |||
./config --prefix=$STATICLIBSSL no-shared enable-ec_nistp_64_gcc_128 \ | |||
&& make depend \ | |||
&& make \ | |||
&& make install_sw | |||
#-- Build nginx | |||
hg clone http://hg.nginx.org/nginx | |||
cd $BPATH/nginx | |||
mkdir -p $BPATH/opt/nginx | |||
hg pull | |||
./auto/configure --with-cc-opt="-I $STATICLIBSSL/include -I/usr/include" \ | |||
--with-ld-opt="-L $STATICLIBSSL/lib -Wl,-rpath -lssl -lcrypto -ldl -lz" \ | |||
--prefix=$BPATH/opt/nginx \ | |||
--with-pcre=$BPATH/pcre-8.33 \ | |||
--with-http_ssl_module \ | |||
--with-http_spdy_module \ | |||
--with-file-aio \ | |||
--with-ipv6 \ | |||
--with-http_gzip_static_module \ | |||
--with-http_stub_status_module \ | |||
--without-mail_pop3_module \ | |||
--without-mail_smtp_module \ | |||
--without-mail_imap_module \ | |||
&& make && make install | |||
NGINXBIN=$BPATH/opt/nginx/sbin/nginx | |||
if [ -x $NGINXBIN ]; then | |||
$NGINXBIN -V | |||
echo -e "\nNginx binary build in $BPATH/opt/nginx/sbin/nginx\n" | |||
fi | |||
</code> | |||
=== Server Name Identification === | |||
Support for SNI is built into recent versions of nginx. Use nginx -V to check: | |||
<pre> | |||
# /opt/nginx -V | |||
... | |||
TLS SNI support enabled | |||
... | |||
</pre> | |||
=== Configuration directives === | |||
==== ssl_certificate ==== | |||
This parameter points to file that contains the server and intermediate certificates, concatenated together. Nginx loads that file and sends its content in the SERVER HELLO message during the handshake. | |||
==== ssl_certificate_key ==== | |||
This is the path to the private key. | |||
==== ssl_dhparam ==== | |||
When DHE ciphers are used, a prime number is shared between server and client to perform the Diffie-Hellman Key Exchange. I won't get into the details of Perfect Forward Secrecy here, but do know that the larger the prime is, the better the security. Nginx lets you specify the prime number you want the server to send to the client in the ssl_dhparam directive. The prime number is sent by the server to the client in the Server Key Exchange message of the handshake. To generate the dhparam, use openssl: | |||
<pre> | |||
$ openssl dhparam -rand – 4096 | |||
</pre> | |||
A word of warning though, it appears that Java 6 does not support dhparam larger than 1024 bits. Clients that use Java 6 won't be able to connect to your site if you use a larger dhparam. (there might be issues with other libraries as well, I only know about the java one). | |||
==== ssl_session_timeout ==== | |||
When a client connects multiple time to a server, the server uses session caching to accelerate the subsequent handshakes, effectively reusing the session key generated in the first handshake multiple times. This is called session resumption. This parameter sets the session timeout to 5 minutes, meaning that the session key will be deleted from the cache if not used for 5 minutes. | |||
==== ssl_session_cache ==== | |||
The session cache is a shared memory that contains all the session keys. All the Nginx workers can access the shared memory. It is used for session resumption, and significantly reduces handshake latency when one client connects multiple times. | |||
==== ssl_protocols ==== | |||
List the versions of TLS you wish to support. It's pretty much safe to disable SSLv3 these days, but TLSv1 is still required by a bunch of clients. Remember that clients are not only web browsers, but also libraries that might be used to crawl your site. | |||
==== ssl_ciphers ==== | |||
The ciphersuite is truly the core of an SSL configuration. Mine is very long, and I spent a ridiculous amount of time researching it. I won't get into the details of its construction here, as I'll be writing more on this in the next few weeks. | |||
==== ssl_prefer_server_ciphers ==== | |||
This parameter force nginx to pick the preferred cipher from its own ciphersuite, as opposed to using the one preferred by the client. This is an important option since most clients have unsafe or outdated preferences, and you'll most likely provide better security by enforcing a strong ciphersuite server-side. | |||
==== HTTP Strict Transport Security ==== | |||
HSTS is a HTTP header that tells clients to connect to the site using HTTPS only. It enforces security, by telling clients that any HTTP URL to a given site should be ignored. The directive is cached on the client size for the duration of max-age. In this case, 182 days. | |||
==== ssl_stapling ==== | |||
When connecting to a server, clients should verify the validity of the server certificate using either a Certificate Revocation List (CRL), or an Online Certificate Status Protocol (OCSP) record. The problem with CRL is that the lists have grown huge and take forever to download. OCSP is much more lightweight, as only one record is retrieved at a time. But the side effect is that OCSP requests must be made to a 3rd party OCSP responder when connecting to a server. | |||
The solution is to allow the server to send the OCSP record during the TLS handshake, therefore bypassing the OCSP responder. This mechanism saves a roundtrip between the client and the OCSP responder, and is called OCSP Stapling. | |||
Nginx supports OCSP stapling in two modes. The OCSP file can be downloaded and made available to nginx, or nginx itself can retrieve the OCSP record and cache it. We use the second mode in the configuration below. | |||
The location of the OCSP responder is taken from the Authority Information Access field of the signed certificate: | |||
<pre> | |||
Authority Information Access: | |||
OCSP - URI:http://ocsp.startssl.com/sub/class1/server/ca | |||
</pre> | |||
==== ssl_stapling_verify ==== | |||
Nginx has the ability to verify the OCSP record before caching it. But to enable it, a list of trusted certificate must be available in the ssl_trusted_certificate parameter. | |||
==== ssl_trusted_certificate ==== | |||
This is a path to a file where CA certificates are concatenated. For ssl_stapling_verify to work, this file must contain the Root CA cert and the Intermediate CA certificates. In the case of StartSSL, the Root CA and Intermediate I use are here: http://jve.linuxwall.info/ressources/code/startssl_trust_chain.txt | |||
==== resolver ==== | |||
Nginx needs a DNS resolver to obtain the IP address of the OCSP responder. |