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


29

ssh構成ファイルを使用して、ssh-agentに追加されたsshキーの転送を有効にすることができます。gpgキーでも同じことができますか?


3
どちらの答えも、socatを実行して、TCPポートでGPGエージェントのUNIXソケットを公開することを提案しています。ただし、UNIXソケットとは異なり、TCPポートのアクセス制御は同じレベルではありません。特に、同じホスト上のすべてのユーザーがGPGエージェントに接続できるようになりました。シングルユーザーのラップトップをお持ちの場合、これはおそらく大丈夫ですが、他のユーザーも同じシステム(GPGエージェントが実行されているシステム)にログインできる場合は、GPGエージェントにアクセスすることもでき、重大なセキュリティ問題を引き起こします。これを解決するには、おそらくsocatにEXECアドレスタイプを使用してSSHを直接起動させることが最善の方法です。
マタイスクーイマン14

openssh 6.7+ソリューションの別のプレゼンテーションについては、2015.rmll.info
IMG / pdf /

これは私にとって有用でした。
phs 16

回答:


16

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

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

ただし、次のようなプログラムを使用して、socatTCPを介して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ソケットにフォールバックするように、リモートホスト上で未定義であることを確認してください。

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


構成ファイルで転送が設定されると、sshエージェントキーが自動的に転送されます。これを試してみます。
txwikinger

ssh-agentはUnixソケットも使用しますが、特別なサポートがあります(ここでは少し疲れています)。それでも、解決策は機能するはずです。
-b0fh

1
このソリューションでは、ファイアウォール/ NATの背後にいなければ、ポート12345を介してgpg-agentにパブリックにアクセスできます。これは答えで言及されるべきです。
ジョナスシェーファー

ジョナス、最後の編集でその問題が修正されたと思いますか?localhost今だけに拘束されます。
jmtd

これは、リモートホストのからの次の引数で私のために失敗しますgpg-connect-agentcan't connect to server: ec=31.16383 gpg-connect-agent: error sending RESET command: Invalid value passed to IPCsocatその後、リモートが死にます。地元の人たちはsocat死んでしまったsocat[24692] E connect(3, AF=1 "", 2): Invalid argumentこのページは、エージェントがキー(パスフレーズのみ)を保存しないため、これが機能しないことを信じさせます。これは誰によっても機能することが確認されていますか?
jmtd

17

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

@DrewR。それを聞いてうれしい。
ブライアンミントン

2
必要な重要な詳細が見つかりました。リモート(プライベートキーレス)マシンには、署名IDの公開キーが存在する必要があります。ローカルgpgバージョン2.1.15 OS X、リモート2.1.11 linux。
phs

4

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サーバーを再起動し、リモートマシンに再接続します-これで動作するはずです。


トラブルシューティングを含む詳細なチュートリアルはこちらにあります:mlohr.com/gpg-agent-forwarding
MaLo

1
リモートホストがDebianの現在のバージョンを実行してsystemctl --global mask --now gpg-agent.service gpg-agent.socket gpg-agent-ssh.socket gpg-agent-extra.socket gpg-agent-browser.socketいる場合、systemdがリモートgpg-agentを盗むソケットを起動しないようにするために実行する必要があるようです。bugs.debian.org/850982によると、これは意図した動作です。
サンピ

3

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

全体が一度にすべての設定を行うため、おそらく自動設定に近くなります。

リモートホストでは、次のものが必要です。

  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'

を使用して1つのSSHコマンド呼び出し(リモートホストからローカルホストに接続し直す)を含むソリューションもあると思いますが-o LocalCommand、終了時にそれを便利に強制終了する方法がわかりませんでした。


最後のコマンドで、socatの前に 'user @ host'引数が欠落していませんか?とにかくそれを修正した後でも、gpg-connect-agentをリモートで試行すると、「socat [6788] E connect(3、AF = 2 127.0.0.1:0、16):Connection refused」というメッセージがローカルに表示されて失敗します。
デビッドフォール

1

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>
    

@brian minton:追加のソケットに転送しないと機能しません。
ドーク

0

修正する代わりに/etc/ssh/sshd_configしてStreamLocalBindUnlink yes、あなたの代わりに置き換える必要があるソケットファイルの作成を防ぐことができます。

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

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

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

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

それがうまくいかない場合(私にとってはうまくいかなかったため)、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によって作成されました。

(現在、ホストへの物理的なアクセス権がないため、sshd を再起動するには ward病service reload sshdでした。明らかに不十分でした...)

Ubuntu 16.04でテスト済み

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.