Ink

Contents related to tech, hobby, etc

~gpg --search-keys~ がうまくいかなかったので調べる

|

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_errnogethostbyname(3)に定義されている。

なので、あとはそこを追えばよさそう!!!

...なのだけど、この段階になって先に述べた解決方法が 判明してしまったのでここまでで打ち切り。