Випадкові числа в linux (rng) або як - наповнити

Мабуть всім користувачам Linux відомі такі файли псевдо-пристроїв як / dev / random та / dev / urandom. Ці пристрої є інтерфейсом до генератора випадкових чисел ядра (RNG, random number generator).

Випадкові числа (вони ж - непередбачуваний набір бітів) дуже важливі в криптографії. Вони є базовими цеглинками для криптографічних протоколів. Від якості (неповторності, непередбачуваності) цих чисел залежить стійкість всіляких TLS-сертифікатів, SSH і GPG ключів, сесійних симетричних TLS-ключів і т.д. Так само випадкові числа є основою для генерації UUID'ов, PID'ов, TCP sequence numbers і багато чого іншого.

RNG генерує випадкові числа на основі даних з пулу ентропії (entropy pool) в ядрі Linux. Наповненням цього пулу так само займається RNG і робиться це на основі випадкових подій в системі таких як: тайминги клавіатури і дисків, руху миші, переривання (interrupts), мережевий трафік.

Пул ентропії має фіксований об'ємом 4096 bits:

Розмір пулу не можна змінити, це захардкожено в ядрі.

Подивитися поточний обсяг даних в пулі:

Доступний обсяг ентропії постійно змінюється, в залежності від швидкості поповнення і споживання відповідно.

Власне через / dev / random та / dev / urandom додатки в user space отримують ці самі випадкові числа \ дані.

/ Dev / random є джерелом випадкових даних найвищої якості які може надати ядро. Але при цьому він блокується, що означає, що додаток читає з / dev / random повисне в очікуванні даних якщо пул ентропії виявиться порожнім.

Настійно рекомендується для будь-яких довго-живучих ключів, наприклад для TLS-сертифікатів використовувати / dev / random тому тільки він гарантує якість випадкових чисел. Але, більшість додатків таких як Apache, Nginx, sshd і про Боже ssh-keygen, openssl використовують / dev / urandom. Тут в принципі зрозуміло Apache, Nginx, sshd не хочуть блокуватися при генерації сесійних ключів. Але те, що ssh-keygen і openssl використовують за замовчуванням / dev / urandom мене вразило. Причому для openssl можна задати пристрій при генерації ключів (нижче приклад) а ось для ssh-keygen я можливості перевизначити поведінка не знайшов.

Загалом неважливо звідки читають ваші програми, не можна допускати спустошення цього самого пулу ентропії і тоді щастя буде і с / dev / urandom.

The amount of seed material required to generate a cryptographic key equals the effective key size of the key. For example, a 3072-bit RSA or Diffie-Hellman private key has an effective key size of 128 bits (it requires about 2 ^ 128 operations to break) so a key generator only needs 128 bits (16 bytes) of seed material from / dev / random.

Наприклад openssl для генерації RSA ключа довжиною 10240 bit використовує всього 2048 вихідного матеріалу з / dev / random:

Краще рішення це використання спеціальних апаратних засобів (TPM, Trusted Platform Module) або інструкцій процесора типу RDRAND (є в Intel IvyBridge і Haswell процесорах).

Перевірити наявність подібних пристроїв на сервері допоможе утиліта rngd з пакета rng-tools

Якщо rngd виявить підтримувані засоби то вам пощастило і ви можете запустити сервіс rngd. У моєму випадку їх немає)

В інтернеті можна зустріти рекомендації, де пропонують вказувати / dev / urandom як джерело ентропії для rngd. Тобто джерелом ентропії для ядра по суті буде саме ядро). Це досить сумнівна ідея, і я б не став так робити і вам не раджу. Але заради експерименту я провів тести і результати (які нижче) теж досить непогані.

В основі лежить алгоритм HAVAGE який генерує ентропію на основі лічильників і станів процесора. В силу складного, багаторівневого пристрою процесорів, один і той же код завжди виконується за різний час і це не сталість є основою для алгоритму HAVAGE.

На практиці, це user space демон який як і rngd наповнює пул ентропії ядра через ioctl інтерфейс / dev / random. при цьому не потребує джерелі ентропії як rngd.

Для centos пакет доступний з epel.

Після установки потрібно просто запустити сервіс. З параметрами за замовчуванням haveged буде намагатися тримати пул ентропії ядра на рівні не менші за 1024.

Без rngd і haveged, команда (нижче буде зрозуміло, що вона робить):

Чи не завершилася за добу!

rngd с / dev / urandom як джерело ентропії

(Те, що я вам не рекомендував)

Тест (найгірший з 3-х результат):

Тут потрібно дивитися на successes. failures. і на input channel speed.

При цьому утилізація CPU процесом rngd: 57%

Тест (найгірший з 3-х результат):

При цьому утилізація CPU процесом haveged: 12%

Не рекомендується використовувати haveged всередині ВМ, тому що там ніби як лічильники CPU неспроможний такі точні (типу округлюються) і це позначається на якості ентропії.
Тру шлях це використовувати virt-ioRNG (qemu-kvm) - паравіртуальное пристрій яке буде брати ентропію з пулу хоста. Але, це вже зовсім інша історія ...)

Поділитися посиланням: