Skip to content

gpg-agentをssh-agentとして使う

ssh コマンドが正しくGPGエージェントのUnixドメインソケットにアクセスできるように、以下のような環境変数が必要となる。

Terminal window
unset SSH_AGENT_PID
if [[ "${gnupg_SSH_AUTH_SOCK_by:-0}" -ne $$ ]]
then
export SSH_AUTH_SOCK="$(gpgconf --list-dirs agent-ssh-socket)"
fi

ここで gnupg_SSH_AUTH_SOCK_by は誰が設定するのかでいうと、これは gpg-agent —daemon /bin/bash のように gpg-agent を通して起動したプログラムで設定されているものらしい。

GPGのホームディレクトリを変更する手順を実施している場合、gpg-agent-ssh.socket ユニットも変更が必要になる。

あとは gpg-agent.conf でSSHエージェントを有効にする。設定はbrfg/gpg-guideにサンプルが置かれている。

Terminal window
enable-ssh-support

既存のSSH秘密鍵をインポートする

Section titled “既存のSSH秘密鍵をインポートする”

既存の鍵は、SSH_AUTH_SOCK がGPGエージェントに向いた状態で ssh-add すればいい。取り込む時に、GPGで扱うときのパスフレーズ入力を促されるのでパスフレーズを入力する。

一度登録すると、その鍵は gnupg/private-keys-v1.d 以下にファイルとして残る。ただしこの鍵は ssh -K コマンドではリストされずに gnupg/sshcontrol ファイルに鍵のkeygripが記述される。

Terminal window
$ ls .local/share/gnupg/private-keys-v1.d/
BD461A92F8D624C4522D8A12757CCDEE37799A69.key
$ cat ~/.local/share/gnupg/sshcontrol
BD461A92F8D624C4522D8A12757CCDEE37799A69 0

gpg —edit-key で既存のキーを追加できるらしい。

Terminal window
$ gpg --edit-key --expert C7BF8AB911C50EE3291DD45F1A3BB38A4BC27A81
gpg> addkey

このとき、既存のキー(13)を選択する。また、マスターキーの秘密鍵も必要になる。

上記と異なり、この方法では gpg -K でも扱える状態となる。サブキーの追加方法やロールについてはGPG鍵の管理に書いたのでそれを先に実行しておく。

そのうえで、A ロールの付いた鍵をエクスポートして、GitHub等のサービスに登録する。

gpg --export-ssh-key [keyname]

gnupg/sshcontrol ファイルにkeygripを書く。後ろの数字はキャッシュ期間を秒で指定する。

BD461A92F8D624C4522D8A12757CCDEE37799A69 0

この状態で ssh-add -L を実行するとSSHで利用可能な公開鍵のリストを取得できる。

いくつか要因が考えられる。

公開鍵をサービス側に登録していない

Section titled “公開鍵をサービス側に登録していない”

これはサービス側に登録するしかない。

例えばのようなエントリがあると、ssh は自身で解決しようとファイルを読みに行くようで、この場合はGPGエージェントにアクセスしないので認証エラーになる。

Terminal window
Host aur.archlinux.org
User lufia
IdentitiesOnly yes
IdentityFile ~/.ssh/conf.d/aur/id_ed25519

agent refused operationエラーで弾かれる

Section titled “agent refused operationエラーで弾かれる”

sign_and_send_pubkey: signing failed for ED25519 “(none)” from agent: agent refused operation .git@github.com: Permission denied (publickey). fatal: Could not read from remote repository.

どういう理由だか分からないけど GPG_TTY 環境変数がうまく伝わっていなくて pinentry を起動できない場合に agent refused operation エラーが発生するらしい。次のコマンドでリフレッシュすれば再開できる。

Terminal window
export GPG_TTY=$(tty)
gpg-connect-agent updatestartuptty /bye

手元で実行すれば動作するが、systemdsshuttle を起動すると sudo を求められてうまく動作しない。これの原因は sudo の実行コマンドが変わっているからなので、systemdでsshuttleを管理するのように書き換える。