Технология удалённого шифрования дисковых подсистем в Red Hat Enterprise Linux (Александр Боковой, OSSDEVCONF-2018)
Материал из 0x1.tv
- Докладчик
- Александр Боковой
- Если данные зашифрованы, кто и когда должен иметь к ним доступ при облачном хранении?
- Как предохранить украденные данные от расшифровки?
- Как уменьшить риски воровства при транспортировке физического носителя?
Свободные проекты Clevis и Tang обеспечивают привязку данных к внешним ресурсам. Вместе они создают простую и масштабируемую платформу для шифрования хранимых данных и обеспечения контроля за их доступом.
Содержание
Видео
Посмотрели доклад? Понравился? Напишите комментарий! Не согласны? Тем более напишите.
Презентация
Thesis
Типичная ситуация когда пропадает электричество — машины в датацентре необходимо загрузить заново. Диски этих машин зашифрованы, так что сотрудникам приходится бегать между консолями и вводить пароли. Хотелось бы определённой автоматизации.
Если вчера мы в основном работали над тем, чтобы стандартизировать криптографические примитивы и их использование, то сегодня фокус на автоматизации процессов. Стандарты важны, но их использование тоже должно быть удобным. А завтра нам потребуются правила применения автоматизации, потому что вся эта автоматизация сегодня бинарная: «можно ли разблокировать автоматически этот том? да/нет». Но когда мы мы всё автоматизируем, станет понятно, что мы хотим расшифровывать данные в разных условиях и согласно разным правилам. В конце концов, всё сведётся к ответу «да/нет?», но путь, который к этому ответу приводит, может быть извилистым. Так что политики применения или правила будут скорее «слайдером», чем простым переключателем.
Однако первый вопрос, на который стоит ответить — «Как идёт автоматизация?». Всё начинается со страшной тайны — данных, которые мы хотим зашифровать. Эти данные шифруются с помощью симметричной криптографии. Ключ шифрования наших данных сам подвергается шифрованию с помощью ещё одного симметричного ключа шифрования ключа шифрования. Это стандартная модель, используемая много где, в частности, в подсистеме LUKS в ядре Линукс. Стандартная модель подразумевает, что любой, кто должен расшифровать ключ шифрования, должен иметь доступ к паролю ключа шифрования ключа шифрования.
Чтобы избежать такого распространения паролей, мы используем значительно более стойкий ключ, который сохраним в системе депонирования ключей. В случае необходимости мы запросим этот ключ из системы депонирования ключей. Проблема с этой архитектурой в том, что она подразумевает целый ряд не всегда озвучиваемых требований:
- канал обмена данными с системой депонирования ключей нужно шифровать
- клиент должен удостовериться, что запрос обработан доверяемым сервером системы депонирования ключей
- сервер системы депонирования ключей должен удостовериться, что запрос пришёл от доверяемого клиента
- обе стороны должны поддерживать одну и ту же цепь доверительных отношений, чтобы эта аутентификация и проверка сработала (общий удостоверяющий центр или KDC)
- система депонирования ключей, общий удостоверяющий центр или KDC должны своевременно бэкапиться.
Фактически, нам нужно бэкапить состояние и ключи всех вовлечённых центров и систем. Если мы потеряем ключи, хранимые в системе депонирования, мы потеряем данные на наших машинах. Если потеряем ключи удостоверяющего центра или KDC, не сможем организовать защищённый канал обмена с серверами системы депонирования.
Это стандартная модель депонирования ключей, здесь нет ничего экзотического, её используют многие решения на рынке. К сожалению, уязвимость HEARTBLEED показала, что даже для хорошо налаженной TLS системы возможны сбои и чтение зашифрованных данных в сети.
HEARTBLEED научила нас, что
- опасно предполагать, что перенос ключей можно защитить средствами TLS
- сложность архитектуры увеличивает поверхность для атаки
- системы депонирования ключей сложны для внедрения, даже если использовать средства автоматизации
- x.509 сложно использовать правильно. Ситуации, когда приватный ключ отсылается вместо публичного совсем не единичны. Код, реализующий стандарты семейства x.509, тоже подвержен ошибкам, не говоря уже о классических проблемах с кодированием и декодированием данных в нотации ASN.1.
Однако, то, что мы делаем для получения изначальной страшной тайны, выглядит фактически как обмен ключами. Cтандартный протокол Диффи-Хеллмана на эллиптических кривых позволяет участникам создать общий секрет для порождения ключа для шифрования. Каждый участник генерирует пару приватный-публичный ключи ( и для клиента, и для сервера, соответственно). Оба участника обмениваются своими публичными ключами и используют их для вычисления общего секрета . Если оба участника не используют дополнительную информацию друг о друге, обмен можно считать анонимным. Полученный общий секрет K либо прямо используется для шифрования, либо используется для порождения ключа для шифрования.
Однако этот подход подразумевает, что клиент хранит свой приватный ключ для взаимодействия с сервером. Мы же хотим добиться восстановления ключа шифрования только при наличи сервера. Разобьём процесс на стадию генерации (provision) и стадию восстановления (recovery).
Первый шаг — сервер генерирует приватный ключ. Используя приватный ключ, он генерирует публичный ключ и публикует его для тех, кто его запросит. Клиент может взять этот публичный ключ каким-угодно способом — либо связавшись с сервером или получив этот ключ в оффлайне. Когда клиент захочет зашифровать данные, то он сгенерирует свой приватный ключ и вычислит свой публичный ключ. Используя публичный ключ сервера и свой приватный ключ, он может вычислить общий секрет . Этот ключ (или его производную) клиент затем использует для шифрования данных.
Когда данные зашифрованы, клиент уничтожает общий секрет и приватный ключ клиента. Это означает, что у клиента остаётся только его публичный ключ и публичный ключ сервера. Клиент больше не может вычислить общий секрет самостоятельно.
Для восстановления клиент может послать собственный публичный ключ серверу. Сервер вычислит общий секрет и отправит его назад. Этот режим значительно легче, чем традиционная система депонирования ключей. У сервера нет никакого состояния клиента. Всё, что ему достаточно знать — свой приватный ключ. К сожалению, этот режим полностью небезопасен.
Во-первых, общий секрет теперь посылается по сети в открытом виде, так что он доступен пассивному наблюдателю. Даже если этот наблюдатель не сумел перехватить обмен с сервером, ему достаточно получить доступ к публичному ключу клиента, чтобы самому повторить этот обмен. К тому же, сам сервер, получив доступ к публичному ключу клиента, вычисляет общий секрет и может скомпромитировать клиента. То есть, публичный ключ клиента в этом обмене должен быть секретным.
Мы на самом деле можем этого добиться небольшим изменением ECDH, которое было изобретено Натаниелем МакКаллумом и Бобом Релья из Red Hat. На стадии генерации ничего не меняется. Все изменения — при восстановлении ключа. Как и прежде, клиент вычисляет общий секрет , шифрует данные, уничтожает и свой приватный ключ, так что теперь невозможно расшифровать данные в одиночку.
Генерация:
Когда нужно расшифровать данные, клиент генерирует эфемерную пару ключей. Она создаётся каждый раз, когда клиенту необходимо получить ключ для расшифровки данных. Клиент складывает свой основной публичный ключ с эфемерным публичным ключем. Результат отсылается на сервер. Сервер выполняет свою часть протокола Диффи-Хеллмана, посылает общий секрет назад. И клиент может вычислить настоящий общий секрет , вычитая из полученного y произведение публичного ключа сервера на приватный эфемерный ключ. Это очень простая математика, но если мы никогда не распространяем эфемерную пару ключей, то и наш публичный ключ клиента остаётся секретным.
Восстановление:
Сервер получает что-то, что выглядит как случайный публичный ключ. Алгоритму всё равно, над чем производить вычисление, но этот обмен также не содержит никакой информации, которая могла бы идентифицировать клиента (кроме IP-адреса соединения). Для сервера это простая операция, а пассивный наблюдатель не может ничего поделать с перехваченным результатом, потому что у него нет доступа к эфемерной паре ключей.
Этот обмен удивительно быстр. В случае соединения TLS первым делом выполняется обмен Диффи-Хеллмана. В нашем случае нам не требуется выполнять ничего больше. Шифрование данных в сети не требуется, потому что это просто обмен публичными ключами. На сервер не требуется хранить какое-либо состояние для каждого клиента. Никаких дополнительных бэкапов.
Если ключ сервера поместить в крипто-оборудование, то сам сервер не будет иметь доступа к какому-либо крипто-материалу, который можно было бы украсть. Атакующий сможет только добиться подписывания нескольких ключей, но не сможет унести приватный ключ сервера с собой.
Проект, который реализует серверную часть, называется Tang. Сервер очень прост: это минимальный HTTP сервер, общающийся с клиентом при помощи JOSE (JSON Object Signing and Encryption). Он достаточно быстр — однопоточный сервер на обычном ноутбуке справляется с более чем 2000 запросов в секунду. Код минимальный, имеет минимальные зависимости и хорошо переносим.
На стороне клиента мы представили всю логику в рамках проекта Clevis. У него тоже минимальные зависимости, он интегрирован с системой ранней загрузки в Fedora/RHEL/CentOS и со средой GNOME. Clevis доступен в Fedora 24+, RHEL 7.4+, а также в Debian Testing.
Зашифрованные данные представляют из себя стандартный токен JSON Web Encryption.
Зашифрованный блок данных с привязкой к серверу Tang можно хранить где угодно. Например, его можно хранить в заголовке метаданных раздела формата LUKS. Это применимо как к основному тому, который разблокируется при загрузке, если есть доступ к серверу Tang, так и к динамически подключаемым томам в графической среде GNOME.
Разблокирование в момент загрузки подразумевает сетевой доступ из initrd. В результате, полученный том можно разблокировать только при наличии сетевой связности с соответствующим сервером Tang. Если зашифрованный диск перевозят между центрами обработки данных, то за сохранность данных можно не беспокоиться.
Но что делать, если необходимы гарантии доступности данных только в рамках конкретного сервера, если диск вставлен в его шасси?
На помощь приходит другая известная математическая модель. Мы хотим не просто автоматизировать доступ, но сделать это на основании определённых правил. В 1979 году израильский криптоаналитик Ади Шамир предложил пороговую схему разделения секрета между несколькими участниками так, что
- для восстановления секрета достаточно определённое количество участников
- меньшее количество участников не могут получить никакой информации о секрете.
Схема разделения секрета Шамира позволяет строить деревья решений, для которых можно предопределить какие ветки должны присутствовать обязательно одновременно на каждом уровне. В Clevis реализована схема разделения секрета Шамира для связывания различных пинов между собой. Таким образом, можно потребовать ввод пароля, запрос от сервера Tang или что-то ещё и построить политику на основании нужных нам требований. Все операции (пины) Clevis в заданой политике вызывает параллельно друг другу, так что они выполняются независимо.
Одно из новшевств в бета-версии RHEL 7.6 — поддержка стандарта TPM 2.0 в качестве пина Clevis. На платформах, где присутствует TPM 2.0, можно хранить ключ для разблокирования раздела LUKS в аппаратном модуле TPM 2.0. Если в описании политики Clevis использовать схему разделения секрета Шамира и потребовать дополнительно привязку к серверу Tang, то при использовании порога 2 мы фактически требуем одновременно нахождение раздела LUKS в определённом шасси и доступ к определённому серверу Tang.
Примечания и ссылки
Plays:72 Comments:0