gpg --search-keys
がうまくいかなかったので調べる
状況
stackの署名キーを引いてくるために、 --search-keywords
を
してみたところエラーが起きた。
gpg --search-keys 65101FF31C5C154D
gpg: error searching keyserver: Server indicated a failure gpg: keyserver search failed: Server indicated a failure
原因: DNSリゾルバが適切に設定されていなかった
らしい。 systemd-resolvedを使用している場合 注意が必要そう。
具体的には、
GnuPGはドメイン名解決のために /etc/resolv.conf
を参照するが
systemd-resolvedは /etc/resolv.conf
を参照も設定もしない
なので、ドメイン名解決のための設定を何もしていない状況になっていた。
実は archwikiのsystemd-resolvedページに記載があるのでそれに従い、
# 私の場合は元から /etc/resolve.conf が
# 空だったので削除しているが、必要に応じて
# なんかして
rm /etc/resolv.conf
ln -s /run/systemd/resolve/stub-resolv.conf /etc/resolv.conf
としてリンクを作成した。
この後 gpgconf --reload
で設定を読み直したら動くようになった!
過去の調べ物
とりあえず色々調べたけど、 結論今回は関係なかったものたち。 まぁ状況によっては役立つかもなので残しておく。
dirmngr 2.1.17時代のバグの話
これは無関係だった。dirmngrの昔のバージョンにて、 全ての操作が出来無いバグがあったらしい。わぁぉ。
コードリーディングで原因探し
とりあえずもうちょい確信に迫りたかったので、 えいやって gnupgのgitレポジトリcloneしてきて読んだ。
gpg --debug-all --search-keys <key_id>
が出力した
エラーメッセージ "Try again later" をとりあえずgrepする。
けどみつからん。
実は実際はlibgpg-errorの中にエラーメッセージが定義されており、 そちらを探すと以下のコードが見付かる。
312 GPG_ERR_TRY_LATER Try again later
これだけだとわからないが、 まぁ多分これ定数だろうという推測
のもと今度は GPG_ERR_TRY_LATER
を(今度こそ) gnupgのコードベースで
grepしてみる。
と、一箇所だけ見付かる:
find . -regex '.*\.c\|.*\.h' -exec grep 'GPG_ERR_TRY_LATER' {} \+
./dirmngr/dns-stuff.c: case TRY_AGAIN: ec = GPG_ERR_TRY_LATER; break;
これは get_h_errno_as_gpg_error
関数であり、
説明によると H_ERRNO
をgpgで使用されるエラーコードに直してくれるらしい。
...まぁとりあえず使用例を追う。と、 dirmngr/dns-stuff.cの中に2箇所あるがどちらも
res_query
を呼んだ結果によって使用されている。
...
r = res_query (name, C_IN, T_SRV, answer, sizeof res.ans);
my_protect ();
if (r < 0)
return get_h_errno_as_gpg_error ();
...
...
r = res_query (name, C_IN, T_CERT, answer, sizeof res.ans);
my_protect ();
if (r < 0)
return get_h_errno_as_gpg_error ();
...
で、じゃぁこいつが何か...?と思ってgrepしてみると 定義がない。実はこいつはresolverで定義されており、manページを 引くことができるresquery(3)
Cだとこういうのたまに見掛けるので面白いね。
で、芋蔓式にわかるのだけれど h_errno
も gethostbyname(3)に定義されている。
なので、あとはそこを追えばよさそう!!!
...なのだけど、この段階になって先に述べた解決方法が 判明してしまったのでここまでで打ち切り。