Re: SSL Early Data поддерживает только первый worker?

Maxim Dounin mdounin на mdounin.ru
Пн Фев 3 15:40:12 UTC 2020


Hello!

On Mon, Feb 03, 2020 at 05:37:55PM +0300, Sergey Kandaurov wrote:

> 
> > On 29 Jan 2020, at 15:06, Maxim Dounin <mdounin at mdounin.ru> wrote:
> > 
> > Hello!
> > 
> > On Wed, Jan 29, 2020 at 01:40:44PM +0300, Sergey Kandaurov wrote:
> > 
> >> 
> >>> On 29 Jan 2020, at 06:20, Ilya Evseev <nginx-forum at forum.nginx.org> wrote:
> >>> 
> >>> Есть Nginx 1.17.8, собран со свежей BoringSSL stable.
> >>> Запущен на Linux kernel 5.4.10:
> >>> 
> >>> [..]
> >>> SSL в Nginx'e настроен так:
> >>> 
> >>> ssl_dhparam /etc/pki/tls/private/dhparam2048.pem;
> >>> ssl_session_timeout 1h;
> >>> ssl_session_cache shared:SSL:10m;
> >>> ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
> >>> ssl_ciphers
> >>> kEECDH+ECDSA+AESGCM:kEECDH+AES128:kEECDH:kEDH:-3DES:kRSA+AES128:kEDH+3DES:DES-CBC3-SHA:!RC4:!aNULL:!eNULL:!MD5:!EXPORT:!LOW:!SEED:!CAMELLIA:!IDEA:!PSK:!SRP:!SSLv2;
> >>> ssl_prefer_server_ciphers on;
> >>> ssl_early_data on;
> >>> 
> >>> Проверяю, поддерживает ли он SSL early data:
> >>> 
> >>> docker run --rm -it nablac0d3/sslyze --early_data 1.2.3.4
> >>> 
> >>> Результат:
> >>> 
> >>> - Если в nginx'e настроен "worker_processes 1;", sslyze всегда возвращает
> >>> "Suppported - Server accepted early data"
> >>> - Если воркеров больше одного, "Supported" начинает возвращаться не всегда.
> >>> Чем больше воркеров - тем чаще возвращается "Not supported".
> >>> 
> >>> Т.е. выглядит так, будто SSL Early Data поддерживает только первый воркер.
> >>> 
> >>> Этому есть какое-то объяснение?
> >> 
> >> Тут дело не в early data, а в том что BoringSSL по какой-то причине не
> >> разрешает сохранять тикеты в session cache.  В итоге сессия восстанавливается
> >> только по тикету из того же рабочего процесса, который его породил.
> >> Это означает, что восстановление сессий из кеша (в т.ч. shared) не будет
> >> работать и для TLSv1.2 со включёнными по умолчанию тикетами.
> > 
> > Э.  Тикеты - восстанавливаются по ключу, который задаётся в 
> > master-процессе и соответственно одинаковый во всех рабочих 
> > процессах.  То есть восстановление тикетов должно работать вне 
> > зависимости от session cache, и работать всегда.
> 
> И действительно.  В BoringSSL ключи создаются не во время вызова
> SSL_CTX_new() в master-процессе, а по необходимости при работе
> с тикетами, где таким образом каждый рабочий процесс получает
> уникальное значение в соответствующих структурах SSL_CTX.  Это
> препятствует восстановлению сессии по тикету в другом процессе.
> Помимо этого, применяется механизм автовращания ключей через
> SSL_DEFAULT_TICKET_KEY_ROTATION_INTERVAL секунд после создания,
> но здесь это не столь важно.
> 
> Использование коллбека SSL_CTX_set_tlsext_ticket_key_cb отменяет это.

[...]

> https://boringssl.googlesource.com/boringssl/+/72912d2

Ну э, молодцы.  То есть доступный прямо сейчас workaround для 
BoringSSL - задать ssl_session_ticket_key явно.  Что, конечно, 
делает прямо противоположное тому, что было целью авторов данного 
изменения - вместо вращения ключей при каждом чтении конфигурации, 
которое было раньше, и в пару к которому хотелось сделать 
автовращение, мы получаем вечно лежащий на диске ключ.

Возможно, стоит подумать о том, чтобы явно отключить всю эту 
красоту для BoringSSL, явно задав случайные ключи при чтении 
конфигурации, скажем, с помощью SSL_CTX_set_tlsext_ticket_keys().

Ну или сделать, наконец, автовращение ключей на уровне nginx'а, с 
синхронизацией ключей между рабочими процессами через разделяемую 
память.

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


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