Security/TLS Configurations

< Security
Revision as of 16:33, 12 January 2016 by Ulfr (talk | contribs) (Created page with "= TLS Configurations = This is a backup of the configurations that were previously listed on Security/Server_Side_TLS == Nginx == Nginx provides OCSP Stapling, custom DH...")
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

TLS Configurations

This is a backup of the configurations that were previously listed on Security/Server_Side_TLS

Nginx

Nginx provides OCSP Stapling, custom DH parameters, and the full flavor of TLS versions (from OpenSSL).

server {
    listen 443 ssl;

    # 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;
    ssl_session_timeout 5m;
    ssl_session_cache shared:SSL:5m;

    # Diffie-Hellman parameter for DHE ciphersuites, recommended 2048 bits
    ssl_dhparam /path/to/dhparam.pem;

    # Intermediate configuration. tweak to your needs.
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers '<paste intermediate ciphersuite here>';
    ssl_prefer_server_ciphers on;

    # Enable this if your want HSTS (recommended)
    # 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>;

    ....
}

Apache

Apache supports OCSP Stapling, but only in httpd 2.3.3 and later.

Before Apache 2.4.7, the DH parameter is always set to 1024 bits and is not user configurable. This has been fixed in mod_ssl 2.4.7 that Red Hat has backported into their RHEL 6 Apache 2.2 distribution with httpd-2.2.15-32.el6. Future versions of Apache will automatically select a better value for the DH parameter.

<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

    # Intermediate configuration, tweak to your needs
    SSLProtocol             all -SSLv2 -SSLv3
    SSLCipherSuite          <paste intermediate ciphersuite here>
    SSLHonorCipherOrder     on
    SSLCompression          off

    # OCSP Stapling, only in httpd 2.3.3 and later
    SSLUseStapling          on
    SSLStaplingResponderTimeout 5
    SSLStaplingReturnResponderErrors off
    # On Apache 2.4+, SSLStaplingCache must be set *outside* of the VirtualHost
    SSLStaplingCache        shmcb:/var/run/ocsp(128000)

    # Enable this if your want HSTS (recommended)
    # Header add Strict-Transport-Security "max-age=15768000"

    ...
</VirtualHost>
# TLS Session cache, outside of virtual host, apache 2.4+
# the path doesn't need to exist
SSLSessionCache         shmcb:/path/to/ssl_gcache_data(5120000)

Haproxy

SSL support in Haproxy is stable in 1.5. Haproxy supports OCSP Stapling and custom DH parameters size. It can be used as a TLS termination in AWS using ELBs and the PROXY protocol. See Guidelines for HAProxy termination in AWS

global
    # set default parameters to the Intermediate configuration
    tune.ssl.default-dh-param 2048
    ssl-default-bind-ciphers <paste intermediate ciphersuite here>

frontend ft_test
    mode    http
    bind    0.0.0.0:443 ssl no-sslv3 crt /path/to/<cert+privkey+intermediate+dhparam>
    # Enable this if your want HSTS (recommended)
    # rspadd  Strict-Transport-Security:\ max-age=15768000
OCSP Stapling support

While HAProxy can serve OCSP stapled responses, it cannot fetch and update OCSP records from the CA automatically. The OCSP response must be downloaded by another process and placed next to the certificate, with a '.ocsp' extension.

/etc/haproxy/certs/
├── ca.pem
├── server_cert.pem
├── server_bundle.pem
└── server_bundle.pem.ocsp

The file 'server_bundle.pem.ocsp' must be retrieved and updated at regular intervals. A cronjob can be used for this:

$ openssl ocsp -noverify -issuer /etc/haproxy/certs/ca.pem \
-cert /etc/haproxy/certs/server_cert.pem \
-url http://ocsp.startssl.com/sub/class1/server/ca \
-no_nonce -header Host ocsp.startssl.com \
-respout /etc/haproxy/certs/server_bundle.pem.ocsp

The URL above is taken from the server certificate:

$ openssl x509 -in server_cert.pem -text | grep OCSP
OCSP - URI:http://ocsp.startssl.com/sub/class1/server/ca

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 TLS 1.2 ciphers.

# 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 = "<paste intermediate ciphersuite here>"

# Enforce server cipher list order
#
# type: boolean
prefer-server-ciphers = on

Amazon Web Services Elastic Load Balancer (AWS ELB)

The ELB service supports TLS 1.2 and ciphers ordering, but lacks support for custom DH parameters and OCSP Stapling.

The default configuration of ELBs has old settings, that can be customized in the Web Console or via the API. We recommend that you use the Security/Server_Side_TLS#elb_ciphers.py to enforce the right TLS configuration on an elastic load balancer.

Below is a side-by-side comparison of the 'intermediate' recommended configuration versus the default ELB configuration. The top ciphers are the same, but SSLv3 and various deprecated ciphers are removed from the intermediate configuration.

= INTERMEDIATE configuration =                                               |  = default ELB configuration =
                                                                             |
prio  ciphersuite                  protocols              pfs_keysize        |  prio  ciphersuite                  protocols                    pfs_keysize
1     ECDHE-RSA-AES128-GCM-SHA256  TLSv1.2                ECDH,P-256,256bits |  1     ECDHE-RSA-AES128-GCM-SHA256  TLSv1.2                      ECDH,P-256,256bits
2     ECDHE-RSA-AES128-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 |  3     ECDHE-RSA-AES128-SHA         SSLv3,TLSv1,TLSv1.1,TLSv1.2  ECDH,P-256,256bits
4     ECDHE-RSA-AES256-GCM-SHA384  TLSv1.2                ECDH,P-256,256bits |  4     ECDHE-RSA-AES256-GCM-SHA384  TLSv1.2                      ECDH,P-256,256bits
5     ECDHE-RSA-AES256-SHA384      TLSv1.2                ECDH,P-256,256bits |  5     ECDHE-RSA-AES256-SHA384      TLSv1.2                      ECDH,P-256,256bits
6     ECDHE-RSA-AES256-SHA         TLSv1,TLSv1.1,TLSv1.2  ECDH,P-256,256bits |  6     ECDHE-RSA-AES256-SHA         SSLv3,TLSv1,TLSv1.1,TLSv1.2  ECDH,P-256,256bits
7     AES128-GCM-SHA256            TLSv1.2                                   |  7     AES128-GCM-SHA256            TLSv1.2
8     AES128-SHA256                TLSv1.2                                   |  8     AES128-SHA256                TLSv1.2
9     AES128-SHA                   TLSv1,TLSv1.1,TLSv1.2                     |  9     AES128-SHA                   SSLv3,TLSv1,TLSv1.1,TLSv1.2
10    AES256-GCM-SHA384            TLSv1.2                                   |  10    AES256-GCM-SHA384            TLSv1.2
11    AES256-SHA256                TLSv1.2                                   |  11    AES256-SHA256                TLSv1.2
12    AES256-SHA                   TLSv1,TLSv1.1,TLSv1.2                     |  12    AES256-SHA                   SSLv3,TLSv1,TLSv1.1,TLSv1.2
13    DHE-RSA-AES128-SHA           TLSv1,TLSv1.1,TLSv1.2  DH,1024bits        |  13    DHE-RSA-AES128-SHA           SSLv3,TLSv1,TLSv1.1,TLSv1.2  DH,1024bits
14    CAMELLIA128-SHA              TLSv1,TLSv1.1,TLSv1.2                     |  14    ECDHE-RSA-RC4-SHA            SSLv3,TLSv1,TLSv1.1,TLSv1.2  ECDH,P-256,256bits
15    DHE-RSA-AES256-GCM-SHA384    TLSv1.2                DH,1024bits        |  15    RC4-SHA                      SSLv3,TLSv1,TLSv1.1,TLSv1.2
16    DHE-RSA-AES256-SHA256        TLSv1.2                DH,1024bits        |
17    DHE-RSA-AES256-SHA           TLSv1,TLSv1.1,TLSv1.2  DH,1024bits        |  Certificate: trusted, 2048 bit, sha256WithRSAEncryption signature
18    CAMELLIA256-SHA              TLSv1,TLSv1.1,TLSv1.2                     |  TLS ticket lifetime hint: 300
19    DHE-RSA-AES128-GCM-SHA256    TLSv1.2                DH,1024bits        |  OCSP stapling: not supported
20    DHE-RSA-AES128-SHA256        TLSv1.2                DH,1024bits        |
                                                                             |
Certificate: trusted, 2048 bit, sha256WithRSAEncryption signature            |
TLS ticket lifetime hint: 300                                                |
OCSP stapling: not supported                                                 |

elb_ciphers.py

This python script uses boto to create a TLS policy and apply it to a given load balancer. Make sure you have an AWS access key configured in ~/.boto to use this script, then invoke it as follow:

$ python cipher.py us-east-1 stooge-lb-prod-1 modern
New Policy 'Mozilla-OpSec-TLS-Modern-v-3-2' created and applied to load balancer stooge-lb-prod-1 in us-east-1

If no mode is specified, the intermediate mode will be used. The modes are 'old', 'intermediate' and 'modern', and map to the recommended configurations.

#!/usr/bin/env python

# Apply recommendation from https://wiki.mozilla.org/Security/Server_Side_TLS

# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
#
# Contributors:
# Gene Wood [:gene]
# Julien Vehent [:ulfr]
# JP Schneider [:jp]

import boto.ec2.elb
import sys

if len(sys.argv) < 3:
  print "usage : %s REGION ELB-NAME <MODE>" % sys.argv[0]
  print ""
  print "Example : %s us-west-2 persona-org-0810" % sys.argv[0]
  print "MODE can be 'old', 'intermediate' (default) or 'modern'"
  print "see https://wiki.mozilla.org/Security/Server_Side_TLS"
  sys.exit(1)

region = sys.argv[1]
load_balancer_name = sys.argv[2]
try:
    conf_mode = sys.argv[3]
except IndexError:
    conf_mode = 'intermediate'
conn_elb = boto.ec2.elb.connect_to_region(region)

#import logging
#logging.basicConfig(level=logging.DEBUG)

policy = {'old':{},
          'intermediate':{},
          'modern':{}}

policy['old']['name'] = 'Mozilla-OpSec-TLS-Old-v-3-3'
policy['old']['ciphersuite'] = {
                "ECDHE-ECDSA-AES128-GCM-SHA256": True,
                "ECDHE-RSA-AES128-GCM-SHA256": True,
                "ECDHE-ECDSA-AES128-SHA256": True,
                "ECDHE-RSA-AES128-SHA256": True,
                "ECDHE-ECDSA-AES128-SHA": True,
                "ECDHE-RSA-AES128-SHA": True,
                "ECDHE-ECDSA-AES256-GCM-SHA384": True,
                "ECDHE-RSA-AES256-GCM-SHA384": True,
                "ECDHE-ECDSA-AES256-SHA384": True,
                "ECDHE-RSA-AES256-SHA384": True,
                "ECDHE-RSA-AES256-SHA": True,
                "ECDHE-ECDSA-AES256-SHA": True,
                "ADH-AES128-GCM-SHA256": False,
                "ADH-AES256-GCM-SHA384": False,
                "ADH-AES128-SHA": False,
                "ADH-AES128-SHA256": False,
                "ADH-AES256-SHA": False,
                "ADH-AES256-SHA256": False,
                "ADH-CAMELLIA128-SHA": False,
                "ADH-CAMELLIA256-SHA": False,
                "ADH-DES-CBC3-SHA": False,
                "ADH-DES-CBC-SHA": False,
                "ADH-RC4-MD5": False,
                "ADH-SEED-SHA": False,
                "AES128-GCM-SHA256": True,
                "AES256-GCM-SHA384": True,
                "AES128-SHA": True,
                "AES128-SHA256": True,
                "AES256-SHA": True,
                "AES256-SHA256": True,
                "CAMELLIA128-SHA": True,
                "CAMELLIA256-SHA": True,
                "DES-CBC3-MD5": False,
                "DES-CBC3-SHA": True,
                "DES-CBC-MD5": False,
                "DES-CBC-SHA": False,
                "DHE-DSS-AES128-GCM-SHA256": True,
                "DHE-DSS-AES256-GCM-SHA384": True,
                "DHE-DSS-AES128-SHA": True,
                "DHE-DSS-AES128-SHA256": True,
                "DHE-DSS-AES256-SHA": True,
                "DHE-DSS-AES256-SHA256": True,
                "DHE-DSS-CAMELLIA128-SHA": False,
                "DHE-DSS-CAMELLIA256-SHA": False,
                "DHE-DSS-SEED-SHA": False,
                "DHE-RSA-AES128-GCM-SHA256": True,
                "DHE-RSA-AES256-GCM-SHA384": True,
                "DHE-RSA-AES128-SHA": True,
                "DHE-RSA-AES128-SHA256": True,
                "DHE-RSA-AES256-SHA": True,
                "DHE-RSA-AES256-SHA256": True,
                "DHE-RSA-CAMELLIA128-SHA": False,
                "DHE-RSA-CAMELLIA256-SHA": False,
                "DHE-RSA-SEED-SHA": False,
                "EDH-DSS-DES-CBC3-SHA": False,
                "EDH-DSS-DES-CBC-SHA": False,
                "EDH-RSA-DES-CBC3-SHA": False,
                "EDH-RSA-DES-CBC-SHA": False,
                "EXP-ADH-DES-CBC-SHA": False,
                "EXP-ADH-RC4-MD5": False,
                "EXP-DES-CBC-SHA": False,
                "EXP-EDH-DSS-DES-CBC-SHA": False,
                "EXP-EDH-RSA-DES-CBC-SHA": False,
                "EXP-KRB5-DES-CBC-MD5": False,
                "EXP-KRB5-DES-CBC-SHA": False,
                "EXP-KRB5-RC2-CBC-MD5": False,
                "EXP-KRB5-RC2-CBC-SHA": False,
                "EXP-KRB5-RC4-MD5": False,
                "EXP-KRB5-RC4-SHA": False,
                "EXP-RC2-CBC-MD5": False,
                "EXP-RC4-MD5": False,
                "IDEA-CBC-SHA": False,
                "KRB5-DES-CBC3-MD5": False,
                "KRB5-DES-CBC3-SHA": False,
                "KRB5-DES-CBC-MD5": False,
                "KRB5-DES-CBC-SHA": False,
                "KRB5-RC4-MD5": False,
                "KRB5-RC4-SHA": False,
                "PSK-3DES-EDE-CBC-SHA": False,
                "PSK-AES128-CBC-SHA": False,
                "PSK-AES256-CBC-SHA": False,
                "PSK-RC4-SHA": False,
                "RC2-CBC-MD5": False,
                "RC4-MD5": False,
                "RC4-SHA": False,
                "SEED-SHA": False,
                "Protocol-SSLv2": False,
                "Protocol-SSLv3": True,
                "Protocol-TLSv1": True,
                "Protocol-TLSv1.1": True,
                "Protocol-TLSv1.2": True,
                "Server-Defined-Cipher-Order": True
                }

# reuse the Old policy minus SSLv3 and 3DES
policy['intermediate']['name'] = 'Mozilla-OpSec-TLS-Intermediate-v-3-3'
policy['intermediate']['ciphersuite'] = policy['old']['ciphersuite'].copy()
policy['intermediate']['ciphersuite'].update(
    {"Protocol-SSLv3": False})

# reuse the intermediate policy minus TLSv1 and non PFS ciphers
policy['modern']['name'] = 'Mozilla-OpSec-TLS-Modern-v-3-3'
policy['modern']['ciphersuite'] = policy['intermediate']['ciphersuite'].copy()
policy['modern']['ciphersuite'].update(
    {"Protocol-TLSv1": False,
    "AES128-GCM-SHA256": False,
    "AES256-GCM-SHA384": False,
    "DHE-DSS-AES128-SHA": False,
    "AES128-SHA256": False,
    "AES128-SHA": False,
    "DHE-DSS-AES256-SHA256": False,
    "AES256-SHA256": False,
    "AES256-SHA": False,
    "CAMELLIA128-SHA": False,
    "CAMELLIA256-SHA": False,
    "DES-CBC3-SHA": False})

if not conf_mode in policy.keys():
    print "Invalid policy name, must be one of %s" % policy.keys()
    sys.exit(1)

# Create the Ciphersuite Policy
params = {'LoadBalancerName': load_balancer_name,
          'PolicyName': policy[conf_mode]['name'],
          'PolicyTypeName': 'SSLNegotiationPolicyType'}
conn_elb.build_complex_list_params(
    params,
    [(x, policy[conf_mode]['ciphersuite'][x]) for x in policy[conf_mode]['ciphersuite'].keys()],
    'PolicyAttributes.member',
    ('AttributeName', 'AttributeValue'))
policy_result = conn_elb.get_list('CreateLoadBalancerPolicy', params, None, verb='POST')

# Apply the Ciphersuite Policy to your ELB
params = {'LoadBalancerName': load_balancer_name,
          'LoadBalancerPort': 443,
          'PolicyNames.member.1': policy[conf_mode]['name']}

result = conn_elb.get_list('SetLoadBalancerPoliciesOfListener', params, None)
print "New Policy '%s' created and applied to load balancer %s in %s" % (
    policy[conf_mode]['name'],
    load_balancer_name,
    region)

ELB & HAProxy

If you want better control over TLS than ELB provide, another option in AWS is to terminate SSL on HAproxy, using the PROXY protocol between ELB and HAproxy. https://jve.linuxwall.info/ressources/taf/haproxy-aws/

Zeus Load Balancer (Riverbed Stingray)

ZLB supports TLS1.2 and OCSP Stapling. It lacks support for Elliptic Curves and AES-GCM. As of Riverbed Steelhead 9.6, TLS parameters are configurable per site.

The recommended prioritization is:

  1. SSL_DHE_RSA_WITH_AES_128_CBC_SHA
  2. SSL_DHE_RSA_WITH_AES_256_CBC_SHA
  3. SSL_RSA_WITH_AES_128_CBC_SHA
  4. SSL_RSA_WITH_AES_256_CBC_SHA
  5. SSL_RSA_WITH_3DES_EDE_CBC_SHA

The following strings can be used directly in the ZLB configuration, under global settings > ssl3_ciphers. with 3DES

SSL_DHE_RSA_WITH_AES_128_CBC_SHA,SSL_DHE_RSA_WITH_AES_256_CBC_SHA,SSL_RSA_WITH_AES_128_CBC_SHA,SSL_RSA_WITH_AES_256_CBC_SHA,SSL_RSA_WITH_3DES_EDE_CBC_SHA

without 3DES

SSL_DHE_RSA_WITH_AES_128_CBC_SHA,SSL_DHE_RSA_WITH_AES_256_CBC_SHA,SSL_RSA_WITH_AES_128_CBC_SHA,SSL_RSA_WITH_AES_256_CBC_SHA

While the recommended DH prime size is 2048, problems with client libraries, such as Java 6/7, make this impossible to deploy for now. Therefore, a DH prime of 1024 bits should be used until all clients are compatible with larger primes.

Citrix Netscaler

There is an issue with Netscaler's TLS1.2 and DHE ciphers. When DHE is used, the TLS handshake fails with a fatal 'Decode error'. TLS1.2 works fine with AES and RC4 ciphers.

Netscaler documentation is at http://support.citrix.com/proddocs/topic/netscaler-traffic-management-10-map/ns-ssl-supported-ciphers-list-ref.html

The configuration sample below shows how a default ciphersuite object can be created and attached to a vserver.

First, create a default ciphersuite that can be used in all vservers.

> add ssl cipher MozillaDefault
> 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-DHE-DSS-AES-256-CBC-SHA
> bind ssl cipher MozillaDefault -cipherName TLS1-DHE-RSA-AES-256-CBC-SHA
> bind ssl cipher MozillaDefault -cipherName TLS1-AES-128-CBC-SHA
> bind ssl cipher MozillaDefault -cipherName TLS1-AES-256-CBC-SHA
> bind ssl cipher MozillaDefault -cipherName SSL3-DES-CBC3-SHA

Second, create a DH parameter. If backward compatibility with Java 6/7 isn't needed, use 2048 instead of 1024.

> create ssl dhparam /nsconfig/ssl/dh1024.pem 1024 -gen 5

Third, configure the vserver to use the default ciphersuite and DH parameter.

> 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
> set ssl vserver <domain>:https -dh ENABLED -dhFile /nsconfig/ssl/dh1024.pem -dhCount 1000

The resulting configuration can be viewed with 'show ssl'

> show ssl vserver marketplace.firefox.com:https

    Advanced SSL configuration for VServer marketplace.firefox.com:https:
    DH: ENABLED    DHParam File: /nsconfig/ssl/dh1024.pem    Refresh Count: 1000
    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

Go

The Go standard library supports TLS1.2 and a limited subset of ECDHE and GCM ciphers. To configure a Go program accepting TLS connections, use the following code:

    config := tls.Config{
        MinVersion:               tls.VersionTLS10,
        PreferServerCipherSuites: true,
        CipherSuites: []uint16{
            tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
            tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
            tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
            tls.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
            tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
            tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
            tls.TLS_RSA_WITH_AES_128_CBC_SHA,
            tls.TLS_RSA_WITH_AES_256_CBC_SHA,
            tls.TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,
            tls.TLS_RSA_WITH_3DES_EDE_CBC_SHA},
    }

F5 BIG-IP

BIG-IP uses SSL profiles which may be applied to one or multiple 'virtual servers' (VIPs). SSL profiles may use F5's default recommended cipher suites or may be manually configured to explicitly state which, and in what order, they are applied. SSL profiles can make use of multiple key types and support alternate key chains for each type (RSA, DSA and ECDSA). This can be performed either via the management web interface or via the TMOS command line (console or SSH).

Configuring Recommended Cipher-suites

To create a new SSL profile to conform to the Modern Compatibility cipher suite use the tmsh create profile command as follows...

tmsh create /ltm profile client-ssl moz_modern ciphers 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:DHE+AES-GCM:
ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-CBC-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:
ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-CBC-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:
DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:!EXPORT:!DES:!RC4:!3DES:!MD5

Note that Null ciphers are automatically rejected and are only made available if explicitly allowed by the F5 administrator.

Currently DHE-RSA-AES128-SHA256 & DHE-RSA-AES256-SHA256 are not available in TMOS v11.6.x. This is expected to be resolved in an upcoming hotfix and the next major release of TMOS. The full list of support ciphers is available here: https://support.f5.com/kb/en-us/solutions/public/13000/100/sol13163.html

To apply this new profile to an existing virtual server use either the management web interface or the following command line:

tmsh modify /ltm virtual my_virtual_server profiles add { moz_modern }

Any subsequenty changes to the SSL profile do not need to be manually re-applied to the LTM virtual server.

OCSP Stapling

Using the modify command allows us to easily add settings to our new SSL profile. Adding OCSP stapling is a 3 step process. First we must create a DNS resolver for outbound queries. Secondly we create our OCSP Stapling profile making use of this DNS resolver. Finally we add the OCSP Stapling profile to our SSL profile.

1. Creating the DNS resolver This command creates a DNS resolver for all domains (.) and uses Googles public DNS servers

tmsh create net dns-resolver myResolver forward-zones add { . { nameservers add { 8.8.8.8:53 } nameservers add { 8.8.4.4:53 } } }

2. Creating the OCSP Stapling profile The following command is used to create an OCSP stapling profile called myOCSP with our new DNS resolver myResolver

tmsh create ltm profile ocsp-stapling-params myOCSP dns-resolver myResolver trusted-ca ca-bundle.crt

3. Applying the OCSP Stapling profile to the DNS profile Using the modify command we will replace the default certificate and key in our existing SSL profile with the same default cert/key but, this time, making using of our new OCSP profile.

tmsh modify ltm profile client-ssl moz_modern cert-key-chain replace-all-with { default { cert default.crt key default.key ocsp-stapling-params myOCSP } }
Session Resumption

To enable session resumption using Session Tickets enable the option in the SSL profile via the management web interface or use the session-ticket enabled parameter when creating the profile at the command line. Again, we can use the modify command to append this to our existing moz_modern SSL profile.

For example:

tmsh modify /ltm profile client-ssl moz_modern session-ticket enabled
Viewing the config

To confirm the configuration of your new SSL profile and to ensure that it is correctly applied to your virtual server use the list command.

View your SSL profile:

tmsh list ltm profile client-ssl moz_modern

Which outputs all configuration paratmers of the profile called moz_modern:

ltm profile client-ssl moz_modern {
    app-service none
    cert-key-chain {
        default {
            cert default.crt
            key default.key
            ocsp-stapling-params myOCSP
        }
    }
    ciphers 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:DHE+AES-GCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-CBC-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-CBC-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:!EXPORT:!DES:!RC4:!3DES:!MD5
    inherit-certkeychain true
    session-ticket enabled
}

And to check it is correctly applied to your virtual server:

list ltm virtual vs_myWebsite

Which should list the SSL profile by name:

ltm virtual vs_myWebsite {
    destination 10.0.0.100:https
    ip-protocol tcp
    mask 255.255.255.255
    pool pool_webServers
    profiles {
        http { }
        http2 { }
        manual_profile { }
        moz_modern {
            context clientside
        }
        spdy { }
        tcp { }
        wan-optimized-compression { }
    }
    rules { }
    source 0.0.0.0/0
    source-address-translation {
        type automap
    }
    vs-index 4
}
Enabling HSTS

iRules are F5's flexible scripting language and can be used to easily enable HSTS for any TLS website. The standard HTTP should have redirection configured to send users to the HTTPS site. The following simple iRule is then applied to the HTTPS virtual server to insert the HSTS header enabling the maximum allowed age and including sub domains.

when HTTP_RESPONSE {
   HTTP::header insert Strict-Transport-Security "max-age=15768000; includeSubDomains"
}