GnuPG for Windows : gpg-agent について
gpg-agent
gpg-agent
は GnuPG の中核コンポーネントで,秘密鍵の管理1 を行い一定期間キャッシュする。
gpg-agent
は gpg
, gpgsm
, gpgconf
, gpg-connect-agent
といったコンポーネントから常駐プロセスとして起動されお互いに通信を行う2。
gpg-agent
が稼働中かどうかは gpg-agent
を引数なしで起動すれば分かる。
以下は既に起動している場合。
$ gpg-agent
gpg-agent[3996]: gpg-agent running and available
gpg-agent
が稼働していない場合は
$ gpg-agent
gpg-agent[9552]: no gpg-agent running in this session
などと表示される。
手動で gpg-agent
を起動する場合は以下のコマンドで起動する。
$ gpg-connect-agent /bye
gpg-connect-agent: no running gpg-agent - starting 'C:\path\to\GnuPG\bin\gpg-agent.exe'
gpg-connect-agent: waiting for the agent to come up ... (5s)
gpg-connect-agent: connection to agent established
逆に gpg-agent
を手動で停止したい場合は
$ gpg-connect-agent killagent /bye
OK closing connection
とすれば安全に停止できる。
Pinentry
Pinentry はパスフレーズ3 やスマートカードの PIN コードを入力する際に gpg-agent
から呼び出される。
Windows 版では Pinentry プログラムとして pinentry-basic.exe
が同梱されている。
同等の機能を持つものであれば他のプログラムと差し替えることもできる。
gpg
に --batch
(または --pinentry-mode loopback
)オプションとパスフレーズ指定オプション(--passphrase
, --passphrase-fd
, --passphrase-file
)をセットで指定している場合は Pinentry を迂回できることがある(--quick-gen-key
コマンドの場合など)。
gpg-agent のオプション
gpg-agent
のオプションは GnuPG ホームディレクトリ4 直下にある gpg-agent.conf
ファイルで設定する。
設定は以下の様なフォーマットで行う。
default-cache-ttl 600
max-cache-ttl 7200
gpg-agent.conf
ファイルで使いそうなオプションを以下に挙げる。
オプション名 | 内容 |
---|---|
log-file |
ログの出力先をフルパスで指定する。 挙動をチェックしたい場合など |
default-cache-ttl |
直前にアクセスしたキャッシュ・エントリの有効期間を秒単位で指定する。 既定値は 600 |
max-cache-ttl |
キャッシュ・エントリの有効期間の最大値を秒単位で指定する。 アクセスの有無にかかわらずこの期間が過ぎるとキャッシュがクリアされる。 既定値は 7200 |
pinentry-program |
独自に Pinentry プログラムを指定する場合はここにフルパスで指定する |
pinentry-timeout |
Pinentry プログラムの表示時間を秒単位で指定する。 既定値は 0 (タイムアウトなし) |
他にも,鍵生成時にパスフレーズの文字種や最小文字長を指定したり,パスフレーズの有効期間(期間が過ぎると警告が出るらしい)を設定できたりするようだ。 オプション項目について詳しくははマニュアル(英語)を参照のこと。
PuTTY with gpg-agent
PuTTY は Windows 用の SSH クライアント兼ターミナル・エミュレータである。 PuTTY には Plink と呼ばれるコマンドラインベースの SSH 接続ツールがあり,他ツール(例えば Git for Windows)と連携できるようになっている。 さらに PuTTY には Pageant と呼ばれるエージェントツールもあり,認証用の秘密鍵をキャッシュすることができる。
今回は Pageant を gpg-agent
で置き換えることを考える。
gpg-agent のオプション
gpg-agent.conf
ファイルに以下のオプションを追加する(enable-putty-support
以外は任意)。
オプション名 | 内容 |
---|---|
enable-putty-support |
Pageant プロトコルを有効にする |
default-cache-ttl-ssh |
直前にアクセスしたキャッシュ・エントリの有効期間を秒単位で指定する。 既定値は 1800 |
max-cache-ttl-ssh |
キャッシュ・エントリの有効期間の最大値を秒単位で指定する。 アクセスの有無にかかわらずこの期間が過ぎるとキャッシュがクリアされる。 既定値は 7200 |
設定を保存したら gpg-connect-agent
を使って gpg-agent
を再起動する。
$ gpg-connect-agent killagent /bye
OK closing connection
$ gpg-connect-agent /bye
gpg-connect-agent: no running gpg-agent - starting 'C:\path\to\GnuPG\bin\gpg-agent.exe'
gpg-connect-agent: waiting for the agent to come up ... (5s)
gpg-connect-agent: connection to agent established
なお, GnuPG の各コンポーネントは必要に応じて自動的に gpg-agent
を起動するので問題ないのだが, PuTTY は GnuPG と連動しているわけではないため, PuTTY 起動時に gpg-agent
が起動していない状況もありうる。
そこで, Windows ログイン時に gpg-connect-agent
を使って gpg-agent
を起動しておくことをお薦めする。
SSH 鍵のインポート
SSH 鍵のインポートには2通りの方法あるようだが,今回は簡単な方でいく5。
鍵ファイル(ここでは id_rsa.PPK
とする)を Pageant で開く。
ファイルの関連付けがされている場合はエクスプローラから該当の PPK ファイルをダブルクリックすればいい。
そうでない場合は以下のコマンドで PPK ファイルを開く。
$ pageant.exe id_rsa.PPK
すると Pageant のプロンプトが1回, gpg-agent
のプロンプトが2回表示され,都合3回パスフレーズを入力させられる。
これで秘密鍵が private-keys-v1.d
フォルダに格納される。
また sshcontrol
ファイルが作成され,インポートした鍵の情報が書き込まれる。
# List of allowed ssh keys. Only keys present in this file are used
# in the SSH protocol. The ssh-add tool may add new entries to this
# file to enable them; you may also add them manually. Comment
# lines, like this one, as well as empty lines are ignored. Lines do
# have a certain length limit but this is not serious limitation as
# the format of the entries is fixed and checked by gpg-agent. A
# non-comment line starts with optional white spaces, followed by the
# keygrip of the key given as 40 hex digits, optionally followed by a
# caching TTL in seconds, and another optional field for arbitrary
# flags. Prepend the keygrip with an '!' mark to disable it.
# RSA key added on: 2016-03-10 21:24:32
# MD5 Fingerprint: 56:ff:fd:60:38:a1:7a:44:0c:37:86:90:94:8d:7f:6a
F65BB98767E88930612C6EABC4D4918E2A573903 0
この F65B...
の長ったらしい数字列は keygrip と呼ばれる鍵の識別子で OpenPGP の鍵 ID とは異なるもののようだ6。
これで鍵のインポートができたので PuTTY で実際に SSH 接続してみると
とプロンプトが表示された。 めでたし!
Git for Windows との連携
Git for Windows と PuTTY を連携するには,環境変数 GIT_SSH
に Plink へのフルパスをセットする。
setx GIT_SSH=C:\path\to\PuTTY\plink.exe
ただし,最近の Git for Windows ではインストール時の SSH 接続設定で PuTTY を使うよう指定すれば自動的に環境変数をセットしてくれるので,手動で設定する必要はないと思われる。
Windows 版 gpg-agent は OpenSSH と相性が悪い?
gpg-agent
は OpenSSH の ssh-agent
と置き換えることもできる7。
gpg-agent
への SSH 鍵のインポートには ssh-add
を使うのだが, Windows 環境では上手く動かない。
どうやらファイル・ディスクリプタ S.gpg-agent.ssh
が上手く機能しないようだ。
MSYS2 版8 と PowerShell 用の OpenSSH で試してみたのだが,いずれも上手くいかなかった。 MSYS2 版については MSYS2 の GnuPG を使えば上手くいくのかもしれないが,面倒なので試してない。
ssh-pageant 経由で OpenSSH と連携できる!
フィードバックで教えていただいたのだが ssh-pageant
というツールがあって,これを経由して gpg-agent
と OpenSSH を繋げられるようだ。
ssh-pageant
は最近の Git for Windows には同梱されている。
ssh-pageant
が常駐している状態では, OpenSSH からは ssh-agent
が起動しているように見える。
一方, gpg-agent
には PuTTY から要求があるように見える。
この方法の利点は, enable-putty-support
オプションを有効にしておけば, gpg-agent
は PuTTY とも OpenSSH とも全く等価にアクセスできる点だろう。
欠点は,結局のところ PuTTY は手放せないということだろうか(だって bash 以外の環境では今まで通りだし)。
Git for Windows に関しては… もう Plink での接続でいいんじゃないかな。
まぁ Windows だしね。
ssh-pageant
の起動は bash から以下のコマンドを起動する。
$ eval $(/usr/bin/ssh-pageant -r -a "/tmp/.ssh-pageant-$USERNAME")
ssh-agent
と似たようなやりかただな。
ssh-pageant
は完全に土管として機能するので,上のコマンドを .bash_profile
か .bashrc
に書いておいて bash 起動時に常駐させておけばいいだろう9。
ssh-add
で鍵のインポートができるかどうかは試してないが(Pageant からインポートできてるし), ssh-add -l
ってやったらちゃんと鍵情報が取れたので,多分できるんじゃないかな?
参考になる(かもしれない) Web ページ
-
Convert keys between GnuPG, OpenSsh and OpenSSL - Sysmic.org
-
KeeAgent – lechnology.com : パスワード管理ツール KeePass のプラグインで, KeePass のパスワードデータベースを使って SSH 鍵を管理し Agent 機能で SSH に鍵を渡す仕組みらしい。 PuTTY と OpenSSH に対応しているようだ
-
How to enable SSH access using a GPG key for authentication | Opensource.com
-
前回も書いたが, classic version と現行バージョンでは鍵(特に秘密鍵)の管理の仕方が異なるため両者を混在させる場合は注意が必要である。 Classic version で作成した鍵を現行バージョンにも反映させたいのであれば
gpg-v21-migrated
ファイルを削除すると再度移行処理が走るらしい。 Classic version を使わなければならない状況(Linux などではパッケージ管理ツールがアプリケーションの証明用に GnuPG の classic version を使うことがある)でないのなら現行バージョンに一本化するほうがお勧めである。 ↩︎ -
現行バージョンでは
gpg-agent
が必須である。したがって,かつての--use-agent
,--no-use-agent
,--gpg-agent-info
各オプションは無効(ダミーオプション)になっている。また UNIX 互換プラットフォームでgpg-agent
利用する際はGPG_AGENT_INFO
環境変数でソケットを指定する必要があるが, Windows では不要なためここでは割愛する。 ↩︎ -
パスワード(password)とパスフレーズ(passphrase)の違いは,パスフレーズでは英数字以外に空白文字や記号が使え文字数の制限がないことにある。ちなみに OpenPGP の秘密鍵にはいかなる形でもパスフレーズを保持しない(S2K パラメータ情報は持っている)。 ↩︎
-
Windows では, GnuPG ホームディレクトリの既定は
%APPDATA%\gnupg
となっている。これを変更するにはGNUPGHOME
環境変数または--homedir
オプションを使う。(前回を参照のこと) ↩︎ -
今回は PPK ファイルを直接読み込む方法をとったが, PPK ファイルから OpenSSH 形式にエクスポートし,それを更に X.509 形式に変換した後
gpgsm
でインポートすることもできるらしい。(参考: Convert keys between GnuPG, OpenSsh and OpenSSL) ↩︎ -
OpenPGP 鍵以外の鍵にも対応するためらしい。 OpenPGP 鍵の keygrip は
--with-keygrip
オプションを付けて鍵を表示すると見ることができる。ちなみにprivate-keys-v1.d
フォルダにある秘密鍵のファイルは,この keygrip 値がそのままファイル名になっている。 ↩︎ -
gpg-agent.conf
ファイルにenable-ssh-support
オプションをセットする。 ↩︎ -
Git for Windows に同梱されている bash も MSYS2 である。 ↩︎
-
うちの Git for Windows 付属の bash では何故か
.bash_profile
を読んでくれない。ので.bashrc
に書いている。 ↩︎