OCSP stapling in Nginx >=1.3.7

Maxim Dounin mdounin на mdounin.ru
Чт Сен 20 13:01:46 UTC 2018


Hello!

On Thu, Sep 20, 2018 at 05:40:16AM +0300, Gena Makhomed wrote:

> On 20.09.2018 3:06, Maxim Dounin wrote:
> 
> >> Правильной была бы цель "сделать обязательной проверку отзыва"
> >> без каких-либо дополнительных условий?
> 
> > Именно так. Потому что мешать в одну кучу требование о проверке
> > отзыва сертфиката и технические аспекты одного из вариантов этой
> > проверки - это плохой путь.
> 
> >> Правильным решением в таком случае был бы флаг в сертификате
> >> "обязательно проверять отзыв сертификата", так что если веб-сервер
> >> прислал OCSP-ответ прикрепленный к сертификату сервером, браузер
> >> использует его, а если веб-сервер ничего не прислал, тогда браузер
> >> должен сам в обязательном порядке сделать OCSP-запрос и получить ответ?
> >> И только если браузер не смог получить OCSP-ответ, только в этом случае
> >> запрещать клиенту доступ к сайту с таким флагом в сертификате?
> 
> > И это было бы логично: именно так сейчас браузеры, использующие
> > OCSP, и работают, с той лишь разницей, что по результатам
> > неудачной проверки доступ - не запрещают.
> 
> Может быть еще не поздно предложить RFC в котором будет
> описан такой флаг "сделать обязательной проверку отзыва" ?

Лично я - далёк от того, чтобы заниматься вопросами стандартизации 
чего бы то ни было.   Возможно, "must staple" сам рано или поздно 
мигрирует в такое поведение.

> >> Такое решение задачи наверное было бы наиболее удобным для создателей
> >> веб-серверов, но значительно увеличило бы нагрузку на инфраструктуру CA,
> 
> > Не увеличило бы.  Потому что по факту - OCSP сейчас и так включён
> > по умолчанию во всех браузерах, его использующих.
> 
> Если не увеличило бы, почему же тогда представители CA были против?

ЕМНИП, на тот момент проверка отзыва был в большинстве браузеров 
по умолчанию выключена.

> >>> В тот момент, когда от клиента пришло соединение с запросом
> >>> certificate status и OpenSSL'ем был вызван соответствующий
> >>> callback - у nginx'а нет возможности как-либо отложить обработку
> >>> этого соединения.
> >>>
> >>> Соответственно либо к этому моменту у nginx'а уже есть
> >>> соответствующий OCSP-ответ - и тогда он может его отправить
> >>> клиенту, либо соответствующего OCSP-ответа нет - и тогда он не
> >>> может его отправить, а максимум что может - это инициировать
> >>> запрос к OCSP-серверу, чтобы этот ответ получить для последующих
> >>> клиентов.
> 
> >> У nginx есть отдельный процесс cache manager, который управляет кэшем
> >> независимо от рабочих процессов nginx, может быть имеет смысл также
> >> сделать ocsp cache manager, который будет заниматься получением
> >> и кэшированием OCSP-ответов для всех присутствующих сертификатов?
> 
> > Можно сделать много всего.  Но это не избавляет от ситуации, когда
> > соединение, в котором надо вернуть OCSP-ответ, уже есть, а самого
> > OCSP-ответа - ещё нет.
> 
> Избавляет полностью, если OCSP responder отвечает на запросы.
> 
> Когда в конфиг добавили новый сертификат и сделали reload -
> сначала ocsp cache manager убеждается, что у него есть актуальные
> OCSP-ответы для всех "Must Staple" сертификатов и только после этого
> применяется новая конфигурация для всех рабочих процессов nginx'а.
> 
> Когда в конфиг добавили новый сертификат и запустили nginx -
> сначала запускается ocsp cache manager, убеждается, что у него есть
> актуальные OCSP-ответы для всех "Must Staple" сертификатов и только
> после этого запускаются рабочие процессы nginx'а.
> 
> Когда в процессе работы nginx'а OCSP responder не доступен более
> чем 50% времени жизни OCSP-ответа - это форс-мажорная ситуация
> и в таком случае nginx просто закрывает соединение с клиентом
> для всех соединений с "Must Staple" сертификатами до тех пор,
> пока актуальный OCSP-ответ не будет получен. Это лучше, чем
> возвращать клиенту "Must Staple" сертификат без OCSP-ответа.

О чём и речь.  Во всей этой конструкции - описано множество вещей, 
которые надо программировать, чтобы "must staple" хоть как-то 
заработал.  И вещей, которые надо делать на старте nginx'а - 
просто для того, чтобы начать работать.  И при этом нет сколь-либо 
разумного решения для ситуации, когда OCSP responder по каким-то 
причинам оказывается недоступен.

Закрывать соединения - это плохой, негодный подход.  Очень 
напоминает подход "ошибка аллокации памяти - это форс-мажорная 
ситуация, в таком случае надо делать abort(), это лучше, чем 
продолжать работать".

При этом всего этого можно было бы легко избежать, не пытаясь 
вводить "must staple" вместо требования проверки отзыва.

> >>> Эту проблему можно столь же успешно решить, просто не пытаясь
> >>> включать "ssl_prefer_server_ciphers".  Попытки же изобретать
> >>> сложную логику - "здесь играем, здесь не играем, здесь рыбу
> >>> заворачивали" - выглядят, скажем мягко, странно.
> 
> >> Эта сложная логика уже изобретена и встроена в OpenSSL,
> >> достаточно только указать флаг SSL_OP_PRIORITIZE_CHACHA.
> >>
> >> Получается очень красивое решение, так что и Forward Secrecy
> >> можно получить с большинством браузеров и мобильные клиенты
> >> будут использовать наиболее эффективный для них шифр ChaCha20.
> 
> > Это что угодно, но только не красивое решение. Люди потратили
> > массу сил и времени на изобретение сложной логики (и теперь хотят,
> > чтобы разработчики nginx'а и все пользователи nginx'а -
> > присоединились к процессу, потому что встроить эту логику в
> > существующий механизм выбора приоритета шифров - не осилили). 
> > И всё ради того, чтобы насильно обеспечить Forward Secrecy людям,
> > сознательно забившим на обновление софта.
> 
> Не только. Директива ssl_prefer_server_ciphers применяется
> и в тех случаях, когда в каком-то шифре находят уязвимость,
> тогда этот шифр с помощью серверных приоритетов ставится
> на последнее место. Совсем выключить нельзя, потому что
> некоторые клиенты не умеют ничего другого кроме этого шифра.
> Такое уже было, например, когда нашли уязвимость в RC4.
> Или когда до того, наоборот, ставили RC4 на первое место,
> чтобы защититься от уязвимости в браузерах по имени BEAST.

Случаи с RC4, на самом деле, хороший пример, почему подобноё 
управление шифрами - как раз требует чёткого понимания автором 
конфигурации целей и задач, и требует регулярного пересмотра.

Потому что RC4 в nginx'е - по умолчанию запрещён начиная с nginx 
0.8.20, выпущенного в 2009 году.  И соответственно сначала все его 
подобавляли для борьбы с BEAST - а потом выпиливали из 
конфигураций обратно, когда стало понятно, что RC4 даже хуже, чем 
считалось до этого.  При том, что сколько-нибудь реальной исходная 
проблема с BEAST была - разве что несколько недель после анонса, 
пока браузеры не выкатили свой аналог OpenSSL'ного "insert empty 
fragments".

> В такой ситуации все пользователи nginx'а будут поставлены
> перед выбором: или защитить клиентов от уязвимости в шифре
> но при этом быстро съедать батарею у мобильных пользователей
> или экономить батарею у мобильных пользователей но иметь
> включенным и выбираемым частью клиентов уязвимый шифр.
> 
> Если бы была возможность включить SSL_OP_PRIORITIZE_CHACHA
> через директиву конфигурации nginx - это бы упростило жизнь,
> тогда можно и уязвимый шифр выключить и батарею экономить.

Я не спорю с тем, что соответствующая возможность - может 
оказаться полезной в каких-то ситуациях.

Мне тут в первую очередь печально, что со стороны OpenSSL 
получилось очередной ad-hoc решение, требующее отдельной ручки - 
вместо, например, групп шифров с одинаковым приоритетом в строке 
спецификации шифров.

Ну и равно печально, что люди не понимают, что включать 
ssl_prefer_server_ciphers в отсутствии серьёзных проблем, которые 
нужно решать на стороне сервера - не стоит.

-- 
Maxim Dounin
http://mdounin.ru/


Подробная информация о списке рассылки nginx-ru