はじめに
gpgでクライアント側の鍵を使ってホスト上のファイルに署名をしたい。下記リンクを参照した。
Forwarding gpg-agent to a remote system over SSH
この通りに進めたのだが、途中で所々つまずいた。
前提
- ホスト側にsshでログインできる。
- クライアント側でgpgの鍵を生成済み。
- ホスト・クライアントともにバージョン2.1.1以上のgpgをインストール済み。
方法
クライアント側で、
$ gpgconf --list-dir agent-extra-socket
/Users/username/.gnupg/S.gpg-agent.extra
と入力することで、ソケットの場所が表示される。
次にホスト側で、
$ gpgconf --list-dir agent-socket
/run/user/uid/gnupg/S.gpg-agent
と入力することで、同様にソケットの場所が表示される。
ソケット位置が分かったところで、.ssh/config
に、
Host hostname
RemoteForward /run/user/uid/gnupg/S.gpg-agent /Users/username/.gnupg/S.gpg-agent.extra
を書き加える。これでsshをすれば、gpg-agentがforwardingされる。
ここまでが Forwarding gpg-agent to a remote system over SSH に書いてある内容。
接続に失敗する
ところが、sshで接続すると、
$ ssh hostname
Warning: remote port forwarding failed for listen path /run/user/uid/gnupg/S.gpg-agent
表示され、forwardingに失敗することがある。ホスト側で、
$ gpg -K
/home/username/.gnupg/pubring.kbx
---------------------------------
sec# rsa4096 20**-**-** [expires: 20**-**-**]
****************
uid [ unknown] User <user@mail.com>
ssb# rsa4096 20**-**-**
とし、クライアント側の鍵情報が表示されれば、forwardingに成功している。
この原因がいくつかあった。
クライアント側のgpg-agentが起動していない
そもそもクライアント側のgpg-agentが起動していないとforwardingできない。gpg-agent
で起動しているかを確認できる。起動している場合は、
$ gpg-agent
gpg-agent[1111]: gpg-agent running and available
と表示される。一方で、
$ gpg-agent
gpg-agent[1111]: no gpg-agent running in this session
と表示された場合はgpg-agentが起動していない。手動で起動するためには、
$ gpgconf --launch gpg-agent
とする。
gpg-agentのmanには、
The agent is automatically started on demand by gpg, gpgsm, gpgconf, or gpg-connect-agent. Thus there is no reason to start it manually.
と書かれているのだが、gpg-agentが起動していないことがあった。なぜ自動で起動してくれないのかは分からない。
毎回手動で起動するのは面倒なので、.bashrc
などに、
gpgconf --launch gpg-agent
を書き加えておくと、shellの起動時にgpg-agentも起動される。
ホスト側に S.gpg-agent
が生成されてない。
先ほどの gpgconf --list-dir agent-socket
でホスト側のソケットが生成されているはずだが、なぜか生成されていないことがある。生成されていれば、
$ ls /run/user/uid/gnupg/
S.dirmngr S.gpg-agent
と S.gpg-agent
があることを確認できる。
色々試しているうちに、どうやらgpg-agentだけでなく、dirmngrも必要らしいと分かった。dirmngrは、
$ gpgconf --launch dirmngr
で起動する。また、gpg-agentは先ほど書いたように、
$ gpgconf --launch gpg-agent
で起動。この後で、
$ gpgconf --list-dir agent-socket
/run/user/uid/gnupg/S.gpg-agent
とする。
$ ls /run/user/uid/gnupg/
S.dirmngr S.gpg-agent
と S.gpg-agent が生成されていることを確認できればok。
S.gpg-agent
が更新されていない。
ホスト側の S.gpg-agent
はsshでのログイン時に更新されるか、再生成されるらしい。S.gpg-agent
の更新時刻を
$ ls -l /run/user/uid/gnupg
total 0
srwx------ 1 user staff 0 Dec 17 12:00 S.dirmngr
srw------- 1 user staff 0 Dec 19 18:00 S.gpg-agent
などで確認する。S.gpg-agent
の更新時刻がログインした時刻と同じになっていれば問題ない。ログイン時刻よりも前だったりすると更新されておらず、forwardingできない模様。
解決策がわからなかったので、.bash_logout
に、
rm -f /run/user/uid/gnupg/S.gpg-agent
を書き加え、ログアウト時に自動削除することにした。ログイン時には新しく S.gpg-agent
が生成される。