Linux

ssh-agent の代わりに gpg-agent を使う手順

投稿日:2020年3月12日 更新日:

1. はじめに

以前、【SSH】ssh-agent の使い方 という記事を書いたのですが、これに関連して gpg-agent を ssh-agent の代わりに使う手順について説明します。

※ 私は gpg-agent を使っていません。これは、sshの鍵を gpg-agent から削除する方法がちゃんと用意されていない等の理由によりますが(後述)、私が知らないだけかもしれません。使ってはいないのですが、せっかく調べたので現時点で分かっている使い方について書いておくことにしました。

2. gpg-agent とは?

gpg-agent は、GnuPG の鍵を利用する際に必要なパスフレーズを覚えておいてくれるツールです。頻繁に鍵を使う場合に、パスフレーズを何度も入力する手間が省けます。

ssh サポート機能

gpg-agent には sshサポート機能があり、ssh の鍵のパスフレーズを gpg-agent が保持してくれ、入力の手間を省いてくれます。

問題はこの機能がどこまでの操作をサポートしているかなのですが、細かい部分についてはその都度書いていきます。

3. gpg-agent で sshサポート機能を使う手順

環境

ここでは、Ubuntu 18.04 (on WSL) において、まだ gpg-agent を使ったことがないという状況を前提とします。

準備作業

(1) gpg-agent をインストールする

apt コマンドで、gpg-agent パッケージをインストールするのですが、今回の環境では既にインストールされていました。

パスフレーズを入力する部分の機能として、 pinentry-curses パッケージも使いますが、こちらもインストール済でした。

pinentry-curses によるパスフレーズ入力画面

もしこれらがインストールされていなければ、以下のコマンドでインストールします。

$ sudo apt install gpg-agent pinentry-curses

(2) 設定ファイルを記述する

~/.gnupg/gpg-agent.conf ファイルに以下を記述します。

pinentry-program  /usr/bin/pinentry-curses

enable-ssh-support
default-cache-ttl-ssh    7200
max-cache-ttl-ssh       28800

ここには gpg-agent コマンドのオプションを記述しておくことができます。

オプション 説明
pinentry-program
  • パスフレーズやPIN番号を対話的に入力する画面を提供するプログラムを指定します。
enable-ssh-support
  • OpenSSH のエージェントプロトコルが使えるようになります。
default-cache-ttl-ssh
  • キャッシュエントリーにアクセスがあってから何秒でキャッシュをクリアするか。
max-cache-ttl-ssh
  • キャッシュエントリーの寿命(アクセスの有無に関係なくキャッシュがクリアされる)

各オプションの詳細については、gpg-agent(1): Secret key management for GnuPG – Linux man page を参照してください。

(3) gpg-agent を開始する準備

ここでは、~/.bashrc ファイルに、gpg-agent を実行する関数を記述します。

function gpg-agent-start()
{
    if [ -n "`pgrep -x gpg-agent 2> /dev/null`" ];then
        return
    fi

    if [ -n "`which gpg-agent 2> /dev/null`" ];then
        export GPG_TTY=$(tty)
        LANG=C gpg-connect-agent updatestartuptty /bye
        export SSH_AUTH_SOCK="$(gpgconf --list-dirs agent-ssh-socket)"
    else
        echo "gpg-agent NOT exists"
    fi
}
  • gpg-agent を起動するコマンドとして、gpg-connect-agent コマンドを使っています(参考:gpg-connect-agent(1) – Linux man page)。
  • パスフレーズを入力する画面は英語で表示して欲しかったので、LANG=C を付けて gpg-connect-agent を実行しています。
  • gpg-agent がインストールされていない場合は何もしません。
  • gpg-agent が既に起動していた場合も何もしません。

この関数を有効にするには、ターミナルにログインし直してください。

gpg-agent を使う

gpg-agent を開始する

今回はこの操作を関数にしたので、この関数を実行します。

$ gpg-agent-start

ssh の鍵を追加する

ssh の鍵を gpg-agent に追加するには、以下のコマンドを実行します。

$ ssh-add [鍵ファイルへのパス]

ssh の鍵を一覧表示する

追加した ssh の鍵を一覧表示するには、以下のコマンドを実行します。

$ ssh-add -L

gpg-agent が稼働しているか確認する

$ gpg-agent

gpg-agent を停止する

$ gpgconf --kill gpg-agent

4. gpg-agent の動作に関するメモ

  • 追加した ssh の秘密鍵は、gpg の秘密鍵と同じ ~/.gnupg/private-keys-v1.d/ ディレクトリ以下に保存されます。 1ファイルが1つの鍵を表しており、ファイル名はランダムな文字列(keygripと呼ばれる)になっています。どの鍵がどのファイルなのかは、~/.gnupg/sshcontrol ファイルを見れば分かります (ssh の鍵に関しては)。
  • 追加した ssh の秘密鍵のフィンガープリントと keygrip が、~/.gnupg/sshcontrol ファイルに記録されます。SSHプロトコルでは、ここに記録された鍵だけが使用されます。

5. 問題点

取り込んだ秘密鍵が消せない?

ssh-agent であれば、ssh の鍵をエージェントから削除するには、ssh-add -dssh-add -D といったコマンドを実行すればよいのですが、gpg-agent ではこれらのコマンドを実行しても削除してくれません。ssh-add -L を実行するとその鍵は表示されなくなりますが、その後も ssh コマンドの実行時に消したはずの鍵が適用されてしまいます。 ~/.gnupgp/ 以下に取り込んだ秘密鍵は削除されません。削除したければ、~/.gnupg/private-keys-v1.d/ ディレクトリ以下から手動で削除します(gpg-connect-agent コマンドで込み入った操作をすれば削除はできますが、結構面倒です)。

~/.gnupg/sshcontrol ファイル内で、該当する鍵のエントリーの先頭に「!」を記述すると、その鍵が無効になるはずなのですが、それも効かないようでした。

使用するコマンドの一貫性に欠ける

gpg-agent を使うために必要なコマンドが、gpg-agent, gpg-connect-agent, gpgconf, ssh-add などいろいろとあり扱いづらいです。

6. おわりに

gpg-agent の方が ssh-agent より高機能なので、できれば gpg-agent を使いたかったのですが、上に書いた問題点が気になってしまい採用には至っていません。

7. 参考

📂-Linux

執筆者:labo


comment

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

関連記事

CentOS

CentOS Stream 8 の PHP 7.2 を 7.4 に変更する

CentOS Stream 8 の PHP 7.2 を 7.4 に変更する作業について説明します。

docker

CentOS 上の Docker にウェブサーバーを入れて80番以外のポートで公開することができない問題【未解決】

CentOS 7 上の Dockerコンテナ にウェブサーバーを入れた場合、80番以外のポートで公開することはできないようです。 例えば、 まず、firewall-cmd コマンドで 8080番ポート …

CentOS

CentOS 6 での yum update エラーに対応しました

問題 先日、CentOS 6.9 で yum update したところ、以下のエラーが発生しました。 https://ca.mirror.babylon.network/remi/enterprise …

Let's Encrypt

Let’s Encrypt を使ってみました

無料でSSL証明書が発行できる Let’s Encrypt を使ってみました。 その時の操作手順を紹介します。 本記事執筆時に存在していた「Let’s Encrypt 総合ポー …

Linux

環境変数PATHにセットされたパスを1行毎に表示する

環境変数PATHにセットされたパスを1行毎に表示する方法について説明しています。