mozilla / ssl-config-generator

Mozilla SSL Configuration Generator
https://ssl-config.mozilla.org/
Mozilla Public License 2.0
358 stars 59 forks source link

Exim with GnuTLS #115

Open ygoe opened 3 years ago

ygoe commented 3 years ago

Exim uses GnuTLS by default, so the OpenSSL config options do not apply. Exim does not come with any documentation about what exactly we should set in the configuration and does not recommend any security config itself. So we're left alone with this. Can you make a suggestion here?

My config still only disables SSLv3 and leaves the rest unconfigured. This might need to be updated. The GnuTLS version is 3.

tomato42 commented 3 years ago

email is a tricky beast, as vast majority of mail servers will gladly drop down to plaintext, so disabling protocols or ciphers on port 25 (i.e. MX port) is counter productive: even 3DES in SSLv3 or anonymous Diffie-Hellman is better than plaintext...

So unless you're willing to disallow plaintext communication on port 25, you shouldn't change ciphers used by exim

ygoe commented 3 years ago

Then why are there any recommendations (for OpenSSL) at all? Also, there's clients (authenticating with a password) connecting to the server. I'm going to disallow these without encryption.

philpennock commented 3 years ago

With my exim maintainer hat on, there's two very different issues (and some misinformation) here:

  1. Which TLS configuration is used for MX delivery between hosts
  2. Which TLS configuration is used for Submission

and 1 is in turn divided up into (a) "when using DANE so that cleartext fallback is disabled" and (b) "in the normal RFC-compliant fallback-to-cleartext" cases.

The misinformation: Exim supports OpenSSL and GnuTLS. AFAIK most people building Exim for themselves seem to choose OpenSSL. On Debian and derivatives (such as Ubuntu) using GnuTLS is instead more common. So the TLS strings depend upon which SSL library is in used.

For myself, I define macros TLS_SERVER_MX_CIPHERSPEC and TLS_SERVER_SUBMISSION_CIPHERSPEC for port 25 vs ports 465+587, and I define TLS_CLIENT_DEFAULT_CIPHERSPEC and TLS_CLIENT_HIGHSEC_CIPHERSPEC for outbound. I use the highsec spec for dane_require_tls_ciphers = TLS_CLIENT_HIGHSEC_CIPHERSPEC and also via complicated expansion logic for when site-local configuration says that TLS should be used for connections to particular servers.

For the TLS_CLIENT_HIGHSEC_CIPHERSPEC and TLS_SERVER_SUBMISSION_CIPHERSPEC values, ssl-config-generator values are very appropriate.

ygoe commented 3 years ago

Hm, I'm no wiser than before now. What is the correct config syntax for getting a recommended security with GnuTLS? I'm not building anything but use the Ubuntu distribution packages. People building stuff themselves use other distributions that are made for that. I did that many years ago but it was just way too much work to keep up with all relevant updates.

Does GnuTLS understand the same config values as OpenSSL? I couldn't find any documentation about that, so it looks to me that GnuTLS is unconfigurable. Why is that even used when everybody (except the Exim developers maybe) prefers OpenSSL?

philpennock commented 3 years ago

For GnuTLS, the syntax of those strings is a "priority string": https://www.exim.org/exim-html-current/doc/html/spec_html/ch-encrypted_smtp_connections_using_tlsssl.html#SECTreqciphgnu

The GnuTLS docs: https://www.gnutls.org/manual/html_node/Priority-Strings.html

Exim just passes the strings through to the GnuTLS library.

ygoe commented 3 years ago

OK, and which of these should I use? After all, that's the purpose of this tool. I'm not a security professional, I don't know much about the details of all these algorithms.

philpennock commented 3 years ago

If there's not an equivalent to the Mozilla ssl-config generator and you don't have the expertise to make calls, then keep it simple and avoid naming explicit ciphers. For the high-sec cases (server listening on 465/587, NOT for the MX port 25; the dane_require_tls_ciphers option on an SMTP Transport), perhaps something like:

SECURE128:-VERS-TLS1.0:-VERS-TLS1.1

Run: gnutls-cli --list --priority='SECURE128:-VERS-TLS1.0:-VERS-TLS1.1' to test.

That would be "anything of at least 128 bits security, disabling TLS1.0 and TLS1.1". This avoids you having to get involved in deciding what is or is not secure, but involves trusting the decisions of the library maintainers.

Otherwise, you use the ssl-config strings and the GnuTLS docs and spend time figuring out how well each one does or does not translate to GnuTLS. Use gnutls-cli --list --priority='your_candidate' to test.

philpennock commented 3 years ago

(For clarity: I am not a maintainer of the Mozilla tool, I'm an Exim maintainer and saw your issue which looking for something else)

ygoe commented 3 years ago

Strange, this command seems to include some TLS 1.0, but no TLS 1.1. Both seem to be explicitly excluded.

peterthomassen commented 3 years ago

@ygoe I observe the same behavior.

gene1wood commented 3 years ago

@philpennock Thanks for your comments here. Are there any concrete changes we (Mozilla) should make to the Exim config to improve things?

philpennock commented 3 years ago

I am no longer an Exim maintainer.

Invoking exim -bP macros will give you values for, potentially, _HAVE_TLS, _HAVE_OPENSSL, _HAVE_GNUTLS (going partly from memory, test to be sure). That will let you interrogate to know which options to suggest for a given installation, or you can emit with .ifdef directives:

.ifdef _HAVE_OPENSSL
openssl_options = X
tls_require_ciphers = Y
.elifdef _HAVE_GNUTLS
tls_require_ciphers = Z
.elifdef _HAVE_TLS
# unsupported TLS configuration, at the time this was written Exim only supported OpenSSL and GnuTLS
.else
# TLS not enabled in this build
.endif

You might want to refer people to https://www.exim.org/exim-html-current/doc/html/spec_html/ch-encrypted_smtp_connections_using_tlsssl.html for the docs on TLS with Exim.

I would definitely push for a configuration such as the ${if =={$received_port}{25} example, to support MX "have to be more forgiving" behavior vs submission(s) "have decent security" behavior. You might include a warning comment that if debugging on a non-standard port then this will push that connection to stricter security. There are ways to make the configuration more complicated to support that, but not worth pushing for in a simple recommendations tool, so just a warning comment IMO.

Take a look over the DANE section and figure out what you want to configure for the remote_smtp transport to provide better security by default for outbound connections; look at whatever current git has as the default configuration file for people to work from (https://git.exim.org/exim.git/blob/HEAD:/src/src/configure.default) and see what is done for the smarthost_smtp case (where we push for better TLS behavior) vs the default.

Anything in terms of policy beyond that, I defer to the current maintainers rather than step on their toes.

grinapo commented 2 years ago

I don't see how the generator could generate anything for gnutls syntax (instead of openssl).

The preference tls_require_ciphers = SECURE128:-VERS-TLS1.0:-VERS-TLS1.1:%SERVER_PRECEDENCE:-AES-256-CBC:-AES-128-CBC

seems to provide a good baseline, forcibly removing CBC (and breaking compatibility for some I guess) TLS1.0 cyphers as well.

(It provides, on my current config:

Naturally this holds ony for the gnutls-compiled versions, namely all Debian and clones.

grinapo commented 2 years ago

Yep, still broken. Can't generate config for gnutls.

Happy anniversary!

Technically I don't see what the problem is. Exim+gnutls uses the standard gnutls syntax and opions, using the aforementioned tls_require_cypers keyword.

All the tls related config options are, for the record:

acl_smtp_starttls = 
no_gnutls_allow_auto_pkcs11
no_gnutls_compat_mode
no_ldap_start_tls
tls_advertise_hosts = *
tls_certificate = /etc/wherever/cert.pem
tls_crl = 
tls_dh_max_bits = 2236
tls_dhparam = 
tls_eccurve = auto
tls_ocsp_file = 
tls_on_connect_ports = 
tls_privatekey = /etc/wherever/key.pem
no_tls_remember_esmtp
tls_require_ciphers = SECURE128:-VERS-TLS1.0:-VERS-TLS1.1:%SERVER_PRECEDENCE:+CAMELLIA-256-GCM:+CAMELLIA-128-GCM
tls_try_verify_hosts = 
tls_verify_certificates = 
tls_verify_hosts = 
gene1wood commented 2 years ago

@grinapo Thanks for your comments here. Are there any concrete changes we (Mozilla) should make to the Exim config to improve things?

grinapo commented 2 years ago

Are there any concrete changes we (Mozilla) should make to the Exim config to improve things?

@gene1wood Definitely. I have tried to figure out how and where you generate the specifics but run beyond my allocated timeframe, so unfortunately I cannot come up with a useful patch.

Do you generate GNUTLS compatible configs? As you can see from my config snippet above exim4 uses either openssl (with your current and working advice) or GNUTLS. The latter does not use openssl_* config and uses tls_require_ciphers with GNUTLS syntax.

Since picking the proper crypto isn't a simple task I cannot assure that the example I have shared above is either optimal or secure, but it's probably a good starting point to test. (I believe it can be tested with GNUTLS command line utilities.)

So, you should have two exim: one with openssl and one with gnutls (or, have one exim but offer two config versions, I believe that's harder to implement with the current scheme), and provide the proper require_cypher syntax.

gene1wood commented 2 years ago

Thanks for the details.

Do you generate GNUTLS compatible configs?

I see that the lighthttpd generator seems to support gnutls though it doesn't appear to manifest in the config differently than if openssl was used.

Ok so it sounds like the ask is, if someone would PR an addition of Exim but with GnuTLS, potentially basing it on this block of config settings that would come into play and using Mozilla's TLS profiles as the guide for the values.

janbrasna commented 6 months ago

@gene1wood The lighttpd generator template doesn't support gnutls values in reality (the tool can populate only one set of tls names read from the configs, supporting more tls modules under one config entry is not currently available) — It's the server that passes the ssl.openssl* values to mod_gnutls or mod_wolfssl transparently but the cipher lists must be in the right format, and that doesn't get mapped automatically, user would have to provide the correct cipher configuration string anyways:/

It's something the generator can't do right now, generating lighttpd+openssl vs. lighttpd+gnutls at the same time from one template. So the same applies for Exim here, as mentioned above the (only?) viable solution would be keeping two configs, exim+openssl vs. exim+gnutls as even the API differs here, not just the cipher naming…

(As a sidenote there's currently no config with GnuTLS in place. The cipher naming is in the JSON specs so in theory this could work; in reality we don't have any feedback about real world usage of GnuTLS tuned to Mozilla SSTLS outputs. Every distro has their own defaults, and unlike OpenSSL things once disabled in GnuTLS conf then can't be re-enabled application-side in server configurations later on so e. g. you might be unable to run "old" configs completely as re-enabling old TLS versions that are disabled on OS level isn't possible.)