ssh代理和屏幕


8

前一阵子,我问了有关ssh-agent和crontab的问题。我现在对linux系统上的ssh-agent和screen也有类似的问题。

因此,在我的Mac上,ssh-agent在系统启动时启动,因此它始终对我可用。我认为,如果我使用的是X-Windows,则在Linux(redhat el5 / fedora)下是正确的。但是,这是一台远程服务器,我总是通过ssh登录。

我希望正确设置ssh密钥,这样就不必在svn更新或提交期间多次输入密码。我很高兴在每个会话中输入一次密码,并且不鼓励我们的团队使用无密码的ssh键。

短暂的一闪,似乎在我的.bash_profile中执行“ eval`ssh-agent -s`”,并与我注销时杀死ssh-agent的命令配对,似乎可行。但是,我们大量使用屏幕来管理长期运行的交互式程序和开发环境。如果像我刚才描述的那样启动和停止ssh-agent,那么当您退出终端时,它将被杀死,并且曾经引用该ssh-agent实例的屏幕子会话将被放弃。

那么...我如何才能成为控制台用户,使用屏幕,使用带有ssh键的密码,而不必不断输入密码的控制台用户?

Answers:


4

使用以下设置,您无需任何包装即可调用screen。此外,它避免了使用/tmp(随之而来的安全风险)。

  1. 确保您有一个〜/ tmp目录:

    mkdir ~/tmp
    
  2. 添加到.screenrc以下行:

    setenv SSH_AUTH_SOCK "$HOME/tmp/ssh-agent-screen"
    
    • 这确保了内screenssh会在同一位置总是插座,而不是改变路径。
    • 您必须使用所用的setenv任何外壳程序,因为它是屏幕而不是外壳程序命令。
  3. 添加到.bash_profile以下行:

    [ -n "$SSH_AUTH_SOCK" ] && [ "$SSH_AUTH_SOCK"!="$HOME/tmp/ssh-agent-screen" ] && ln -sf "$SSH_AUTH_SOCK" "$HOME/tmp/ssh-agent-screen"
    
    • 这将从固定位置(在ssh外观上)链接到实际位置,并且必须启动出现ssh-agent
    • 未设置[ -n "$SSH_AUTH_SOCK" ]时,使用可以正确防止错误SSH_AUTH_SOCK
    • [ "$SSH_AUTH_SOCK"!="$HOME/tmp/ssh-agent-screen" ]如果屏幕来源,将防止屏幕会话将$ HOME / tmp / ssh-agent-screen链接到自身.bash_profile
  4. 而不是启动的ssh-agent.bash_profile,你可以考虑用连接ssh -A(在使用代理转发,使远程机器使用你的经纪人)。

完成此设置后,您可以只使用标准屏幕命令。您只需要重新创建现有会话或将其中的SSH_AUTH_SOCK手动设置为步骤2的固定位置即可。

这个想法归功于这个网站;我避免使用/tmp这个答案很相似,但是使用了额外的别名。


2

您可以从initscript启动ssh-agent .bash_profile吗?例如,我可能会把

su -c 'ssh-agent -s > ~/.ssh_agent_env' myusername

在中的适当部分/etc/conf.d/local,尽管RHEL / Fedora可能使用其他系统。正如您在评论中指出的那样,终端会话将需要能够连接到代理,这就是为什么该命令.ssh_agent_env在用户的主目录中创建文件的原因。然后您可以添加

[ -f ~/.ssh_agent_env ] && source ~/.ssh_agent_env >/dev/null

.bash_profile

您可以做的另一件事是将以下内容放入 .bash_profile

ps -U myusername | grep -q ssh-agent || ssh-agent -s > ~/.ssh_agent_env
source ~/.ssh_agent_env >/dev/null

ssh-agent仅在尚未运行时才会启动。然后,您不必杀死它。

与第二个建议稍有不同ssh-agent,您可以检查文件是否存在,而不是检查进程是否存在~/.ssh_agent_env

[ -f ~/.ssh_agent_env ] || ssh-agent -s > ~/.ssh_agent_env
source ~/.ssh_agent_env >/dev/null

如果一切正常,两种方式之间应该没有太大的区别。


初始脚本的想法很有趣-基本上,是在系统启动时为所有需要它的用户启动它吗?那行得通。我们没有很多用户会关心。一个有趣的问题是,这是否比根本没有密码好得多,因为我怀疑这意味着您只需在每台机器重启时输入一次即可。嗯 这和第二个建议都依赖于新的终端会话能够连接到ssh-agent(如果已运行)。我不能完全肯定就是这么简单,但我还没试过。感谢您的想法!
Michael H.

@khedron:是的,但是您必须为/etc/conf.d/local使用代理的每个用户添加一行(或您的等效名称),以为每个用户启动单独的ssh-agent进程。如您所说,如果您没有大量的用户,那还不错。您提出了关于附加到代理程序上的终端会话的一个好点(我忘记考虑了)。看到我对答案的修改。
David


2

更好的方法是使用ssh代理转发-A可选)。这允许使用ssh的人使用来自其所在机器(可能是他们实际所在的工作站)上的ssh-agent的密钥。


这也使攻击者破坏了您的帐户,从而破坏了该代理可以访问的其他计算机上的帐户。因此,我尝试将ssh代理转发保持在最低水平。
保罗·普赖斯

2

要跟进ssh代理转发,您会发现默认情况下,一旦注销,重新登录并重新加入会话,转发的ssh凭据在屏幕会话中将不可用。

不过,您可以通过将SSH_AUTH_SOCK环境变量设置为众所周知的环境变量,并将该已知位置更新为当前的auth套接字来解决此问题。

我使用此shell函数重新输入屏幕并修复ssh auth袜子:

function sr () { 
    if [ ${+STY} = 1 ] ;then 
            echo already in screen\!
    else
            if [ "${SSH_AUTH_SOCK}x" != "x" ]; then
                    if [ ! -d /tmp/screenssh ]; then
                            mkdir /tmp/screenssh 
                    fi
                    rm -f /tmp/screenssh/socket
                    ln -s $SSH_AUTH_SOCK /tmp/screenssh/socket
                    echo $REMIP > /tmp/screenssh/remip
            fi                
            screen -DR
    fi
}

我的.screenrc中有这个:

setenv SSH_AUTH_SOCK /tmp/screenssh/socket

希望这可以帮助。


使用/ tmp意味着计算机上的其他任何人都可以破坏您的任何文件(如果他知道它们的路径)。
Blaisorblade

1

如果我理解正确,那么您只需要进行一次屏幕会话,有时您将其分离并重新连接,但再也不想再次输入ssh-agent的密码(您的私钥密码)了。

我认为最简单的方法是启动屏幕,而不是先用子外壳启动ssh-agent,然后再停留在该子外壳中。即

screen
ssh-agent bash
ssh-add   # enter your password once

# some commands, some logins and logouts to remote servers via ssh public key

# <ctrl>+<a>, <ctrl>+<d> to detach screen
# you can now logout from this computer
# login again

# reattach to your screen
screen -r
# ssh-agent is still running

这基本上就是我要做的。我使用屏幕将其中的“标签”之一标记为具有ssh-agent的功能,并将其用于svn工作等。还有一个额外的折痕,就是我强迫ssh-agent在几个小时后重新授权,但是,这基本上就是我所在的位置。
Michael H.
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.