/dev/randomのエントロピー不足対応
ns-lab BBのサーバ群は基本的に仮想サーバで構築しており、
ハイパーバイザーはKVM・Hyper-Vが主に、VPSを借りたりもしている。
その時微妙に問題になるのが深夜のスクリプト処理でCPUが奪い合いになる事と、
/dev/randomのエントロピー不足によるReadLockであったりする。
今までは表面化していなかったのだが、kernel 4.16辺りで導入された、
“crng_init” の初期化仕様変更に伴い、起動直後から/dev/randomを直参照する必要が出てきた。
ただ、起動直後は乱数の元となるエントロピーが溜まっていない為、
ReadLockが発生してしまいOSの起動が止まってしまった。
この問題に行き着く迄に1週間を費やし、kernelリビルドを10回程実行 ヘ(゚∀゚ヘ)
LKML.ORGを見るとこの問題の対応方針がまだ決まっていない見たいだが、
CVE-2018-1108の脆弱性対応も含まれているらしく、仕様がひっくり返る事は無さそう。
「だったら起動直後からエントロピーを蓄積出来る方法が無い物か」と、
/dev/randomエントロピー蓄積に使えそうな物を探してみた。
Google翻訳片手に頑張った自力解釈なので、間違いがあってもごめんなさい。
ちなみに、下記方法を使っても今回の問題は解決出来ないのであしからず (´・ω:;.:…
理由は最近わかったのだが、問題となっている “crng_init” はkernel読込み時に参照するコードであるが、
下記の方法はkernelが起動した後のOS階層で実行される為、そもそもタイミングが違うらしい。
- TPM (Trusted Platform Module)
rngdから「-o /dev/random -r /dev/my_hw_random_device」の様に定義して利用する
ノートPCに搭載されているチップで、TPM内で公開鍵を作る事も出来る
20KB/s程度のエントロピーを作れるらしく、TPMを搭載しているならば有用な手段
- HAVEGE (Hardware Volatile Entropy Gathering and Expansion)
daemonが/dev/randomのIOに直接エントロピーを提供するらしい
多くのディストリビューションでパッケージが提供されているので手軽に実装出来る
- bcm2708-rng / bcm2835-rng
Raspberry Piで使える手法。ラズパイのバージョンによりチップも変わる
kernelで [bcm2708-rng (bcm2835-rng)] モジュールを呼び出した後、
rngdを起動する事で/dev/randomのエントロピー収集元として、
/dev/hwrngを参照するようになる
- NeuG (True Random Number Generator)
A/D変換器のノイズをエントロピーとして利用する
A/D変換を使う為ハードウェアが必須となり、FST-01Gが存在する
- VirtIO RNG
仮想環境はハードウェアに直結する実装が少ない為、エントロピーが不足しやすい
「だったら、ホストOSのエントロピーをパススルーする」のがVirtIO RNGの手法
libvirtで利用するならコチラのサイトでXMLの設定方法を紹介している
………
乱数エントロピーは色々な種類があり、超高価な物なら核反応の分裂数を使ったりもするらしい。
調べればもっと出てくると思うが、個人レベルで入手出来る物だとNeuG辺りになるのかもしれない。
後はRaspberry Piに搭載されているBCM2708も良い乱数元になりそう。
どれを選ぶにしても本来の目的であった “crng_init” 制御には使えないのだが、
/dev/randomのReadLockはハマると怖いので動作仕様を把握しておこうと思う。