ADG Оставить заявку
Блог Информационная безопасность 5 мин чтения

Meltdown и Spectre: первые рабочие дни года - инвентаризация, патчи, просадка производительности

CVE-2017-5754 (Meltdown) и CVE-2017-5753/5715 (Spectre) опубликованы 3 января. Оцениваем парк серверов, патчим ядра Linux, смотрим что происходит с базами данных.

Контекст момента

Публикация CVE-2017-5754 (Meltdown) и CVE-2017-5753/5715 (Spectre) 3 января 2018 - аппаратные уязвимости в механизме спекулятивного выполнения процессоров Intel, AMD и ARM

Новый год начался с подарка. 3 января публикуют CVE-2017-5754, CVE-2017-5753 и CVE-2017-5715 - Meltdown и Spectre. Аппаратные уязвимости в механизме спекулятивного выполнения, затрагивающие процессоры Intel (Meltdown - почти все выпущенные за последние десять лет), AMD и ARM (Spectre). Механика - атакующий из пространства пользователя может читать содержимое памяти ядра. В облачной среде - потенциально данные соседнего арендатора.

У нас в тот момент праздничный режим, половина команды в отпуске. Но это из серии «отложить нельзя».

Что вообще произошло

Meltdown (CVE-2017-5754) - уязвимость в процессорах Intel, позволяющая пользовательскому процессу читать произвольную память ядра. Закрывается патчем ядра - технология называется KPTI (Kernel Page-Table Isolation), она изолирует таблицы страниц ядра от пространства пользователя. Цена - дополнительный syscall overhead, который зависит от нагрузки.

Spectre (CVE-2017-5753 и CVE-2017-5715) - другая механика, основана на side-channel через branch predictor. Закрывается сложнее: частично патчами компилятора, частично микрокодом CPU, частично изменениями в ядре. И AMD, и Intel, и ARM под угрозой в разной степени.

К моменту публикации CVE патчи для Linux ядра уже готовы - ветки 4.14, 4.9 и 4.4 получили KPTI до публичного раскрытия. Дистрибутивы на подходе.

Инвентаризация: что у нас вообще есть

Первый шаг - понять масштаб. Наш парк серверов у клиентов неоднородный: RHEL 6 и 7, Debian 8 и 9, Ubuntu 14.04 и 16.04, несколько VMware-кластеров. Плюс облачные инстансы - AWS и несколько арендованных серверов у европейских провайдеров.

Собираем список: что на каком ядре, когда последний раз обновлялось. Картина ожидаемо грустная: часть серверов не обновлялась с лета, у одного клиента вообще RHEL 6 с ядром 2.6.32, которое в стоке, без backport-патча, закрыть будет нетривиально.

Версии ядра сами по себе не дают полный ответ на «под угрозой или нет» - важно, применён ли KPTI. Проверяем:

dmesg | grep -i "page table isolation"
cat /sys/devices/system/cpu/vulnerabilities/meltdown

Второй файл появился чуть позже с обновлёнными ядрами - удобный способ проверить статус прямо из userspace.

Патчим

Дистрибутивы выкатывают патчи быстро. Ubuntu 16.04 получил обновлённое ядро 4.4.0-108 через несколько дней после раскрытия. RHEL 7 - соответствующий backport в 3.10.0-693. Debian 9 - 4.9.65.

Алгоритм стандартный для такого случая:

  • Сначала staging. Обновляем ядро на тестовых серверах, перезагружаем, проверяем что всё поднялось.
  • Потом production по одному. Серверы баз данных - в последнюю очередь, после того как посмотрели на поведение.
  • Автоматизация через Ansible. yum update kernel или apt-get dist-upgrade, потом reboot с ожиданием. Playbook несложный, но важно что он логирует время каждого шага - потом понадобится.

Проблем с загрузкой не было. На VMware пришлось обновить и гипервизоры - vSphere выпустил патчи для ESXi почти одновременно, но это отдельный процесс с обслуживанием кластера.

Производительность баз данных: смотрим внимательно

Вот это место оказалось интереснее, чем ожидалось. KPTI добавляет overhead на каждый системный вызов - а базы данных делают системных вызовов очень много. PostgreSQL и MySQL активно используют read(), write(), fsync(), сетевые вызовы. Каждый из них теперь стоит чуть дороже за счёт смены контекста таблиц страниц.

Конкретные цифры мы мерить не торопились - слишком много переменных, и сравнивать «до патча / после патча» в production без подготовленного бенчмарка - метод ненадёжный. Но ряд наблюдений сделали:

pgbench на тестовом PostgreSQL 9.6 показал заметное падение TPS на OLTP-нагрузке с короткими транзакциями. Логично - именно они делают больше всего syscall'ов на единицу полезной работы. Чем тяжелее и длиннее транзакция, тем меньше относительный overhead.

MySQL под InnoDB вёл себя похоже. Самую большую разницу увидели на воркload'е типа «много мелких SELECT'ов» - что характерно для приложений с ORM и N+1 запросами.

Нагрузка на CPU вверх - ожидаемо. KPTI требует сброса TLB при переключении контекстов, это процессорное время. На серверах с HT это немного смягчается.

Клиентам с критичными по latency базами данных рекомендовали запустить свои бенчмарки до раскатки в production и после - чтобы понять именно их дельту, а не ориентироваться на чужие цифры из интернета. Рабочие нагрузки разные.

Где стоим сейчас

К концу первой недели января все production-серверы под нашим управлением получили патчи ядра. По Meltdown - закрыто. По Spectre - сложнее: CVE-2017-5715 требует ещё и обновления микрокода Intel, которого на момент написания поста для части процессоров нет или оно ещё не добралось до всех вендоров. Следим.

Spectre CVE-2017-5753 частично закрывается компиляторными патчами - retpoline и co. - но это история для следующего апдейта.

Один практический вывод уже сейчас: аудит с инвентаризацией парка и версий ядер - это не разовая история перед сертификацией. Ситуация когда за три дня нужно понять что вообще крутится и в каком состоянии - нормальная при таких инцидентах. Организации, у которых CMDB живая, а не декоративная, справились с инвентаризацией за пару часов. Остальные разбирались вручную.

Контакт

Нужна такая же инженерная работа?

Опишите задачу и контекст. Ответим в течение рабочего дня, при необходимости подпишем NDA.