例えば以下のように。
$ gpg --gen-key (snip) Not enough random bytes available. Please do some other work to give the OS a chance to collect more entropy! (Need 284 more bytes) (snip)
システムのエントロピープールは以下のようにを確認できる。この値が1000を下回るとエントロピーの枯渇状態と言うことらしい。
$ cat /proc/sys/kernel/random/entropy_avail 26
解決策としては以下のようなものがあるようだ。
- 適当にマウスやキーボードを動かす
- ディスクへのランダムアクセスを発生させる。dd、ls -R /等
- エントロピー生成用のツールを使う。EGD、rng-tools。
今回は rng-tools (rngd) を使って解決。インストール。
# apt-get install rng-tools
現在のエントロピープールの時間変化を確認しておくと以下。8/10sec くらいのスピードで利用可能なエントロピーが貯まっていく。200 くらいまで貯まると90くらい減るのを繰り返している。
$ while [ 1 ]; do A=$(cat /proc/sys/kernel/random/entropy_avail); printf "%s % 6s % 6s\n" "$(date +%T)" ${A} $(echo ${A} - ${B} | bc); B=${A}; sleep 10; done; (snip) 15:21:47 131 -81 15:21:57 139 8 15:22:07 146 7 15:22:17 154 8 15:22:27 162 8 15:22:37 169 7 15:22:47 178 9 15:22:57 186 8 15:23:07 193 7 15:23:17 201 8 15:23:27 209 8 15:23:37 216 7 15:23:47 135 -81 15:23:57 143 8 15:24:07 151 8 15:24:17 158 7 15:24:27 165 7 15:24:37 172 7 15:24:47 180 8 15:24:57 186 6 15:25:07 193 7 15:25:17 200 7 15:25:27 209 9 15:25:37 216 7 15:25:47 129 -87 (snip)
この状況下で、gpg で鍵生成開始。"Not enough random bytes available." というメッセージが出る。
$ date '+%T' && cat << 'EOT' | gpg --batch --gen-key %echo Generating a default key Key-Type: RSA Key-Length: 4096 Key-Usage: encrypt sign Subkey-Type: RSA Subkey-Length: 4096 Subkey-Usage: encrypt Name-Real: hoge fuga Name-Email: hoge@example.com Expire-Date: 0 Passphrase: hoge # Do a commit here, so that we can later print "done" :-) %commit %echo done EOT 15:32:04 gpg: Generating a default key Not enough random bytes available. Please do some other work to give the OS a chance to collect more entropy! (Need 287 more bytes)
鍵生成を開始した 15:32:04 以降の挙動を見ると、エントロピーの増加率はあんまり変わらないけど、ベースが落ちた感じ。gpg --gen-key は一向に終わらない。
(snip) 15:29:48 132 -87 15:29:58 140 8 15:30:08 147 7 15:30:18 156 9 15:30:28 163 7 15:30:38 172 9 15:30:48 179 7 15:30:58 187 8 15:31:08 195 8 15:31:18 204 9 15:31:28 211 7 15:31:38 219 8 15:31:48 131 -88 15:31:58 139 8 15:32:08 11 -128 15:32:18 18 7 15:32:28 26 8 15:32:38 35 9 15:32:48 41 6 15:32:58 49 8 15:33:08 57 8 15:33:18 1 -56 15:33:28 10 9 15:33:38 19 9 15:33:48 26 7 15:33:58 33 7 15:34:08 41 8 15:34:18 48 7 15:34:28 55 7 15:34:38 63 8 15:34:48 6 -57 15:34:58 14 8 15:35:08 21 7 15:35:18 29 8 15:35:28 36 7 15:35:38 44 8 15:35:48 52 8 15:35:59 59 7 15:36:09 3 -56 (snip)
まずはディスクにランダムアクセスを発生させる方針で変化を見る。
$ while [ 1 ]; do date '+%T' && dd if=/dev/urandom of=~/tmp/dummy bs=1M count=512; done; rm ~/tmp/dummy; 15:43:29 512+0 records in 512+0 records out 536870912 bytes (537 MB) copied, 81.8706 s, 6.6 MB/s 15:44:51 512+0 records in 512+0 records out 536870912 bytes (537 MB) copied, 94.2846 s, 5.7 MB/s 15:46:26 512+0 records in 512+0 records out 536870912 bytes (537 MB) copied, 82.263 s, 6.5 MB/s 15:47:48 512+0 records in 512+0 records out 536870912 bytes (537 MB) copied, 75.5354 s, 7.1 MB/s 15:49:04 512+0 records in 512+0 records out 536870912 bytes (537 MB) copied, 93.0178 s, 5.8 MB/s 15:50:37
多少増加率が良くなったように見えるけどほとんど変化なし (~11/10sec) 。gpg も終了しない。ということでディスクへのランダムアクセスは中止。
15:48:20 8 -55 15:48:30 17 9 15:48:40 29 12 15:48:50 38 9 15:49:00 49 11 15:49:10 57 8 15:49:20 3 -54 15:49:30 12 9 15:49:40 21 9 15:49:50 31 10 15:50:00 40 9 15:50:10 50 10 15:50:20 60 10 15:50:30 4 -56
エントロピープールを貯めるもう一つの方法として rngd がある。以下のようにして rngd をフォアグラウンドで実行。
# date '+%T' && rngd --foreground --rng-device /dev/urandom; 15:57:06 rngd 2-unofficial-mt.14 starting up... entropy feed to the kernel ready
そうすると gpg の動作が進行して鍵が生成される。
.....+++++ .................................+++++ +++++ ......................................+++++ gpg: key 9FBA206D marked as ultimately trusted gpg: done 15:58:10
15:57:06 近くのエントロピープールを見ると rngd 開始後にエントロピープールが急増。15:58:10 までは gpg の鍵生成に使っていたとして、それ以降も安定して2000程度の値をキープ。いわゆる健康な状態と言える。
15:54:51 4 -52 15:55:01 13 9 15:55:11 22 9 15:55:21 30 8 15:55:31 39 9 15:55:41 46 7 15:55:51 54 8 15:56:01 62 8 15:56:11 5 -57 15:56:21 12 7 15:56:31 20 8 15:56:41 28 8 15:56:51 36 8 15:57:01 43 7 15:57:11 1384 1341 15:57:21 1389 5 15:57:31 2105 716 15:57:41 2109 4 15:57:51 1984 -125 15:58:01 1989 5 15:58:11 1993 4 15:58:21 1998 5 15:58:31 2135 137 15:58:41 2138 3 15:58:51 2013 -125 15:59:01 2019 6 15:59:11 2023 4 15:59:21 2028 5 15:59:31 2162 134 15:59:41 2165 3 15:59:51 2041 -124 16:00:01 2046 5 16:00:11 2051 5 16:00:21 2054 3 16:00:31 2184 130 16:00:41 2187 3 16:00:51 2062 -125 16:01:01 2065 3 16:01:11 2068 3 16:01:21 2071 3 16:01:31 2200 129 16:01:41 2203 3
# echo HRNGDEVICE=/dev/urandom >> /etc/default/rng-tools; # service rng-tools restart;
$ cat << 'EOT' | gpg2 --batch --gen-key %echo Generating a default key Key-Type: default Subkey-Type: default Name-Real: Joe Tester Name-Comment: with stupid passphrase Name-Email: joe@foo.bar Expire-Date: 0 Passphrase: abc %pubring foo.pub %secring foo.sec # Do a commit here, so that we can later print "done" :-) %commit %echo done EOT
$ gpg --list-secret-keys --fingerprint 35254714 sec 4096R/35254714 2015-12-30 Key fingerprint = B333 412D 0419 5F96 0F44 36BC 87C5 D4EB 3525 4714 uid hoge fuga <hoge@example.com> ssb 4096R/C186C613 2015-12-30 $ gpg --list-key --fingerprint 35254714 gpg: checking the trustdb gpg: 3 marginal(s) needed, 1 complete(s) needed, PGP trust model gpg: depth: 0 valid: 1 signed: 0 trust: 0-, 0q, 0n, 0m, 0f, 1u pub 4096R/35254714 2015-12-30 Key fingerprint = B333 412D 0419 5F96 0F44 36BC 87C5 D4EB 3525 4714 uid hoge fuga <hoge@example.com> sub 4096R/C186C613 2015-12-30 $ gpg --no-greeting --delete-secret-keys 35254714 sec 4096R/35254714 2015-12-30 hoge fuga <hoge@example.com> Delete this key from the keyring? (y/N) y This is a secret key! - really delete? (y/N) y $ gpg --no-greeting --delete-keys 35254714 pub 4096R/35254714 2015-12-30 hoge fuga <hoge@example.com> Delete this key from the keyring? (y/N) y