Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Updates to support OpenSSL 3.x #256

Open
wants to merge 4 commits into
base: master
Choose a base branch
from

Conversation

gstrauss
Copy link
Collaborator

@gstrauss gstrauss commented Oct 10, 2024

Updates to support OpenSSL 3.x

Tracked in #260
Resolves #238
Resolves #188

  • Set SECLEVEL=0 in cipherstring for old output to allow TLSv1–v1.1 for OpenSSL 3.x
  • Hide DH parameters for servers calling OpenSSL interfaces SSL_CTX_set_dh_auto() or SSL_set_dh_auto() to use RFC7919.

TODO/OQ:

  • add an AND helper for conditional blocks only (not) matching two values
  • review all use of output.usesDhe, output.dhCommand, output.dhParamSize
  • verify exim doesn't need removal of +no_ssl* flags
  • decide on tomcat (that may or may not use openssl implementation…)
  • verify oraclehttp support (=> mod_ossl is Oracle Secure Sockets Layer, not openssl)

openssl SSL_CTX_set_dh_auto() or SSL_set_dh_auto() interfaces support
RFC7919 Negotiated Finite Field Diffie-Hellman Ephemeral Parameters
for Transport Layer Security (TLS)

github: closes mozilla#238
@gstrauss
Copy link
Collaborator Author

For DH parameters code review, I checked all servers which had .hbs configs containing {{#if output.usesDhe}}. I downloaded the source code and checked the history to find supported versions.

lighttpd - no change; does the right things with the appropriate versions

apache - small changes to do the right things with appropriate versions
postfix - small changes to do the right things with appropriate versions
redis - small changes to do the right things with appropriate versions

coturn - no change; does not call SSL_CTX_set_dh_auto/SSL_set_dh_auto
dovecot - no change; does not call SSL_CTX_set_dh_auto/SSL_set_dh_auto
exim - no change; does not call SSL_CTX_set_dh_auto/SSL_set_dh_auto
haproxy - no change; does not call SSL_CTX_set_dh_auto/SSL_set_dh_auto
nginx - no change; does not call SSL_CTX_set_dh_auto/SSL_set_dh_auto
postgresql - no change; does not call SSL_CTX_set_dh_auto/SSL_set_dh_auto
proftpd - no change; does not call SSL_CTX_set_dh_auto/SSL_set_dh_auto
squid - no change; does not call SSL_CTX_set_dh_auto/SSL_set_dh_auto

There are some apps, such as stunnel and postgresql, which use built-in 2048-bit pregenerated DH params, if none is otherwise configured. Some other servers many support DH params included in certificate PEM file. This PR does not review bit sizes of DH params as that is out of scope for this PR -- which is focused on upgrading the OpenSSL version supported by ssl-config-generator. Besides, best practices in modern configs no longer use DHE.

@gstrauss

This comment was marked as resolved.

@janbrasna

This comment was marked as resolved.

src/js/state.js Outdated
if (configs[server].usesOpenssl !== false) {
// set SECLEVEL=0 for openssl 3 to support TLSv1 and TLSv1.1 for Old config
if (minver('3.0.0', form['openssl'].value) === true) {
ciphers.unshift('@SECLEVEL=0');
Copy link
Collaborator

Choose a reason for hiding this comment

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

Haven't looked into properly, only quick observation: https://gst-os3--mozsslconf-dev.netlify.app/#server=oraclehttp&version=12.2.1&config=old&openssl=3.3.2&guideline=5.7

# old configuration
SSLProtocol             All 
SSLCipherSuite          @SECLEVEL=0:@SECLEVEL=0:@SECLEVEL=0:@SECLEVEL=0:@SECLEVEL=0:@SECLEVEL=0:@SECLEVEL=0:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-

Not that it wouldn't work, right? (I haven't tried tbh;D) but it just doesn't look right.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

That is funny. I believe I had tested with stunnel.hbs, and hadn't looked across the rest. I'll see about modifying the javascript tomorrow or later in the weekend.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I pushed a change to fix this. If you're concerned with the condition if (ciphers[0] !== '@SECLEVEL=0') { on a possibly empty ciphers list (which should not happen for the Old config), then I can change the logic to something similar used to set usesDhe further below in the same routine: if (ciphers.join(":").includes("@SECLEVEL=0") === false) {.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Not an urgent concern of mine, but the repetition that I now have to check for suggests that there are some performance gains on the client-side to be had by eliminating unnecessary repetition of work. Obviously, things need to be re-evaluated, when a config change is made by the user, but it should not need to be re-evaluated 5 times.

Copy link
Collaborator

Choose a reason for hiding this comment

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

I was basically more concerned about how it got iterated over so many times in the first place;)

I was trying to avoid creating a new variable for @SECLEVEL=0 that had to be pasted onto the cipher list and have code added to each and every hbs

Sure, that is similar to tls13 logic also filtering out stuff in state.js before passing it on opaquely to the template output. That's definitely a good place!

(BTW, it's plain JS here, not HBS, so you don't have to nest the conditions so bizarrely (:) and can use falsy bool values without too much remorse really…)

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I am not a javascript developer, so I appreciate any recommendations for better coding idioms or coding standard preferences.

Please add to your wishlist an issue to ask why this code is being run repeatedly for some templates. It did not appear to run repeatedly for the (new) stunnel template.

src/js/state.js Outdated Show resolved Hide resolved
@gstrauss

This comment was marked as resolved.

@gstrauss

This comment was marked as resolved.

@gstrauss gstrauss force-pushed the openssl-3.x branch 2 times, most recently from eded910 to 0505bcc Compare October 10, 2024 07:39
@gstrauss

This comment was marked as outdated.

@gstrauss

This comment was marked as outdated.

@gstrauss

This comment was marked as resolved.

@gstrauss
Copy link
Collaborator Author

I incorporated the changes in #257 and updated the Apache version here.

@gstrauss gstrauss force-pushed the openssl-3.x branch 2 times, most recently from 962806a to 466d00d Compare October 11, 2024 18:33
@gstrauss
Copy link
Collaborator Author

Ready for review again with the changes from #257. The last few pushes were whitespace cleanup.

@janbrasna
Copy link
Collaborator

janbrasna commented Oct 11, 2024

I will also try to document what info should be added upstream, to the recommendation contents, as a rationale for the choices we're making to support OpenSSL 3. (I will add it to the #260 epic where I intend to track things even spanning the actual repos…)

I'm thinking about a review meeting to go through some of the things, TBD, I'll put together a list/backlog for that to see how much we have left that I'd like to discuss before confirming any decisions.

(I have more questions than actual time to even ask them — some of the issues are solving themselves over time, I'm not sure about Tomcat impact (if you can try to find out it won't trip over the seclevel in cipherstring as it does some own parsing before passing anything on…), will have more questions about the seclevel bit-strength threshold wrt our other output values than just the protocols etc. …)

What's mostly unknown to me are the os-level specifics that can differ for folks, e.g.:

"This may have more implications than just re-enabling TLSv1.0 and 1.1 (or rather: SHA1 and MD5 signature algorithms, used by these protocols) though, depending on the OpenSSL version. See man SSL_CTX_set_security_level(3) on the same machine." — #188 (comment)

Can you think of any wild differences among versions or distros/defaults?

I would love for this to be first released as "opt-in" — say by skipping the 3.x version in configs.js now, we can ask people to manually test 3.x configs by punching in the version (or via permalink), before settling on that as the new default for anyone and everyone. Mainly to verify we're still good on 1.1.1 not bringing any regressions to the existing logic, and giving it few weeks for feedback before flipping that switch. (If it is long overdue, long+14d overdue doesn't make much difference.)

@gstrauss
Copy link
Collaborator Author

I'm not sure about Tomcat impact

No impact. Tomcat is configured in src/js/config.js with usesOpenssl: false and that is checked before adding SECLEVEL=0

"This may have more implications than just re-enabling TLSv1.0 and 1.1 ...

Can you think of any wild differences among versions or distros/defaults?

From a practical perspective, it does not matter since it is required to support TLSv1 and TLSv1.1, and if the Old config provides support for TLSv1 and TLSv1.1, then SECLEVEL=0 must be set if OpenSSL 3.x is used.

I would love for this to be first released as "opt-in" — say by skipping the 3.x version in configs.js now

Ok. I will push momentarily with that commit removed.

@janbrasna
Copy link
Collaborator

This PR does not review bit sizes of DH params as that is out of scope for this PR

I'm actually comfortable with letting intermediate fail to apply on <80 bits — that's a reminder for the consumer they're not careful with the key size as instructed.

The default SECLEVEL=2, and we should retain that. At SECLEVEL=1, TLSv1 and TLSv1.1 are disabled, so if the Old config needs them, those who need it must use SECLEVEL=0

Ah right, I meant <112 bits, sorry. That kinda enforces the RSA and DHE keys length 2048b+ for us, so I'm not sure there's anything to review as that's on par with the recommendations (and good it's actually enforced now) — did you mean anything beyond that?

@gstrauss
Copy link
Collaborator Author

My earlier comment was addressing the poster's recommendation to use at least ffdhe3072. That is not in scope for this PR and will be addressed in the future with specification review. :)

src/js/state.js Outdated Show resolved Hide resolved
Comment on lines +17 to +25
{{#if (minver "6.2.7" form.serverVersion)}}
{{#unless (minver "3.0.0" form.opensslVersion)}}
# {{output.dhCommand}} > /path/to/dhparam
tls-dh-params-file /path/to/dhparam
{{/unless}}
{{else}}
# {{output.dhCommand}} > /path/to/dhparam
tls-dh-params-file /path/to/dhparam
{{/if}}
Copy link
Collaborator

Choose a reason for hiding this comment

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

OK would you be willing to add an "AND" helper (e.g. https://github.com/helpers/handlebars-helpers/blob/master/lib/comparison.js …) to avoid this repetition all over the place, please?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Seems doable. Time allowing, I'll try to revisit this on Sun.

If this existing code in this PR works correctly, I would prefer this PR not be blocked for this kind of polishing.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Turns out to not be trivial.
Examples in https://stackoverflow.com/questions/8853396/logical-operator-in-a-handlebars-js-if-conditional work on simple values but not on items which need to be evaluated.

Some possible (not tested) solutions include https://github.com/jmurphyau/ember-truth-helpers and or lvalue = Embers.Handlerbars.get(this, lvalue) || lvalue or https://gist.github.com/servel333/21e1eedbd70db5a7cfff327526c72bc5

Possible solutions need to be evaluated for security XSS.

A better solution, IMHO, is to hoist logic which needs multiple conditions out of the templates and into javascript, and have the templates access the result. I don't think adding more dependencies and bloating the generated page is the best solution. Please create a separate github issue if you would like to evaluate options. At the moment, the small bits of duplication in the templates is a workable solution for this PR.

@gstrauss
Copy link
Collaborator Author

verify exim doesn't need removal of +no_ssl* flags

I verified the exim code.

decide on tomcat (that may or may not use openssl implementation…)

src/js/configs.js specifies usesOpenssl: false

@gstrauss
Copy link
Collaborator Author

review all use of output.usesDhe, output.dhCommand, output.dhParamSize

I did review this. Please be more specific for what you/I might look.

@gstrauss
Copy link
Collaborator Author

I wrote:

My earlier comment was addressing the poster's recommendation to use at least ffdhe3072. That is not in scope for this PR and will be addressed in the future with specification review. :)

I should note that some servers hard-code ffdhe2048. stunnel is one. I think postgresql was another. (I was not keeping track as I quickly reviewed source code for calls to SSL_CTX_set_dh_auto() or SSL_set_dh_auto().)

lighttpd is a third, but lighttpd only uses ffdhe2048 if openssl version is too old. The reason I have not updated lighttpd is because if you're on an ancient system and using an ancient openssl version, you are probably on an underpowered system and you likely have many other system security risks more important than DHE bit length. If this is a concern, you should, of course, configure lighttpd with your own appropriate DHParameters.

@gstrauss
Copy link
Collaborator Author

A large amount of time is being spent on DHParameters, even though modern security recommendations do not include ciphers which require them. I do not think we would be spending time on this if the Mozilla TLS recommendations were reviewed and updated.

Note: https://developers.cloudflare.com/ssl/edge-certificates/additional-options/cipher-suites/recommendations/ recommends ECDHE and does not recommend any DHE ciphers, even for Legacy. (If TLSv1 and TLSv1.1 are needed, then weaker ciphers are made available for such Legacy use.)

@gstrauss
Copy link
Collaborator Author

add an AND helper for conditional blocks only (not) matching two values

That is an underlying code change which has not effect on the output. It should not be part of this PR and should be tested and rolled out separately, in a separate PR.

decide on tomcat (that may or may not use openssl implementation…)

As already stated, this is not an issue with the current code which sets usesOpenssl: false. If you want to change that for Tomcat, that IS NOT PART OF THIS PR and should not block this PR.

verify oraclehttp support

https://docs.oracle.com/middleware/12213/webtier/administer-ohs/GUID-C76BCA2A-9C28-4D16-9758-9346FBCF7512.htm#HSADM1016

I don't have access to test oraclehttp, but if someone reports an issue with the Old config and SECLEVEL=0, then we can add code to oraclehttp.hbs to filter out SECLEVEL=0. Please remember that this is for the Old config; the Old config is old and people are strongly discouraged from using it.


@janbrasna Please focus on the "minimum viable product" to approve this PR so that it can be deployed for testing. This PR does not bump the openssl version, so you'll continue to have plenty of time for turd polishing for the Old config after this PR is merged and deployed. Please move as many of your testing concerns as you can from this PR to #263

@polarathene
Copy link
Contributor

recommendation to use at least ffdhe3072

2048-bit is still plenty, using the hashrate of the bitcoin global network in 2024 I did some napkin math (see near end of comment for 2048-bit math) which calculated 54,000 years, but that was just against the entropy with the hashrate as operations. I don't have math on me from old notes for GFNS which also requires considerable resources beyond CPU at this scale, but IIRC the attack cost should be higher... thus really not pragmatic / worthwhile.

TLS 1.3 also supports ffdhe2048 as a minimum IIRC and that's auto-negotiated? Usually you only see a desire to use more because the user does not understand the math, or some regulation compliance has raised the bar without adequate justification (presumably as a precaution or external perception/expectation).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
3 participants