Skip to content

Use best practice cipher suites for 2021#1802

Merged
georglauterbach merged 19 commits intodocker-mailserver:masterfrom
polarathene:feat/use-best-practice-ciphers-2021
Feb 18, 2021
Merged

Use best practice cipher suites for 2021#1802
georglauterbach merged 19 commits intodocker-mailserver:masterfrom
polarathene:feat/use-best-practice-ciphers-2021

Conversation

@polarathene
Copy link
Copy Markdown
Member

@polarathene polarathene commented Feb 9, 2021

Description

Continuation of my original PR: #1475

TL;DR

  • The modern TLS_LEVEL cipherlist is updated to accommodate OWASP B and Mozilla Intermediate ciphers.
  • The intermediate TLS_LEVEL cipherlist has only received housekeeping. Removing ciphers that are presently excluded by smtpd_tls_exclude_ciphers anyway.
  • smtpd_tls_exclude_ciphers has also received housekeeping. It has been reduced to only the relevant excludes, matching the same cipher support presently offered - except for ECDSA, which is no longer excluded.
  • ECDSA, despite having ciphers for it in the cipherlist, has not been supported by this image afaik. It seems to require a user supplied ECDSA cert(RSA is default), however the exclude list ignored these ciphers from what I can tell. I've not kept it excluded as that seems like it was a bug.

See the original PR and/or commit messages for added details.

One major highlight is enabling ECDSA certificate support. Some users have previously had issues due to ECDSA cipher suites being excluded when their certificates were provisioned as ECDSA (ECC). It should be relatively safe to use, possibly with the exception of some very old clients. A related PR enables supporting an RSA certificate as a fallback for those legacy clients.

NOTE: modern TLS_LEVEL has now dropped the AES-CBC cipher suites to prefer only AEAD ciphers (secure and modern, avoids many of the security issues CBC suites has ran into over the years). AEAD ciphers require TLS 1.2 minimum as a result (only when using mandatory TLS/STARTTLS ports, port 25 does not restrict cipher suites to tls_high_cipherlist). Dropping these 4 additional cipher suites changes the reference OWASP cipher list from grade B to A, as the CBC ciphers are the only difference.

While this PR does not cover everything I originally set out to do, I would like to get it reviewed and merged for the benefit of others. If time permits I'll contribute further additions in a future PR.

Type of change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Improvement (non-breaking change that does improve existing functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • This change requires a documentation update

ECDSA (fix.. and new feature?)
Revised cipherlists and exclude + review (improvement)
Dropping of AES-CBC cipher suites on modern (possible breaking change?)

Checklist:

  • My code follows the style guidelines of this project
  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation (README.md or ENVIRONMENT.md or the Wiki)
  • If necessary I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes

Moved to the front of the list:

```
ECDHE-ECDSA-AES128-GCM-SHA256
ECDHE-RSA-AES128-GCM-SHA256
```

`AES128-GCM-SHA256` may be weaker but is still considered quite secure, thus has been positioned for [performance reasons according to mozilla](mozilla/ssl-config-generator#48 (comment)). 

When allowing the client to choose the cipher from the list instead, which [mozilla advises for their intermediate and modern profiles](mozilla/ssl-config-generator#48 (comment)), the client can opt for what would suit it best, all ciphers the server advertises from this list are considered strong. 

[`tls_preempt_cipherlist`](http://www.postfix.org/postconf.5.html#tls_preempt_cipherlist) controls this in postfix. They have set it to `no`, which is the default, it could also be commented to remain visible in config, or removed if preferred. I have not changed it to `no` in this commit, as that would require port 25 inbound `STARTTLS` to also use the same custom cipherlist to follow Mozilla's advice. Probably a good idea to switch to `no` for `modern` profile at least?

Neither OWASP or Mozilla include the following two ciphers, so they've been removed. I think they may have been in a previous cipherlist from Mozilla when this list was last updated?

```
ECDHE-ECDSA-AES256-SHA384
ECDHE-ECDSA-AES128-SHA256
```

[Mozilla](https://ssl-config.mozilla.org/#server=postfix&version=3.4.8&config=intermediate&openssl=1.1.1d&guideline=5.4) ends its list with these two:

```
DHE-RSA-AES128-GCM-SHA256
DHE-RSA-AES256-GCM-SHA384
```

[OWASP B](https://cheatsheetseries.owasp.org/cheatsheets/TLS_Cipher_String_Cheat_Sheet.html) adds non-GCM DHE variants, and retains the last two ciphers in the current list. These are the only difference between OWASP A and B grades, so could be dropped if choosing to opt for grade A instead:

```
DHE-RSA-AES256-SHA256
DHE-RSA-AES128-SHA256
ECDHE-RSA-AES256-SHA384
ECDHE-RSA-AES128-SHA256
```

OWASP B also lists 3 TLS 1.3 ciphers, but these [rarely need to be specified for most software](mozilla/ssl-config-generator#53), as such they're not included:

```
TLS_AES_256_GCM_SHA384
TLS_CHACHA20_POLY1305_SHA256
TLS_AES_128_GCM_SHA256
```
Related is the `smtpd_tls_exclude_ciphers` parameter. Mozilla doesn't include it, and while it's possible to find relatively recent blogs / guides making use of it, they often don't explain any useful reasoning for the choices. I think it has just become a bit of parroting of information and a "better safe than sorry if I don't understand this" approach. Looking at the [postfix docs](http://www.postfix.org/postconf.5.html#smtpd_tls_exclude_ciphers) we have:

> List of ciphers or cipher types to exclude from the SMTP server cipher list at all TLS security levels. 

> Excluding valid ciphers *can create interoperability problems*. **DO NOT** exclude ciphers unless it is essential to do so.

> Cipher types listed in `smtpd_tls_mandatory_exclude_ciphers` or `smtpd_tls_exclude_ciphers` are excluded from the base definition of the selected cipher grade. 

> The underlying cipherlists for grades other than "null" include anonymous ciphers, but these are automatically filtered out if the server is configured to ask for remote SMTP client certificates. You are very unlikely to need to take any steps to exclude anonymous ciphers, **they are excluded automatically as required**. 

Additionally [`aNULL` also excludes `ADH`](https://community.letsencrypt.org/t/using-lets-encrypt-certs-with-postfix/18957/8). 

I have verified parity of the current excluded ciphers with this reduced set. They should be clear which ciphers they're responsible for, except for `MEDIUM` which handled the two `SEED` ciphers. Since `MEDIUM` is ambiguous to what it's covering(the others are still required for parity), I have switched `MEDIUM` to `SEED`. In my testing these excluded ciphers are still graded an `A`, only anon certs that `aNULL` excludes provide a lower `F` grade, but the docs state it's a non-issue with remote connections.

We could also change the `high` cipherlist to `medium` like mozilla does or keep the expanded coverage for inbound mail. Should be possible to have submission ports be considered more trustworthy and better cipher support, allowing the client to choose the cipher from the high list would be a good improvement.
`modern` TLS_LEVEL has had it's cipherlist updated to match the postfix `main.cf`change in the related prior commit. See that commit message for more details about the change.

`intermediate` TLS_LEVEL has had it's cipherlist truncated. None of these appear to remain available after applying the excludes on them. If the excludes are removed, each TLS level presents ciphers(when the cipherlist is only set to this removed list) with the warning:

> Forward Secrecy not supported by any cipher

This is misleading when associating them with a `high` grade list intended for mandatory TLS support. Despite the warning, the nmap tool grades them all with with A for encryption strength(if that's at all trustworthy of a metric).

The `intermediate` cipherlist still produces the same cipher support with the reduced list and exclusions from the previous commit.
Same changes to cipherlist as communicated in the related postfix `main.cf` commit.
There was an extra `E` accidentally in the first `ECDHE`.
This was the same content for the most part. Shared content was moved into a function call and dynamic content passed in as variables from each TLS_LEVEL case.
Seems appropriate to prefix the function name with `_` based on other internal function names, assuming convention.

Modified `sed` calls, removing `-r` option and regex token`$` as they're not necessary.

Uppercase variables as per style guide, `local` prefix for variable initialization.
Original cipherlist matched that of the postfix/dovecot config defaults (same as `tls_high_cipherlist`).
Mozilla's TLS reference once included these. They are the only difference between OWASP A and B Grades.

They are available in the intermediate cipher list. Removing these from our modern profile:

DHE-RSA-AES256-SHA256
DHE-RSA-AES128-SHA256
ECDHE-RSA-AES256-SHA384
ECDHE-RSA-AES128-SHA256

These four cipher suites are using AES-CBC for the cipher. By removing them, we only support AEAD (AES-GCM and ChaCha20-Poly1305) ciphers. These require a minimum of TLS 1.2 support and represent modern and secure cipher suites.
@wernerfred wernerfred added area/enhancement area/security kind/new feature A new feature is requested in this issue or implemeted with this PR priority/medium pr/missing integration tests This PR lacks tests and removed pr/needs review labels Feb 9, 2021
@georglauterbach
Copy link
Copy Markdown
Member

georglauterbach commented Feb 9, 2021

@wernerfred When this is merged, I guess 8.1.0 should be released.

While this PR does not cover everything I originally set out to do, I would like to get it reviewed and merged for the benefit of others.

This is very much appreciated!

NOTE: modern TLS_LEVEL has now dropped the AES-CBC cipher suites to prefer only AEAD ciphers

I think this is a welcome change.

  • This change requires a documentation update

That's true, but could you briefly write a changelog similar in style to this? Maybe it could look something like this:

  • [security] Adjusting TLS levels
    • this change, and that change...
    • some more changes
  • [security] Now supporting ECDSA

Possibly breaking changes

  • [security] this
  • [security] and that

  • New and existing unit tests pass locally with my changes

But tests pass on GH CI. What's the status with tests?

  • I have made corresponding changes to the documentation (README.md or ENVIRONMENT.md or the Wiki)

We will just need this in ENVIRONMENT.md for the TLS_LEVEL variable.


Al in all, a very welcome change. Thank you for taking the time!

@polarathene
Copy link
Copy Markdown
Member Author

That's true, but could you briefly write a changelog similar in style to this?

Yeah sure :)

Do you want that written here, or is there a file you'd like me to update? Did you want the same for the hybrid/dual certificate PR as well?

@georglauterbach
Copy link
Copy Markdown
Member

georglauterbach commented Feb 10, 2021

Do you want that written here, or is there a file you'd like me to update? Did you want the same for the hybrid/dual certificate PR as well?

Here in this PR is absolutely fine. I will then make sure this is written to all the places it belongs. It'd be appreciated if you could do this for the other PR too, yes.

And please reach back to me as soon as this PR can be reviewed so I can mark maintainers as reviewers.

@polarathene
Copy link
Copy Markdown
Member Author

polarathene commented Feb 11, 2021

Release notes, revised a terser version (the visible one).

The collapsed section Changes for TLS_LEVEL modern below.. I'm not sure how relevant that is for the release notes? The part explaining cipherlist sort order could be migrated to the wiki.


For tests, since CI on this PR passed, I just need to consider any tests to add? There's quite a few .pem files in the repo:

  • test/config/letsencrypt/(3 cert.pem, 2 key.pem, 1 privkey.pem, 2 chain.pem, 3 fullchain.pem)
  • test/config/dovecot-lmtp/ssl (dovecot.pem)
  • target/shared (ffdhe4096.pem DH params only)
  • test/test-files/ssl (custom-dhe-params.pem DH params only)

Should I add two self-signed certs? (RSA and ECDSA)
I could add a mix of variants? (separate keys and cert, bundled fullchain)
I can then add some tests for the different SSL_TYPE modes. Not sure about letsencrypt and ECDSA, but I could look into that?


Release Notes

  • [security] TLS: You can now use ECDSA certificates! 🎉
    • Warning: ECDSA may not be supported by legacy systems (most pre-2014). You can provide an RSA certificate as a fallback (<dual cert wiki docs link>).
  • [security] TLS: TLS_LEVEL=modern cipher list follows best practices by supporting only AEAD cipher suites.

Breaking Changes:

  • [security] TLS: TLS_LEVEL=modern has changed the server-side preference order to 128-bit before 256-bit encryption.
    • NOTE: This is still very secure but may result in misleading lower scores/grades from security audit websites.
  • [security] TLS: TLS_LEVEL=modern removed support for AES-CBC cipher suites.
    • NOTE: As TLS 1.2 is the minimum required for modern already, AEAD cipher suites should already be supported and preferred.
  • [security] TLS: TLS_LEVEL=intermediate has removed support for cipher suites using RSA for key exchange (only available with an RSA certificate).
    • NOTE: This only affects Dovecot which supported 5 extra cipher suites using AES-CBC and AES-GCM. Your users MUA clients should be unaffected, preferring ECDHE or DHE for key exchange.
EDIT: Not relevant. TLS_LEVEL modern enforces a minimum of TLS 1.2, lack of AES-CBC should not cause any breakage
  • [security] TLS: TLS_LEVEL=modern removed AES-CBC cipher suites. All mail ports (except 25), must now support TLS 1.2 minimum.
    • You're probably compatible with anything released from 2017 or the following minimum platform versions: iOS 10, macOS 10.12, Windows 10, Android 5.0, and mail servers deployed since 2012 (2014 for ECDSA and ECDHE support on RHEL and CentOS) when exchanging mail over ports other than 25.
    • If you need to support something older but only because of mail client (eg Apple devices with Apple Mail); instead of changing to TLS_LEVEL=intermediate, try advising Thunderbird which bundles it's own modern TLS support.
---

There's some extra details below, but I felt may not have added as much value to justify the verbosity?

Original release notes (Verbose)
  • [security] TLS: Postfix now supports ECDSA certificates, as ECDSA cipher suites are no longer excluded.
  • [security] TLS: The TLS_LEVEL=modern cipherlist matches OWASP A and Mozilla Intermediate recommended cipher suites as of Feb 2021. (NOTE: TLS_LEVEL has no effect on cipher suites for Port 25)
    • Now supporting only AEAD ciphers (requires TLS 1.2 as a minimum).
    • Removed support for obsolete AES-CBC cipher suites due to historical vulnerabilities with TLS implementations.
    • Platform support for TLS 1.2 (mostly anything released from 2017 is safe, with support ramping up from 2014):
      • iOS10 and macOS 10.12 (Sep 2016) and newer is required for Apple Mail (Secure Transport).
      • Old versions (released before 2014) of Windows (7, 8, 2008 R2) may lack cipher suites support for ECDHE+RSA with AES-GCM, however ECDHE+ECDSA and DHE+RSA are ok (assuming AES-GCM is available).
      • Servers like RHEL lacked ECC support until 2014-2016 depending on software package (aka requires DHE+RSA, lacks ECDHE and ECDSA support).
      • ChaCha20-Poly1305 was standardized around 2016 and typically only seen supported on mobile devices. Android 5.0 (Nov 2014) and newer support TLS 1.2.
      • If your platform lacks TLS 1.2 support but only needs a MUA client, Thunderbird bundles it's own TLS support so you can remain secure.
Changes for TLS_LEVEL modern:

Added (DHE+RSA fallbacks):

DHE-RSA-AES128-GCM-SHA256
DHE-RSA-AES256-GCM-SHA384

Removed (AES-CBC cipher suites):

ECDHE-ECDSA-AES256-SHA384
ECDHE-RSA-AES256-SHA384
ECDHE-ECDSA-AES128-SHA256
ECDHE-RSA-AES128-SHA256

TLS_LEVEL intermediate removes the following (Postfix never negotiated these, Dovecot supported AES cipher suites if using RSA key exchange, only available with an RSA certificate):

ECDHE-ECDSA-DES-CBC3-SHA
ECDHE-RSA-DES-CBC3-SHA
EDH-RSA-DES-CBC3-SHA
AES128-GCM-SHA256
AES256-GCM-SHA384
AES128-SHA256
AES256-SHA256
AES128-SHA
AES256-SHA
DES-CBC3-SHA
!DSS

The new modern cipher list uses the following cipher suites (in server preference order):

ECDHE-ECDSA-AES128-GCM-SHA256
ECDHE-RSA-AES128-GCM-SHA256
ECDHE-ECDSA-AES256-GCM-SHA384
ECDHE-RSA-AES256-GCM-SHA384
ECDHE-ECDSA-CHACHA20-POLY1305
ECDHE-RSA-CHACHA20-POLY1305
DHE-RSA-AES128-GCM-SHA256
DHE-RSA-AES256-GCM-SHA384

DHE+RSA provides additional compatibility for some older clients. Why only these two?:

  • DHE+ECDSA cipher suites do not exist.
  • If ChaCha20-Poly1305 can be negotiated, ECDHE would be supported and preferable (also applies for ECDSA).

How the cipher list is sorted:

The cipher list matches the server preference order from Mozilla Intermediate:

  • Key Exchange (ephemeral keys only for forward secrecy):
    • ECDHE before DHE (ECDHE is more efficient to compute and reduced bandwidth, DHE has a weakness when misconfigured, retained for older client compatibility)
  • Authentication via Digital Signature (matches your certificate type):
    • ECDSA before RSA (ECDSA is more efficient on server (signing vs client verification) and reduced bandwidth)
  • Encryption Cipher (AEAD ciphers only):
    • AES128-GCM before AES256-GCM (128-bit is already very secure, prefer efficiency)
    • Otherwise ChaCha20-Poly1305 (more efficient if AES-NI is not supported, mostly for mobile devices)
  • Message Authentication Code (verifies integrity of encrypted data):
    • Not relevant with AEAD ciphers, the cipher itself handles the MAC with the correct order of Encrypt-then-MAC.

@georglauterbach
Copy link
Copy Markdown
Member

georglauterbach commented Feb 11, 2021

I'm not sure how relevant that is for the release notes? [...]
There's some extra details below, but I felt may not have added as much value to justify the verbosity?

Thanks for writing the log. I will look through it and decide what goes into the changelog and what does not:)

For tests, since CI on this PR passed, I just need to consider any tests to add?

I think one or two more tests which especially test the new changes are fine.

Should I add two self-signed certs? (RSA and ECDSA)
I could add a mix of variants? (separate keys and cert, bundled fullchain)
I can then add some tests for the different SSL_TYPE modes. Not sure about letsencrypt and ECDSA, but I could look into that?

We are, of course, always in the favor of more tests - but you said you were short on time. I guess doing what you deem appropriate for this PR is fine.

@georglauterbach georglauterbach changed the title FEAT: Use best practice cipher suites for 2021 Use best practice cipher suites for 2021 Feb 11, 2021
@polarathene
Copy link
Copy Markdown
Member Author

I've had a look through existing tests and see nothing specific to cipher suite testing or RSA/ECDSA. No additional tests are required, a future PR can contribute new tests that cover this area more thoroughly.

Likewise existing documentation doesn't appear to need any updating in regard to these changes AFAIK. I might have missed something on the wiki, I noticed some of the wiki is out of sync with the move to an organization too.

Should be fine to have this reviewed for merging now 👍


Last modified:

  • Postfix tls_high_cipherlist and Dovecot ssl_cipher_list (March 2018)
  • Postfix smtpd_tls_exclude_ciphers (April 2016)

This shouldn't require me to re-run my earlier tests which were part of my large WIP support document 😀

As that portion of the document is relevant to this PR, I am including it below in it's own comment. It is a far more detailed reference of the impact of this PR changes and some of the considerations that went into ensuring and verifying the security of the cipher list changes.

I have reviewed it once more with some minor edits, and realized that the release notes were missing some details, I've updated the terse version above.

Future PR should consider the following changes:

  • Port 25 STARTTLS could use the same TLS_LEVEL cipher lists? (There doesn't seem to be much benefit for the average MTA to support additional cipher suites, maybe you'd keep it on intermediate if needing broader MTA support than modern would allow)
  • The intermediate cipher list could be more consistent with it's sorting? (It's not entirely consistent with how it's prioritizing order, and with changes to modern it'd probably also benefit from prioritizing 128-bit over 256-bit, unclear why intermediate has ChaCha20-Poly1305 being forced over modern forcing AES-GCM for server preference)
  • At least for modern, it would make sense to enable client-side preference instead of server. This would probably get marked down incorrectly by certain audit testing sites.
  • An excessive TLS_LEVEL could be added if users prefer higher security scores/grades from testing sites vs understanding why it's considered excessive and negatively impacting other real world metrics?
  • Ideally we could adopt something like Docusaurus (maintained by facebook, dev demo) to generate a docs/wiki site based off the current wiki markdown (which presently is freely editable instead of going through a proper PR process).
    • This would be helpful as the wiki isn't included by a clone of the repo? Thus no results from wiki when performing searches through it's contents. I do recall pulling a copy of the wiki at one point.
    • I'll contribute this in future sometime if it's desirable (it could be hosted for free via github pages, vercel, netlify, etc).

@polarathene
Copy link
Copy Markdown
Member Author

polarathene commented Feb 12, 2021

Postfix + Dovecot cipher suite config overview

Quick overview of Postfix and Dovecot configuration related to the cipher suites and their relation to ports.

Summary:

  • While the intermediate and modern TLS_LEVEL cipher suites we assign are the same for both Postfix and Dovecot, only Postfix has an exclusion setting (smtpd_tls_exclude_ciphers), however that has no effect on our defined cipher suites as there are none that match the exclusion list, only the cipher suites on SMTP port 25 will match excludes, which at present does not use our custom cipher suite lists.
  • Any port that uses STARTTLS and requires authentication (110, 143, 587), has been configured to use mandatory TLS (Postfix enforces our high cipherlist defined by TLS_LEVEL) which will reject insecure connections (unable to negotiate a cipher suite). Thus only port 25 should technically differ in expectations.

Postfix config:

  • smtpd_tls_ciphers Opportunistic TLS only - Used only by Port 25 STARTTLS. It's default cipher suite list uses the Postfix medium cipher grade (a default list that may change with Postfix releases), TLS_LEVEL does not modify that cipher list.
  • smtpd_tls_mandatory_ciphers Mandatory TLS only - Used by implicit TLS port 465. Explicit TLS port 587 has also been configured for mandatory TLS instead of opportunistic. These connections use a cipher list defined by the Postfix high cipher grade, which TLS_LEVEL will replace with our own cipher list by modifying tls_high_cipherlist.
  • Thus our TLS_LEVEL ENV values intermediate and modern only affect the mandatory TLS cipher suite list (ports 465, 587), opportunistic TLS on port 25 is unaffected.
  • While only the cipher suites as configured in the previously mentioned options are allowed to be negotiated (ignoring >=TLS1.3 which doesn't support excluding cipher suites), Postfix supports excluding cipher suites that match values in smtpd_tls_exclude_ciphers; this setting affects all cipher grade lists. smtpd_tls_mandatory_exclude_ciphers provides additional control to only disallow cipher suites using mandatory TLS.
  • We only use smtpd_tls_exclude_ciphers, and it's relevance is only on the medium cipher suite list that port 25 uses, as none of the intermediate or modern cipher suites we explicitly define for tls_high_cipherlist match any of the exclusions.

Dovecot config:

  • Ports supporting STARTTLS (110, 143) are configured to enforce mandatory TLS.
  • Dovecot does not have separate cipher lists for opportunistic and mandatory TLS (not that it matters due to enforcing mandatory TLS). All ports (110, 143, 993, 995) are offering the same cipher suites via ssl_cipher_list.
  • Only supports assigning cipher suites to allow. There is no additional option for exclusions.

Cipher list comparisons

Upstream refers to results prior to applying the changes from this PR.

intermediate TLS_LEVEL <TLS 1.2 supported cipher suites (Upstream only)

Upstream cipher suites for TLS v1.0 and TLS v1.1 by ports/service
  • Output title lists service responsible for ports (Postfix or Dovecot), the relevant ports and TLS mode.
  • More than one port means they all provide the same output.
  • Output is from testssl.sh.

Postfix - Explicit TLS + Opportunistic STARTTLS (25 SMTP)

If no cipher suite can be negotiated, falls back to cleartext to ensure delivery.

Hexcode  Cipher Suite Name (OpenSSL)       KeyExch.   Encryption  Bits     Cipher Suite Name (IANA/RFC)
-----------------------------------------------------------------------------------------------------------------------------
SSLv2
 - 
SSLv3
 - 
TLSv1 (server order)
 xc013   ECDHE-RSA-AES128-SHA              ECDH 256   AES         128      TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA                 
 xc014   ECDHE-RSA-AES256-SHA              ECDH 256   AES         256      TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA                 
 x33     DHE-RSA-AES128-SHA                DH 4096    AES         128      TLS_DHE_RSA_WITH_AES_128_CBC_SHA                   
 x39     DHE-RSA-AES256-SHA                DH 4096    AES         256      TLS_DHE_RSA_WITH_AES_256_CBC_SHA                   
TLSv1.1 (server order)
 xc013   ECDHE-RSA-AES128-SHA              ECDH 256   AES         128      TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA                 
 xc014   ECDHE-RSA-AES256-SHA              ECDH 256   AES         256      TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA                 
 x33     DHE-RSA-AES128-SHA                DH 4096    AES         128      TLS_DHE_RSA_WITH_AES_128_CBC_SHA                   
 x39     DHE-RSA-AES256-SHA                DH 4096    AES         256      TLS_DHE_RSA_WITH_AES_256_CBC_SHA                   

Postfix - Implicit TLS (465 submissions) , Explicit TLS + Mandatory STARTTLS (587 submission)

(Same results as SMTP Port 25 results above)

Submitting mail to send to an address, requires authentication, configured to enforce TLS even on 587 STARTTLS, cleartext (unencrypted) transmission will be refused.

Hexcode  Cipher Suite Name (OpenSSL)       KeyExch.   Encryption  Bits     Cipher Suite Name (IANA/RFC)
-----------------------------------------------------------------------------------------------------------------------------
SSLv2
 - 
SSLv3
 - 
TLSv1 (server order)
 xc013   ECDHE-RSA-AES128-SHA              ECDH 256   AES         128      TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA                 
 xc014   ECDHE-RSA-AES256-SHA              ECDH 256   AES         256      TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA                 
 x33     DHE-RSA-AES128-SHA                DH 4096    AES         128      TLS_DHE_RSA_WITH_AES_128_CBC_SHA                   
 x39     DHE-RSA-AES256-SHA                DH 4096    AES         256      TLS_DHE_RSA_WITH_AES_256_CBC_SHA                   
TLSv1.1 (server order)
 xc013   ECDHE-RSA-AES128-SHA              ECDH 256   AES         128      TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA                 
 xc014   ECDHE-RSA-AES256-SHA              ECDH 256   AES         256      TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA                 
 x33     DHE-RSA-AES128-SHA                DH 4096    AES         128      TLS_DHE_RSA_WITH_AES_128_CBC_SHA                   
 x39     DHE-RSA-AES256-SHA                DH 4096    AES         256      TLS_DHE_RSA_WITH_AES_256_CBC_SHA                   

Dovecot - Implicit TLS (993 IMAPS, 995 POP3S), Explicit TLS + Mandatory STARTTLS (110 POP3, 143 IMAP)

Retrieve mail with a MUA client, no reason to accept cleartext, thus enforces mandatory TLS on ports offering STARTTLS - If a cipher suite cannot be negotiated, mail cannot be accessed/retrieved from inbox.

Hexcode  Cipher Suite Name (OpenSSL)       KeyExch.   Encryption  Bits     Cipher Suite Name (IANA/RFC)
-----------------------------------------------------------------------------------------------------------------------------
SSLv2
 - 
SSLv3
 - 
TLSv1 (server order)
 xc013   ECDHE-RSA-AES128-SHA              ECDH 256   AES         128      TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA                 
 xc014   ECDHE-RSA-AES256-SHA              ECDH 256   AES         256      TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA                 
 x33     DHE-RSA-AES128-SHA                DH 4096    AES         128      TLS_DHE_RSA_WITH_AES_128_CBC_SHA                   
 x39     DHE-RSA-AES256-SHA                DH 4096    AES         256      TLS_DHE_RSA_WITH_AES_256_CBC_SHA                   
 x2f     AES128-SHA                        RSA        AES         128      TLS_RSA_WITH_AES_128_CBC_SHA                       
 x35     AES256-SHA                        RSA        AES         256      TLS_RSA_WITH_AES_256_CBC_SHA                       
TLSv1.1 (server order)
 xc013   ECDHE-RSA-AES128-SHA              ECDH 256   AES         128      TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA                 
 xc014   ECDHE-RSA-AES256-SHA              ECDH 256   AES         256      TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA                 
 x33     DHE-RSA-AES128-SHA                DH 4096    AES         128      TLS_DHE_RSA_WITH_AES_128_CBC_SHA                   
 x39     DHE-RSA-AES256-SHA                DH 4096    AES         256      TLS_DHE_RSA_WITH_AES_256_CBC_SHA                   
 x2f     AES128-SHA                        RSA        AES         128      TLS_RSA_WITH_AES_128_CBC_SHA                       
 x35     AES256-SHA                        RSA        AES         256      TLS_RSA_WITH_AES_256_CBC_SHA                       

intermediate TLS_LEVEL differences for TLSv1.0 + TLSv1.1 (Upstream vs PR)

Additions / Removals:

  • +2 Postfix ECDHE-ECDSA-* cipher suites available when using ECDSA certs (ECDHE-ECDSA-AES128-SHA, ECDHE-ECDSA-AES256-SHA). Previously postfix ignored any ECDSA certs due to the upstream smtpd_tls_exclude_ciphers list.
  • -2 Dovecot RSA+AES cipher suites (AES128-SHA, AES256-SHA). These were applied in the allowed intermediate cipher lists setting in start-mailserver.sh, however Postfix excluded them with the RSA+AES rule in smtpd_tls_exclude_ciphers.
    • RSA key exchange should be avoided, if the private key is compromised, then any past recorded encrypted traffic could be decrypted with it. This is a non-issue with DHE/ECDHE key exchange cipher suites due to their use of ephemeral keys (unique per session).

testssl.sh report insights that can be ignored:

All TLSv1.0 and TLSv1.1 cipher suites we accept connections for are using CBC for message encryption. We cannot drop these from intermediate without removing support for TLSv1.0 and TLSv1.1.

Additional info regarding CBC cipher suite attacks (In particular Lucky13)

These cipher suites have had numerous vulnerabilities due to exploits with AES-CBC using padding oracle attacks (exploits timing information), however these types of attacks aren't as practical over a network if latency is too variable, and to my knowledge no known attack affects any of the mail protocols; many attacks are targeted for HTTP and require running code on the client (eg JS making many requests within a single session).

Cloudflare article on Lucky13 (2016 variant details these types of attacks better):

The good news is that our analysis of the newest vulnerability suggests that, while theoretically possible, it is fairly difficult to exploit. It is a timing attack and you'd need to create a fairly large number of connections and measure the differences in timing. That's possible, but non-trivial.

TLS hardening (July 2014) paper provides some additional insights:

Fortunately, Lucky 13 needs the attacker to temper with TLS traffic, which means it must be in a position to act as a Man in the Middle (MITM). And since it is a timing dependent attack, it requires a network connection with low jitter (jitter is the variation of latency), and a lot of requests to succeed and recover a session cookie. The risk is hence low for now. It can be lowered by limiting session cookie lifetime, or even better, by binding it to the number of requests done.

If we assume the client has not been updated, we can have server-side mitigation, by avoiding TLS session renegotiation

However there are other threats against clients, for which no server-side mitigation is available

We may assume timing variant workarounds to be implemented in the client, but we have no way to assess it is the case. Unfortunately, this client workaround, and the difficulty to run a Lucky 13 attack, are our only solutions against Lucky 13 until the day TLS 1.2 is universally supported.

intermediate TLS_LEVEL differences for TLSv1.2 - Parity with upstream, only added ECDSA support for Postfix

+7 Postfix new ECDSA cert enabled cipher suites (by appearance in server preference order):

ECDHE-ECDSA-CHACHA20-POLY1305
ECDHE-ECDSA-AES128-GCM-SHA256
ECDHE-ECDSA-AES256-GCM-SHA384
ECDHE-ECDSA-AES128-SHA256
ECDHE-ECDSA-AES128-SHA
ECDHE-ECDSA-AES256-SHA384
ECDHE-ECDSA-AES256-SHA

Postfix Port 25 TLSv1.2 cipher suites - Parity with upstream, only added ECDSA support for Postfix

9 TLS 1.2 cipher suites that TLS_LEVEL of intermediate and modern do not include (by appearance in server preference order):

  • Only Postfix port 25 provides these as it doesn't use either TLS_LEVEL list.
    • No difference from upstream, only additional cipher suites that port 25 currently accepts that other ports do not.
DHE-RSA-CHACHA20-POLY1305
DHE-RSA-AES256-CCM8
DHE-RSA-AES256-CCM
DHE-RSA-ARIA256-GCM-SHA384
ECDHE-ARIA256-GCM-SHA384
DHE-RSA-AES128-CCM8
DHE-RSA-AES128-CCM
DHE-RSA-ARIA128-GCM-SHA256
ECDHE-ARIA128-GCM-SHA256

+6 ECDHE-ECDSA-* cipher suites for Postfix port 25 on intermediate. The reason it's only 6 from the above list of 9 is due to:

  • ECDHE-ECDSA-CHACHA20-POLY1305 was already accounted for in the previous section.
  • DHE-ECDSA-* cipher suites don't exist.
  • ARIA256 and ARIA128 cipher suites above are paired with both DHE+RSA and ECDHE+RSA (ECDHE-ARIA* uses RSA for authentication algorithm). Thus the 4 cipher suites only have 2 ECDSA siblings (ECDHE+ECDSA with ARIA128-GCM-SHA256 and ARIA256-GCM-SHA256).
  • Leaving the other 4 ECDHE+ECDSA equivalents as AES128 and AES256 paired with both CCM and CCM8 cipher modes.

Asessment

  • DHE-RSA-CHACHA20-POLY1305 - It is unclear why this is omitted from both Mozilla and OWASP cipher suite lists, presumably because any modern client that would support it likely would choose ECDHE-ECDSA/ECDHE-RSA variants?
  • AES-CCM ciphers are AEAD, but have some weaknesses compared to ChaCha20-Poly1305 and AES-GCM. They're mostly useful for less capable hardware like embedded devices to use as alternative.
    • For example, a document scanner machine with built-in e-mail feature may prefer to use AES-CCM. It is one of the three ciphers supported in TLS v1.3, but generally disabled by default for security reasons.
  • ARIA-GCM cipher should be fine, the pairing with ARIA I cannot comment much on, other than that general advice seems to not bother with ARIA or CCM cipher suites. ARIA was a competing AES cipher but did not see as much support to stay relevant. No known weaknesses.

Leaving port 25 with a more relaxed cipher suite list should be fine, but it might be easier to maintain a single controlled list? (Despite the Postfix maintainer advising against customizing cipher lists)

intermediate vs modern TLS_LEVEL differences for TLSv1.2 (Upstream vs PR)

  • modern reduces the available supported cipher suites and differs slightly from Upstream vs this PR.
  • The cipher suite support has been tested as equivalent for all Postfix/Dovecot implicit & mandatory TLS ports. Thus only Port 25 is unaffected.

Upstream modern drops all DHE cipher suites, only supporting ECDHE as the key exchange. This PR retains two DHE cipher suites from upstream intermediate that are AEAD based (Mozilla's intermediate profile includes these for compatibility as a fallback):

DHE-RSA-AES256-GCM-SHA384
DHE-RSA-AES128-GCM-SHA256

Both upstream and this PR drop the following AES-CBC cipher suite support with modern (Upstream still includes AES-CBC cipher suites with SHA256 and SHA384 MAC, this PR additionally removes support for those):

ECDHE-RSA-AES256-SHA
DHE-RSA-AES256-SHA
ECDHE-RSA-AES128-SHA
DHE-RSA-AES128-SHA

TLS 1.2 introduced the SHA-2 family (of which SHA-256 and SHA-384 belong to) for HMACs which are preferable. No other SHA (aka SHA-1) cipher suites remain in modern after these are dropped.

These are all paired with AES block ciphers using CBC as a mode of operation. CBC seems to be avoided as a best practice due to the history of vulnerabilities related to cipher suites using that mode.

  • Only OpenSSL cipher suite names are shown here, the longer IANA names are more explicit with CBC in their cipher suite names, if it just says AES* with no associated mode of operation such as GCM or CCM, it's likely to be implicitly CBC.
Additional notes on MAC & SHA

The MAC specified in the cipher suite is often used with the given cipher for encryption (except AEAD ciphers which use a separate MAC internally), but beyond that it is also used elsewhere during the handshake process in TLS 1.2 for the PRF or the HKDF in TLS 1.3 (which replaces the PRF as stated in TLS 1.3 RFC 8446 - Section 7.5).

SHA-1 (1995) has been deprecated by NIST since 2011, it's insecure with a notable attack in 2017 (SHAttered).

Although in the context of TLS cipher suites, this vulnerability doesn't affect the integrity from SHA-1 usage as a MAC. The vulnerability could have been an issue with TLS certificates using SHA-1 in the signature algorithm, but those have been prohibited from being issued by CAs for a while now (and have nothing to do with cipher suites anyway).


AES-CBC changes in modern:

This PR drops the following from upstreams modern list:

ECDHE-ECDSA-AES256-SHA384
ECDHE-RSA-AES256-SHA384
ECDHE-ECDSA-AES128-SHA256
ECDHE-RSA-AES128-SHA256

EDIT: Previously this PR included the following 4 cipher suites at the end of the list due to referencing OWASP B (upstream modern lacked the DHE variants):

  • Note: DHE-RSA-AES256-SHA384 isn't a valid cipher suite, only DHE-RSA-AES256-SHA256 is (which has no ECDHE equivalent, only AES256-SHA384 or AES128-SHA256).
DHE-RSA-AES256-SHA256
DHE-RSA-AES128-SHA256
ECDHE-RSA-AES256-SHA384
ECDHE-RSA-AES128-SHA256

It has since been decided that modern should not support AES-CBC for better security practices. TLS v1.2 is already the required minimum for modern, AEAD cipher suites should be supported for negotiation.

Housekeeping:

intermediate has truncated the end of it's list where upstream appended the following ciphers that were always excluded and/or no longer supported by OpenSSL due to known vulnerabilities:

ECDHE-ECDSA-DES-CBC3-SHA
ECDHE-RSA-DES-CBC3-SHA
EDH-RSA-DES-CBC3-SHA
AES128-GCM-SHA256
AES256-GCM-SHA384
AES128-SHA256
AES256-SHA256
AES128-SHA
AES256-SHA
DES-CBC3-SHA
!DSS

This does affect Dovecot which previously allowed RSA key exchange (only available with an RSA certificate) with the above AES cipher suites. There should not be any reason to require kRSA for Dovecot. DHE or ECDHE are far better alternatives that should be supported by MUA clients.


Asessment

  • AES-GCM and ChaCha20-Poly1305 AEAD ciphers are great 👍
  • Other ciphers are less commonly supported. Don't provide by default to minimize potential risk 👍
  • RSA key exchange imposes risk 👎
  • AES-CBC as a cipher in TLS has multiple known weaknesses, even if most aren't presently practical 👎
  • ECDHE-ECDSA-AES256-SHA384 and ECDHE-ECDSA-AES128-SHA256 should be fine to add to add back AFAIK, unless we follow general advice to move away from cipher suites using CBC block ciphers (eg drop the 4 cipher suites from OWASP B, switching us to OWASP A grade list). (EDIT: Dropped support for AES-CBC in modern)
    • To my knowledge, at present there is no vulnerability or security risk if we choose to keep these cipher suites around for presumably broader compatibility.
    • It would seem that the AES-CBC ciphersuites are only available for older client support, which aren't likely to support these particular cipher suites, so minimizing their availability is preferred?
    • EDIT: Decision was to follow OWASP A and Mozilla Intermediate and ditch AES-CBC (especially since modern requires TLS 1.2 as a minimum).

Up to 17 ECDHE-ECDSA cipher suites now available, only 3 with modern when ignoring port 25:

Cipher suite lists Total TLS 1.2 TLS 1.1 TLS 1.0
Port 25 (Opportunistic) 17 13 2 2
intermediate 11 7 2 2
modern 3 3 N/A N/A

@polarathene
Copy link
Copy Markdown
Member Author

polarathene commented Feb 12, 2021

Another section from my WIP supporting document if it helps with the review. It's primarily informational about ciphers, informing the decision of what to have in modern and understanding the Postfix exclude list syntax and decisions.

Ciphers

  • AES - US Govenmernt / NIST (although from Dutch origins).
    • A list of reasons to prefer AES (compared against Camellia, but still insightful).
    • Security wise, only side-channel attacks have really been effective. Those tend to rely on implementation errors in software, AES is usually accelerated by hardware instructions that protect against such attacks. It can also depend on the Mode of Operation, and software implementations can slow down performance to better resist timing attacks.
  • Camellia - Japanese Government.
    • Similar to AES with some advantages in low-power (mentioned in RFC 4132) embedded environments. The algorithm is described in RFC 3713 (2004).
    • Introduced into TLS with RFC 4132 (2005) which was later obsoleted by RFC 5932 (2010) that additionally adds SHA-256 variants (only for TLS 1.2).
    • RFC 6367 (2011) adds GCM and PSK variants (min version of TLSv1 for PSK. GCM is AEAD, thus requires TLS 1.2), however OpenSSL does not add the GCM support as can be verified with openssl ciphers -s -V CAMELLIA.
    • No longer supported by Firefox or Chrome.
    • Firefox comments on their decision to drop Camellia support in 2015, citing similar reasons for GOST (Russian cipher). This aligns with Mozilla's guidelines choice to omit Camellia.
    • While Camellia can use hardware acceleration like AES, this StackExchange answer references a 2013 paper where AES-NI acceleration performance with Camellia vs AES shows Camellia as 4x slower.
  • ARIA - South Korean Government.
    • Like Camellia, it's similar to AES.
    • RFC 6209 (2011) introduces ARIA into TLS 1.2 (No specific TLS versions or extensions mentioned, min version was confirmed via openssl ciphers -s -V ARIA). Section 1.1 states since 2004 it has been widely used in Korea for encryption, especially for government-to-public services. (this document also references IETF gradually moving away from SHA-1 HMAC, so these cipher suites only support SHA-2 HMAC).
    • Some Oracle customers in South Korea only use ARIA with CBC mode in 2017 (later points out that ARIA was unrelated to communications with Oracle software)
    • ARIA-GCM cipher suite support arrived in 2017 for OpenSSL (but released in Sep 2018 OpenSSL 1.1.1). Note that OpenSSL does not support ARIA-CBC.
  • SEED - South Korean Government.
    • Introduced to TLS around 2005 with RFC 4162 (TLS 1.1 released in 2006). The RFC notes that SEED operates in CBC mode.
    • IE was a common browser to support SEED via an ActiveX plugin, as major TLS libs and web browsers often lacked support for SEED.
    • In 2015 it was announced to remove the ActiveX dependency from at least 90% of the countries top 100 websites by 2017. They reference prioritizing the private sector followed by public sector websites. Doesn't indicate that they're dropping SEED, just the ActiveX dependency, perhaps via WASM as an alternative or something.
    • Also supported by the standard for S/MIME (e-mail encryption).

Availability of AES-CCM, Camellia, ARIA, SEED, ChaCha20-Poly1305

Many TLS implementations do not support AES-CCM, Camellia, ARIA, SEED:

  • OpenSSL 1.1.0 (Aug 2016) excludes these ciphers from the DEFAULT cipher list (also when AES-CCM support arrived). That doesn't prevent them from being usable with Postfix and Dovecot.
  • Windows and OSX / macOS native TLS implementations lack support. Both OS platforms lack native support for ChaCha20-Poly1305 too (although that's fine as they'll benefit from AES-GCM with AES-NI).
    • Some software such as web browsers may package their own TLS implementations internally.
    • OpenSSL can be supported on both platforms.
  • Mbed (from ARM, popular TLS library choice for embedded hardware) notably has support for all these ciphers except SEED.

Thus server support for these ciphers is less useful. Potentially AES-CCM is worthwhile for embedded products (eg scanners/printers).

Camellia, ARIA, SEED may be used by other MTAs, but are only likely to be encountered within their respective origin regions, perhaps mostly from government services or private sector?

  • It would be assumed they support ciphers commonly used internationally as well, or that any MTA using this project would be aware that they need to support these ciphers (potentially requiring them for mandatory TLS and MUA clients too).
  • If following OWASP and Mozilla TLS guidelines, these could be ignored by default.
  • Supported ciphers in TLS 1.3 (which by default with OpenSSL does not offer CCM), may also influence that stance to omit such ciphers going forward.

Insecure Ciphers

Since OpenSSL 1.0.2h and 1.1.0 (Aug 2016), OpenSSL default builds do not include RC4 or 3DES cipher suites. They can only be enabled with the enable-weak-ssl-ciphers build option.

  • 3DES, old cipher that was commonly used (often prioritized over RC4 in server order preference).
    • NIST deprecated it in 2017, Microsoft in Dec 2018, OpenSSL support dropped in 2016 to an opt-in compile time option.
    • Notable vulnerability that affected 3DES (and other ciphers that offer a block size of 64 bits or less) was Sweet32 in 2016, although it isn't particularly practical to carry out (requires long lived TLS connection) with HTTPS or VPNs being viable targets, SMTP not so much AFAIK.
  • RC4, another popular and widely implemented cipher. It was notable as one of the only stream ciphers available in TLS, which provided immunity to the BEAST vulnerability in 2011. RC4 has not always been implemented correctly and there has been notable attacks on exploiting this cipher algorithm.
    • The use of RC4 in TLS is prohibited by RFC 7465 (Feb 2015).

Block Ciphers - Modes of Operation

AEAD Stream Cipher - ChaCha20-Poly1305

  • An AEAD stream cipher commonly used as a fallback to AES-GCM, both of which are the only default ciphers in TLS 1.3 (AES-CCM requires application opt-in, at least with OpenSSL)
  • Added to TLS 1.2 with RFC 7905 (2016).
  • Supported by OpenSSL 1.1.0 (2016).
  • When HW accel support from AES-NI is unavailable, this AEAD cipher is said to perform 3x faster than AES-GCM. Support should be fairly common on mobile devices.
ChaCha20-Poly1305 - Additonal details

In 2014 Google added ChaCha20-Poly1305 to Android Chrome as it's highest priority cipher choice, it efficiently leverages CPU vector instructions to achieve a 3x perf advantage over AES-GCM (when lacking hardware acceleration support, AES-NI).

  • At the time AES-NI support was uncommon on mobile devices.

HW accel for AES arrived with ARMv8-A which IPhone5S in late 2013 was the first device, with Android devices arriving around late 2014 onwards.

  • It is however an optional feature. Even in 2020, budget devices such as Android Go phones can be found still using ARMv8-A Cortex 53 cores in their SoC and lacking AES-NI. Thus this alternative AEAD cipher remains relevant today.

This covers the history of ChaCha20-Poly1305 well.

Performance

In Feb 2019, a developer for Amazon's TLS implementation s2n looked into server preference with client prioritization support, linking to a benchmark gist (using OpenSSL) against AES256-GCM with and without AES-NI support.

  • They note ChaCha20-Poly1305 is only ~80% of the speed of AES256-GCM using AES-NI. AES256-GCM without AES-NI however declined to ~20% of the AES-NI speed, giving ChaCha20-Poly1305 4x the perf advantage when AES-NI is not available.
  • I shared my own results on that issue which differ a bit, but maintains roughly the same performance ratio software AES256-GCM has to ChaCha-Poly1305.

Compared to AES

This discussion notes that AES prioritizes performance/efficiency in hardware implementations, while ChaCha20 is designed for efficiency within software and being easy to implement at the expense of not being as suitable for further acceleration via dedicated hardware (ASICs).

  • Some additional technical details between the two compared here.
  • ChaCha20 is safer to implement, especially within software where AES-GCM can be prone to mistakes risking security (software implementations for AES-GCM usually have to decrease performance further to avoid vulnerability to certain attacks as a result).

Prioritization support over other cipher suites when using server order preference

If your supported cipher suites have no disadvantage/risk to necessitate server order preference; It would be better to let the client hint their preference instead. Should be ok with our TLS_LEVEL modern cipher list.


Postfix cipher suite exclusion rules

OpenSSL docs clarify the syntax accepted for smtpd_tls_exclude_ciphers:

  • LOW, MEDIUM, HIGH are cipher suites grouped by how many bits of encryption are offered.
    • MEDIUM contains 128-bit ciphers.
    • HIGH is for ciphersuites offering more than 128 bits.
    • LOW is no longer relevant, those were all removed as of OpenSSL 1.1.0 (Aug 2016).
  • aNULL cipher suites that offer no authentication.
  • eNULL cipher suites that offer no encryption.
  • RSA is an alias for kRSA, usage of RSA for key-exchange. aRSA refers to authentication (an RSA certificate).
  • AES cipher suites that use either 128-bit and 256-bit AES for encryption, can be more specific with AES128 or AES256. RSA+AES only applies to cipher suites that use RSA as a key exchange and AES for encrytion.
  • AESCCM likewise matches cipher suites using AES-CCM for encryption. CCM has 16 and 8 octet variants but only seems to offer AESCCM8 as a variant.

@polarathene

This comment has been minimized.

Checks that results from `testssl.sh` are valid.
Ports 587, 465, 143, 993, 110, 995 all share the same cipher lists.
DRY-ing up some code.
All ports can now be tested via single method including port 25.

`KEY_TYPE` and `TLS_LEVEL` in the `check_ports()` function overrides variable scope, and child function calls share that scope not requiring passing down as additional parameters.

Still requires running multiple `testssl.sh` runs to cover each combinatino of `KEY_TYPE` and `TLS_LEVEL`, along with corresponding `mailserver-testing:ci` instances.
Remaining change to support testing combinations of `KEY_TYPE` and `TLS_LEVEL` by running `testssl.sh` and `mailserver-testing:ci` containers per test case.
Running the `testssl.sh` container with `--user "0:0"` (root) is a problem as the CI user is unable to remove written files afterwards for cleanup (lacks permissions as root has more authority).

Tried a different approach that should work better by using the current users uid and gid.
The `docker` process itself is being run as root, so volume mounts are still creating directories with root ownership. This can be avoided when the directories already exist.

Added `cd` commands for supporting `testssl.sh` outside of docker, if it's switched to that. `|| exit` is from `shellcheck` linting suggestion when using `cd`.

`rm -rf` had it's shared variable path swapped for hard-coded path, just as an added precaution due to risk that command can impose on a user running tests locally.
Doesn't seem to be a problem with `testssl.sh` but pulling the image in advance.

`jq` pulling it's image was triggering failure for `assert_output` which is only interested in `jq` command not anything else caught by `stdout`..

`jq` is now an expected dependency to perform tests.
@polarathene
Copy link
Copy Markdown
Member Author

Tests are finally working for all combinations. Let me know if I've done it right as this was my first time (I must say writing unit tests in bash added a fair bit of friction to the process).

Both jq and testssl.sh are currently run via docker images, I can add a commit to switch jq to native binary, but I think it's important to discuss about doing the same for testssl.sh (submodule of the git repo?).


Presently testssl.sh 3.1-dev is used, this isn't a static version of the script but includes a bunch of changes since the 3.0 release from some time ago IIRC, eventually a 3.2 release is expected. With Docker images I can specify an image digest for the tag instead which is a more reliable way of having a consistent version of 3.1-dev being run (for docker, instead of the current 3.1-dev tag which updates often), though I doubt it'll cause any stability issues for how it's being used.

The docker image has the benefits of using the docker daemons internal DNS so that I can reach the mail container via DNS query to example.test (a network alias on a custom docker network that both containers share). That can be useful for properly testing a certificate locally matches the given SAN it was provisioned for, but is not required for this set of tests.

Without that, we could use IP addresses instead, and I can recreate the certs to include an IP address that we assign the mailserver-testing:ci docker container with to use, unclear at this point if there is much value in doing so. I tested with a docker network assigned a subnet (which turned out to be required for specifying a container IP), performance went from 9 minute test run to 2 hours, seems to be a networking bug/issue within Docker. We can just expose ports and use localhost. testssl.sh outside of docker will require some additional logic to create and switch between directories for it's output.

testssl.sh native performance is about 90-100 seconds to test a port instead of 200-220 seconds (~400 sec when parallelized across all ports via --file <filename> --mode --parallel). jq native vs docker, I'm seeing it's runtime go from 8 seconds to 61 seconds.

I can probably reduce the scope of the testssl.sh command which might help reduce total test time. Alternatively, for this particular set of tests, now that the logic is all in place perhaps testssl.sh could be replaced with something else if there are faster options, or the tests could later be improved to extract the other data from testssl.sh to catch security concerns.


Test time (22 minutes) via my VPS instance (Vultr Ubuntu 20.10 $5/month):
$ ./test/bats/bin/bats -T test/mail_ssl_cipherlists.bats
 - first (skipped: This version natively supports setup/teardown_file)
 ✓ checking tls: cipher list - rsa intermediate [416sec]
 ✓ checking tls: cipher list - rsa modern [349sec]
 ✓ checking tls: cipher list - ecdsa intermediate [314sec]
 ✓ checking tls: cipher list - ecdsa modern [262sec]
 - last (skipped: this test is only there to reliably mark the end for the teardown_file)

6 tests, 0 failures, 2 skipped in 1341 seconds

@georglauterbach georglauterbach removed the pr/missing integration tests This PR lacks tests label Feb 17, 2021
@georglauterbach
Copy link
Copy Markdown
Member

LGTM

Copy link
Copy Markdown
Member

@wernerfred wernerfred left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm honest with you I do not get every point of your changes. I quickly looked over the tests in a logical manner and it looks good in my opinion.
As the tests pass I think we can merge.

For a deeper inspection and style review i need more time (but can be done later)

@polarathene
Copy link
Copy Markdown
Member Author

I'm honest with you I do not get every point of your changes.

Could you be more specific? And I'll do my best to elaborate more clearly.


If you're referring to the tests, all that happens is ${KEY_TYPE}(rsa or ecdsa certificate) is tested against it's ${TLS_LEVEL} (intermediate and modern) profiles. Every port should produce the same results except for port 25 (as presently we only influence that with smtpd_tls_exclude_ciphers, modern and intermediate should not have any difference on port 25).

We could enforce our ${TLS_LEVEL} profiles on port 25 as well if you like, originally I was asked not to tamper with anything but modern cipher suite support. If we do this ARIA and CCM cipher suites will be removed, I don't personally see this being a problem (I've detailed why above when sharing my notes on ciphers).

Removing those ciphers would also have the benefit of removing RSA key exchange support (which I could better enforce by adjusting the smtpd_tls_exclude_ciphers, if permitted to alter the supported cipher suites) that lacks Forward Secrecy (DHE and ECDHE provide this via ephemeral session keys, RSA for key exchange does not have unique session keys, anyone who compromises the server and gets the private key could decrypt past recorded or future session data).


Beyond that, testssl.sh is run against each port (defined in the file it's --file option references which defines filenames to save to as well, using --mode parallel to speed up the testing process), each is output to a port_p<port #>.json file in a /tmp/results/<key_type>/<tls_level>/ directory.

These json files contain extensive testing data, if you'd like a more human friendly version, I would suggest running testssl.sh yourself via terminal against the mail server container or any website and the terminal output (stdout) will be much easier to analyze and digest. Here's an example for port 25:

Docker local test setup example:

Create a user-defined network, this allows for internal DNS between containers, allowing for a container to be reached by it's container name or alias: docker network create test-network.

Bring up the mail container (assumes project root directory, just like when running bats tests, otherwise replace ${PWD} appropriately):

docker run -d --name tls_test_cipherlists \
  --volume "${PWD}/test/duplicate_configs/security_tls_cipherlists.bats/:/tmp/docker-mailserver/" \
  --volume "${PWD}/test/test-files/ssl/example.test/:/config/ssl/:ro" \
  --env DMS_DEBUG=0 \
  --env SSL_TYPE="manual" \
  --env SSL_CERT_PATH="/config/ssl/cert.rsa.pem" \
  --env SSL_KEY_PATH="/config/ssl/key.rsa.pem" \
  --env TLS_LEVEL="intermediate" \
  --hostname "mail.example.test" \
  --tty \
  --network test-network \
  --network-alias "example.test" \
  mailserver-testing:ci

Run testssl.sh against the mail container (or instead of setting up the mail container and network, you could just run this against a public website like https://github.com instead):

mkdir -p "/tmp/results/rsa/intermediate" && \
docker run --rm \
  --user "$(id -u):$(id -g)" \
  --network test-network \
  --volume "/tmp/results/rsa/intermediate/:/output" \
  --workdir /output \
  drwetter/testssl.sh:3.1dev --jsonfile-pretty port_25.json --logfile  port_25.txt --color 0 --starttls smtp example.test:25

When testssl.sh is finished, check /tmp/results/rsa/intermediate/port_25.txt for results.


testssl.sh text log for port 25 - rsa intermediate

Shell output (colour highlighting stripped via --color 0):

## Scan started as: "testssl.sh --jsonfile-pretty port_25.json --logfile port_25.txt --color 0 --starttls smtp example.test:25"
## at b8c80034bf0a:/home/testssl/bin/openssl.Linux.x86_64
## version testssl: 3.1dev  from 
## version openssl: "1.0.2-chacha" from "Jan 18 17:12:17 2019")

 Start 2021-02-17 22:36:47        -->> 172.30.0.2:25 (example.test) <<--

 rDNS (172.30.0.2):      tls_test_cipherlists.test-network.
 Service set:            STARTTLS via SMTP

 Testing protocols via sockets 

 SSLv2      not offered (OK)
 SSLv3      not offered (OK)
 TLS 1      offered (deprecated)
 TLS 1.1    offered (deprecated)
 TLS 1.2    offered (OK)
 TLS 1.3    offered (OK): final

 Testing cipher categories 

 NULL ciphers (no encryption)                      not offered (OK)
 Anonymous NULL Ciphers (no authentication)        not offered (OK)
 Export ciphers (w/o ADH+NULL)                     not offered (OK)
 LOW: 64 Bit + DES, RC[2,4], MD5 (w/o export)      not offered (OK)
 Triple DES Ciphers / IDEA                         not offered
 Obsoleted CBC ciphers (AES, ARIA etc.)            offered
 Strong encryption (AEAD ciphers) with no FS       offered (OK)
 Forward Secrecy strong encryption (AEAD ciphers)  offered (OK)


 Testing server's cipher preferences 

 Has server cipher order?     yes (OK) -- TLS 1.3 and below
 Negotiated protocol          TLSv1.3
 Negotiated cipher            TLS_AES_256_GCM_SHA384, 253 bit ECDH (X25519)
 Cipher per protocol

Hexcode  Cipher Suite Name (OpenSSL)       KeyExch.   Encryption  Bits     Cipher Suite Name (IANA/RFC)
-----------------------------------------------------------------------------------------------------------------------------
SSLv2
 - 
SSLv3
 - 
TLSv1 (server order)
 xc014   ECDHE-RSA-AES256-SHA              ECDH 256   AES         256      TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA                 
 x39     DHE-RSA-AES256-SHA                DH 4096    AES         256      TLS_DHE_RSA_WITH_AES_256_CBC_SHA                   
 xc013   ECDHE-RSA-AES128-SHA              ECDH 256   AES         128      TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA                 
 x33     DHE-RSA-AES128-SHA                DH 4096    AES         128      TLS_DHE_RSA_WITH_AES_128_CBC_SHA                   
TLSv1.1 (server order)
 xc014   ECDHE-RSA-AES256-SHA              ECDH 256   AES         256      TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA                 
 x39     DHE-RSA-AES256-SHA                DH 4096    AES         256      TLS_DHE_RSA_WITH_AES_256_CBC_SHA                   
 xc013   ECDHE-RSA-AES128-SHA              ECDH 256   AES         128      TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA                 
 x33     DHE-RSA-AES128-SHA                DH 4096    AES         128      TLS_DHE_RSA_WITH_AES_128_CBC_SHA                   
TLSv1.2 (server order)
 xc030   ECDHE-RSA-AES256-GCM-SHA384       ECDH 253   AESGCM      256      TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384              
 x9f     DHE-RSA-AES256-GCM-SHA384         DH 4096    AESGCM      256      TLS_DHE_RSA_WITH_AES_256_GCM_SHA384                
 xcca8   ECDHE-RSA-CHACHA20-POLY1305       ECDH 253   ChaCha20    256      TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256        
 xccaa   DHE-RSA-CHACHA20-POLY1305         DH 4096    ChaCha20    256      TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256          
 xc0a3   DHE-RSA-AES256-CCM8               DH 4096    AESCCM8     256      TLS_DHE_RSA_WITH_AES_256_CCM_8                     
 xc09f   DHE-RSA-AES256-CCM                DH 4096    AESCCM      256      TLS_DHE_RSA_WITH_AES_256_CCM                       
 xc061   ECDHE-ARIA256-GCM-SHA384          ECDH 253   ARIAGCM     256      TLS_ECDHE_RSA_WITH_ARIA_256_GCM_SHA384             
 xc053   DHE-RSA-ARIA256-GCM-SHA384        DH 4096    ARIAGCM     256      TLS_DHE_RSA_WITH_ARIA_256_GCM_SHA384               
 xc028   ECDHE-RSA-AES256-SHA384           ECDH 253   AES         256      TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384              
 x6b     DHE-RSA-AES256-SHA256             DH 4096    AES         256      TLS_DHE_RSA_WITH_AES_256_CBC_SHA256                
 xc014   ECDHE-RSA-AES256-SHA              ECDH 253   AES         256      TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA                 
 x39     DHE-RSA-AES256-SHA                DH 4096    AES         256      TLS_DHE_RSA_WITH_AES_256_CBC_SHA                   
 xc051   ARIA256-GCM-SHA384                RSA        ARIAGCM     256      TLS_RSA_WITH_ARIA_256_GCM_SHA384                   
 xc02f   ECDHE-RSA-AES128-GCM-SHA256       ECDH 253   AESGCM      128      TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256              
 x9e     DHE-RSA-AES128-GCM-SHA256         DH 4096    AESGCM      128      TLS_DHE_RSA_WITH_AES_128_GCM_SHA256                
 xc0a2   DHE-RSA-AES128-CCM8               DH 4096    AESCCM8     128      TLS_DHE_RSA_WITH_AES_128_CCM_8                     
 xc09e   DHE-RSA-AES128-CCM                DH 4096    AESCCM      128      TLS_DHE_RSA_WITH_AES_128_CCM                       
 xc060   ECDHE-ARIA128-GCM-SHA256          ECDH 253   ARIAGCM     128      TLS_ECDHE_RSA_WITH_ARIA_128_GCM_SHA256             
 xc052   DHE-RSA-ARIA128-GCM-SHA256        DH 4096    ARIAGCM     128      TLS_DHE_RSA_WITH_ARIA_128_GCM_SHA256               
 xc027   ECDHE-RSA-AES128-SHA256           ECDH 253   AES         128      TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256              
 x67     DHE-RSA-AES128-SHA256             DH 4096    AES         128      TLS_DHE_RSA_WITH_AES_128_CBC_SHA256                
 xc013   ECDHE-RSA-AES128-SHA              ECDH 253   AES         128      TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA                 
 x33     DHE-RSA-AES128-SHA                DH 4096    AES         128      TLS_DHE_RSA_WITH_AES_128_CBC_SHA                   
 xc050   ARIA128-GCM-SHA256                RSA        ARIAGCM     128      TLS_RSA_WITH_ARIA_128_GCM_SHA256                   
TLSv1.3 (server order)
 x1302   TLS_AES_256_GCM_SHA384            ECDH 253   AESGCM      256      TLS_AES_256_GCM_SHA384                             
 x1303   TLS_CHACHA20_POLY1305_SHA256      ECDH 253   ChaCha20    256      TLS_CHACHA20_POLY1305_SHA256                       
 x1301   TLS_AES_128_GCM_SHA256            ECDH 253   AESGCM      128      TLS_AES_128_GCM_SHA256                             


 Testing robust forward secrecy (FS) -- omitting Null Authentication/Encryption, 3DES, RC4 

 FS is offered (OK)           TLS_AES_256_GCM_SHA384
                              TLS_CHACHA20_POLY1305_SHA256
                              ECDHE-RSA-AES256-GCM-SHA384
                              ECDHE-RSA-AES256-SHA384 ECDHE-RSA-AES256-SHA
                              DHE-RSA-AES256-GCM-SHA384
                              ECDHE-RSA-CHACHA20-POLY1305
                              DHE-RSA-CHACHA20-POLY1305 DHE-RSA-AES256-CCM8
                              DHE-RSA-AES256-CCM DHE-RSA-AES256-SHA256
                              DHE-RSA-AES256-SHA DHE-RSA-ARIA256-GCM-SHA384
                              ECDHE-ARIA256-GCM-SHA384 TLS_AES_128_GCM_SHA256
                              ECDHE-RSA-AES128-GCM-SHA256
                              ECDHE-RSA-AES128-SHA256 ECDHE-RSA-AES128-SHA
                              DHE-RSA-AES128-GCM-SHA256 DHE-RSA-AES128-CCM8
                              DHE-RSA-AES128-CCM DHE-RSA-AES128-SHA256
                              DHE-RSA-AES128-SHA DHE-RSA-ARIA128-GCM-SHA256
                              ECDHE-ARIA128-GCM-SHA256 
 Elliptic curves offered:     prime256v1 secp384r1 secp521r1 X25519 X448 
 DH group offered:            ffdhe4096

 Testing server defaults (Server Hello) 

 TLS extensions (standard)    "renegotiation info/#65281"
                              "EC point formats/#11" "session ticket/#35"
                              "supported versions/#43" "key share/#51"
                              "supported_groups/#10" "max fragment length/#1"
                              "encrypt-then-mac/#22"
                              "extended master secret/#23"
 Session Ticket RFC 5077 hint 7200 seconds, session tickets keys seems to be rotated < daily
 SSL Session ID support       yes
 Session Resumption           Tickets: yes, ID: no
 TLS clock skew               Random values, no fingerprinting possible 
 Client Authentication        none
 Signature Algorithm          SHA256 with RSA
 Server key size              RSA 2048 bits (exponent is 65537)
 Server key usage             Digital Signature, Key Encipherment
 Server extended key usage    TLS Web Server Authentication, TLS Web Client Authentication
 Serial / Fingerprints        9CF42A11521763A5A0FBD1CEDB085F33 / SHA1 9D6A770D287245F2D19513493761429E2AD89619
                              SHA256 C2E3D67194D5AD96458CE3143698E89D3E8C3CBA87C7B9B3E3B67641A6948498
 Common Name (CN)             Smallstep self-signed 
 subjectAltName (SAN)         example.test mail.example.test 
 Trust (hostname)             Ok via SAN (same w/o SNI)
 Chain of trust               NOT ok (chain incomplete)
 EV cert (experimental)       no 
 Certificate Validity (UTC)   3604 >= 60 days (2021-01-01 00:00 --> 2031-01-01 00:00)
                              >= 10 years is way too long
 ETS/"eTLS", visibility info  not present
 Certificate Revocation List  --
 OCSP URI                     --
                              NOT ok -- neither CRL nor OCSP URI provided
 OCSP stapling                not offered
 OCSP must staple extension   --
 DNS CAA RR (experimental)    not offered
 Certificate Transparency     N/A
 Certificates provided        1
 Issuer                       Smallstep self-signed
 Intermediate Bad OCSP (exp.) Ok


 Testing vulnerabilities 

 Heartbleed (CVE-2014-0160)                not vulnerable (OK), no heartbeat extension
 CCS (CVE-2014-0224)                       not vulnerable (OK)
 ROBOT                                     not vulnerable (OK)
 Secure Renegotiation (RFC 5746)           supported (OK)
 Secure Client-Initiated Renegotiation     not vulnerable (OK)
 CRIME, TLS (CVE-2012-4929)                not vulnerable (OK) (not using HTTP anyway)
 POODLE, SSL (CVE-2014-3566)               not vulnerable (OK), no SSLv3 support
 TLS_FALLBACK_SCSV (RFC 7507)              Downgrade attack prevention supported (OK)
 SWEET32 (CVE-2016-2183, CVE-2016-6329)    not vulnerable (OK)
 FREAK (CVE-2015-0204)                     not vulnerable (OK)
 DROWN (CVE-2016-0800, CVE-2016-0703)      not vulnerable on this host and port (OK)
                                           make sure you don't use this certificate elsewhere with SSLv2 enabled services
                                           https://censys.io/ipv4?q=C2E3D67194D5AD96458CE3143698E89D3E8C3CBA87C7B9B3E3B67641A6948498 could help you to find out
 LOGJAM (CVE-2015-4000), experimental      common prime with 4096 bits detected: RFC7919/ffdhe4096 (4096 bits),
                                           but no DH EXPORT ciphers
 BEAST (CVE-2011-3389)                     TLS1: ECDHE-RSA-AES256-SHA
                                                 DHE-RSA-AES256-SHA
                                                 ECDHE-RSA-AES128-SHA
                                                 DHE-RSA-AES128-SHA 
                                           VULNERABLE -- but also supports higher protocols  TLSv1.1 TLSv1.2 (likely mitigated)
 LUCKY13 (CVE-2013-0169), experimental     potentially VULNERABLE, uses cipher block chaining (CBC) ciphers with TLS. Check patches
 Winshock (CVE-2014-6321), experimental    not vulnerable (OK)
 RC4 (CVE-2013-2566, CVE-2015-2808)        no RC4 ciphers detected (OK)
 STARTTLS injection (experimental)         not vulnerable (OK)


 Running client simulations via sockets 

 Browser                      Protocol  Cipher Suite Name (OpenSSL)       Forward Secrecy
------------------------------------------------------------------------------------------------
 Android 8.1 (native)         TLSv1.2   ECDHE-RSA-AES256-GCM-SHA384       253 bit ECDH (X25519)
 Android 9.0 (native)         TLSv1.3   TLS_AES_256_GCM_SHA384            253 bit ECDH (X25519)
 Android 10.0 (native)        TLSv1.3   TLS_AES_256_GCM_SHA384            253 bit ECDH (X25519)
 Java 6u45                    No connection
 Java 7u25                    TLSv1.0   ECDHE-RSA-AES128-SHA              256 bit ECDH (P-256)
 Java 8u161                   TLSv1.2   ECDHE-RSA-AES256-GCM-SHA384       256 bit ECDH (P-256)
 Java 11.0.2 (OpenJDK)        TLSv1.3   TLS_AES_256_GCM_SHA384            256 bit ECDH (P-256)
 Java 12.0.1 (OpenJDK)        TLSv1.3   TLS_AES_256_GCM_SHA384            256 bit ECDH (P-256)
 OpenSSL 1.0.2e               TLSv1.2   ECDHE-RSA-AES256-GCM-SHA384       256 bit ECDH (P-256)
 OpenSSL 1.1.0l (Debian)      TLSv1.2   ECDHE-RSA-AES256-GCM-SHA384       253 bit ECDH (X25519)
 OpenSSL 1.1.1d (Debian)      TLSv1.3   TLS_AES_256_GCM_SHA384            253 bit ECDH (X25519)


 Rating (experimental) 

 Rating specs (not complete)  SSL Labs's 'SSL Server Rating Guide' (version 2009q from 2020-01-30)
 Specification documentation  https://github.com/ssllabs/research/wiki/SSL-Server-Rating-Guide
 Protocol Support (weighted)  0 (0)
 Key Exchange     (weighted)  0 (0)
 Cipher Strength  (weighted)  0 (0)
 Final Score                  0
 Overall Grade                T
 Grade cap reasons            Grade capped to T. Issues with the chain of trust (chain incomplete)
                              Grade capped to T. Encryption via STARTTLS is not mandatory (opportunistic).
                              Grade capped to B. TLS 1.1 offered
                              Grade capped to B. TLS 1.0 offered

 Done 2021-02-17 22:40:11 [ 206s] -->> 172.30.0.2:25 (example.test) <<--

Terminal output with colour variant (cat this document in a terminal to view with syntax highlighting): testssl.sh text log for port 25 - rsa intermediate

Shell output:

## Scan started as: "testssl.sh --jsonfile-pretty port_25.json --logfile port_25.txt --starttls smtp example.test:25"
## at 85f9e108f9d3:/home/testssl/bin/openssl.Linux.x86_64
## version testssl: 3.1dev  from 
## version openssl: "1.0.2-chacha" from "Jan 18 17:12:17 2019")

�[7m Start 2021-02-17 22:26:08        -->> 172.30.0.2:25 (example.test) <<--�[m

 rDNS (172.30.0.2):      tls_test_cipherlists.test-network.
 Service set:            STARTTLS via SMTP

�[1m�[4m Testing protocols �[m�[4mvia sockets �[m

�[1m SSLv2      �[m�[1;32mnot offered (OK)�[m
�[1m SSLv3      �[m�[1;32mnot offered (OK)�[m
�[1m TLS 1      �[m�[1;33moffered�[m (deprecated)
�[1m TLS 1.1    �[m�[1;33moffered�[m (deprecated)
�[1m TLS 1.2    �[m�[1;32moffered (OK)�[m
�[1m TLS 1.3    �[m�[1;32moffered (OK)�[m: final

�[1m�[4m Testing cipher categories �[m

�[1m NULL ciphers (no encryption)                      �[m�[1;32mnot offered (OK)�[m
�[1m Anonymous NULL Ciphers (no authentication)        �[m�[1;32mnot offered (OK)�[m
�[1m Export ciphers (w/o ADH+NULL)                     �[m�[1;32mnot offered (OK)�[m
�[1m LOW: 64 Bit + DES, RC[2,4], MD5 (w/o export)      �[m�[0;32mnot offered (OK)�[m
�[1m Triple DES Ciphers / IDEA                         �[mnot offered
�[1m Obsoleted CBC ciphers (AES, ARIA etc.)            �[m�[1;33moffered�[m
�[1m Strong encryption (AEAD ciphers) with no FS       �[m�[0;32moffered (OK)�[m
�[1m Forward Secrecy strong encryption (AEAD ciphers)  �[m�[1;32moffered (OK)�[m


�[1m�[4m Testing server's cipher preferences �[m

�[1m Has server cipher order?     �[m�[1;32myes (OK)�[m -- TLS 1.3 and below
�[1m Negotiated protocol          �[m�[1;32mTLSv1.3�[m
�[1m Negotiated cipher            �[m�[1;32mTLS_AES_256_GCM_SHA384�[m, �[0;32m253 bit ECDH (X25519)�[m
�[1m Cipher per protocol�[m

Hexcode  Cipher Suite Name (OpenSSL)       KeyExch.   Encryption  Bits     Cipher Suite Name (IANA/RFC)
-----------------------------------------------------------------------------------------------------------------------------
�[4mSSLv2�[m
 - 
�[4mSSLv3�[m
 - 
�[4mTLSv1�[m (server order)
 xc014   ECDHE-RSA-AES256-SHA              ECDH�[0;32m 256�[m   AES         256      TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA                 
 x39     DHE-RSA-AES256-SHA                DH�[0;32m 4096�[m    AES         256      TLS_DHE_RSA_WITH_AES_256_CBC_SHA                   
 xc013   ECDHE-RSA-AES128-SHA              ECDH�[0;32m 256�[m   AES         128      TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA                 
 x33     DHE-RSA-AES128-SHA                DH�[0;32m 4096�[m    AES         128      TLS_DHE_RSA_WITH_AES_128_CBC_SHA                   
�[4mTLSv1.1�[m (server order)
 xc014   ECDHE-RSA-AES256-SHA              ECDH�[0;32m 256�[m   AES         256      TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA                 
 x39     DHE-RSA-AES256-SHA                DH�[0;32m 4096�[m    AES         256      TLS_DHE_RSA_WITH_AES_256_CBC_SHA                   
 xc013   ECDHE-RSA-AES128-SHA              ECDH�[0;32m 256�[m   AES         128      TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA                 
 x33     DHE-RSA-AES128-SHA                DH�[0;32m 4096�[m    AES         128      TLS_DHE_RSA_WITH_AES_128_CBC_SHA                   
�[4mTLSv1.2�[m (server order)
 xc030   ECDHE-RSA-AES256-GCM-SHA384       ECDH�[0;32m 253�[m   AESGCM      256      TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384              
 x9f     DHE-RSA-AES256-GCM-SHA384         DH�[0;32m 4096�[m    AESGCM      256      TLS_DHE_RSA_WITH_AES_256_GCM_SHA384                
 xcca8   ECDHE-RSA-CHACHA20-POLY1305       ECDH�[0;32m 253�[m   ChaCha20    256      TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256        
 xccaa   DHE-RSA-CHACHA20-POLY1305         DH�[0;32m 4096�[m    ChaCha20    256      TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256          
 xc0a3   DHE-RSA-AES256-CCM8               DH�[0;32m 4096�[m    AESCCM8     256      TLS_DHE_RSA_WITH_AES_256_CCM_8                     
 xc09f   DHE-RSA-AES256-CCM                DH�[0;32m 4096�[m    AESCCM      256      TLS_DHE_RSA_WITH_AES_256_CCM                       
 xc061   ECDHE-ARIA256-GCM-SHA384          ECDH�[0;32m 253�[m   ARIAGCM     256      TLS_ECDHE_RSA_WITH_ARIA_256_GCM_SHA384             
 xc053   DHE-RSA-ARIA256-GCM-SHA384        DH�[0;32m 4096�[m    ARIAGCM     256      TLS_DHE_RSA_WITH_ARIA_256_GCM_SHA384               
 xc028   ECDHE-RSA-AES256-SHA384           ECDH�[0;32m 253�[m   AES         256      TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384              
 x6b     DHE-RSA-AES256-SHA256             DH�[0;32m 4096�[m    AES         256      TLS_DHE_RSA_WITH_AES_256_CBC_SHA256                
 xc014   ECDHE-RSA-AES256-SHA              ECDH�[0;32m 253�[m   AES         256      TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA                 
 x39     DHE-RSA-AES256-SHA                DH�[0;32m 4096�[m    AES         256      TLS_DHE_RSA_WITH_AES_256_CBC_SHA                   
 xc051   ARIA256-GCM-SHA384                RSA        ARIAGCM     256      TLS_RSA_WITH_ARIA_256_GCM_SHA384                   
 xc02f   ECDHE-RSA-AES128-GCM-SHA256       ECDH�[0;32m 253�[m   AESGCM      128      TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256              
 x9e     DHE-RSA-AES128-GCM-SHA256         DH�[0;32m 4096�[m    AESGCM      128      TLS_DHE_RSA_WITH_AES_128_GCM_SHA256                
 xc0a2   DHE-RSA-AES128-CCM8               DH�[0;32m 4096�[m    AESCCM8     128      TLS_DHE_RSA_WITH_AES_128_CCM_8                     
 xc09e   DHE-RSA-AES128-CCM                DH�[0;32m 4096�[m    AESCCM      128      TLS_DHE_RSA_WITH_AES_128_CCM                       
 xc060   ECDHE-ARIA128-GCM-SHA256          ECDH�[0;32m 253�[m   ARIAGCM     128      TLS_ECDHE_RSA_WITH_ARIA_128_GCM_SHA256             
 xc052   DHE-RSA-ARIA128-GCM-SHA256        DH�[0;32m 4096�[m    ARIAGCM     128      TLS_DHE_RSA_WITH_ARIA_128_GCM_SHA256               
 xc027   ECDHE-RSA-AES128-SHA256           ECDH�[0;32m 253�[m   AES         128      TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256              
 x67     DHE-RSA-AES128-SHA256             DH�[0;32m 4096�[m    AES         128      TLS_DHE_RSA_WITH_AES_128_CBC_SHA256                
 xc013   ECDHE-RSA-AES128-SHA              ECDH�[0;32m 253�[m   AES         128      TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA                 
 x33     DHE-RSA-AES128-SHA                DH�[0;32m 4096�[m    AES         128      TLS_DHE_RSA_WITH_AES_128_CBC_SHA                   
 xc050   ARIA128-GCM-SHA256                RSA        ARIAGCM     128      TLS_RSA_WITH_ARIA_128_GCM_SHA256                   
�[4mTLSv1.3�[m (server order)
 x1302   TLS_AES_256_GCM_SHA384            ECDH�[0;32m 253�[m   AESGCM      256      TLS_AES_256_GCM_SHA384                             
 x1303   TLS_CHACHA20_POLY1305_SHA256      ECDH�[0;32m 253�[m   ChaCha20    256      TLS_CHACHA20_POLY1305_SHA256                       
 x1301   TLS_AES_128_GCM_SHA256            ECDH�[0;32m 253�[m   AESGCM      128      TLS_AES_128_GCM_SHA256                             


�[1m�[4m Testing robust forward secrecy (FS)�[m�[4m -- omitting Null Authentication/Encryption, 3DES, RC4 �[m

�[0;32m FS is offered (OK) �[m          TLS_AES_256_GCM_SHA384
                              TLS_CHACHA20_POLY1305_SHA256
                              ECDHE-RSA-AES256-GCM-SHA384
                              ECDHE-RSA-AES256-SHA384 ECDHE-RSA-AES256-SHA
                              DHE-RSA-AES256-GCM-SHA384
                              ECDHE-RSA-CHACHA20-POLY1305
                              DHE-RSA-CHACHA20-POLY1305 DHE-RSA-AES256-CCM8
                              DHE-RSA-AES256-CCM DHE-RSA-AES256-SHA256
                              DHE-RSA-AES256-SHA DHE-RSA-ARIA256-GCM-SHA384
                              ECDHE-ARIA256-GCM-SHA384 TLS_AES_128_GCM_SHA256
                              ECDHE-RSA-AES128-GCM-SHA256
                              ECDHE-RSA-AES128-SHA256 ECDHE-RSA-AES128-SHA
                              DHE-RSA-AES128-GCM-SHA256 DHE-RSA-AES128-CCM8
                              DHE-RSA-AES128-CCM DHE-RSA-AES128-SHA256
                              DHE-RSA-AES128-SHA DHE-RSA-ARIA128-GCM-SHA256
                              ECDHE-ARIA128-GCM-SHA256 
�[1m Elliptic curves offered:     �[m�[0;32mprime256v1�[m �[0;32msecp384r1�[m �[0;32msecp521r1�[m �[0;32mX25519�[m �[0;32mX448�[m 
�[1m DH group offered:            �[m�[0;32mffdhe4096�[m

�[1m�[4m Testing server defaults (Server Hello) �[m

�[1m TLS extensions (standard)    �[m"renegotiation info/#65281"
                              "EC point formats/#11" "session ticket/#35"
                              "supported versions/#43" "key share/#51"
                              "supported_groups/#10" "max fragment length/#1"
                              "encrypt-then-mac/#22"
                              "extended master secret/#23"
�[1m Session Ticket RFC 5077 hint �[m7200 seconds, session tickets keys seems to be rotated < daily
�[1m SSL Session ID support       �[myes
�[1m Session Resumption           �[mTickets: yes, ID: no
�[1m TLS clock skew�[m               Random values, no fingerprinting possible 
�[1m Client Authentication        �[mnone
�[1m Signature Algorithm          �[m�[0;32mSHA256 with RSA�[m
�[1m Server key size              �[mRSA 2048 bits (exponent is 65537)
�[1m Server key usage             �[mDigital Signature, Key Encipherment
�[1m Server extended key usage    �[mTLS Web Server Authentication, TLS Web Client Authentication
�[1m Serial / Fingerprints        �[m9CF42A11521763A5A0FBD1CEDB085F33 / SHA1 9D6A770D287245F2D19513493761429E2AD89619
                              SHA256 C2E3D67194D5AD96458CE3143698E89D3E8C3CBA87C7B9B3E3B67641A6948498
�[1m Common Name (CN)             �[m�[3mSmallstep self-signed �[m
�[1m subjectAltName (SAN)         �[m�[3mexample.test mail.example.test �[m
�[1m Trust (hostname)             �[m�[0;32mOk via SAN�[m (same w/o SNI)
�[1m Chain of trust�[m               �[1;31mNOT ok�[m (chain incomplete)
�[1m EV cert�[m (experimental)       no 
�[1m Certificate Validity (UTC)   �[m�[0;32m3604 >= 60 days�[m (2021-01-01 00:00 --> 2031-01-01 00:00)
                              �[0;31m>= 10 years is way too long�[m
�[1m ETS/"eTLS"�[m, visibility info  not present
�[1m Certificate Revocation List  �[m--
�[1m OCSP URI                     �[m--
                              �[0;31mNOT ok --�[m neither CRL nor OCSP URI provided
�[1m OCSP stapling                �[mnot offered
�[1m OCSP must staple extension   �[m--
�[1m DNS CAA RR�[m (experimental)    �[1;33mnot offered�[m
�[1m Certificate Transparency     �[mN/A
�[1m Certificates provided�[m        1
�[1m Issuer                       �[m�[3mSmallstep self-signed�[m
�[1m Intermediate Bad OCSP�[m (exp.) �[0;32mOk�[m


�[1m�[4m Testing vulnerabilities �[m

�[1m Heartbleed�[m (CVE-2014-0160)                �[1;32mnot vulnerable (OK)�[m, no heartbeat extension
�[1m CCS�[m (CVE-2014-0224)                       �[1;32mnot vulnerable (OK)�[m
�[1m ROBOT                                     �[m�[1;32mnot vulnerable (OK)�[m
�[1m Secure Renegotiation (RFC 5746)           �[m�[1;32msupported (OK)�[m
�[1m Secure Client-Initiated Renegotiation     �[m�[0;32mnot vulnerable (OK)�[m
�[1m CRIME, TLS �[m(CVE-2012-4929)                �[0;32mnot vulnerable (OK)�[m (not using HTTP anyway)
�[1m POODLE, SSL�[m (CVE-2014-3566)               �[1;32mnot vulnerable (OK)�[m, no SSLv3 support
�[1m TLS_FALLBACK_SCSV�[m (RFC 7507)              �[0;32mDowngrade attack prevention supported (OK)�[m
�[1m SWEET32�[m (CVE-2016-2183, CVE-2016-6329)    �[1;32mnot vulnerable (OK)�[m
�[1m FREAK�[m (CVE-2015-0204)                     �[1;32mnot vulnerable (OK)�[m
�[1m DROWN�[m (CVE-2016-0800, CVE-2016-0703)      �[1;32mnot vulnerable on this host and port (OK)�[m
                                           make sure you don't use this certificate elsewhere with SSLv2 enabled services
                                           https://censys.io/ipv4?q=C2E3D67194D5AD96458CE3143698E89D3E8C3CBA87C7B9B3E3B67641A6948498 could help you to find out
�[1m LOGJAM�[m (CVE-2015-4000), experimental      common prime with 4096 bits detected: �[3mRFC7919/ffdhe4096�[m (�[0;32m4096 bits�[m),
                                           but no DH EXPORT ciphers
�[1m BEAST�[m (CVE-2011-3389)                     TLS1: �[1;33mECDHE-RSA-AES256-SHA
                                                 DHE-RSA-AES256-SHA
                                                 ECDHE-RSA-AES128-SHA
                                                 DHE-RSA-AES128-SHA �[m
                                           �[1;33mVULNERABLE�[m -- but also supports higher protocols  TLSv1.1 TLSv1.2 (likely mitigated)
�[1m LUCKY13�[m (CVE-2013-0169), experimental     potentially �[1;33mVULNERABLE�[m, uses cipher block chaining (CBC) ciphers with TLS. Check patches
�[1m Winshock�[m (CVE-2014-6321), experimental    �[1;32mnot vulnerable (OK)�[m
�[1m RC4�[m (CVE-2013-2566, CVE-2015-2808)        �[0;32mno RC4 ciphers detected (OK)�[m
�[1m STARTTLS injection�[m (experimental)         �[0;32mnot vulnerable (OK)�[m


�[1m�[4m Running client simulations �[m�[1m�[4mvia sockets �[m

 Browser                      Protocol  Cipher Suite Name (OpenSSL)       Forward Secrecy
------------------------------------------------------------------------------------------------
 Android 8.1 (native)         TLSv1.2   ECDHE-RSA-AES256-GCM-SHA384       �[0;32m253 bit ECDH (X25519)�[m
 Android 9.0 (native)         TLSv1.3   TLS_AES_256_GCM_SHA384            �[0;32m253 bit ECDH (X25519)�[m
 Android 10.0 (native)        TLSv1.3   TLS_AES_256_GCM_SHA384            �[0;32m253 bit ECDH (X25519)�[m
 Java 6u45                    No connection
 Java 7u25                    TLSv1.0   ECDHE-RSA-AES128-SHA              �[0;32m256 bit ECDH (P-256)�[m
 Java 8u161                   TLSv1.2   ECDHE-RSA-AES256-GCM-SHA384       �[0;32m256 bit ECDH (P-256)�[m
 Java 11.0.2 (OpenJDK)        TLSv1.3   TLS_AES_256_GCM_SHA384            �[0;32m256 bit ECDH (P-256)�[m
 Java 12.0.1 (OpenJDK)        TLSv1.3   TLS_AES_256_GCM_SHA384            �[0;32m256 bit ECDH (P-256)�[m
 OpenSSL 1.0.2e               TLSv1.2   ECDHE-RSA-AES256-GCM-SHA384       �[0;32m256 bit ECDH (P-256)�[m
 OpenSSL 1.1.0l (Debian)      TLSv1.2   ECDHE-RSA-AES256-GCM-SHA384       �[0;32m253 bit ECDH (X25519)�[m
 OpenSSL 1.1.1d (Debian)      TLSv1.3   TLS_AES_256_GCM_SHA384            �[0;32m253 bit ECDH (X25519)�[m


�[1m�[4m Rating (experimental) �[m

�[1m Rating specs�[m (not complete)  SSL Labs's 'SSL Server Rating Guide' (version 2009q from 2020-01-30)
�[1m Specification documentation  �[mhttps://github.com/ssllabs/research/wiki/SSL-Server-Rating-Guide
�[1m Protocol Support�[m (weighted)  0 (0)
�[1m Key Exchange�[m     (weighted)  0 (0)
�[1m Cipher Strength�[m  (weighted)  0 (0)
�[1m Final Score                  �[m0
�[1m Overall Grade                �[m�[1;31mT�[m
�[1m Grade cap reasons            �[mGrade capped to T. Issues with the chain of trust (chain incomplete)
                              Grade capped to T. Encryption via STARTTLS is not mandatory (opportunistic).
                              Grade capped to B. TLS 1.1 offered
                              Grade capped to B. TLS 1.0 offered

�[7m Done 2021-02-17 22:29:50 [ 225s] -->> 172.30.0.2:25 (example.test) <<--�[m

testssl.sh json log for port 25 - rsa intermediate

JSON output:

{
          "Invocation"  : "testssl.sh --jsonfile-pretty port_25.json --logfile port_25.txt --starttls smtp example.test:25",
          "at"          : "85f9e108f9d3:/home/testssl/bin/openssl.Linux.x86_64",
          "version"     : "3.1dev ",
          "openssl"     : "OpenSSL 1.0.2-chacha from Jan 18 17:12:17 2019",
          "startTime"   : "1613600765",
          "scanResult"  : [
          {
                    "targetHost"      : "example.test",
                    "ip"              : "172.30.0.2",
                    "port"            : "25",
                    "rDNS"            : "tls_test_cipherlists.test-network.",
                    "service"         : "smtp",
                    "pretest"           : [
                            {
                                "id"           : "pre_128cipher",
                                "severity"     : "INFO",
                                "finding"      : "No 128 cipher limit bug"
                           }
                    ],
                    "protocols"         : [
                            {
                                "id"           : "SSLv2",
                                "severity"     : "OK",
                                "finding"      : "not offered"
                           },{
                                "id"           : "SSLv3",
                                "severity"     : "OK",
                                "finding"      : "not offered"
                           },{
                                "id"           : "TLS1",
                                "severity"     : "LOW",
                                "finding"      : "offered (deprecated)"
                           },{
                                "id"           : "TLS1_1",
                                "severity"     : "LOW",
                                "finding"      : "offered (deprecated)"
                           },{
                                "id"           : "TLS1_2",
                                "severity"     : "OK",
                                "finding"      : "offered"
                           },{
                                "id"           : "TLS1_3",
                                "severity"     : "OK",
                                "finding"      : "offered with final"
                           }
                    ],
                    "grease"            : [

                    ],
                    "ciphers"           : [
                            {
                                "id"           : "cipherlist_NULL",
                                "severity"     : "OK",
                                "cwe"          : "CWE-327",
                                "finding"      : "not offered"
                           },{
                                "id"           : "cipherlist_aNULL",
                                "severity"     : "OK",
                                "cwe"          : "CWE-327",
                                "finding"      : "not offered"
                           },{
                                "id"           : "cipherlist_EXPORT",
                                "severity"     : "OK",
                                "cwe"          : "CWE-327",
                                "finding"      : "not offered"
                           },{
                                "id"           : "cipherlist_LOW",
                                "severity"     : "OK",
                                "cwe"          : "CWE-327",
                                "finding"      : "not offered"
                           },{
                                "id"           : "cipherlist_3DES_IDEA",
                                "severity"     : "INFO",
                                "cwe"          : "CWE-310",
                                "finding"      : "not offered"
                           },{
                                "id"           : "cipherlist_AVERAGE",
                                "severity"     : "LOW",
                                "cwe"          : "CWE-310",
                                "finding"      : "offered"
                           },{
                                "id"           : "cipherlist_GOOD",
                                "severity"     : "OK",
                                "finding"      : "offered"
                           },{
                                "id"           : "cipherlist_STRONG",
                                "severity"     : "OK",
                                "finding"      : "offered"
                           }
                    ],
                    "fs"                : [
                            {
                                "id"           : "cipher_order",
                                "severity"     : "OK",
                                "finding"      : "server"
                           },{
                                "id"           : "protocol_negotiated",
                                "severity"     : "OK",
                                "finding"      : "Default protocol TLS1.3"
                           },{
                                "id"           : "cipher_negotiated",
                                "severity"     : "OK",
                                "finding"      : "TLS_AES_256_GCM_SHA384, 253 bit ECDH (X25519)"
                           },{
                                "id"           : "cipher-tls1_xc014",
                                "severity"     : "LOW",
                                "finding"      : "TLSv1   xc014   ECDHE-RSA-AES256-SHA              ECDH 256   AES         256      TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA"
                           },{
                                "id"           : "cipher-tls1_x39",
                                "severity"     : "LOW",
                                "finding"      : "TLSv1   x39     DHE-RSA-AES256-SHA                DH 4096    AES         256      TLS_DHE_RSA_WITH_AES_256_CBC_SHA"
                           },{
                                "id"           : "cipher-tls1_xc013",
                                "severity"     : "LOW",
                                "finding"      : "TLSv1   xc013   ECDHE-RSA-AES128-SHA              ECDH 256   AES         128      TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA"
                           },{
                                "id"           : "cipher-tls1_x33",
                                "severity"     : "LOW",
                                "finding"      : "TLSv1   x33     DHE-RSA-AES128-SHA                DH 4096    AES         128      TLS_DHE_RSA_WITH_AES_128_CBC_SHA"
                           },{
                                "id"           : "cipherorder_TLSv1",
                                "severity"     : "INFO",
                                "finding"      : "ECDHE-RSA-AES256-SHA DHE-RSA-AES256-SHA ECDHE-RSA-AES128-SHA DHE-RSA-AES128-SHA"
                           },{
                                "id"           : "cipher-tls1_1_xc014",
                                "severity"     : "LOW",
                                "finding"      : "TLSv1.1   xc014   ECDHE-RSA-AES256-SHA              ECDH 256   AES         256      TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA"
                           },{
                                "id"           : "cipher-tls1_1_x39",
                                "severity"     : "LOW",
                                "finding"      : "TLSv1.1   x39     DHE-RSA-AES256-SHA                DH 4096    AES         256      TLS_DHE_RSA_WITH_AES_256_CBC_SHA"
                           },{
                                "id"           : "cipher-tls1_1_xc013",
                                "severity"     : "LOW",
                                "finding"      : "TLSv1.1   xc013   ECDHE-RSA-AES128-SHA              ECDH 256   AES         128      TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA"
                           },{
                                "id"           : "cipher-tls1_1_x33",
                                "severity"     : "LOW",
                                "finding"      : "TLSv1.1   x33     DHE-RSA-AES128-SHA                DH 4096    AES         128      TLS_DHE_RSA_WITH_AES_128_CBC_SHA"
                           },{
                                "id"           : "cipherorder_TLSv1_1",
                                "severity"     : "INFO",
                                "finding"      : "ECDHE-RSA-AES256-SHA DHE-RSA-AES256-SHA ECDHE-RSA-AES128-SHA DHE-RSA-AES128-SHA"
                           },{
                                "id"           : "cipher-tls1_2_xc030",
                                "severity"     : "OK",
                                "finding"      : "TLSv1.2   xc030   ECDHE-RSA-AES256-GCM-SHA384       ECDH 253   AESGCM      256      TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384"
                           },{
                                "id"           : "cipher-tls1_2_x9f",
                                "severity"     : "OK",
                                "finding"      : "TLSv1.2   x9f     DHE-RSA-AES256-GCM-SHA384         DH 4096    AESGCM      256      TLS_DHE_RSA_WITH_AES_256_GCM_SHA384"
                           },{
                                "id"           : "cipher-tls1_2_xcca8",
                                "severity"     : "OK",
                                "finding"      : "TLSv1.2   xcca8   ECDHE-RSA-CHACHA20-POLY1305       ECDH 253   ChaCha20    256      TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256"
                           },{
                                "id"           : "cipher-tls1_2_xccaa",
                                "severity"     : "OK",
                                "finding"      : "TLSv1.2   xccaa   DHE-RSA-CHACHA20-POLY1305         DH 4096    ChaCha20    256      TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256"
                           },{
                                "id"           : "cipher-tls1_2_xc0a3",
                                "severity"     : "OK",
                                "finding"      : "TLSv1.2   xc0a3   DHE-RSA-AES256-CCM8               DH 4096    AESCCM8     256      TLS_DHE_RSA_WITH_AES_256_CCM_8"
                           },{
                                "id"           : "cipher-tls1_2_xc09f",
                                "severity"     : "OK",
                                "finding"      : "TLSv1.2   xc09f   DHE-RSA-AES256-CCM                DH 4096    AESCCM      256      TLS_DHE_RSA_WITH_AES_256_CCM"
                           },{
                                "id"           : "cipher-tls1_2_xc061",
                                "severity"     : "OK",
                                "finding"      : "TLSv1.2   xc061   ECDHE-ARIA256-GCM-SHA384          ECDH 253   ARIAGCM     256      TLS_ECDHE_RSA_WITH_ARIA_256_GCM_SHA384"
                           },{
                                "id"           : "cipher-tls1_2_xc053",
                                "severity"     : "OK",
                                "finding"      : "TLSv1.2   xc053   DHE-RSA-ARIA256-GCM-SHA384        DH 4096    ARIAGCM     256      TLS_DHE_RSA_WITH_ARIA_256_GCM_SHA384"
                           },{
                                "id"           : "cipher-tls1_2_xc028",
                                "severity"     : "LOW",
                                "finding"      : "TLSv1.2   xc028   ECDHE-RSA-AES256-SHA384           ECDH 253   AES         256      TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384"
                           },{
                                "id"           : "cipher-tls1_2_x6b",
                                "severity"     : "LOW",
                                "finding"      : "TLSv1.2   x6b     DHE-RSA-AES256-SHA256             DH 4096    AES         256      TLS_DHE_RSA_WITH_AES_256_CBC_SHA256"
                           },{
                                "id"           : "cipher-tls1_2_xc014",
                                "severity"     : "LOW",
                                "finding"      : "TLSv1.2   xc014   ECDHE-RSA-AES256-SHA              ECDH 253   AES         256      TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA"
                           },{
                                "id"           : "cipher-tls1_2_x39",
                                "severity"     : "LOW",
                                "finding"      : "TLSv1.2   x39     DHE-RSA-AES256-SHA                DH 4096    AES         256      TLS_DHE_RSA_WITH_AES_256_CBC_SHA"
                           },{
                                "id"           : "cipher-tls1_2_xc051",
                                "severity"     : "OK",
                                "finding"      : "TLSv1.2   xc051   ARIA256-GCM-SHA384                RSA        ARIAGCM     256      TLS_RSA_WITH_ARIA_256_GCM_SHA384"
                           },{
                                "id"           : "cipher-tls1_2_xc02f",
                                "severity"     : "OK",
                                "finding"      : "TLSv1.2   xc02f   ECDHE-RSA-AES128-GCM-SHA256       ECDH 253   AESGCM      128      TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"
                           },{
                                "id"           : "cipher-tls1_2_x9e",
                                "severity"     : "OK",
                                "finding"      : "TLSv1.2   x9e     DHE-RSA-AES128-GCM-SHA256         DH 4096    AESGCM      128      TLS_DHE_RSA_WITH_AES_128_GCM_SHA256"
                           },{
                                "id"           : "cipher-tls1_2_xc0a2",
                                "severity"     : "OK",
                                "finding"      : "TLSv1.2   xc0a2   DHE-RSA-AES128-CCM8               DH 4096    AESCCM8     128      TLS_DHE_RSA_WITH_AES_128_CCM_8"
                           },{
                                "id"           : "cipher-tls1_2_xc09e",
                                "severity"     : "OK",
                                "finding"      : "TLSv1.2   xc09e   DHE-RSA-AES128-CCM                DH 4096    AESCCM      128      TLS_DHE_RSA_WITH_AES_128_CCM"
                           },{
                                "id"           : "cipher-tls1_2_xc060",
                                "severity"     : "OK",
                                "finding"      : "TLSv1.2   xc060   ECDHE-ARIA128-GCM-SHA256          ECDH 253   ARIAGCM     128      TLS_ECDHE_RSA_WITH_ARIA_128_GCM_SHA256"
                           },{
                                "id"           : "cipher-tls1_2_xc052",
                                "severity"     : "OK",
                                "finding"      : "TLSv1.2   xc052   DHE-RSA-ARIA128-GCM-SHA256        DH 4096    ARIAGCM     128      TLS_DHE_RSA_WITH_ARIA_128_GCM_SHA256"
                           },{
                                "id"           : "cipher-tls1_2_xc027",
                                "severity"     : "LOW",
                                "finding"      : "TLSv1.2   xc027   ECDHE-RSA-AES128-SHA256           ECDH 253   AES         128      TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256"
                           },{
                                "id"           : "cipher-tls1_2_x67",
                                "severity"     : "LOW",
                                "finding"      : "TLSv1.2   x67     DHE-RSA-AES128-SHA256             DH 4096    AES         128      TLS_DHE_RSA_WITH_AES_128_CBC_SHA256"
                           },{
                                "id"           : "cipher-tls1_2_xc013",
                                "severity"     : "LOW",
                                "finding"      : "TLSv1.2   xc013   ECDHE-RSA-AES128-SHA              ECDH 253   AES         128      TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA"
                           },{
                                "id"           : "cipher-tls1_2_x33",
                                "severity"     : "LOW",
                                "finding"      : "TLSv1.2   x33     DHE-RSA-AES128-SHA                DH 4096    AES         128      TLS_DHE_RSA_WITH_AES_128_CBC_SHA"
                           },{
                                "id"           : "cipher-tls1_2_xc050",
                                "severity"     : "OK",
                                "finding"      : "TLSv1.2   xc050   ARIA128-GCM-SHA256                RSA        ARIAGCM     128      TLS_RSA_WITH_ARIA_128_GCM_SHA256"
                           },{
                                "id"           : "cipherorder_TLSv1_2",
                                "severity"     : "INFO",
                                "finding"      : "ECDHE-RSA-AES256-GCM-SHA384 DHE-RSA-AES256-GCM-SHA384 ECDHE-RSA-CHACHA20-POLY1305 DHE-RSA-CHACHA20-POLY1305 DHE-RSA-AES256-CCM8 DHE-RSA-AES256-CCM ECDHE-ARIA256-GCM-SHA384 DHE-RSA-ARIA256-GCM-SHA384 ECDHE-RSA-AES256-SHA384 DHE-RSA-AES256-SHA256 ECDHE-RSA-AES256-SHA DHE-RSA-AES256-SHA ARIA256-GCM-SHA384 ECDHE-RSA-AES128-GCM-SHA256 DHE-RSA-AES128-GCM-SHA256 DHE-RSA-AES128-CCM8 DHE-RSA-AES128-CCM ECDHE-ARIA128-GCM-SHA256 DHE-RSA-ARIA128-GCM-SHA256 ECDHE-RSA-AES128-SHA256 DHE-RSA-AES128-SHA256 ECDHE-RSA-AES128-SHA DHE-RSA-AES128-SHA ARIA128-GCM-SHA256"
                           },{
                                "id"           : "cipher-tls1_3_x1302",
                                "severity"     : "OK",
                                "finding"      : "TLSv1.3   x1302   TLS_AES_256_GCM_SHA384            ECDH 253   AESGCM      256      TLS_AES_256_GCM_SHA384"
                           },{
                                "id"           : "cipher-tls1_3_x1303",
                                "severity"     : "OK",
                                "finding"      : "TLSv1.3   x1303   TLS_CHACHA20_POLY1305_SHA256      ECDH 253   ChaCha20    256      TLS_CHACHA20_POLY1305_SHA256"
                           },{
                                "id"           : "cipher-tls1_3_x1301",
                                "severity"     : "OK",
                                "finding"      : "TLSv1.3   x1301   TLS_AES_128_GCM_SHA256            ECDH 253   AESGCM      128      TLS_AES_128_GCM_SHA256"
                           },{
                                "id"           : "cipherorder_TLSv1_3",
                                "severity"     : "INFO",
                                "finding"      : "TLS_AES_256_GCM_SHA384 TLS_CHACHA20_POLY1305_SHA256 TLS_AES_128_GCM_SHA256"
                           }
                    ],
                    "serverPreferences" : [
                            {
                                "id"           : "FS",
                                "severity"     : "OK",
                                "finding"      : "offered"
                           },{
                                "id"           : "FS_ciphers",
                                "severity"     : "INFO",
                                "finding"      : "TLS_AES_256_GCM_SHA384 TLS_CHACHA20_POLY1305_SHA256 ECDHE-RSA-AES256-GCM-SHA384 ECDHE-RSA-AES256-SHA384 ECDHE-RSA-AES256-SHA DHE-RSA-AES256-GCM-SHA384 ECDHE-RSA-CHACHA20-POLY1305 DHE-RSA-CHACHA20-POLY1305 DHE-RSA-AES256-CCM8 DHE-RSA-AES256-CCM DHE-RSA-AES256-SHA256 DHE-RSA-AES256-SHA DHE-RSA-ARIA256-GCM-SHA384 ECDHE-ARIA256-GCM-SHA384 TLS_AES_128_GCM_SHA256 ECDHE-RSA-AES128-GCM-SHA256 ECDHE-RSA-AES128-SHA256 ECDHE-RSA-AES128-SHA DHE-RSA-AES128-GCM-SHA256 DHE-RSA-AES128-CCM8 DHE-RSA-AES128-CCM DHE-RSA-AES128-SHA256 DHE-RSA-AES128-SHA DHE-RSA-ARIA128-GCM-SHA256 ECDHE-ARIA128-GCM-SHA256"
                           },{
                                "id"           : "FS_ECDHE_curves",
                                "severity"     : "OK",
                                "finding"      : "prime256v1 secp384r1 secp521r1 X25519 X448"
                           },{
                                "id"           : "DH_groups",
                                "severity"     : "OK",
                                "finding"      : "ffdhe4096"
                           }
                    ],
                    "serverDefaults"    : [
                            {
                                "id"           : "TLS_extensions",
                                "severity"     : "INFO",
                                "finding"      : "'renegotiation info/#65281' 'EC point formats/#11' 'session ticket/#35' 'supported versions/#43' 'key share/#51' 'supported_groups/#10' 'max fragment length/#1' 'encrypt-then-mac/#22' 'extended master secret/#23'"
                           },{
                                "id"           : "TLS_session_ticket",
                                "severity"     : "INFO",
                                "finding"      : "valid for 7200 seconds only (<daily)"
                           },{
                                "id"           : "SSL_sessionID_support",
                                "severity"     : "INFO",
                                "finding"      : "yes"
                           },{
                                "id"           : "sessionresumption_ticket",
                                "severity"     : "INFO",
                                "finding"      : "supported"
                           },{
                                "id"           : "sessionresumption_ID",
                                "severity"     : "INFO",
                                "finding"      : "not supported"
                           },{
                                "id"           : "TLS_timestamp",
                                "severity"     : "INFO",
                                "finding"      : "random"
                           },{
                                "id"           : "clientAuth",
                                "severity"     : "INFO",
                                "finding"      : "none"
                           },{
                                "id"           : "cert_numbers",
                                "severity"     : "INFO",
                                "finding"      : "1"
                           },{
                                "id"           : "cert_signatureAlgorithm",
                                "severity"     : "OK",
                                "finding"      : "SHA256 with RSA"
                           },{
                                "id"           : "cert_keySize",
                                "severity"     : "INFO",
                                "finding"      : "RSA 2048 bits (exponent is 65537)"
                           },{
                                "id"           : "cert_keyUsage",
                                "severity"     : "INFO",
                                "finding"      : "Digital Signature, Key Encipherment"
                           },{
                                "id"           : "cert_extKeyUsage",
                                "severity"     : "INFO",
                                "finding"      : "TLS Web Server Authentication, TLS Web Client Authentication"
                           },{
                                "id"           : "cert_serialNumber",
                                "severity"     : "INFO",
                                "finding"      : "9CF42A11521763A5A0FBD1CEDB085F33"
                           },{
                                "id"           : "cert_fingerprintSHA1",
                                "severity"     : "INFO",
                                "finding"      : "9D6A770D287245F2D19513493761429E2AD89619"
                           },{
                                "id"           : "cert_fingerprintSHA256",
                                "severity"     : "INFO",
                                "finding"      : "C2E3D67194D5AD96458CE3143698E89D3E8C3CBA87C7B9B3E3B67641A6948498"
                           },{
                                "id"           : "cert",
                                "severity"     : "INFO",
                                "finding"      : "-----BEGIN CERTIFICATE----- MIIDRzCCAi+gAwIBAgIRAJz0KhFSF2OloPvRztsIXzMwDQYJKoZIhvcNAQELBQAw IDEeMBwGA1UEAxMVU21hbGxzdGVwIHNlbGYtc2lnbmVkMB4XDTIxMDEwMTAwMDAw MFoXDTMxMDEwMTAwMDAwMFowIDEeMBwGA1UEAxMVU21hbGxzdGVwIHNlbGYtc2ln bmVkMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4nj6rxuC7pKMtpuW 7qdPuN1y7MaFl6hTwK0MBMkjXT71Gs54txT9YVMeUQNUZGA8hzjJ/OxVjsDdgoys 2em47jfflWDZ8gL2IQTgr9LFGrY+X9w6MbjmxzeLelNUsSFhNDEFqm8oiIktrEP4 T7DnVxf+tk2zfA70NFgctwbpMxPTKmjrQcNcz6nxdrRBns2GakqAawXNXA8abfaN 7VCitfeXAHUbNp/oaOdD1BzMftMD4MW+VKvp5NxTNmyyRvtyvSbnm8ZFqb5K4xC4 gFXuKGMJCWCc+1f0xzaPCTkynSaSS3hRnOu8dGHsgG5zWV1S8gKVJPdHnWqysxc1 nUhYgQIDAQABo3wwejAOBgNVHQ8BAf8EBAMCBaAwHQYDVR0lBBYwFAYIKwYBBQUH AwEGCCsGAQUFBwMCMB0GA1UdDgQWBBQFrGNR4kShRvgIhtnvaTKyiW3azjAqBgNV HREEIzAhggxleGFtcGxlLnRlc3SCEW1haWwuZXhhbXBsZS50ZXN0MA0GCSqGSIb3 DQEBCwUAA4IBAQBQR3tZJp2N9+TcA5SwNeQDt5QWfrZ5xbvnYdvK5iLMyKCfnbB8 EkPsp/P+rQpEaWl/xzH3P+iYpzdDvftbxoWFkdwpI8trqarw8GJ5zkOMXyhJ7qHU FmdrWcMVZePTOzXaWTUzKl6KWf8UuVGljgt8G6Gx9IkaPy/XsY0jCnp54cIDtS/u NBapZye2EGdd9B3Ws+CrgD1Z/LxLGlX7NnX/44hz4xZNKxd7KiGjGBQEGbO4ETlV P84ht9NdjXjVOuCyF0GtPI6lorrrPbaeLO991cxxywdUIUKBeUUrk3STocnxXl4R PazfVZg3RNJVpRWpM3lu/klt5XugHBLFG00z -----END CERTIFICATE-----"
                           },{
                                "id"           : "cert_commonName",
                                "severity"     : "OK",
                                "finding"      : "Smallstep self-signed"
                           },{
                                "id"           : "cert_commonName_wo_SNI",
                                "severity"     : "INFO",
                                "finding"      : "Smallstep self-signed"
                           },{
                                "id"           : "cert_subjectAltName",
                                "severity"     : "INFO",
                                "finding"      : "example.test mail.example.test"
                           },{
                                "id"           : "cert_trust",
                                "severity"     : "OK",
                                "finding"      : "Ok via SAN (same w/o SNI)"
                           },{
                                "id"           : "cert_chain_of_trust",
                                "severity"     : "CRITICAL",
                                "finding"      : "failed (chain incomplete)."
                           },{
                                "id"           : "cert_certificatePolicies_EV",
                                "severity"     : "INFO",
                                "finding"      : "no"
                           },{
                                "id"           : "cert_expirationStatus",
                                "severity"     : "OK",
                                "finding"      : "3604 >= 60 days"
                           },{
                                "id"           : "cert_notBefore",
                                "severity"     : "INFO",
                                "finding"      : "2021-01-01 00:00"
                           },{
                                "id"           : "cert_notAfter",
                                "severity"     : "OK",
                                "finding"      : "2031-01-01 00:00"
                           },{
                                "id"           : "cert_extlifeSpan",
                                "severity"     : "HIGH",
                                "finding"      : "3652 days"
                           },{
                                "id"           : "cert_eTLS",
                                "severity"     : "INFO",
                                "finding"      : "not present"
                           },{
                                "id"           : "cert_crlDistributionPoints",
                                "severity"     : "INFO",
                                "finding"      : "--"
                           },{
                                "id"           : "cert_ocspURL",
                                "severity"     : "INFO",
                                "finding"      : "--"
                           },{
                                "id"           : "cert_revocation",
                                "severity"     : "HIGH",
                                "finding"      : "Neither CRL nor OCSP URI provided"
                           },{
                                "id"           : "OCSP_stapling",
                                "severity"     : "INFO",
                                "finding"      : "not offered"
                           },{
                                "id"           : "cert_mustStapleExtension",
                                "severity"     : "INFO",
                                "finding"      : "--"
                           },{
                                "id"           : "DNS_CAArecord",
                                "severity"     : "LOW",
                                "finding"      : "--"
                           },{
                                "id"           : "certificate_transparency",
                                "severity"     : "INFO",
                                "finding"      : "N/A"
                           },{
                                "id"           : "certs_countServer",
                                "severity"     : "INFO",
                                "finding"      : "1"
                           },{
                                "id"           : "certs_list_ordering_problem",
                                "severity"     : "INFO",
                                "finding"      : "no"
                           },{
                                "id"           : "cert_caIssuers",
                                "severity"     : "INFO",
                                "finding"      : "Smallstep self-signed"
                           },{
                                "id"           : "intermediate_cert_badOCSP",
                                "severity"     : "OK",
                                "finding"      : "intermediate certificate(s) is/are ok"
                           }
                    ],
                    "headerResponse"    : [

                    ],
                    "vulnerabilities"   : [
                            {
                                "id"           : "heartbleed",
                                "severity"     : "OK",
                                "cve"          : "CVE-2014-0160",
                                "cwe"          : "CWE-119",
                                "finding"      : "not vulnerable, no heartbeat extension"
                           },{
                                "id"           : "CCS",
                                "severity"     : "OK",
                                "cve"          : "CVE-2014-0224",
                                "cwe"          : "CWE-310",
                                "finding"      : "not vulnerable"
                           },{
                                "id"           : "ROBOT",
                                "severity"     : "OK",
                                "cve"          : "CVE-2017-17382 CVE-2017-17427 CVE-2017-17428 CVE-2017-13098 CVE-2017-1000385 CVE-2017-13099 CVE-2016-6883 CVE-2012-5081 CVE-2017-6168",
                                "cwe"          : "CWE-203",
                                "finding"      : "not vulnerable"
                           },{
                                "id"           : "secure_renego",
                                "severity"     : "OK",
                                "cwe"          : "CWE-310",
                                "finding"      : "supported"
                           },{
                                "id"           : "secure_client_renego",
                                "severity"     : "OK",
                                "cve"          : "CVE-2011-1473",
                                "cwe"          : "CWE-310",
                                "finding"      : "not vulnerable"
                           },{
                                "id"           : "CRIME_TLS",
                                "severity"     : "OK",
                                "cve"          : "CVE-2012-4929",
                                "cwe"          : "CWE-310",
                                "finding"      : "not vulnerable (not using HTTP anyway)"
                           },{
                                "id"           : "POODLE_SSL",
                                "severity"     : "OK",
                                "cve"          : "CVE-2014-3566",
                                "cwe"          : "CWE-310",
                                "finding"      : "not vulnerable, no SSLv3"
                           },{
                                "id"           : "fallback_SCSV",
                                "severity"     : "OK",
                                "finding"      : "supported"
                           },{
                                "id"           : "SWEET32",
                                "severity"     : "OK",
                                "cve"          : "CVE-2016-2183 CVE-2016-6329",
                                "cwe"          : "CWE-327",
                                "finding"      : "not vulnerable"
                           },{
                                "id"           : "FREAK",
                                "severity"     : "OK",
                                "cve"          : "CVE-2015-0204",
                                "cwe"          : "CWE-310",
                                "finding"      : "not vulnerable"
                           },{
                                "id"           : "DROWN",
                                "severity"     : "OK",
                                "cve"          : "CVE-2016-0800 CVE-2016-0703",
                                "cwe"          : "CWE-310",
                                "finding"      : "not vulnerable on this host and port"
                           },{
                                "id"           : "DROWN_hint",
                                "severity"     : "INFO",
                                "cve"          : "CVE-2016-0800 CVE-2016-0703",
                                "cwe"          : "CWE-310",
                                "finding"      : "Make sure you don't use this certificate elsewhere with SSLv2 enabled services, see https://censys.io/ipv4?q=C2E3D67194D5AD96458CE3143698E89D3E8C3CBA87C7B9B3E3B67641A6948498"
                           },{
                                "id"           : "LOGJAM-common_primes",
                                "severity"     : "INFO",
                                "cve"          : "CVE-2015-4000",
                                "cwe"          : "CWE-310",
                                "finding"      : "RFC7919/ffdhe4096"
                           },{
                                "id"           : "LOGJAM",
                                "severity"     : "OK",
                                "cve"          : "CVE-2015-4000",
                                "cwe"          : "CWE-310",
                                "finding"      : "not vulnerable, no DH EXPORT ciphers,"
                           },{
                                "id"           : "BEAST_CBC_TLS1",
                                "severity"     : "MEDIUM",
                                "cve"          : "CVE-2011-3389",
                                "cwe"          : "CWE-20",
                                "finding"      : "ECDHE-RSA-AES256-SHA DHE-RSA-AES256-SHA ECDHE-RSA-AES128-SHA DHE-RSA-AES128-SHA"
                           },{
                                "id"           : "BEAST",
                                "severity"     : "LOW",
                                "cve"          : "CVE-2011-3389",
                                "cwe"          : "CWE-20",
                                "finding"      : "VULNERABLE -- but also supports higher protocols  TLSv1.1 TLSv1.2 (likely mitigated)"
                           },{
                                "id"           : "LUCKY13",
                                "severity"     : "LOW",
                                "cve"          : "CVE-2013-0169",
                                "cwe"          : "CWE-310",
                                "finding"      : "potentially vulnerable, uses TLS CBC ciphers"
                           },{
                                "id"           : "winshock",
                                "severity"     : "OK",
                                "cve"          : "CVE-2014-6321",
                                "cwe"          : "CWE-94",
                                "finding"      : "not vulnerable"
                           },{
                                "id"           : "RC4",
                                "severity"     : "OK",
                                "cve"          : "CVE-2013-2566 CVE-2015-2808",
                                "cwe"          : "CWE-310",
                                "finding"      : "not vulnerable"
                           },{
                                "id"           : "starttls_injection",
                                "severity"     : "OK",
                                "cwe"          : "CWE-74",
                                "finding"      : "not vulnerable"
                           }
                    ],
                    "cipherTests"       : [

                    ],
                    "browserSimulations": [
                            {
                                "id"           : "clientsimulation-android_81",
                                "severity"     : "INFO",
                                "finding"      : "TLSv1.2 ECDHE-RSA-AES256-GCM-SHA384"
                           },{
                                "id"           : "clientsimulation-android_90",
                                "severity"     : "INFO",
                                "finding"      : "TLSv1.3 TLS_AES_256_GCM_SHA384"
                           },{
                                "id"           : "clientsimulation-android_X",
                                "severity"     : "INFO",
                                "finding"      : "TLSv1.3 TLS_AES_256_GCM_SHA384"
                           },{
                                "id"           : "clientsimulation-java_6u45",
                                "severity"     : "INFO",
                                "finding"      : "No connection"
                           },{
                                "id"           : "clientsimulation-java_7u25",
                                "severity"     : "INFO",
                                "finding"      : "TLSv1.0 ECDHE-RSA-AES128-SHA"
                           },{
                                "id"           : "clientsimulation-java_8u161",
                                "severity"     : "INFO",
                                "finding"      : "TLSv1.2 ECDHE-RSA-AES256-GCM-SHA384"
                           },{
                                "id"           : "clientsimulation-java1102",
                                "severity"     : "INFO",
                                "finding"      : "TLSv1.3 TLS_AES_256_GCM_SHA384"
                           },{
                                "id"           : "clientsimulation-java1201",
                                "severity"     : "INFO",
                                "finding"      : "TLSv1.3 TLS_AES_256_GCM_SHA384"
                           },{
                                "id"           : "clientsimulation-openssl_102e",
                                "severity"     : "INFO",
                                "finding"      : "TLSv1.2 ECDHE-RSA-AES256-GCM-SHA384"
                           },{
                                "id"           : "clientsimulation-openssl_110l",
                                "severity"     : "INFO",
                                "finding"      : "TLSv1.2 ECDHE-RSA-AES256-GCM-SHA384"
                           },{
                                "id"           : "clientsimulation-openssl_111d",
                                "severity"     : "INFO",
                                "finding"      : "TLSv1.3 TLS_AES_256_GCM_SHA384"
                           }
                    ],
                    "rating"            : [
                            {
                                "id"           : "rating_spec",
                                "severity"     : "INFO",
                                "finding"      : "SSL Labs's 'SSL Server Rating Guide' (version 2009q from 2020-01-30)"
                           },{
                                "id"           : "rating_doc",
                                "severity"     : "INFO",
                                "finding"      : "https://github.com/ssllabs/research/wiki/SSL-Server-Rating-Guide"
                           },{
                                "id"           : "protocol_support_score",
                                "severity"     : "INFO",
                                "finding"      : "0"
                           },{
                                "id"           : "protocol_support_score_weighted",
                                "severity"     : "INFO",
                                "finding"      : "0"
                           },{
                                "id"           : "key_exchange_score",
                                "severity"     : "INFO",
                                "finding"      : "0"
                           },{
                                "id"           : "key_exchange_score_weighted",
                                "severity"     : "INFO",
                                "finding"      : "0"
                           },{
                                "id"           : "cipher_strength_score",
                                "severity"     : "INFO",
                                "finding"      : "0"
                           },{
                                "id"           : "cipher_strength_score_weighted",
                                "severity"     : "INFO",
                                "finding"      : "0"
                           },{
                                "id"           : "final_score",
                                "severity"     : "INFO",
                                "finding"      : "0"
                           },{
                                "id"           : "overall_grade",
                                "severity"     : "CRITICAL",
                                "finding"      : "T"
                           },{
                                "id"           : "grade_cap_reason_1",
                                "severity"     : "INFO",
                                "finding"      : "Grade capped to T. Issues with the chain of trust (chain incomplete)"
                           },{
                                "id"           : "grade_cap_reason_2",
                                "severity"     : "INFO",
                                "finding"      : "Grade capped to T. Encryption via STARTTLS is not mandatory (opportunistic)."
                           },{
                                "id"           : "grade_cap_reason_3",
                                "severity"     : "INFO",
                                "finding"      : "Grade capped to B. TLS 1.1 offered"
                           },{
                                "id"           : "grade_cap_reason_4",
                                "severity"     : "INFO",
                                "finding"      : "Grade capped to B. TLS 1.0 offered"
                           }
                    ]
          }
          ],
                    "scanTime"  : 225
}

All we're doing with the JSON data atm is using jq to lookup results from each test about the reported cipher suites (and if applicable the given server preference order). testssl.sh splits the cipher suites reported to each version of TLS, thus I query each one and compare against an expected list (a previous test run).

These won't match start-mailserver.sh lists exactly as a result, but they'll catch a discrepancy (I could add additional test to prove that if desirable), when the tests fail due to a mismatch, it's likely due to Postfix/Dovecot cipher lists changing, the error output for the cipher list mismatch can then be used to update the relevant list in the test file.

If there's anything else needing clarification, please let me know.

@polarathene
Copy link
Copy Markdown
Member Author

polarathene commented Feb 18, 2021

Assuming we stick with using docker image for testssl.sh, I've removed some redundant code and added some TODO comments linking to related github issues.

Instead of cleaning up /tmp/results/*, it's retained now, should have no impact on CI runs, but useful for local runs if debugging and wanting access to those results. As every test file creates it's own test directory (for docker volume to use) and those aren't cleaned up, it seemed an appropriate change. --overwrite option on the testssl.sh command works around the issue of any previous existing testssl.sh JSON results causing an error.

Finally, I reduced the testing scope with --preference for testssl.sh, as we're only presently interested in the results data that this option provides. Total run time of all test cases is reduced down to about ~35% (8 minutes instead of 22 minutes). That can be halved again with non-docker version of testssl.sh if it's ever a concern, otherwise each CI run will pull the latest 3.1-dev image which is useful.

For the benefit of maintenance, added some more comments to clarify choices, along with `TODO` improvements once related linked github issues are resolved.

Added `--overwrite --preference` options to the `testssl.sh` command.

`--overwrite` avoids the need to clean up json logs between test runs, which is useful for inspection when not run via CI, they're stored in `/tmp` thus not persisted across boots.

`--preference` provides a test speed up since we're only using `testssl.sh` presently to enumerate in server order the available cipher suites for a given TLS config.

`mkdir`/`cd` commands can be dropped since interest to shift from the `testssl.sh` utility using docker hasn't been expressed. Running native would lose the ability to use `example.test` URI for testing, and instead use `0.0.0.0` IP to exposed ports. The non-docker version performs at 2x the speed.
@polarathene polarathene force-pushed the feat/use-best-practice-ciphers-2021 branch from 046e290 to 1aeb83d Compare February 18, 2021 07:52
@georglauterbach
Copy link
Copy Markdown
Member

Alright. This seems to be ready for merging. @polarathene do we have your Go?

@polarathene
Copy link
Copy Markdown
Member Author

@aendeavor yep all good 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/security kind/new feature A new feature is requested in this issue or implemeted with this PR priority/medium

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants