我可以使用ssh配置文件来启用添加到ssh-agent的ssh密钥的转发。如何使用gpg键做同样的事情?
我可以使用ssh配置文件来启用添加到ssh-agent的ssh密钥的转发。如何使用gpg键做同样的事情?
Answers:
编辑:此答案已过时,因为已在OpenSSH中实现了适当的支持,请参阅Brian Minton的答案。
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
套接字。
现在希望您所需要的只是一种自动运行所有这些的方式!
localhost
现在。
从版本6.7开始,OpenSSH的新Unix域套接字转发可以直接执行此操作。
您应该能够执行以下操作:
ssh -R /home/bminton/.gnupg/S.gpg-agent:/home/bminton/.gnupg/S-gpg-agent -o "StreamLocalBindUnlink=yes" -l bminton 192.168.1.9
在新版本的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服务器,重新连接到远程计算机-然后它将正常工作。
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,这是预期的行为。
我必须做同样的事情,并且将脚本基于b0fh的解决方案,并进行了一些微小的修改:它捕获出口并杀死后台进程,并且使用“ fork”和“ reuseaddr”选项进行socat,从而节省了循环(并使背景socat完全可以杀死)。
整个过程一口气设置了所有转发,因此它可能更接近于自动设置。
请注意,在远程主机上,您将需要:
GPG_AGENT_INFO
变量。我用~/.gnupg/S.gpg-agent:1:1
- 预填充我的第一个-gpg代理的PID(我将其伪称为“ init”,它一直在运行),第二个是代理协议版本号。这应该与在本地计算机上运行的计算机相匹配。
#!/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'
我相信,还有一种解决方案仅涉及使用SSH命令调用(从远程主机连接回本地主机)-o LocalCommand
,但我不太想知道如何在退出时方便地将其杀死。
根据GnuPG Wiki,您必须将远程套接字转发S.gpg-agent.extra
到本地套接字S.gpg-agent
。此外,您需要StreamLocalBindUnlink
在服务器上启用。
请记住,您还需要远程GnuPG上可用的公开密钥。
gpgconf --list-dir agent-socket
分别gpgconf --list-dir agent-extra-socket
在遥控器上使用以获取实际路径。
远程配置/etc/sshd_config
:
StreamLocalBindUnlink yes
将您的公钥导入远程:
gpg --export <your-key> >/tmp/public
scp /tmp/public <remote-host>:/tmp/public
ssh <remote-host> gpg --import /tmp/public
通过启用了gpg-agent转发的SSH连接的命令:(我的Debian的路径)
ssh -R /run/user/1000/gnupg/S.gpg-agent:/run/user/1000/gnupg/S.gpg-agent.extra <remote-host>
作为替代修改/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,因为我现在无法物理访问主机。service reload sshd
显然这还不够...)
在Ubuntu 16.04上测试