Livepatch: обновление ядра Linux без перезагрузки

Во время эксплуатации сервера Linux необходимо регулярно применять обновления программного обеспечения для поддержания приложений и операционной системы в максимально работоспособном и безопасном состоянии. Большинство программ можно перезапустить автоматически с помощью такого инструмента, как needrestart, но для обновления ядра ОС такой способ не подходит.

Livepatch является механизмом ядра Linux, который позволяет обновлять ядро без перезагрузки. Из данной статьи вы узнаете, как работает Livepatch, и подходит ли он для вашей системы.

Увеличение времени безотказной работы с помощью Livepatch

Обновление ядра «на лету»

Перезагрузка системы может быть нежелательна по ряду причин. Многие критические системы подразумевают безостановочную работу, однако даже при стабильности программного обеспечения могут выходить обновления безопасности, которые относятся к ядру ОС и при традиционном подходе приводят к перезагрузке ОС.

Исправление ядра в реальном времени — это процесс установки исправлений безопасности для работающего ядра Linux без перезагрузки системы. Реализация для Linux называется Livepatch. Процесс исправления живого ядра — довольно сложный процесс. Однако, он обладает рядом преимуществ. Одним из них является возможность отложить перезагрузку до выполнения планового обслуживания. Это позволяет максимально увеличить доступность системы. Еще одним преимуществом является то, что обновления для системы безопасности не только устанавливаются, но и немедленно активируются.

Хотя обновление ядра «на лету» имеет свои риски, последствия известных проблем можно минимизировать.

Требования

Для оперативного обновления необходимо обеспечить выполнение некоторых требований. Прежде всего, нужно обеспечить поддержку Livepatch в самом ядре. В версиях 4.x первоначальная поддержка уже добавлена, то есть достаточно использовать более современное ядро. Во-вторых, системе необходим клиентский инструмент для извлечения патчей ядра и их загрузки. Чтобы разрешить загрузку патчей ядра, в системе должна быть включена возможность загрузки модулей ядра. Патчи ядра обычно создаются поставщиком дистрибутива Linux. Чтобы знать, как перенаправлять наборы команд, требуется определенная практика.

Как работает обновление ядра «на лету»?

Обновление ядра в процессе его работы реализуется с помощью трех механизмов:

  • Kernel probes (Kprobes). Kprobes позволяет внедрять код в ядро. Это называется точкой останова и позволяет разработчику определить желаемое поведение при ее достижении. Такое действие может быть использовано для запуска нового набора инструкций.
  • Function tracing (Ftrace). Ftrace используется для измерения производительности функций ядра.
  • Live patching (Livepatch). Livepatch — это третий компонент. С помощью специального обработчика Ftrace он может перенаправлять процедуры и переходить к исправленному набору инструкций.

Исправление начинается с создания патча. Это означает, что конкретная функция ядра должна быть изменена. Создание патча может быть сделано с помощью такого инструмента, как kpatch-build. В результате получается модуль ядра, который затем распространяется. Когда этот модуль загружен, он обеспечивает, что процессы, использующие определенный системный вызов, используют его исправленную версию.

История реализации механизмов live patching

Первой рабочей реализацией исправления ядра на лету была Ksplice. Этот проект был частью университетских исследований MIT. Для продвижения новой технологии четверо студентов создали компанию Ksplice, Inc. Oracle приобрели компанию Ksplice и сделали сервис одним из основных компонентов своего дистрибутива Oracle Linux.

В 2014 году Red Hat создала Kpatch и выпустила его под лицензией GPLv2. В том же году SUSE объявил о выходе kGraft. Обе технологии очень похожи с небольшими отличиями. Оба инструмента нацелены в первую очередь на подмену функций с использованием встроенного механизма ядра Ftrace. Патч для наложения в обоих случаях оформляется как подгружаемый модуль ядра. Тем не менее, как в механизме применения патчей, так и в их формате и процедуре их подготовки у Kpatch и kGraft есть существенные различия. В частности, при применении патчей Kpatch проверяет, что ни один из процессов не выполняет функции, которые будут обновлены. Для этого приходится ненадолго останавливать все процессы в системе. kGraft же работает с каждым процессом отдельно – некоторые из них при этом могут использовать старые варианты функций, некоторые – уже новые. Постепенно все процессы в системе переходят на использование новых функций. При этом нет необходимости их останавливать. Если kGraft требует создания патча вручную, Kpatch позволяет создавать патчи как вручную, так и автоматически.

Коммерческие предложения

Поскольку эта функция пользуется большим спросом, большинство дистрибутивов Linux предлагают такую возможность только в качестве платного дополнения. Такие технологии, как Ksplice, Kpatch и kGraft, коммерчески интересны для поставщиков. Типичный пользователь Livepatch готов платить за ее использование.

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

Kernel Live Patching Core

Реализация, расположенная в дереве исходного кода ядра Linux, называется Livepatch. Она вобрала в себя лучшее от Kpatch и kGraft. Она использует Kernel Live Patching Core и доступна каждому. Специальных патчей не требуется, так как эта функциональность теперь является одним из компонентов ядра.

Дистрибутивы, поддерживающие обновление ядра без перезагрузки

На данный момент тестировать Livepatch непросто, так как не все ядра его поддерживают или имеют инструменты клиента для добавления и применения патчей. Но есть другие различные технологии, такие как Kpatch, ksplice, kGraft и Livepatch. Приведем краткий обзор некоторых доступных в дистрибутивах реализаций исправления без перезагрузки.

  • Arch Linux (Livepatch, Kpatch-git)
  • Gentoo (Kpatch или ksplice)
  • Oracle Linux (ksplice)
  • Red Hat Enterprise Linux 7 (Kpatch или ksplice)
  • SUSE (kGraft)
  • Ubuntu 16.04 и выше (Livepatch)

Поддержка Livepatch в ядре

Чтобы проверить, поддерживается ли у вас обновление ядра без перезагрузки, посмотрите, включена ли настройка CONFIG_HAVE_LIVEPATCH. Выберите способ проверки в зависимости от используемого дистрибутива Linux:

Arch Linux

zcat /proc/config.gz | grep LIVEPATCH

Если настройка включена, вернется ответ CONFIG_HAVE_LIVEPATCH=y.

Ubuntu

При работе на Ubuntu загляните в директорию /boot:

cat /boot/config-$(uname -r) | grep LIVEPATCH

Статус Livepatch через Sysfs

Если в ядре включена поддержка добавления патчей без перезагрузки, есть другой способ проверки. Записи и патчи Livepatch можно найти в псевдо-файловой системе sysfs. Найдите каталог /sys/kernel/livepatch.

ls -ld /sys/kernel/livepatch

Если каталог livepatch присутствует, значит, поддержка ядра включена.

Применение патчей ядра Linux без перезагрузки

Для обновления патчей ядра без перезагрузки нужен клиент. У клиента есть инструкции, как работать с конкретным ядром. В статье мы будем использовать Ubuntu 16.04 (LTS). Клиентская утилита является коммерческой (предоставляется Canonical). К счастью, пользователям разрешается вносить изменения в одну-три системы бесплатно. Чтобы использовать утилиту, необходимо создать токен.

Установка клиента

Воспользуемся canonical-livepath (Ubuntu)

Первым шагом является установка утилиты Livepatch с именем canonical-livepatch с помощью snap.

sudo snap install canonical-livepatch

Активируем Livepatch:

sudo canonical-livepatch enable [token]

Должен прийти положительный ответ Successfully enabled device. Using machine-token: [token]. Если вернулась ошибка, обратитесь к разделу в конце статьи, где описаны возможные типичные ошибки.

Теперь, когда клиентская утилита установлена, можно ее использовать. Запустите ее командой status.

canonical-livepatch status

Также, можно использовать флаг --verbose для просмотра информации о примененных патчах. Например, можно посмотреть, какая CVE используется.

Убедимся, что ядро успешно обновлено

Для проверки примененных патчей вы можете использовать следующие способы:

1.Использование директории livepatch

Первым способом является проверка директории /sys/kernel/livepatch, посмотрим, есть ли в ней какие-либо записи.

Мы видим, что один патч применен. Его версия совпадает с версией ядра. Последняя цифра в имени директории является номером версии, указанной в выводе canonical-livepatch.

2. Использование флага tainted

Другой способ проверить, что ядро обновилось, — посмотреть, есть ли в /proc/sys/kernel/tainted значение больше нуля. Если есть, то это говорит дебаггеру и другим устройствам о том, что ядро было изменено.

cat /proc/sys/kernel/tainted

Больше информации о том, кто внес изменения в ядро можно узнать, используя dmesg:

dmesg -T | grep tainted

Можно использовать эту же команду для просмотра деталей обновлений.

Предостережения

Если ваша система хорошо защищена, и загрузка модулей ядра отключена, то Livepatch работать не будет.

Чтобы проверить, разрешает ли ваше ядро загрузку модулей, посмотрите /proc/sys/kernel/modules_disabled.

cat /proc/sys/kernel/modules_disabled

Если возвращается 1, то модули ядра нельзя загрузить, и Livepatch не будет работать.

Ошибки в работе Livepatch

Соединение с демоном разорвалось (Ubuntu)

$ canonical-livepatch
2016/10/19 17:01:26 Error executing enable.
Connection to the daemon failed: Get http://127.0.0.1/enable: dial unix /var/snap/canonical-livepatch/15/livepatchd.sock: connect: no such file or directory

Это ошибка наиболее часто возникает, когда пакет snapd устарел. Обновите его, используя sudo apt install snapd.

Команда не найдена (Ubuntu)

sudo: canonical-livepatch: command not found

Скорее всего, каталог для snaps не определен в переменной PATH. В этом случае обратитесь к утилите, используя полный путь (/snap/bin/canonical-livepatch).

Полезные ссылки

Больше информации о Livepatch можно найти по ссылкам: