Ошибки SSL/TLS при подключении к Discourse в очень старых браузерах

После настройки экземпляра Discourse с использованием поддержки Let’s Encrypt по умолчанию я получил сообщения от некоторых пользователей о том, что их браузер не может установить защищённое соединение с Discourse. Один скриншот, полученный от пользователя, явно указывает на ошибку SSL/TLS. Это ошибка на стороне браузера, и пользователи даже не видят ничего из содержимого Discourse.

Судя по контексту, у этих пользователей, похоже, более старые операционные системы или браузеры. Сначала я предположил, что проблема в поддержке TLS 1.2, но пользователь, с которым я проверил, использует Safari 10.1.2 на macOS (версия неизвестна), и согласно Can I use... Support tables for HTML5, CSS3, etc, Safari должен поддерживать TLS 1.2 начиная с версии 7.

Есть ли другая причина, кроме отсутствия поддержки TLS 1.2, которая могла бы привести к тому, что браузер или операционная система не смогут установить защищённое соединение с установкой Discourse по умолчанию, использующей стандартную поддержку TLS через Let’s Encrypt? Я пытаюсь понять, какие вопросы стоит задать пользователям, чтобы определить суть проблемы и понять, где именно её нужно исправлять.

Как временное решение: насколько я понимаю, по умолчанию трафик, идущий на http, перенаправляется на https. Есть ли способ сначала выполнить проверку, например «только если браузер поддерживает TLS 1.2» или «только если версия браузера/ОС выше определённой», и в противном случае оставить http?

Вот URL, на случай если у вас возникнет идея, как проверить, не настроено ли что-то неправильно: https://forum.stadtteilgenossenschaft-wik.de

Вы можете протестировать свой сайт с помощью SSL Server Test. В результатах теста есть раздел под названием «Имитация рукопожатия» (Handshake Simulation), который показывает комбинации браузеров/ОС, которые работают или не работают.

С использованием последнего образа Docker я наблюдаю следующую конфигурацию TLS:

Вы можете направить ваших пользователей на https://www.ssllabs.com/ssltest/viewMyClient.html, чтобы получить дополнительную информацию о версиях их браузеров и операционных систем, а также о поддерживаемых версиях TLS.

Спасибо за подробный ответ!

Я запустил тест SSL Server и не нашёл ничего неправильного в результатах:

Они такие же, как в вашем сообщении, насколько я могу судить.

Единственные неудачи связаны со старыми версиями ОС + Safari (Safari 8+9) и старыми версиями Windows с IE 11. Последнее немного беспокоит: разве IE 11 не должен поддерживаться Discourse и по умолчанию поддерживать TLS 1.2?

Также в тесте отсутствует проверка для Safari 10 на самой старой всё ещё поддерживаемой ОС, так что, возможно, и там есть проблемы…

Для пользователей со старыми версиями Windows, скорее всего, потребуется включить шифры CBC:

Следующим шагом отправьте этих пользователей на

чтобы получить информацию о том, что поддерживает их браузер. Самый простой способ поделиться результатом — вероятно, попросить их сохранить страницу в PDF и отправить вам.

Спасибо, я получил ответ от моего пользователя. Он использует очень старый iPod Touch:

Возможности SSL/TLS вашего браузера
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

Поддержка протоколов

Ваш user agent имеет хорошую поддержку протоколов.

Ваш user agent поддерживает TLS 1.2, который на данный момент является рекомендуемой версией протокола.

Таким образом, хотя устройство старое (и я понимаю, что оно далеко от минимально поддерживаемой ОС и браузера для Discourse), я хотел бы дать ему возможность хотя бы подключиться к сайту и посмотреть, как его браузер справляется с современным HTML и JavaScript.

Вот подробный отчет о поддержке TLS:

Особенности протоколов

Протоколы

TLS 1.3 Нет
TLS 1.2 Да
TLS 1.1 Да
TLS 1.0 Да
SSL 3 Да
SSL 2 Нет

Наборы шифров (в порядке предпочтения)

TLS_EMPTY_RENEGOTIATION_INFO_SCSV ( 0xff ) -
TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 ( 0xc024 ) СЛАБЫЙ 256
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 ( 0xc023 ) СЛАБЫЙ 128
TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA ( 0xc00a ) СЛАБЫЙ 256
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA ( 0xc009 ) СЛАБЫЙ 128
TLS_ECDHE_ECDSA_WITH_RC4_128_SHA ( 0xc007 ) НЕБЕЗОПАСНЫЙ 128
TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA ( 0xc008 ) СЛАБЫЙ 112
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 ( 0xc028 ) СЛАБЫЙ 256
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 ( 0xc027 ) СЛАБЫЙ 128
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA ( 0xc014 ) СЛАБЫЙ 256
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA ( 0xc013 ) СЛАБЫЙ 128
TLS_ECDHE_RSA_WITH_RC4_128_SHA ( 0xc011 ) НЕБЕЗОПАСНЫЙ 128
TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA ( 0xc012 ) СЛАБЫЙ 112
TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 ( 0xc026 ) СЛАБЫЙ 256
TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 ( 0xc025 ) СЛАБЫЙ 128
TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 ( 0xc02a ) СЛАБЫЙ 256
TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 ( 0xc029 ) СЛАБЫЙ 128
TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA ( 0xc004 ) СЛАБЫЙ 128
TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA ( 0xc005 ) СЛАБЫЙ 256
TLS_ECDH_ECDSA_WITH_RC4_128_SHA ( 0xc002 ) НЕБЕЗОПАСНЫЙ 128
TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA ( 0xc003 ) СЛАБЫЙ 112
TLS_ECDH_RSA_WITH_AES_128_CBC_SHA ( 0xc00e ) СЛАБЫЙ 128
TLS_ECDH_RSA_WITH_AES_256_CBC_SHA ( 0xc00f ) СЛАБЫЙ 256
TLS_ECDH_RSA_WITH_RC4_128_SHA ( 0xc00c ) НЕБЕЗОПАСНЫЙ 128
TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA ( 0xc00d ) СЛАБЫЙ 112
TLS_RSA_WITH_AES_256_CBC_SHA256 ( 0x3d ) СЛАБЫЙ 256
TLS_RSA_WITH_AES_128_CBC_SHA256 ( 0x3c ) СЛАБЫЙ 128
TLS_RSA_WITH_AES_128_CBC_SHA ( 0x2f ) СЛАБЫЙ 128
TLS_RSA_WITH_RC4_128_SHA ( 0x5 ) НЕБЕЗОПАСНЫЙ 128
TLS_RSA_WITH_RC4_128_MD5 ( 0x4 ) НЕБЕЗОПАСНЫЙ 128
TLS_RSA_WITH_AES_256_CBC_SHA ( 0x35 ) СЛАБЫЙ 256
TLS_RSA_WITH_3DES_EDE_CBC_SHA ( 0xa ) СЛАБЫЙ 112
TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 ( 0x67 ) СЛАБЫЙ 128
TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 ( 0x6b ) СЛАБЫЙ 256
TLS_DHE_RSA_WITH_AES_128_CBC_SHA ( 0x33 ) СЛАБЫЙ 128
TLS_DHE_RSA_WITH_AES_256_CBC_SHA ( 0x39 ) СЛАБЫЙ 256
TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA ( 0x16 ) СЛАБЫЙ 112
TLS_ECDHE_ECDSA_WITH_NULL_SHA ( 0xc006 ) НЕБЕЗОПАСНЫЙ 0
TLS_ECDHE_RSA_WITH_NULL_SHA ( 0xc010 ) НЕБЕЗОПАСНЫЙ 0
TLS_ECDH_ECDSA_WITH_NULL_SHA ( 0xc001 ) НЕБЕЗОПАСНЫЙ 0
TLS_ECDH_RSA_WITH_NULL_SHA ( 0xc00b ) НЕБЕЗОПАСНЫЙ 0
TLS_RSA_WITH_NULL_SHA256 ( 0x3b ) НЕБЕЗОПАСНЫЙ 0
TLS_RSA_WITH_NULL_SHA ( 0x2 ) НЕБЕЗОПАСНЫЙ 0
TLS_RSA_WITH_NULL_MD5 ( 0x1 ) НЕБЕЗОПАСНЫЙ 0
(1) Если браузер поддерживает SSL 2, его наборы шифров только для SSL 2 отображаются только при первом подключении к этому сайту. Чтобы увидеть их, закройте все окна браузера, затем откройте эту страницу напрямую. Не обновляйте страницу.

Детали протокола

Указание имени сервера (SNI) Да
Безопасное пересогласование Да
Сжатие TLS Нет
Сессионные билеты Нет
Подшивка OCSP Нет
Алгоритмы подписи SHA384/RSA, SHA256/RSA, SHA1/RSA, SHA256/ECDSA, SHA1/ECDSA
Именованные группы secp256r1, secp384r1, secp521r1
Согласование следующего протокола Нет
Согласование протокола прикладного уровня Нет
Совместимость рукопожатия SSL 2 Нет

Обработка смешанного контента

Тесты смешанного контента
Изображения (пассивные) Да
CSS (активные) Да
Скрипты (активные) Да
XMLHttpRequest (активные) Да
WebSockets (активные) Да
Фреймы (активные) Да
(1) Эти тесты могут вызвать предупреждение о смешанном контенте в вашем браузере. Это нормально.
(2) Если вы видите неудачный тест, попробуйте перезагрузить страницу. Если ошибка сохраняется, пожалуйста, свяжитесь с нами.

Извините за форматирование: пользователь скопировал и вставил для меня HTML-разметку с форматированием, и часть её теряется при вставке в Discourse. Позже я постараюсь разобраться, как исправить форматирование.

Как я уже сказал, я хотел бы дать ему возможность хотя бы установить безопасное соединение, чтобы он увидел что-то, и это должно быть возможно, так как браузер поддерживает TLS 1.2. Но, полагаю, мне придется включить некоторые менее безопасные настройки для TLS 1.2, чтобы поддержать его браузер. Я недостаточно знаю о TLS, чтобы сопоставить вывод этого отчета с тем, что поддерживает сервер, и что мне нужно изменить. Можете ли вы сказать мне, чего не хватает и что мне нужно изменить?

У меня есть общее представление о том, что вы имеете в виду, но я не знаю, как это сделать. Можете ли вы указать мне на документацию, объясняющую, как изменить конфигурацию TLS контейнера Docker Discourse для включения этих шифров?

Я не думаю, что Safari 6 заработает, даже если вы решите проблемы с TLS, добавив дополнительные наборы шифров.

Вы можете добавить отсутствующие наборы шифров, переопределив файл конфигурации nginx. Добавьте следующий фрагмент (не тестировался, но должен работать) в секцию hooks файла app.yml и измените значение ssl_ciphers на своё усмотрение.

  after_ssl:
    - replace:
        filename: "/etc/nginx/conf.d/discourse.conf"
        from: /ssl_ciphers .*/
        to: ssl_ciphers <ваш_полный_список_шифров>;

Кстати: я пытаюсь добавить поддержку сертификатов на эллиптических кривых для Discourse, что позволит ему работать с IE11 «из коробки».

iOS 6?! Последняя версия этой ОС вышла в начале 2014 года! Это было более 5 лет назад!

Я знаю, я был так же удивлён, как и вы. Я не ожидаю, что вы это поддержите, но мне бы хотелось, чтобы пользователь получил хотя бы немного HTML и увидел, что работает, а что нет.

Спасибо, @gerhard. Я внес изменения, которые вы описали, в файл /var/discourse/containers/app.yml (надеюсь, это правильный файл app.yml), а затем выполнил команду /var/discourse/launcher rebuild app, как указано в комментариях к app.yml.

После этого я снова запустил тест на ssllabs.com, но, похоже, результат не изменился: https://www.ssllabs.com/ssltest/analyze.html?d=forum.stadtteilgenossenschaft-wik.de&s=68.183.214.228&hideResults=on

Не уверен, как проверить, действительно ли изменение конфигурации сработало (но оно не повлияло на результат теста), или же изменение конфигурации не было применено.

О, я не правильно прочитал твой пост, @gerhard. Если я правильно понял, указанный тобой конфиг явно задаёт используемые шифры, но само значение по сути такое же, как и по умолчанию, верно? Значит, мне всё равно придётся дополнять его другими шифрами, которые могут поддерживаться старыми браузерами.

Да, именно. Я не хотел публиковать решение по добавлению слабых шифров в конфигурацию. Вам придётся разобраться с этим самостоятельно. :wink:

Но если вы вносите эти изменения, следите за моим ранее упомянутым запросом на слияние. Если его примут, IE11 будет работать из коробки.

Понятно, вы не хотите упрощать настройку до уровня, когда она становится небезопасной. Я уважаю это и тоже не буду публиковать полный код.

Вот что у меня пока получилось: я определил недостающие наборы шифров для поддержки старых браузеров и ОС, изучив, например, страницу Qualys SSL Labs - Projects / User Agent Capabilities: Safari 6 / iOS 6.0.1 (а также аналогичные для других устройств). Поскольку наборы шифров клиента перечислены в порядке предпочтения, я всегда выбирал первый в списке и убедился, что он поддерживается, полагая, что если сервер поддерживает хотя бы один из них, этого должно быть достаточно. Вот выявленные мною наборы шифров:

  • ECDHE-ECDSA-AES256-CBC-SHA384 для Safari 6–8
  • ECDHE-RSA-AES256-CBC-SHA384 для IE 11 на Windows 7/8.1/Phone 8.1 Update (согласно @supermathie)
  • ECDHE-RSA-AES128-CBC-SHA256 для IE 11 на Windows Phone 8.1

Я добавил эти значения в конец списка ssl_ciphers, разделив их двоеточиями, предполагая, что «конец списка» означает «наименее предпочтительный, будет использоваться только если клиент не поддерживает ничего другого». Затем я выполнил команду /var/discourse/launcher rebuild app для применения новой конфигурации и снова запустил тест на SSL Server Test (Powered by Qualys SSL Labs) после очистки кэша. Однако результаты не изменились.

Я ожидал, что теперь тесты для IE 11 и Safari 6–8 пройдут успешно, но рукопожатие всё равно не удаётся. Значит, я что-то упускаю.

Кроме того, один из моих пользователей использует iPhone с iOS 9 и Safari 9, и у него соединение тоже не устанавливается. Но согласно результатам теста SSL Labs, это соединение должно работать из коробки (что также видно в результате @gerhard выше).

Значит, я упускаю два момента:

  1. Почему соединение всё ещё не работает после добавления поддержки нужных шифров?
  2. Почему SSL Labs показывает, что соединение работает для iOS 9 + Safari 9, но на самом деле у моего пользователя оно не работает?

По поводу пункта 1: я всё ещё не уверен, что правильно применил конфигурацию. Кроме теста SSL Labs, есть ли другой способ проверить, какие наборы шифров поддерживает сервер, чтобы убедиться, что моё изменение конфигурации действительно применено корректно?

После более внимательного изучения результата SSLLab я думаю, что это не работает.

Вот результат, который я вижу на SSLLabs для своего сервера после применения конфигурации и пересборки:

Согласно моим представлениям, там должно быть указано гораздо больше пунктов, так как конфигурация содержит множество дополнительных опций. Не означает ли это, что изменение конфигурации не сработало?

Кажется, выбранные вами шифры названы неправильно. Mapping OpenSSL cipher suite names to IANA names — отличный ресурс для сопоставления шифров, перечисленных в SSL Server Test, с именами, используемыми в OpenSSL (nginx).

В моих тестах я добавил :ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES256-SHA, и после пересборки тест выглядит так:

Возможно, в тесте есть ошибка? :man_shrugging: У меня нет такой старой версии Safari для тестирования. Мы поддерживаем только Safari 10+. Вы уверены, что проблема всё ещё связана с ошибкой TLS?

Спасибо, попробую!

Я немного подробнее изучил файлы конфигурации Discourse и нашел templates/web.ssl.template.yml. В чем разница между внесением этого изменения в шифры через файл app.yml и прямым изменением списка ssl_ciphers в templates/web.ssl.template.yml?

Шаблон находится под контролем версий, а файл app.yml — нет. При редактировании шаблона у вас возникнут проблемы с обновлением репозитория.

Спасибо, это и было проблемой. Исправление названий позволило установить соединение (handshake) во всех браузерах, протестированных в списке SSLLabs. Огромное спасибо за ваше терпение!

Теперь мне интересно узнать, что видят мои пользователи, когда они преодолевают ошибку HTTPS на своих старых браузерах. :smiley: