SSL/TLS errors on very old browsers connecting to Discourse

After setting up my Discourse instance using the default Let’s Encrupt support, I got reports from some of my users that their browser can’t establish a secure connection to Discourse. One screenshot I got from a user clearly points to an SSL/TLS error. It’s a browser-side error and the users don’t even see anything from Discourse.

Judging by the context those users seem to have somewhat older operating systems/browsers. I first suspected TLS 1.2 support to be the issue, but the user I checked with is running Safari 10.1.2 on macOS (unknown version) and according to Can I use... Support tables for HTML5, CSS3, etc Safari should be supporting TLS 1.2 since version 7.

Is there another reason except for TLS 1.2, which would cause a browser/operating system to fail to establish a secure connection to a default Discourse installation using the default TLS support via Let’s Encrypt? I’m trying to figure out what questions I should ask of my users to figure out what their issue is and on what end it should be fixed.

As a workaround: Afaict, the default is to redirect the traffic going to http to https. Is there a way to do a check first, something like “only if Browser supports TLS 1.2” or “only if Browser/OS greater than version”, otherwise stay with http?

This is the URL, in case you have an idea how to check whether something is incorrectly configured: https://forum.stadtteilgenossenschaft-wik.de

4 Likes

You can test your site using the SSL Server Test. The test results contain a section named “Handshake Simulation” which should show you browser/OS combinations that work / do not work.

With the latest Docker image I’m seeing the following TLS configuration:

You can send your users to Qualys SSL Labs - Projects / SSL Client Test in order to get more information about their browser and OS versions as well as supported TLS versions.

6 Likes

Thank you for the detailed response!

I ran the SSL Server Test and can’t find anything wrong with the result:
https://www.ssllabs.com/ssltest/analyze.html?d=forum.stadtteilgenossenschaft-wik.de&hideResults=on

They are the same as the ones in your post, afaict.

The only failures were for old OS+Safari version (Safari 8+9) and old windows versions with IE 11. That last one concerns me a bit: shouldn’t IE 11 be supported by Discourse and also support TLS 1.2 by default?

The test also doesn’t contain a test for Safari 10 on the oldest still supported OS, so maybe that also fails…

For those users on old Windows versions, you probably need to enable the CBC ciphers:

The very next thing you should do is send those users to

to get information about what their browser supports. The easiest way to share their result is probably having them print to a PDF and send it to you.

5 Likes

Thank you, I got a response from my user. They are using a very old iPod Touch:

SSL/TLS Capabilities of Your Browser
User Agent: Mozilla/5.0 (iPod; CPU iPhone OS 6_1_6 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) Version/6.0 Mobile/10B500 Safari/8536.25

Protocol Support

Your user agent has good protocol support.

Your user agent supports TLS 1.2, which is recommended protocol version at the moment.

So while it’s old (and I’m aware that it’s far away from Discourse‘s minimum supported OS+browser) I‘d like to enable them to a least connect to the site and see how their browser fares with the modern HTML and JavaScript.

This is the detailed TLS support report:

Protocol Features

Protocols

TLS 1.3 No
TLS 1.2 Yes
TLS 1.1 Yes
TLS 1.0 Yes
SSL 3 Yes
SSL 2 No

Cipher Suites (in order of preference)

TLS_EMPTY_RENEGOTIATION_INFO_SCSV ( 0xff ) -
TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 ( 0xc024 ) WEAK 256
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 ( 0xc023 ) WEAK 128
TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA ( 0xc00a ) WEAK 256
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA ( 0xc009 ) WEAK 128
TLS_ECDHE_ECDSA_WITH_RC4_128_SHA ( 0xc007 ) INSECURE 128
TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA ( 0xc008 ) WEAK 112
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 ( 0xc028 ) WEAK 256
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 ( 0xc027 ) WEAK 128
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA ( 0xc014 ) WEAK 256
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA ( 0xc013 ) WEAK 128
TLS_ECDHE_RSA_WITH_RC4_128_SHA ( 0xc011 ) INSECURE 128
TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA ( 0xc012 ) WEAK 112
TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 ( 0xc026 ) WEAK 256
TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 ( 0xc025 ) WEAK 128
TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 ( 0xc02a ) WEAK 256
TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 ( 0xc029 ) WEAK 128
TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA ( 0xc004 ) WEAK 128
TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA ( 0xc005 ) WEAK 256
TLS_ECDH_ECDSA_WITH_RC4_128_SHA ( 0xc002 ) INSECURE 128
TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA ( 0xc003 ) WEAK 112
TLS_ECDH_RSA_WITH_AES_128_CBC_SHA ( 0xc00e ) WEAK 128
TLS_ECDH_RSA_WITH_AES_256_CBC_SHA ( 0xc00f ) WEAK 256
TLS_ECDH_RSA_WITH_RC4_128_SHA ( 0xc00c ) INSECURE 128
TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA ( 0xc00d ) WEAK 112
TLS_RSA_WITH_AES_256_CBC_SHA256 ( 0x3d ) WEAK 256
TLS_RSA_WITH_AES_128_CBC_SHA256 ( 0x3c ) WEAK 128
TLS_RSA_WITH_AES_128_CBC_SHA ( 0x2f ) WEAK 128
TLS_RSA_WITH_RC4_128_SHA ( 0x5 ) INSECURE 128
TLS_RSA_WITH_RC4_128_MD5 ( 0x4 ) INSECURE 128
TLS_RSA_WITH_AES_256_CBC_SHA ( 0x35 ) WEAK 256
TLS_RSA_WITH_3DES_EDE_CBC_SHA ( 0xa ) WEAK 112
TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 ( 0x67 ) WEAK 128
TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 ( 0x6b ) WEAK 256
TLS_DHE_RSA_WITH_AES_128_CBC_SHA ( 0x33 ) WEAK 128
TLS_DHE_RSA_WITH_AES_256_CBC_SHA ( 0x39 ) WEAK 256
TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA ( 0x16 ) WEAK 112
TLS_ECDHE_ECDSA_WITH_NULL_SHA ( 0xc006 ) INSECURE 0
TLS_ECDHE_RSA_WITH_NULL_SHA ( 0xc010 ) INSECURE 0
TLS_ECDH_ECDSA_WITH_NULL_SHA ( 0xc001 ) INSECURE 0
TLS_ECDH_RSA_WITH_NULL_SHA ( 0xc00b ) INSECURE 0
TLS_RSA_WITH_NULL_SHA256 ( 0x3b ) INSECURE 0
TLS_RSA_WITH_NULL_SHA ( 0x2 ) INSECURE 0
TLS_RSA_WITH_NULL_MD5 ( 0x1 ) INSECURE 0
(1) When a browser supports SSL 2, its SSL 2-only suites are shown only on the very first connection to this site. To see the suites, close all browser windows, then open this exact page directly. Don’t refresh.

Protocol Details

Server Name Indication (SNI) Yes
Secure Renegotiation Yes
TLS compression No
Session tickets No
OCSP stapling No
Signature algorithms SHA384/RSA, SHA256/RSA, SHA1/RSA, SHA256/ECDSA, SHA1/ECDSA
Named Groups secp256r1, secp384r1, secp521r1
Next Protocol Negotiation No
Application Layer Protocol Negotiation No
SSL 2 handshake compatibility No

Mixed Content Handling

Mixed Content Tests
Images Passive Yes
CSS Active Yes
Scripts Active Yes
XMLHttpRequest Active Yes
WebSockets Active Yes
Frames Active Yes
(1) These tests might cause a mixed content warning in your browser. That’s expected.
(2) If you see a failed test, try to reload the page. If the error persists, please get in touch.

Sorry about the formatting, the user copy-pasted the rich text HTML for me and some of it gets lost when pasting to Discourse. I’ll try to figure out how to fix the formatting later.

As I said, I’d like to enable them to at least establish a secure connection so they’ll see something and it should be possible as the browser supports TLS 1.2. But I guess I’d have to enable some less-secure config for TLS 1.2 for their browser to be supported. I don’t know enough about TLS condors to match the output of that report to what the server supports and what I’d have to change. Can you tell me what’s missing and what I’d have to change?

I have a rough idea what you mean, but I have no clue how to do that. Can you point me to some documentation that explains how to change the TLS config of the Discourse Docker container to enable these?

I don’t think Safari 6 will work even when you solve the TLS issues by adding additional cipher suites.

You can add missing cipher suites by overriding the nginx config file. Add the following snippet (untested, but it should work) to the hooks section of app.yml and change the value of ssl_ciphers to your liking.

  after_ssl:
    - replace:
        filename: "/etc/nginx/conf.d/discourse.conf"
        from: /ssl_ciphers .*/
        to: ssl_ciphers <your_complete_cipher_list>;

BTW: I’m trying to add support for Elliptic Curve certificates to Discourse which would make it work for IE11 out of the box.

https://github.com/discourse/discourse_docker/pull/444

4 Likes

iOS 6?! The last version of that was released in early 2014! That was more than 5 years ago!

2 Likes

I know, I was as surprised as you are. I don’t expect you to support it, but I’d want the user to get at least some HTML and see what works and what doesn’t.

Thank you @gerhard, I made the change you described to /var/discourse/containers/app.yml (hope that was the correct app.yml file) and then ran /var/discourse/launcher rebuild app as described in the comments of app.yml.

I then reran the test on ssllabs.com, but it seems like the result didn’t change: SSL Server Test: forum.stadtteilgenossenschaft-wik.de (Powered by Qualys SSL Labs)

I’m not sure how to verify whether the config change actually worked (but it didn’t influence the test result) or whether the config change didn’t work.

oh, I didn’t read your post properly @gerhard. If I understand it correctly, the config you provided will make the used ciphers explicit but the value you used is basically the same as the default right? So I’d have to still extend it with other ciphers that might be supported by older browsers.

2 Likes

Yes, exactly. I didn’t want to post a solution for adding weak ciphers to the config. You’ll have to figure this out yourself. :wink:

But if you are making those changes I’d keep an eye on the pull request I mentioned earlier. If it gets merged IE11 will work out of the box.

2 Likes

I see, you don’t want to make it too easy for someone to make their setup insecure. I respect that and will also not post the complete code.

Here’s what I got so far: I identified the cipher suites that are missing to support older browsers/OSs by looking at e.g. Qualys SSL Labs - Projects / User Agent Capabilities: Safari 6 / iOS 6.0.1 (and for others as well). As the client cipher suites are listed by preference I just always picked the topmost one and made sure I’m supporting it, assuming that if the server supports one from the list, that should be sufficient. Here are the ciphers I identified:

  • ECDHE-ECDSA-AES256-CBC-SHA384 for Safari 6-8
  • ECDHE-RSA-AES256-CBC-SHA384 for IE 11 on Win 7/8.1/Phone 8.1 Update (according to @supermathie)
  • ECDHE-RSA-AES128-CBC-SHA256 for IE 11 on Win Phone 8.1

I took these values and added them to the end of the list of ssl_ciphers, separated by colons, assuming that “end of the list” means “least preferred, will only be used if client doesn’t support anything else”. I then ran /var/discourse/launcher rebuild app to apply the new config and reran the test on https://www.ssllabs.com/ssltest/analyze.html?d=forum.stadtteilgenossenschaft-wik.de&s=68.183.214.228&hideResults=on&latest after clearing the cache. But the results didn’t change.

I expected it to now be successful both for the failing IE 11 tests as well as Safari 6-8, but the handshake still fails. So I must be missing something.

Also, one of my users is using an iPhone with iOS 9/Safari 9 and for them the connection also fails. But according to the test results of SSL Labs, that connection should already work out of the box (as is also visible in @gerhard’s result above).

So I must be missing two things:

  1. Why is the connection still not working after adding support for the ciphers?
  2. Why does SSLLabs says it works for iOS 9 + Safari 9 but it doesn’t actually work for my user?

Regarding 1: I’m still not sure I applied the config correctly. Apart from the SSL Labs Test, is there another way to check which ciphers the server supports to see whether my config change was actually applied correctly?

After looking it the SSLLab result more closely, I think this doesn’t work.

This is the result I see on SSLLabs for my server after applying the config and rebuilding:

According to my understanding, it should list many more, as the config has many more options. Does this mean this config change didn’t work?

I think the ciphers you chose have the wrong names. Mapping OpenSSL cipher suite names to IANA names is a good resource for mapping between the ciphers listed by the SSL Server Test and the names used by OpenSSL (nginx).

In my tests I appended :ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES256-SHA and after a rebuild the test looks like this:

Maybe there’s a bug in the test? :man_shrugging: I don’t have such an old Safari for testing. We support only Safari 10+. Are you sure that it still fails due to a TLS error?

3 Likes

Thank you, will try that!

I looked through the Discourse config files a bit more and found templates/web.ssl.template.yml. What’s the difference between making this change to the ciphers via the app.yml file and just changing the list of ssl_ciphers in templates/web.ssl.template.yml directly?

The template is version controlled and the app.yml is not. You’ll have problems updating the repository when you edit the template.

5 Likes

Thank you this was the issue and fixing the names makes the handshake work for all browsers tested in the list of SSLLabs. Thank you so much for your patience!

Now, I’m interested to learn what my users are seeing once they got past the HTTPS error with their old browsers. :smiley:

4 Likes

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.