如果您在 ssh-agent 运行时启动 screen 会话(从 ssh -A 代理转发),则访问 ssh-agent 可以正常工作。但是,如果您从该会话中断开连接,注销,再次登录(使用 ssh-agent 转发),然后重新连接到 screen 会话,则 ssh-agent 访问将不起作用。
如何修复此问题?
答案1
在您的 SSH rc 脚本 (~/.ssh/rc) 中,您将设置从规范位置到“当前” SSH_AUTH_SOCK 的符号链接。以下是我在 bash 中执行此操作的方法(~/.ssh/rc 的内容):
#!/bin/bash if test "$SSH_AUTH_SOCK" ; then ln -sf $SSH_AUTH_SOCK ~/.ssh/ssh_auth_sock fi
(并确保chmod 750 ~/.ssh/rc
)。“测试”只是为了防止在您未运行 ssh-agent 时显示错误(即,您不使用 ssh -A
)。该命令的后半部分在规范位置设置符号链接,该符号链接SSH_AUTH_SOCK
在登录时更新为“真实”位置。这与在 ssh 中使用 shell 或直接调用命令无关,也适用于ssh -t <host> screen -RRD
。
注意: 的存在~/.ssh/rc
会改变 sshd 的行为。值得注意的是,它不会调用 xauth。请参阅 man sshd 了解更多信息以及如何修复此问题。
此外,您不应将“-v”与 ln 一起使用,因为它会破坏 rsync-over-ssh,并出现以下诊断:
$ rsync -n addr.maps.dev.yandex.net: .
protocol version mismatch -- is your shell clean?
(see the rsync man page for an explanation)
rsync error: protocol incompatibility (code 2) at compat.c(173) [Receiver=3.0.7]
在您的 .screenrc 中,您只需将 SSH_AUTH_SOCK 覆盖到规范位置:
setenv SSH_AUTH_SOCK $HOME/.ssh/ssh_auth_sock
请注意,无论您使用什么 shell,都使用 setenv;我认为 setenv 是屏幕语法,而不是 shell。
解决方案最初改编自这个帖子,虽然不起作用,但是想法正确。
答案2
我认为这可以简化@sandip-bhattacharya 的答案。将其放入您的~/.bashrc
文件中,然后在任何当前正在运行的屏幕会话中运行导出命令。
if [ -S "$SSH_AUTH_SOCK" ] && [ ! -h "$SSH_AUTH_SOCK" ]; then
ln -sf "$SSH_AUTH_SOCK" ~/.ssh/ssh_auth_sock
fi
export SSH_AUTH_SOCK=~/.ssh/ssh_auth_sock
其内容为“如果$SSH_AUTH_SOCK
是套接字 ( -S
) 而不是符号链接 ( ! -h
),则在已知路径上创建一个新的符号链接。在所有情况下,重新定义SSH_AUTH_SOCK
为指向已知路径。
! -h
如果多次运行该操作,则可以避免创建循环引用。
此外,如果您使用byobu
,它会自动执行此操作,而无需编辑任何配置文件。
我发现的唯一错误(byobu
也有它)是如果你打开第二个ssh -A
连接ForwardAgent
它将覆盖第一个套接字,如果你在第一个连接之前关闭第二个连接,你将丢失唯一好的套接字。
答案3
“ssh -t some.machine screen -R” 不会运行 bash,因此不会运行创建符号链接的 .bash_profile 脚本。
您可以尝试:ssh -t some.machine bash -c“screen -R”
(当然假设你使用 bash 作为你的 shell)
编辑:那个“答案”实际上是对上面给出的第一个答案:)
答案4
我认为你需要 autossh。我已经用了好几年了,它和 screen 结合使用,让我所有的终端会话都变得完全可移植和透明。我只需关闭 lappy,移动到新位置,打开 lappy,我的所有屏幕和嵌套屏幕就会自动连接。我甚至不再考虑它了。
http://www.linux.com/archive/feature/134133
是基础知识...我用 ruby 编写了一个小脚本来自动执行 .screenrc 中针对给定主机的进程。(还执行我的 ssh 转发,因此在所有这些不同的地方我都可以通过我的服务器建立连接隧道)
在 autossh 发行版中应该有一个名为 rscreen 的程序(而且.. 确实有!)
#!/bin/sh
#
# sample script to use autossh to open up a remote screen
# session, or reconnect to an existing one.
#
# $Id: rscreen,v 1.4 2002/05/07 17:54:13 harding Exp $
#
if [ "X$1" = "X" ]; then
echo "usage: `basename $0` <host>"
exit 1
fi
if [ "X$SSH_AUTH_SOCK" = "X" ]; then
eval `ssh-agent -s`
ssh-add $HOME/.ssh/id_rsa
fi
#AUTOSSH_POLL=600
#AUTOSSH_PORT=20000
#AUTOSSH_GATETIME=30
#AUTOSSH_LOGFILE=$HOST.log
#AUTOSSH_DEBUG=yes
#AUTOSSH_PATH=/usr/local/bin/ssh
export AUTOSSH_POLL AUTOSSH_LOGFILE AUTOSSH_DEBUG AUTOSSH_PATH AUTOSSH_GATETIME
autossh -M 20004 -t $1 "screen -e^Zz -D -R"
这应该有助于解决 ssh/screen 问题
最后,为了保持我的 ssh-agent 运行,我使用了 keychain,因为我有点像 shell 头...我认为 OSX 有一些东西可以让您的代理继续运行...