Linux: удаление пула блокировок /dev/random

Автор оригинала: Джейк Эдж
  • Перевод
  • Tutorial
Как известно, у /dev/random, криптографически стойкого генератора псевдослучайных чисел (CSPRNG), имеется одна неприятная проблема – блокировки. В данной статье рассказывается, каким образом можно ее решить.

За последние несколько месяцев средства генерации случайных чисел в ядре были немного переработаны, но проблемы в этой подсистеме решались на протяжении более широких временных рамок. Самые последние изменения были сделаны с целью предотвратить длительную блокировку системного вызова getrandom () при загрузке системы, но причиной, лежащей в основе этого, было поведение блокирующего случайного пула. Недавний патч удалил бы этот пул, и, следовало ожидать, что он направится к основному ядру.

Энди Лутомирски (Andy Lutomirski) опубликовал третью версию патча в конце декабря. Он вносит «два основных семантических изменения в случайных API Linux». Патч добавляет новый флаг GRND_INSECURE к системному вызову getrandom() (хотя Лутомирский обращается к нему как к getentropy(), который реализован в glibc с помощью getrandom() с фиксированными флагами); этот флаг заставляет вызов всегда возвращать количество запрошенных данных, но без гарантии, что эти данные случайны. Ядро просто приложит все усилия, чтобы дать наилучшие случайные данные, которые у него есть на данный момент времени. «Вероятно, лучшее, что можно сделать, это назвать его „INSECURE“ (небезопасным), чтобы воспрепятствовать использованию этого API для вещей, которые нуждаются в безопасности».

Патчи также удаляют блокирующий пул. В настоящее время ядро поддерживает два пула случайных данных, один из которых соответствует /dev/random, а другой — /dev/urandom, как описано в этой статье 2015 года. Блокирующий пул — это пул для /dev/random; чтение для этого устройства будет блокироваться (имеется в виду его имя) до тех пор, пока из системы не будет собрана «достаточная» энтропия для удовлетворения запроса. Дальнейшие чтения из этого файла также блокируются, если в пуле недостаточно энтропии.

Удаление пула блокировок означает, что чтение из /dev/random ведет себя как getrandom() со значением flags равным нулю (и превращает флаг GRND_RANDOM в noop). После инициализации криптографического генератора случайных чисел (CRNG), чтение из /dev/random и вызовы getrandom(...,0) не приведет к блокировке и вернет запрошенное количество случайных данных.

Лутомирский говорит: «Я считаю, что блокирующий пул Linux изжил себя. CRNG Linux генерирует выходные данные, которые достаточно хороши, чтобы использовать их даже для генерации ключей. Блокирующий пул не является более сильным в любом материальном отношении, и для его поддержания требуется много инфраструктуры сомнительной ценности».

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

«Эти серии не должны нарушать никаких существующих программ. /dev/urandom остается неизменным. /dev/random по-прежнему блокируется сразу после загрузки, но блокируется меньше, чем раньше. getentropy () с существующими флагами вернет результат, который будет таким же подходящим для практических целей, как и раньше».

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

Штефан Мюллер (Stephan Müller) предположил, что его набор патчей для генератора случайных чисел Linux (LRNG) (в настоящее время выпущена 26 версия) может быть способом предоставления истинных случайных чисел для приложений, которые в этом нуждаются. LRNG «полностью соответствует требованиям «Рекомендаций по источникам энтропии, используемым для генерации случайных битов» SP800-90B», что делает его решением проблемы государственных стандартов.
Мэтью Гарретт (Matthew Garrett) возражал против термина «истинные случайные данные», отмечая, что выбираемые устройства в принципе могут быть смоделированы достаточно точно, чтобы сделать их предсказуемыми: «мы здесь не отбираем квантовые события».

Мюллер ответил, что этот термин происходит от немецкого стандарта AIS 31 для описания генератора случайных чисел, который только выдает результат «с такой же скоростью, с какой базовый источник шума производит энтропию».

Помимо разночтений терминологии, наличие пула блокировки, как это предлагается патчами LRNG, просто приведет к различным проблемам, по крайней мере, если он доступен без привилегий.

Как сказал Лутомирский: «Это не решает проблему. Если два разных пользователя запускают глупые программы, такие как gnupg, они просто истощат друг друга. Я вижу, что в настоящее время существуют две основные проблемы с /dev/random: он подвержен DoS (т. е. истощению ресурсов, вредоносному влиянию или чему-то подобному), и, поскольку никаких привилегий для его использования не требуется, он также подвержен злоупотреблениям. Gnupg — это неправильно, это полный коллапс. Если мы добавим новый непривилегированный интерфейс, который будут использовать gnupg и аналогичные программы, мы снова проиграем».

Мюллер отметил, что добавление getrandom() теперь позволит GnuPG использовать этот интерфейс, поскольку он обеспечит необходимую гарантию того, что пул был инициализирован. На основе дискуссий с разработчиком GnuPG Вернером Кохом (Werner Koch) Мюллер считает, что гарантия — это единственная причина, по которой GnuPG в настоящее время читает непосредственно из /dev/random. Но если есть непривилегированный интерфейс, который подвержен отказу в обслуживании (как на сегодня /dev/random), то по утверждению Лутомирского, он будет неправильно использоваться некоторыми приложениями.

Теодор Цао (Theodore Yue Tak Ts'o), разработчик подсистемы случайных чисел Linux, по-видимому, изменил свое мнение по поводу необходимости блокирующего пула. Он сказал, что удаление этого пула позволит эффективно избавиться от идеи, что Linux имеет настоящий генератор случайных чисел (TRNG): «это не является бессмыслицей, так как это именно то, что всегда делали *BSD".

Он также обеспокоен тем, что предоставление механизма TRNG будет просто служить в качестве приманки для разработчиков приложений и считает, что на самом деле, учитывая различные типы аппаратного обеспечения, поддерживаемого Linux, невозможно гарантировать TRNG в ядре. Проблему не решит даже возможность работы с оборудованием только на основе root-привилегий: «Разработчики прикладных программ указывают, чтобы их приложение в целях безопасности было установлено как root, потому только так вы можете получить доступ к «действительно хорошим» случайным числам".

Мюллер спросил, не отказался ли Цао от реализации блокирующего пула, которую он сам давно предложил. Цао ответил, что планирует взять патчи Лутомирского и активно возражает против добавления блокирующего интерфейса обратно в ядро.

«Ядро не может дать никаких гарантий относительно того, был ли охарактеризован noise source надлежащим образом. Единственное, что может получить разработчик GPG или OpenSSL — это смутное ощущение, что TRUERANDOM «лучше», а поскольку они хотят большей безопасности, то, несомненно, попытаются его использовать. В определенный момент он заблокируется, и когда какой-нибудь другой умный пользователь (возможно, специалист по выпуску дистрибутива) вставит его в init скрипт и системы перестанут работать, пользователям останется только жаловаться самому Линусу Торвальдсу».

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

«Ядро не должно смешивать вместе различные noise source, и оно, конечно же, не должно пытаться утверждать, что знает, сколько бит энтропии оно получает, когда пытается играть в какую-то «дерганную игру энтропии» на простой до безобразия архитектуре CPU для пользовательских случаев IOT/Embedded, когда все рассинхронизировано с единственным мастер-генератором, когда нет никакой инструкции CPU для переупорядочения или переименования регистра и т. д.».

«Можно говорить о предоставлении инструментов, которые пытаются сделать эти расчеты, но такие вещи должны проводиться на оборудовании каждого пользователя, что для большинства пользователей дистрибутива просто непрактично. Если же это предназначено только для криптографов, то пусть будет сделано в их пользовательском пространстве. И давайте не будем упрощать GPG, OpenSSL и т. д., чтобы все говорили: «мы хотим «истинной случайности» и не согласны на меньшее». Можно говорить о том, как мы предоставляем интерфейсы криптографам, чтобы они могли получить необходимую информацию благодаря доступу к первичным noise sources, отделенным и поименованным, и, возможно, что каким-то образом noise source сможет аутентифицировать себя в библиотеке или приложении пользовательского пространства».


Имела место небольшая дискуссия о том, как может выглядеть такой интерфейс, ведь, например, для некоторых событий могут иметься последствия в плане безопасности. Цао отметил, что коды сканирования клавиатуры (то есть нажатия клавиш) смешиваются в пул как часть сбора энтропии: «Перенос этого в пользовательское пространство, даже через привилегированный системный вызов, было бы, по меньшей мере, неблагоразумно». Вполне возможно, что и другие тайминги событий могут создать какую-то утечку информации по побочным каналам.

Таким образом, возникает ощущение, что давняя проблема подсистемы случайных чисел Linux находится на пути к решению. Изменения, которые подсистема случайных чисел претерпела в последнее время, фактически приводили только к проблемам DoS в процессе ее использования. Теперь же появились эффективные способы получить наилучшие случайные числа, какие только может предоставить ядро. Если же TRNG все еще желателен для Linux, то этот недостаток нужно будет устранить в будущем, но, скорее всего, это не будет делаться внутри самого ядра.

Немного рекламы :)


Спасибо, что остаётесь с нами. Вам нравятся наши статьи? Хотите видеть больше интересных материалов? Поддержите нас, оформив заказ или порекомендовав знакомым, облачные VPS для разработчиков от $4.99, уникальный аналог entry-level серверов, который был придуман нами для Вас: Вся правда о VPS (KVM) E5-2697 v3 (6 Cores) 10GB DDR4 480GB SSD 1Gbps от $19 или как правильно делить сервер? (доступны варианты с RAID1 и RAID10, до 24 ядер и до 40GB DDR4).

Dell R730xd в 2 раза дешевле в дата-центре Equinix Tier IV в Амстердаме? Только у нас 2 х Intel TetraDeca-Core Xeon 2x E5-2697v3 2.6GHz 14C 64GB DDR4 4x960GB SSD 1Gbps 100 ТВ от $199 в Нидерландах! Dell R420 — 2x E5-2430 2.2Ghz 6C 128GB DDR3 2x960GB SSD 1Gbps 100TB — от $99! Читайте о том Как построить инфраструктуру корп. класса c применением серверов Dell R730xd Е5-2650 v4 стоимостью 9000 евро за копейки?
ua-hosting.company
Хостинг-провайдер: серверы в NL / US до 100 Гбит/с

Комментарии 16

    +1
    Всё очень просто. Интерфейс надо назвать /dev/badrandom. Тогда желающие найти лучшую случайность, но не умеющие читать документацию, сами будут обходить этот интерфейс 10-й дорогой. :)
      +1

      https://www.2uo.de/myths-about-urandom/ Вот тут подробнее. Вкратце: /dev/urandom вполне секурен, и нет никаких причин использовать /dev/random и решать проблемы его блокировки.

        0
        Осталось это объяснить еще паре миллионов разработчиков, и золотой ключик у нас в кармане!
        +8
        Поставил минус, и вот почему:

        1. Тег «Tutorial» абсолютно неуместен для перевода новостной статьи.
        2. Качество перевода оставляет желать лучшего, даже начиная с заголовка. Искажен смысл.

        Например, фраза «blocking pool» несколько раз (в том числе в заголовке) переведена как «пул блокировок». Правильный перевод — блокирующий пул.
          –1
          Правильный перевод с точки зрения кого? Microsoft использует понятие «пул блокировки» во множестве технических текстов, переведенных на русский язык. «Пул блокировки» имеется в курсе «Блокировки объектов» © Postgres Professional, 2019 год Рогова и Лузанова. ИМХО, формулировки «Пул блокировки» или «блокирующий пул» никоим образом не искажают смысл данного явления.
            +1
            Термин «Пул блокировки» действительно существует, но в данном контексте неуместен (и, таким образом, является ошибочным переводом), поскольку относится совсем к другому объекту. А именно, в приведенном вами курсе он относится к теме блокировки одновременного доступа различных потоков или процессов к одному и тому же объекту. Из такого пула (в котором хранятся блокировки) процесс может взять блокировку, попользоваться и вернуть. Пул, таким образом, отслеживает, сколько блокировок осталось. См. habr.com/ru/company/postgrespro/blog/462877.

            В данном же тексте «пул» относится не к блокировкам, а к энтропии, и пул ее накапливает. В пул энтропия примешивается извне, и из пула извлекаются биты. До недавнего времени таких пулов было два: блокирующий (который не дает извлекать биты, а зависает, т.е. блокирует исполнение, если их попытаться извлечь больше, чем поступило энтропии), и неблокирующий (который позволяет извлекать биты до бесконечности, перемешивая свое внутреннее состояние).
              0
              Согласен, относительно контекста Вы правы. Но переводчик вполне может не знать этих нюансов. По собственному опыту скажу — невозможно найти универсальных переводчиков, которые одинаково хорошо разбираются во всей IT-тематике.
                +1
                Согласен насчет несуществования универсальных переводчиков. Считаю это частным случаем проблемы несуществования универсальных IT-специалистов. Но в контексте хабра никто не заставляет конкретного человека переводить конкретную статью. Пусть выбирает и переводит то, в чем на 100% разбирается, т.е. такую статью, где он мог бы (будь она академической) выступить в роли рецензента или оппонента. Тогда и перевод (а точнее — уже пересказ) будет близок к идеальному.
          +1
          Недавно неожиданно столкнулся с этим «багом» на одном из своих ноутов с гентой. Загрузка залипала на инициализации RNG и не грузилась дальше, пока не покормишь её энтропией (поклацать рандомно клавиатурой, повозить мышкой), потом её попускало и всё работало дальше. Залип, видимо, был как раз на getrandom().

          Один из туториалов по решению этой проблемы предложил установить HAVEGED который как-то там доливает недостающую энтропию алгоритмически. И, действительно, помогло. Жаль, что это не упомянуто в статье, как один из «бытовых» способов решения.
            0
            А не могли бы вы уточнить что за софт к этому привёл? Относительно давно пользуюсь гентой и такого что-то не наблюдал
              0
              Никакой софт не «привёл», я просто устанавливал Gentoo Linux на этот ноутбук (HP ProBook 6465b) и сразу при первой же загрузке вылез вот такой спецэффект. На других ноутах с гентой не наблюдал, так что это не её проблема, скорее всего, а самого ноута.
              Вероятно, связано с возрастом подопытного ноутбука, т.к. он из всего моего парка самый старый.
              0
              Тыкните мейнтейнеров ядра в Gentoo вот в этот коммит, он реализует логику, подобную haveged, в самом ядре. Входит в ядро 5.4, по идее должен быть бекпортирован в более ранние ядра.
                0

                Та же фигня на Debian, чинил так же.

                +1
                Он вносит «два основных семантических изменения в случайных API Linux».

                Прямо какой-то chaotic monkey во всей красе: ищите, какие два API были изменены на этой неделе!

                  0
                  Еще бы регуляторы разрешили использовать /dev/random, не говоря уже об /dev/urandom вместо своего «оборудования», со своим супер-кривым софтом в качестве источника энтропии… грёбаные аттестации и грёбаные гсч мне всю малину скоро испортят.
                    0
                    Эта проблема очень сильно портила производительность на ранних android устройствах.

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

                    Самое читаемое