如何在附加到现有tmux会话时自动更新SSH代理环境变量

如何在附加到现有tmux会话时自动更新SSH代理环境变量,tmux,ssh-agent,Tmux,Ssh Agent,当我重新连接断开的tmux会话时,我正在尝试找到一种恢复SSH代理的好方法 原因似乎是SSH代理会话发生了更改,但tmux会话中的环境变量没有更新 在连接会话本身之前,如何自动执行此操作?因为我附加到的会话并不总是有bash提示符,所以我无法在其中键入内容。它必须在创建或附加tmux会话之前运行 我正在运行的代码的一个示例是--一个小型ssh包装器,它使用tmux创建persistem ssh连接。这很好,但有时ssh代理停止工作,因此我无法再使用它连接到其他主机。 Martijn Vermaa

当我重新连接断开的tmux会话时,我正在尝试找到一种恢复SSH代理的好方法

原因似乎是SSH代理会话发生了更改,但tmux会话中的环境变量没有更新

在连接会话本身之前,如何自动执行此操作?因为我附加到的会话并不总是有bash提示符,所以我无法在其中键入内容。它必须在创建或附加tmux会话之前运行

我正在运行的代码的一个示例是--一个小型ssh包装器,它使用tmux创建persistem ssh连接。这很好,但有时ssh代理停止工作,因此我无法再使用它连接到其他主机。

Martijn Vermaat有一个非常好的例子,它深入地解决了您的问题,尽管它是为屏幕用户设计的,所以我在这里针对tmux进行了调整

总结如下:

  • 如果它还不存在,请创建
    ~/.ssh/rc
    ,并添加以下内容:

    #/bin/bash
    #修复SSH身份验证套接字位置,以便代理转发与tmux一起工作
    如果测试“$SSH\u AUTH\u SOCK”;然后
    ln-sf$SSH\u AUTH\u SOCK~/.SSH/SSH\u AUTH\u SOCK
    fi
    
  • 让它在tmux中工作,将其添加到您的
    ~/.tmux.conf

    #在tmux分离时修复ssh代理
    setenv-g SSH\u AUTH\u SOCK$HOME/.SSH/SSH\u AUTH\u SOCK
    
  • 如果要启用X11转发,需要额外的工作,请参阅。

    而默认情况下,
    tmux
    SSH
    变量不需要

    • 更改/添加套接字路径
    • 更改
      SSH\u AUTH\u套接字
      变量
    我喜欢我改为添加函数的解决方案

    fixsh(){
    评估$(tmux显示环境)\
    |sed-n's/^\(SSH\[^=]*\)=\(.*\)/export\1=“\2”/p')
    }
    
    进入
    ~/.bashrc
    。在连接会话之后或在连接会话之前调用
    fixsh

    较新版本的
    tmux
    支持
    show env
    -s
    选项,因此

    eval $(tmux show-env -s |grep '^SSH_')
    

    是可能的。

    以下是我在
    tmux
    窗口(基于Hans Ginzel的脚本)中更新
    SSH\u AUTH\u SOCK
    的方法:

    或者对于没有showenv-s的
    tmux

    alias fixssh='export $(tmux showenv SSH_AUTH_SOCK)'
    

    这是我的解决方案,它包括两种方法,并且在重新连接到tmux会话时不需要额外键入

    alias ssh='[ -n "$TMUX" ] && eval $(tmux showenv -s SSH_AUTH_SOCK); /usr/bin/ssh'
    

    我使用了之前答案的一个变体:

    eval "export $(tmux show-environment -g SSH_AUTH_SOCK)"
    

    假设您从外部环境启动ssh代理。其他环境变量也一样,比如
    DISPLAY

    这里有很多好的答案。但是,在某些情况下,
    tmux-show-environment
    看不到
    SSH\u-AUTH\u-SOCK
    。在这种情况下,您可以使用
    find
    显式定位它

    export SSH_AUTH_SOCK=$(find /tmp -path '*/ssh-*' -name 'agent*' -uid $(id -u) 2>/dev/null | tail -n1)
    
    这很长很复杂,所以我要把它分解

    01  export SSH_AUTH_SOCK=$(
    02    find /tmp \
    03      -path '*/ssh-*'
    04      -name 'agent*'
    05      -uid $(id -u)
    06      2>/dev/null
    07    | tail -n1
    08  )
    
  • export
    SSH\u AUTH\u SOCK
    环境变量设置为
    $()
    命令替换的输出
  • 查找从
    /tmp
  • 将结果限制为路径中只有
    /ssh-
    的结果
  • 仅将结果限制为名称以
    agent
  • 将结果限制为用户id与当前用户匹配的结果
  • 使所有(权限等)错误静音
  • 如果有多个,只取最后一个结果

  • 如果您知道只有一个结果,并且您不关心stderr垃圾,那么您可以省略6和7。

    我更喜欢避免配置TMUX(etc),并将所有内容完全保存在
    ~/.ssh/
    中。在远程系统上:

    创建
    ~/.ssh/rc

    #!/bin/bash
    
    # Fix SSH auth socket location so agent forwarding works within tmux
    if test "$SSH_AUTH_SOCK" ; then
      ln -sf $SSH_AUTH_SOCK ~/.ssh/ssh_auth_sock
    fi
    
    将以下内容添加到
    ~/.ssh/config
    ,使其不再依赖于在分离的终端中过时的
    $ssh\u AUTH\u SOCK

    Host *
      IdentityAgent ~/.ssh/ssh_auth_sock
    
    已知的限制
    • ssh add
      不使用
      ~/.ssh/config
      ,因此无法与
      ssh代理进行通信。像
      ssh add-l这样的命令会产生错误,即使
      sshuser@host
      工作正常,更新通过SSH访问的git远程设备也可以

    我可能已经找到了一个完全封装在
    ~/.tmux.conf
    配置文件中的解决方案。这是一种不同于修改
    ~/.bash_配置文件
    ~/.ssh/rc
    的方法

    仅使用
    ~/.tmux.conf

    只需将以下代码剪切并粘贴到
    ~/.tmux.conf

    #~/.tmux.conf
    #SSH代理转发
    #
    #确保重新连接到tmux时SSH代理转发将正常工作
    #来自不同SSH连接的会话(断开连接后)。
    #此代码将在tmux创建、tmux附加或配置重新加载时运行。
    #
    #如果最初定义了SSH_AUTH_SOCK:
    #1)从更新环境中删除所有SSH相关的环境变量名称。
    #否则,setenv无法覆盖SSH\u AUTH\u SOCK等变量。
    #使用:tmux show选项-g update environment验证更新环境
    #2)强制将SSH\U AUTH\U SOCK设置为已知位置
    #/tmp/ssh\u auth\u sock\u tmux
    #3)强制在已知位置创建第一个找到的ssh代理套接字的链接
    如果shell“[-n$SSH\u AUTH\u SOCK]””\
    设置选项-sg更新环境\“显示WINDOWID X权限\”\
    setenv-g SSH_AUTH_SOCK/tmp/SSH_AUTH_SOCK_tmux\
    运行shell \“ln-sf$(find/tmp/ssh-*-type s-readable | head-n1)/tmp/ssh\u auth\u sock\u tmux\”\
    "
    
    警告

    当启动到同一台机器的多个连接时,上述解决方案以及其他解决方案容易受到竞争条件的影响。考虑这一点:

    • 客户端1连接:SSH到machineX,启动/连接tmux(写入
      SSH\u auth\u sock
      link
      Host *
        IdentityAgent ~/.ssh/ssh_auth_sock
      
      function _update_tmux_ssh
        if set -q TMUX
          eval (tmux show-environment SSH_AUTH_SOCK | sed 's/\=/ /' | sed 's/^/set /')
        end
      end