Защищаем приватные ключи от кражи из VPS

    В начале каждого семестра студенты магистерской программы кафедры МиИТ Академического университета (СПб) и представители компаний-партнеров собираются вместе. Представители рассказывают о проектах, над которыми можно будет работать, а студенты выбирают их.

    В одном из проектов, сделанных в Parallels Labs, наш студент исследовал возможность реализации виртуального Hardware Security Module (HSM). В результате он добавил свою реализацию VHSM в open-source проект OpenVZ. Подробнее о его решении читайте под катом.

    Что такое HSM


    Представим себе приложение, которое подписывает отправляемые на сервер данные с помощью приватного ключа. Пусть утеря данного ключа неприемлема для его собственника. Как защитить такой ценный ключ от утечки в результате удаленного взлома системы? Подход с использованием HSM предлагает нам вообще не давать уязвимой части системы доступ к содержимому ключа. HSM – это физическое устройство, которое само хранит цифровые ключи или другие секретные данные, управляет ими, генерирует их, а также производит с их помощью криптографические операции. Все операции над данными производятся внутри HSM, а пользователь имеет доступ только к результатам этих операций. Внутренняя память устройства защищена от физического доступа и взлома. При попытке проникновения все секретные данные уничтожаются.

    Чтобы начать использовать HSM, пользователь должен себя аутентифицировать. Если аутентификация выполняется через приложение-клиент HSM, работающее в уязвимой части системы, то возможен перехват пароля HSM злоумышленником. Перехваченный пароль даст возможность злоумышленнику использовать HSM без получения секретных данных, хранящихся в нем. Таким образом, аутентификацию желательно выполнять в обход уязвимой части системы, например, при помощи физического ввода PIN.

    Основным барьером в использовании HSM является их высокая стоимость. В зависимости от класса устройства цена может варьироваться от 10$ (USB токены, smart карты) до 30000+$ (устройства с аппаратным ускорением криптографии, защитой от взлома, high availability функциями). Провайдеры cloud решений не оставили без внимания рынок HSM. Например, Amazon продает свой облачный HSM по средней цене 1373$ в месяц.

    Одной из основных особенностей HSM является изоляция уязвимой части системы, использующей криптографические сервисы, от HSM, исполняющей эти сервисы. Заметим, что отдельные инстансы (виртуальные машины, контейнеры и т.д.), в облаке изолированы друг от друга, поэтому если вынести функции HSM за пределы уязвимого инстанса в другой изолированный от внешнего мира инстанс, то мы достаточно точно воспроизведем функциональность физического HSM. Такой подход мы назвали Virtual HSM (VHSM). Рассмотрим как он был реализован нашим студентом для проекта OpenVZ.

    Что такое OpenVZ


    OpenVZ – это одна из технологий для запуска множества изолированных ОС Linux на одном ядре Linux. При этом говорят, что каждая ОС Linux работает в отдельном контейнере. Если сильно упрощать, то фактически в ядро Linux встроена функциональность, которая позволяет изолировать приложения, приписанные разным контейнерам так, чтобы они не подозревали о существовании друг друга. Приложения не могут сменить свой контейнер. Для лучшей изоляции и безопасности коммуникация между приложениями из разных контейнеров при помощи средств IPC запрещена. Обычно она осуществляется с помощью сетевых соединений. В итоге мы видим сходство контейнеров с “обычными” виртуальными машинами. OpenVZ и технологии на ее основе популярны у хостинг провайдеров для создания VPS. В Академическом университете уже делались проекты, связанные с контейнерной виртуализацией. Например habrahabr.ru/company/parallels/blog/174211. Parallels – главный разработчик OpenVZ. Вполне закономерной стала реализация VHSM именно для OpenVZ.

    Архитектура Virtual HSM



    • Client VE – контейнер OpenVZ, в котором выполняются пользовательские приложения, требующие для своей работы криптографические сервисы, такие как шифрование, подпись и т.д. Контейнер доступен для удаленных атак с целью кражи цифровых ключей.
    • VHSM virtual environment (VHSM VE) — контейнер OpenVZ, в котором запущен VHSM server – демон, принимающий команды от приложений в Client VE и исполняющий их. Никаких других приложений в VHSM VE не запущено. VHSM VE изолирован от обычных пользовательских контейнеров при помощи OpenVZ. У контейнера нет сетевых интерфейсов и он не доступен по сети.
    • Transport – модуль ядра Linux, предназначенный для передачи сообщений из Client VE в VHSM VE и обратно.
    • VHSM API – библиотека, реализующая часть стандартного для HSM интерфейса PKCS #11, передающая команды приложений из ClientVE в VHSM server при помощи transport, и возвращающая результат выполнения команды приложению в ClientVE.

    Рассмотри каждый компонент подробнее.

    VHSM virtual environment


    Сервер VHSM отвечает за аутентификацию пользователей, взаимодействие с хранилищем секретных данных и выполнение криптографических операций. Кроме сервера VHSM, VHSM VE содержит Secure Storage – базу данных, хранящую важную информацию в зашифрованном виде. Каждый пользователь VHSM имеет свой мастер ключ, которым шифруются его данные. Мастер ключ генерируется из пароля пользователя при помощи функции PBKDF2. Передаваемая ей на вход соль хранится в незашифрованном виде в базе данных. Таким образом, VHSM не хранит мастер ключ пользователя в БД, а использование PBKDF2 существенно снижает скорость перебора исходного пароля пользователя при краже БД.

    Пользователь регистрируется в VHSM администратором, в роли которого может выступать как человек, так и программа. При регистрации пользователя VHSM генерирует 256-битный ключ аутентификации и шифрует его мастер ключом с помощью AES-GCM. Далее, перед использованием VHSM, пользователь аутентифицирует себя парой логин-пароль. Во время аутентификации, мастер-ключ, сформированный из пароля и соли, используется для расшифровывания ключа аутентификации пользователя. Использование GCM позволяет проверить правильность мастер-ключа при расшифровке. Мастер-ключ получается из пароля пользователя, и потому проверка его правильности позволяет проверить и сам пароль пользователя, переданный при аутентификации. После успешной аутентификации пользователю становятся доступны криптографические сервисы, использующие хранящиеся в VHSM цифровые ключи пользователя.

    VHSM требует явного выбора контейнеров, из которых конкретный пользователь может работать с VHSM. Информация о контейнере, из которого получена команда пользователя, предоставляется OpenVZ.

    VHSM API


    Это C-библиотека, находящаяся в пользовательских контейнерах и реализующая часть стандартного для HSM интерфейса PKCS#11, позволяющего управлять ключами, данными, сессиями, цифровой подписью, шифрованием и т.д. Рассмотрим конкретный пример использования VHSM API:
    1. Приложению в пользовательском контейнере необходимо подписать отправляемое сообщение.
    2. При помощи VHSM API приложение генерирует пару открытый-закрытый ключ, получает ID закрытого ключа и открытый ключ.
    3. Приложение передает сообщение в VHSM API для подписывания закрытым ключом с нужным ID. VHSM API возвращает подписанное сообщение.
    4. Подписанное сообщение и открытый ключ передаются получателю сообщения. При этом закрытый ключ не доступен клиентскому контейнеру.

    В клиентской части проекта также были реализованы OpenSSL engine и PAM-модуль, позволяющие работать с VHSM в существующих приложениях, использующих OpenSSL и PAM. Однако, эта часть проекта слабо проработана и представляет собой скорее proof of concept.

    VHSM Transport


    Как было сказано выше, приложения, исполняющиеся в разных контейнерах, не могут взаимодействовать друг с другом при помощи механизмов IPC Linux. Поэтому для транспортировки сообщений от клиентов к серверу и обратно был реализован свой загружаемый модуль ядра Linux. Модуль запускает Netlink-сервер в ядре, а VHSM-клиенты и VHSM-сервер соединяются с ним. Netlink-сервер отвечает за передачу сообщений от источника (клиента VHSM) к приемнику (серверу VHSM) и обратно. Попутно к сообщениям добавляется ID контейнера источника сообщения, чтобы, например, сервер мог отклонить запросы от контейнеров, из которых конкретному пользователю запрещено использовать VHSM.

    Заключение


    Основной целью создания VHSM было исключение возможности кражи секретных ключей из памяти пользовательских приложений, работающих в пользовательском контейнере. Эта цель была достигнута, т.к. секретные данные доступны только в изолированном контейнере (VHSM VE). Изоляция реализуется OpenVZ.

    Утечка БД из VHSM VE не приведет к немедленной утрате секретных данных, т.к. они хранятся в зашифрованном виде. Ключ шифрования не хранится в БД, а генерируется из пароля пользователя, передающегося при его аутентификации.
    Как и любая технология защиты иформации, приведенное решение является еще одним барьером на пути злоумышленника и не обеспечивает полной защиты информации.

    Comments 19

      +13
      Совершенно бесполезная в реальных условиях VDS'ок схема. Я-то надеялся, что кто-то придумал как использовать секрет, не помещая его plaintext'ом в память и не тыкая спецжелезо.
        +2
        С тем же успехом можно было эту функциональность реализовать как обычный сетевой сервис, никак не связанный с OpenVZ, без модулей ядра и прочей избыточной сложности.
          0
          Обычный сетевой сервис надо дополнительно закрывать от внешнего мира (вот смеху-то будет, если хакер скопирует к себе контейнер и будет работать с ним локально, обращаясь за криптографией к этому самому сервису через инет).

          Кроме того, сетевой трафик можно перехватить — то есть его придется шифровать дополнительно.
            0
            Разрешить доступ к этому сервису для конкретного юзера только с определённого IP — на много порядков проще, чем реализовывать всё, описанное в статье.

            Но я не вижу особой разницы в том, будет хакер после взлома контейнера работать прямо в нём, или запустит копию контейнера у себя — «палится» он в обоих случаях примерно одинаково. Более того, во втором случае сервис автоматически отследит активность с незнакомого IP, даже если не будет её блокировать, а в первом — кто знает, есть ли вообще хоть какая-то IDS в этом контейнере, или, как обычно, хакера никто не будет замечать месяцами.
          0
          Т.е. теперь в контейнере хранится не приватный ключ, а пара логин/пароль для доступа к VHSM? Чем это отличается от хищения приватного ключа? Даже если логин/пароль нужно будет физически вводить, допустим, при каждой перезагрузке контейнера, всё равно угон контейнера с содержимым памяти равнозначен хищению ключа.

          В общем, неясно, чем это может помочь в реальной жизни.
            0
            С содержимым физической памяти сервера? Это да. Но это обычно сложнее, чем угнать один контейнер.
              0
              Но контейнер при этом нельзя будет скопировать куда-нибудь к себе — взломанный контейнер придется использовать на месте. Больше шансов, что заметят.

              Плюс логин с паролем можно поменять не меняя приватный ключ — и не получая на него все сертификаты заново.
              0
              Зачем? После того как выяснится, что произошел взлом, шатдаунится VPS и вы не теряете свой приватный ключ.
              Если добавить сюда многофакторную аутентификацию, то будет еще больше похоже на реальный HSM с физическим вводом PIN. Понадобится еще какой-то UI, работа с телефоном пользователя (если по смс, например).
              Хранение в общей физической памяти ключей плейн текстом — не круто, да. И как написал powerman, можно было действительно обойтись без модулей ядра.

              Если всю VHSM на отдельный сервер перенести и сделать двухфакторную аутентификацию, норм будет? Можно из этого сервис попробовать сделать?
                0
                После того, как произошел взлом, вы уже потеряли свой приватный ключ.
                  –1
                  Если произошел взлом и получен root от машины, у которой есть доступ к [v]hsm этот рут может не угоняя ключа натворить достаточно.
                0
                Зря потратил время на чтение.
                Еще одна software реализация функционала HSM.

                Фактически HSM это комп. с фиксированным внешним интерфейсом. Старый Racal RG8000 вообще на Z80 собран…
                Но деньги производители дерут за то что их железки прошли сертификацию и есть хотя бы какая то гарантия, что дыр нет.

                  0
                  Строго сертифицированные дыры. ))
                  0
                  Это какой-то SSM. Слово Hardware означает все-таки, что должен быть аппаратный модуль. Вся суть в том, что в аппаратном модуле есть защиты от вторжений, в том числе, от аппаратных вторжений. Вы не сможете, например, считать содержимое оперативной памяти HSM. При попытке практически любого внешнего несанкционированного воздействия содержимое HSM просто сотрется.
                    0
                    … коммуникация… при помощи средств IPC запрещена. Обычно она осуществляется с помощью сетевых соединений.


                    Сетевые соединения (сокеты) — это тоже один из видов IPC.
                      0
                      А VHSM может заменить реальные HSM-ы, например, на этапе разработки? Т.е. нужен заказчику HSM, но для разработки\прототипирования используем VHSM, а потом уже подключаем реальный HSM. Собственно вопрос в том насколько этот VHSM совместим с реальными HSM :)
                        0
                        А как собрать? Мне вот интересен транспорт по netlink из доверенной машины до ВПСок на ноде. Где взять модули под это дело и насколько это оттестировано?
                        0
                        Хочу сам реализовать софтварно HSM. Не нашёл ни где аналогов, кроме этого.
                        Думал попробовать уже имеющие API SafeNet и/или Thales. В итоге сейчас получается для Thales отвечать на эхо. :-)
                        С запросами балуюсь через такую тулзу как BP HSM Commander, в качестве эмулятора сейчас использую Hercules с уже заготовленными ответами.

                        Можно где ни будь найти то что отвечает HSM(существующие реальные железки) на те или иные команды? Не хотелось бы реализовывать свой протокол клиент-сервер.

                        Only users with full accounts can post comments. Log in, please.