web-dev-qa-db-ja.com

ssh-agentを介してgpgキーを転送するにはどうすればよいですか?

Ssh構成ファイルを使用して、ssh-agentに追加されたsshキーの転送を有効にできます。 gpgキーで同じことを行うにはどうすればよいですか?

29
txwikinger

編集:OpenSSHに適切なサポートが実装されたため、この回答は廃止されました。BrianMintonの回答を参照してください。

SSHは、トンネル内でTCP接続のみを転送できます。

ただし、socatのようなプログラムを使用して、TCPを介してunixソケットを中継することができます(クライアントとサーバーホストの両方でsocatが必要になります)。

# Get the path of gpg-agent socket:
GPG_SOCK=$(echo "$GPG_AGENT_INFO" | cut -d: -f1)

# Forward some local tcp socket to the agent
(while true; do
    socat TCP-LISTEN:12345,bind=127.0.0.1 UNIX-CONNECT:$GPG_SOCK;
done) &

# Connect to the remote Host via ssh, forwarding the TCP port
ssh -R12345:localhost:12345 Host.example.com

# (On the remote Host)
(while true; do
    socat UNIX-LISTEN:$HOME/.gnupg/S.gpg-agent,unlink-close,unlink-early TCP4:localhost:12345;
done) &

gpg-connect-agentで動作するかどうかをテストします。 GPG_AGENT_INFOがリモートホストで未定義であることを確認して、$HOME/.gnupg/S.gpg-agentソケットにフォールバックするようにします。

うまくいけば、必要なのはこれをすべて自動的に実行する方法です!

16
b0fh

OpenSSHの新しいUnixドメインソケットフォワーディングは、バージョン6.7以降、これを直接実行できます。

次のようなことができるはずです:

ssh -R /home/bminton/.gnupg/S.gpg-agent:/home/bminton/.gnupg/S-gpg-agent -o "StreamLocalBindUnlink=yes" -l bminton 192.168.1.9
17
Brian Minton

GnuPGまたはLinuxディストリビューションの新しいバージョンでは、ソケットのパスが変更される可能性があります。これらはを介して見つけることができます

$ gpgconf --list-dirs agent-extra-socket

そして

$ gpgconf --list-dirs agent-socket

次に、次のパスをSSH構成に追加します。

Host remote
  RemoteForward <remote socket> <local socket>

公開鍵をコピーするためのクイックソリューション:

scp .gnupg/pubring.kbx remote:~/.gnupg/

リモートマシンで、GPGエージェントをアクティブ化します。

echo use-agent >> ~/.gnupg/gpg.conf

リモートマシンで、SSHサーバー構成も変更し、次のパラメーター(/ etc/ssh/sshd_config)を追加します。

StreamLocalBindUnlink yes

SSHサーバーを再起動し、リモートマシンに再接続すると、機能するはずです。

6
MaLo

私は同じことをしなければならず、いくつかの小さな変更を加えて、b0fhによるソリューションに基づいてスクリプトを作成しました。出口をトラップしてバックグラウンドプロセスを強制終了し、「fork」および「reuseaddr」オプションを使用してsocatを実行します。これにより、ループ(バックグラウンドのsocatを完全に強制終了可能にします)。

すべてが一度にすべての転送を設定するため、おそらく自動設定に近づきます。

リモートホストでは、次のものが必要になることに注意してください。

  1. 署名/暗号化/復号化に使用するキーリング。
  2. リモートのgpgのバージョンに応じて、偽のGPG_AGENT_INFO変数。私は~/.gnupg/S.gpg-agent:1:1を事前に入力します-最初の1はgpgエージェントのPIDです(「init」として偽装しており、常に実行されています)。2番目はエージェントのプロトコルバージョン番号です。これは、ローカルマシンで実行されているものと一致する必要があります。

#!/bin/bash -e

FORWARD_PORT=${1:-12345}

trap '[ -z "$LOCAL_SOCAT" ] || kill -TERM $LOCAL_SOCAT' EXIT

GPG_SOCK=$(echo "$GPG_AGENT_INFO" | cut -d: -f1)
if [ -z "$GPG_SOCK" ] ; then
    echo "No GPG agent configured - this won't work out." >&2
    exit 1
fi

socat TCP-LISTEN:$FORWARD_PORT,bind=127.0.0.1,reuseaddr,fork UNIX-CONNECT:$GPG_SOCK &
LOCAL_SOCAT=$!

ssh -R $FORWARD_PORT:127.0.0.1:$FORWARD_PORT socat 'UNIX-LISTEN:$HOME/.gnupg/S.gpg-agent,unlink-close,unlink-early,fork,reuseaddr TCP4:localhost:$FORWARD_PORT'

-o LocalCommandを使用してSSHコマンドを1回呼び出す(リモートホストからローカルホストに接続する)だけの解決策もあると思いますが、終了時にそれを簡単に強制終了する方法がわかりませんでした。

3
antifuchs

/etc/ssh/sshd_configStreamLocalBindUnlink yesで変更する代わりに、次の置換が必要なソケットファイルの作成を防ぐことができます。

systemctl --global mask --now \
  gpg-agent.service \
  gpg-agent.socket \
  gpg-agent-ssh.socket \
  gpg-agent-extra.socket \
  gpg-agent-browser.socket

これは、ホスト上のallユーザーに影響することに注意してください。

ボーナス:GPGエージェント転送が機能していることをテストする方法:

  • ローカル:ssh -v -o RemoteForward=${remote_sock}:${local_sock} ${REMOTE}
  • ${remote_sock}がsshからの詳細出力に表示されていることを確認します
  • リモート:ls -l ${remote_sock}
  • リモート:gpg --list-secret-keys
    • 転送されたトラフィックを示すsshからの多数のdebug1メッセージが表示されるはずです

それが機能しない場合(私にとっては機能しませんでした)、どのソケットGPGがアクセスしているかを追跡できます。

strace -econnect gpg --list-secret-keys

サンプル出力:

connect(5, {sa_family=AF_UNIX, Sun_path="/run/user/14781/gnupg/S.gpg-agent"}, 35) = 0

私の場合、アクセスされているパスは${remote_sock}と完全に一致しましたが、しかしログインしたときにそのソケットはsshdによって作成されませんでした、StreamLocalBindUnlink yesを私の/etc/ssh/sshd_configに追加したにもかかわらず。ログイン時にsystemdによって作成されました。

(現在、ホストに物理的にアクセスできないため、restartsshdには臆病すぎることに注意してください。service reload sshdは明らかにそうではありませんでした。十分...)

Ubuntu16.04でテスト済み

1
RobM

GnuPG Wiki によると、リモートソケットを転送する必要がありますS.gpg-agent.extraローカルソケットS.gpg-agent。さらに、サーバーでStreamLocalBindUnlinkを有効にする必要があります。
リモートGnuPGで利用可能なキーの公開部分も必要であることに注意してください。

使用する gpgconf --list-dir agent-socketそれぞれgpgconf --list-dir agent-extra-socketリモートで実際のパスを取得します。


概要

  1. リモートの追加構成/etc/sshd_config

    StreamLocalBindUnlink yes
    
  2. リモートに公開鍵をインポートします。

    gpg --export <your-key> >/tmp/public
    scp /tmp/public <remote-Host>:/tmp/public
    ssh <remote-Host> gpg --import /tmp/public
    
  3. Gpg-agent転送を有効にしてSSH経由で接続するコマンド:(私のDebianのパス)

    ssh -R /run/user/1000/gnupg/S.gpg-agent:/run/user/1000/gnupg/S.gpg-agent.extra <remote-Host>
    
1
doak