開発用のサーバーにおいてGPG署名を行うために、色々と調べたので、それを今更ながらまとめようと思います。
GPG とは
GPG(GnuPG)とは、GNU Privacy Guardという暗号化ソフトウェアのことです。
OpenPGPの標準仕様に準拠しています。(※1)
要は暗号・復号化や署名・検証を行うソフトウェアのことを指しています。
※1:https://ja.wikipedia.org/wiki/GNU_Privacy_Guard
GPG Agent とは
GPGにおいて、秘密鍵を管理したりパスフレーズをキャッシュするデーモンです。
これが動いていることにより、一定時間以内であればパスフレーズの再入力をスキップすることができます。
やりたかったこと
- gitのコミットに対して、GPGの署名を行う
- サーバーでの開発においても、本人が署名していることを保証したい
一部のリポジトリにおいては、とある事情により署名を強制しています。ただし、そのリポジトリの開発を行う際はサーバーで開発を行うようになっており、鍵をサーバーに置いてしまうと、パスフレーズを設定していない鍵の場合他人が署名できてしまいます。
それを防ぐために、GPGの秘密鍵はサーバーに置かないよう gpg agentを使用して署名する必要がでてきました。
しかしサーバーのgpg agentやSSHのバージョンが古く簡単には接続できなかったので、どうにか実現するためにトリッキーな回避策を取らざるを得なくなりました。
GPG Agent の署名の仕組
流れは上記のとおり、GPGのクライント(コマンドラインツール)が gpg agent に署名のリクエストを送信し、gpg agentが秘密鍵を用いて署名や暗号化を行います。
その際、GPG のクライアントと gpg agentはソケットを用いてデータをやり取りします。
つまり、ソケットをsshのUnix ドメインソケット転送機能を用いて送信することでサーバーとローカルのgpg agentでやり取りを行って、サーバーに秘密鍵を置くことなく署名や暗号化を行うことができます。
それをシーケンス図で表現したのが以下です。
その他のハマりポイント
gpgは署名の際に秘密鍵をgpg agent経由で使用する場合でも、ローカルに公開鍵を置いておく必要があります。
公開鍵をインポートしておかないと署名できないので気をつけましょう。
まとめ
- GPGコマンドは gpg agent に署名や暗号化を依頼している
- GPGとgpg agentはデータのやり取りをソケット通信で行っている
- SSHのUnixドメインソケット転送を使ってソケットを転送することでローカルのgpg agentにある秘密鍵を使用できる
- リモートに公開鍵はインポートしておく
これらを知っていれば細かい設定に困っても、適切に対処できるでしょう。