Cipher Rules And Groups in BIG-IP v13

My mother used to always tell me two things before I left for school in the morning.

  • Be wary of what ciphers your application supports
  • Never use the Default cipher list unless you have compatibility concerns

You may have had a different upbringing from me but my mom's lessons still apply to anyone using SSL/TLS enabled systems. We know from Señor Wagnon's Security Sidebar: Improving Your SSL Labs Test Grade how cumbersome modifying lengthy cipher strings can be to keep your SSL Labs A grade.  We know as BIG-IP matures we update the DEFAULT cipher list to remove deprecated entries and introduce fancy new ones. This causes negative affects on those legacy applications we like to keep lying around.  Lastly, we know that not everyone appreciates meditating in SSH sessions; pondering countless tmm --clientciphers commands to figure out what cipher string they'll need in order to get achieve an SSL Labs A+ grade.  We have a solution for you.

Cipher Rules & Groups

BIG-IP version 13 introduces Cipher Rules & Groups; an alternate way to visualize, organize, and apply cipher suites to your client and ssl profiles.  You still need a basic understanding of cipher strings and I recommend you review Megazone's article: Cipher Suite Practices and Pitfalls article before gallivanting through Cipher Rules & Groups; you'll stub a toe. Cipher rules and the subsequent groups that contain them allow the same boolean operators used in tmm cipher strings.

Boolean Operations in Cipher Groups

  • UNION = Allow the following:
  • INTERSECT = Restrict the Allowed List to the following:
  • DIFFERENCE =Exclude the following from the Allowed List:

F5 includes 5 default cipher rules and applies them via 5 default cipher groups of the same name (included is the tmm command to view each cipher list used):

  • f5-aes =
    tmm --clientciphers AES
  • f5-default =
    tmm --clientciphers DEFAULT
  • f5-ecc =
    tmm --clientciphers ECDHE:ECDHE_ECDSA
  • f5-secure =
    tmm --clientciphers ECDHE:RSA:!SSLV3:!RC4:!EXP:!DES
  • f5-hw_keys =
    tmm --clientciphers 'ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES256-CBC-SHA:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDH-RSA-AES256-GCM-SHA384:ECDH-RSA-AES256-SHA384:ECDH-RSA-AES256-SHA:AES256-GCM-SHA384:AES256-SHA256:AES256-SHA:ECDHE-RSA-DES-CBC3-SHA:DHE-RSA-DES-CBC3-SHA:ECDH-RSA-DES-CBC3-SHA:DES-CBC3-SHA:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES128-CBC-SHA:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:ECDH-RSA-AES128-GCM-SHA256:ECDH-RSA-AES128-SHA256:ECDH-RSA-AES128-SHA:AES128-GCM-SHA256:AES128-SHA256:AES128-SHA:RC4-SHA:RC4-MD5:DHE-RSA-DES-CBC-SHA:DHE-RSA-CAMELLIA256-SHA:CAMELLIA256-SHA:DHE-RSA-CAMELLIA128-SHA:!TLSv1:!TLSv1_1:!SSLv3:!DTLSv1

The last one related to HSM ciphers was crazy long wasn't it. This is why we built cipher rules and groups; to prevent you from banging your head on the table because you got the operand wrong somewhere after ECDHE-RSA-AES128-GCM-SHA256. The F5 provided rules and groups are read-only and should used as a reference or starting template. If you rely only on the default F5 cipher rules/groups they will change as our cryptographic requirements change and you could end up with a bunch of incompatible legacy clients.

Building A Cipher Rule

Because Cipher Rules and Groups are applied to SSL Profiles, you can find them under Local Traffic in the web GUI. Clicking into Local Traffic => Ciphers gives you two options: Cipher Rules and Cipher Groups. I'll create one Cipher Rule based on tmm cipher string ALL:SSLv3:EXPORT. This is only for display purposes to better illustrate the boolean operations when we build the Cipher Group. Current ciphers based on BIG-IP version and Hotfix are listed in the NATIVE cipher list. Remember, we have to support a lot of ciphers that may not be appropriate for public consumption.

Building Cipher Groups

Now we'll build a Cipher Group starting with the chase_all Cipher Rule, because we're gluttons for punishment.  Clicking the + expands the ciphers allowed under each Cipher Rule. Adding it to the "Allow the following" element, the Cipher Audit element below will automatically update to reflect the ciphers this group will provide the Client or Server Profile.  Remember, anything added in that window is performing a Boolean Union operation.

Adding the f5-aes Cipher Rule to the "Restrict the Allowed List to the following:" element which will reduce the chase_all cipher list to only ciphers common to both ALL:SSLv3:EXPORT and AES lists; performing a Boolean Intersection operation. The Cipher Audit element shows the results and we can see those pesky RC4-MD5 suites from EXPORT are gone, but ew... we have some SSLv3-enabled ciphers and we want those out. I'll create a new Cipher Rule called chase_sslv3 with the cipher string only being SSlv3. I'll add this new Cipher Rule to the "Exclude the following from the Allowed List:"; performing a Boolean Difference operation. We can also change the cipher sorting based on speed, strength, FIPS, or hardware accelerated via the Order dropdown.

Ahh.... better, now we've paired down a horribly insecure cipher list with the intersection of the AES ciphers and exclusion of the SSlv3s. Yea, we could have started with the AES Cipher Rule as the base list but that's not as fun for this demonstration. The lifecycle of a BIG-IP SSL profile requires active management of cipher suites. This demo illustrates the flexability of additive/subtractive cipher management which reduces the complexity of recreating the wheel every time someone nullifies the security of existing algorithms or hash functions.

Applying Cipher Groups to Client/Server Profiles

Open an SSL Client or Server Profile and change the configuration to advanced. The cipher list becomes available and is defaulted to a Cipher String.  Now you have a radio button for Cipher Group, selecting the newly created object or click the + button to create one from scratch.

TMSH Support for Cipher Rules and Groups

We have support for tmsh commands so you can take advantage of adding cipher groups to existing profiles.

# tmsh list ltm cipher rule f5-secure all-properties

ltm cipher rule f5-secure {
    app-service none
    cipher ECDHE:RSA:!SSLV3:!RC4:!EXP:!DES
    description "Cipher suites that maximize regulatory compliance."
    partition Common
}
# tmsh show ltm cipher rule f5-secure

-----------------
Ltm::Cipher::Rule
-----------------
Name       Result
-----------------
f5-secure  ECDHE-RSA-AES128-GCM-SHA256/TLS1.2:ECDHE-RSA-AES128-CBC-SHA/TLS1.0:ECDHE-RSA-AES128-CBC-SHA/TLS1.1:ECDHE-RSA-AES128-CBC-SHA/TLS1.2:ECDHE-RSA-AES128-SHA256/TLS1.2:ECDHE-RSA-AES256-GCM-SHA384/TLS1.2:ECDHE-RSA-AES256-CBC-SHA/TLS1.0:ECDHE-RSA-AES256-CBC-SHA/TLS1.1:ECDHE-RSA-AES256-CBC-SHA/TLS1.2:ECDHE-RSA-AES256-SHA384/TLS1.2:ECDHE-RSA-DES-CBC3-SHA/TLS1.0:ECDHE-RSA-DES-CBC3-SHA/TLS1.1:ECDHE-RSA-DES-CBC3-SHA/TLS1.2:AES128-GCM-SHA256/TLS1.2:AES128-SHA/TLS1.0:AES128-SHA/TLS1.1:AES128-SHA/TLS1.2:AES128-SHA/DTLS1.0:AES128-SHA256/TLS1.2:AES256-GCM-SHA384/TLS1.2:AES256-SHA/TLS1.0:AES256-SHA/TLS1.1:AES256-SHA/TLS1.2:AES256-SHA/DTLS1.0:AES256-SHA256/TLS1.2:CAMELLIA128-SHA/TLS1.0:CAMELLIA128-SHA/TLS1.1:CAMELLIA128-SHA/TLS1.2:CAMELLIA256-SHA/TLS1.0:CAMELLIA256-SHA/TLS1.1:CAMELLIA256-SHA/TLS1.2:DES-CBC3-SHA/TLS1.0:DES-CBC3-SHA/TLS1.1:DES-CBC3-SHA/TLS1.2:DES-CBC3-SHA/DTLS1.0
# tmsh list ltm cipher group chases_cipher_group all-properties
ltm cipher group chases_cipher_group {
    allow {
        chase_all { }
    }
    app-service none
    description "MY CIPHERS ARE THE BEST CIPHERS"
    exclude {
        chase_sslv3 { }
    }
    ordering default
    partition Common
    require {
        f5-aes { }
    }
}
# tmsh show ltm cipher group chases_cipher_group

---------------------------
Ltm::Cipher::Group 
---------------------------
Name                 Result
---------------------------
chases_cipher_group  ECDHE-RSA-AES128-CBC-SHA/TLS1.0:ECDHE-RSA-AES128-CBC-SHA/TLS1.1:ECDHE-RSA-AES128-CBC-SHA/TLS1.2:ECDHE-RSA-AES128-SHA256/TLS1.2:ECDHE-RSA-AES256-CBC-SHA/TLS1.0:ECDHE-RSA-AES256-CBC-SHA/TLS1.1:ECDHE-RSA-AES256-CBC-SHA/TLS1.2:ECDHE-RSA-AES256-SHA384/TLS1.2:ECDH-RSA-AES128-SHA256/TLS1.2:ECDH-RSA-AES128-SHA/TLS1.0:ECDH-RSA-AES128-SHA/TLS1.1:ECDH-RSA-AES128-SHA/TLS1.2:ECDH-RSA-AES256-SHA384/TLS1.2:ECDH-RSA-AES256-SHA/TLS1.0:ECDH-RSA-AES256-SHA/TLS1.1:ECDH-RSA-AES256-SHA/TLS1.2:AES128-SHA/TLS1.0:AES128-SHA/TLS1.1:AES128-SHA/TLS1.2:AES128-SHA/DTLS1.0:AES128-SHA256/TLS1.2:AES256-SHA/TLS1.0:AES256-SHA/TLS1.1:AES256-SHA/TLS1.2:AES256-SHA/DTLS1.0:AES256-SHA256/TLS1.2:ECDHE-ECDSA-AES128-SHA/TLS1.0:ECDHE-ECDSA-AES128-SHA/TLS1.1:ECDHE-ECDSA-AES128-SHA/TLS1.2:ECDHE-ECDSA-AES128-SHA256/TLS1.2:ECDHE-ECDSA-AES256-SHA/TLS1.0:ECDHE-ECDSA-AES256-SHA/TLS1.1:ECDHE-ECDSA-AES256-SHA/TLS1.2:ECDHE-ECDSA-AES256-SHA384/TLS1.2:ECDH-ECDSA-AES128-SHA/TLS1.0:ECDH-ECDSA-AES128-SHA/TLS1.1:ECDH-ECDSA-AES128-SHA/TLS1.2:ECDH-ECDSA-AES128-SHA256/TLS1.2:ECDH-ECDSA-AES256-SHA/TLS1.0:ECDH-ECDSA-AES256-SHA/TLS1.1:ECDH-ECDSA-AES256-SHA/TLS1.2:ECDH-ECDSA-AES256-SHA384/TLS1.2:DHE-RSA-AES128-SHA/TLS1.0:DHE-RSA-AES128-SHA/TLS1.1:DHE-RSA-AES128-SHA/TLS1.2:DHE-RSA-AES128-SHA/DTLS1.0:DHE-RSA-AES128-SHA256/TLS1.2:DHE-RSA-AES256-SHA/TLS1.0:DHE-RSA-AES256-SHA/TLS1.1:DHE-RSA-AES256-SHA/TLS1.2:DHE-RSA-AES256-SHA/DTLS1.0:DHE-RSA-AES256-SHA256/TLS1.2:DHE-DSS-AES128-SHA/TLS1.0:DHE-DSS-AES128-SHA/TLS1.1:DHE-DSS-AES128-SHA/TLS1.2:DHE-DSS-AES128-SHA/DTLS1.0:DHE-DSS-AES128-SHA256/TLS1.2:DHE-DSS-AES256-SHA/TLS1.0:DHE-DSS-AES256-SHA/TLS1.1:DHE-DSS-AES256-SHA/TLS1.2:DHE-DSS-AES256-SHA/DTLS1.0:DHE-DSS-AES256-SHA256/TLS1.2:ADH-AES128-SHA/TLS1.0:ADH-AES256-SHA/TLS1.0
# tmsh list ltm profile client-ssl chases_ssl_client_profile

ltm profile client-ssl chases_ssl_client_profile {
    app-service none
    cert default.crt
    cert-key-chain {
        default {
            cert default.crt
            key default.key
        }
    }
    chain none
    cipher-group chases_cipher_group
    ciphers none
    defaults-from clientssl
    inherit-certkeychain true
    key default.key
    passphrase none
}
# tmsh list ltm profile server-ssl chases_ssl_server_profile

ltm profile server-ssl chases_ssl_server_profile {
    app-service none
    cipher-group chases_cipher_group
    ciphers none
    defaults-from serverssl
}

Validating Your Ciphers With NMAP

A lot of users are not always comfortable with how we output our cipher lists. NMAP provides a user-preferred display using the ssl-enum-ciphers script. In this case, we'll check out SSL Labs web server's ciphers. Run the following:

$ nmap -Pn -sT www.ssllabs.com -p 443 --script ssl-enum-ciphers

Starting Nmap 6.40 at 2017-02-24 11:22 PST
Nmap scan report for www.ssllabs.com (64.41.200.100)
Host is up (0.035s latency).
PORT    STATE SERVICE
443/tcp open  https
| ssl-enum-ciphers: 
|   SSLv3: No supported ciphers found
|   TLSv1.0: 
|     ciphers: 
|       TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA - strong
|       TLS_DHE_RSA_WITH_AES_128_CBC_SHA - strong
|       TLS_DHE_RSA_WITH_AES_256_CBC_SHA - strong
|       TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA - strong
|       TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA - strong
|       TLS_RSA_WITH_3DES_EDE_CBC_SHA - strong
|     compressors: 
|       NULL
|   TLSv1.1: 
|     ciphers: 
|       TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA - strong
|       TLS_DHE_RSA_WITH_AES_128_CBC_SHA - strong
|       TLS_DHE_RSA_WITH_AES_256_CBC_SHA - strong
|       TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA - strong
|       TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA - strong
|       TLS_RSA_WITH_3DES_EDE_CBC_SHA - strong
|     compressors: 
|       NULL
|   TLSv1.2: 
|     ciphers: 
|       TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA - strong
|       TLS_DHE_RSA_WITH_AES_128_CBC_SHA - strong
|       TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 - strong
|       TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 - strong
|       TLS_DHE_RSA_WITH_AES_256_CBC_SHA - strong
|       TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 - strong
|       TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 - strong
|       TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA - strong
|       TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 - strong
|       TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 - strong
|       TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA - strong
|       TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 - strong
|       TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 - strong
|       TLS_RSA_WITH_3DES_EDE_CBC_SHA - strong
|     compressors: 
|       NULL
|_  least strength: strong

Nmap done: 1 IP address (1 host up) scanned in 2.73 seconds

Hopefully this overview and mini-demo got you pondering how you can improve cipher management in your infrastructure.  As the crypto world discovers new ways to compromise math, we have to keep on our toes more than ever. Google Research and CWI Amsterdam just published the first real world hash collision for SHA-1 proving we need to stay informed.  The idea is simple, create Cipher Rules based on your needs and reuse them against application or security policy-centric Cipher Groups.  Segregating Cipher management from Client and Server SSL Profiles creates a more flexibility for application owners and should reduce the cipher string headache every time there's a new vulnerability. Drop us a line on your thoughts and let us know if we're going down the right path or if ther are other things you wish to see related to cipher management.

Keep it real.

Updated Jun 06, 2023
Version 2.0