기존 화면에 다시 연결할 때 화면이 현재 ssh-agent에 자동으로 연결되도록하려면 어떻게합니까?


47

ssh-agent가 실행되는 동안 (ssh -A 에이전트 전달에서) 화면 세션을 시작하면 ssh-agent에 액세스하는 것이 좋습니다. 그러나 해당 세션에서 분리하고 로그 아웃 한 후 다시 로그인 (ssh-agent 전달을 사용하여) 한 다음 화면 세션에 다시 연결하면 ssh-agent 액세스가 작동하지 않습니다.

이 문제를 어떻게 해결할 수 있습니까?

답변:


41

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 755 ~ / .ssh / rc를 확인하십시오). "테스트"는 ssh-agent를 실행하지 않는 경우 (예 : -A없이 ssh) 오류가 표시되지 않도록하기위한 것입니다. 이 명령의 후반부는 정식 위치에 로그인 할 때 "실제"SSH_AUTH_SOCK로 자체 업데이트되는 심볼릭 링크를 설정합니다. 이것은 ssh에서 쉘을 사용하거나 명령을 직접 호출하는 것과 무관하며 "ssh -t screen -RRD"에서도 작동합니다.

참고 : ~ / .ssh / rc가 있으면 sshd의 동작이 변경됩니다. 특히 xauth를 호출하지 않습니다. 자세한 내용 및이 문제를 해결하는 방법은 man sshd를 참조하십시오.

또한 다음 진단으로 rsync-over-ssh가 중단되는 즉시 ln과 함께 "-v"를 사용하면 안됩니다.

$ 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]

2) .screenrc에서 SSH_AUTH_SOCK를 정식 위치로 재정의하면됩니다.

setenv SSH_AUTH_SOCK $HOME/.ssh/ssh_auth_sock

어떤 쉘을 사용하든 setenv를 사용합니다. setenv는 쉘이 아니라 화면 구문이라고 생각합니다.

해결책은 원래이 게시물 에서 조정 되었지만 작동하지 않지만 올바른 아이디어가 있습니다.


먼저 로그인 한 다음 화면을 시작한다고 가정합니다. 권리?
innaM

1
다른 방법이 될 수 있습니까? 로그인하지 않고 어떻게 화면을 시작 하시겠습니까?

1
네가 옳아. 그 질문은 어리석게 표현되었습니다. 그러나 로그인하고 쉘을 시작해야하며 거기에서 시작 화면이 필요합니까? 나는 종종 "ssh -t some.machine screen -R"과 같은 것을한다.
innaM

1
그래. 글쎄, 방금 시도했지만 작동하지 않습니다 (예 : ssh-agent가 연결되어 있지 않습니다). ssh 가이 방식으로 사용될 때 적절한 소켓을 설정하지 않는 것 같습니다. 아마도 더 많은 논쟁-foo가 그것을 정리할 수 있습니까?

SSH는 소켓을 설정하지만 쉘을 시작하지 않습니다. 그러나이 팁은 너무 유용하여 습관을 바꿀 수 있다고 생각합니다.
innaM

23

나는 이것이 @ sandip-bhattacharya의 대답을 단순화 한 것으로 생각합니다. 이것을 ~/.bashrc파일에 넣고 현재 실행중인 화면 세션에서 export 명령을 실행하십시오.

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 -AForwardAgent연결하면 첫 번째 소켓을 덮어 쓰며 첫 번째 소켓 전에 두 번째 연결을 닫으면 유일한 소켓이 손실됩니다.


1
이것은 tmux잘 작동합니다 .
Dag Høidahl

훌륭하게 작동하지만 원격으로 마운트 된 홈 폴더를 사용할 때 중단됩니다. 이 경우 ~/.ssh/ssh_auth_sock_"$(hostname)"심볼릭 링크에 사용 하십시오. 각 호스트마다 별도의 인증 소켓을 유지합니다.
Kibber

4

"ssh -t some.machine screen -R"은 bash를 실행하지 않으므로 symlink가 작성된 .bash_profile 스크립트를 실행하지 않습니다.

당신은 시도 할 수 있습니다 : ssh -t some.machine bash -c "screen -R"

(물론 bash를 bash로 사용한다고 가정)

편집 : 그 "답변"은 실제로 위에 주어진 첫 번째 대답 에 대한 주석입니다 :)


"위의 첫 번째 답변"은 투표 등의 답변 변경 순서를 의미하지는 않습니다. 답변이 변경되지 않으므로 언급 한 답변의 공유 링크를 포함하십시오.
rjmunro

3

나는 당신이 autossh가 필요하다고 생각합니다. 나는 수년 동안 그것을 사용해 왔으며 화면과 결합하여 모든 터미널 세션을 완전히 휴대 가능하고 투명하게 만듭니다. 나는 단순히 lappy를 닫고, 새로운 위치로 이동하고, lappy를 열면 모든 내 화면과 중첩 된 화면이 자동으로 연결됩니다. 나는 더 이상 그것에 대해 생각하지 않습니다.

http://www.linux.com/archive/feature/134133

기본입니다 ... 주어진 호스트에 대해 .screenrc의 프로세스를 자동화하기 위해 lil 스크립트를 루비했습니다. (또한 내 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를 계속 실행하기 위해 쉘 헤드이기 때문에 키 체인을 사용합니다 ... OSX에 에이전트를 유지할 수있는 것이 있다고 생각합니다 ...


2

내가 사용하는 방법은 다음과 같습니다.

SOCK=$(sudo cat /proc/$(pgrep -f "screen -(r|DR)")/environ | tr "\0" "\n" | grep SSH_AUTH_SOCK) ; eval $SOCK ; export SSH_AUTH_SOCK
DISP=$(sudo cat /proc/$(pgrep -f "screen -(r|DR)")/environ | tr "\0" "\n" | grep DISPLAY) ; eval $DISP ; export DISP

나는 보통 이들 명령으로 별명이나 쉘 함수를 설정합니다.

function ssh-screen-auth() {
  SOCK=$(sudo cat /proc/$(pgrep -f "screen -(r|DR)")/environ | tr "\0" "\n" | grep SSH_AUTH_SOCK)
  eval $SOCK
  export SSH_AUTH_SOCK
  DISP=$(sudo cat /proc/$(pgrep -f "screen -(r|DR)")/environ | tr "\0" "\n" | grep DISPLAY)
  eval $DISP
  export DISPLAY
}

화면 을 다시 연결하는 데 사용하는 정확한 명령에 정규식 ' screen-(r | DR) '을 적용해야 할 수도 있습니다.

  • 첫 번째 행은 방금 입력 한 " screen -r "명령 의 프로세스 공간에서 SSH_AUTH_SOCK 환경 변수를 읽고 현재 쉘의 값을 업데이트합니다.
  • " ssh -X "를 사용 하여 X11 연결을 전달 하는 경우 두 번째 행이 필요합니다 . 동일한 방식으로 DISPLAY 변수를 업데이트합니다 .

내 방법에 대한주의 사항 : 컴퓨터에서 다른 " 화면 "명령이 실행 되면 문제가 발생할 수 있습니다.


의 불필요한 사용에 대해서는 -1입니다 sudo.
0xC0000022L

1

저는 일반적으로 직장에서 다른 서버의 장기 (6 개월 이상) 세션을 운영합니다. 따라서 반복적 인 재 연결 및 실행 가능한 ssh 전달 에이전트를 갖는 것은 문제가되었습니다. 이것이 내가 시스템에서 설정 한 것입니다.

if [ -z "${STY}" -a -t 0 -a X${USER} = Xmyusername ]; then
    reattach () {
        if [ -n "${SSH_AUTH_SOCK}" ]; then
            ln -snf "${SSH_AUTH_SOCK}" "${HOME}/.ssh/agent-screen"
            SSH_AUTH_SOCK="${HOME}/.ssh/agent-screen" export SSH_AUTH_SOCK
        fi
        exec screen -A -D -RR ${1:+"$@"} ;
    }

    screen -wipe
    echo 'starting screen... (type Cntl-C to abort)'
    sleep 5 && reattach
fi

시작 / 다시 시작 화면없이 원격 서버에 로그인하면 두 개의 "소켓"이 있으며, 하나 screen는 새 쉘 에서 사용 하고 다른 하나는 사용합니다 . 두 개의 "시작"세션이 없어야하지만 두 번째 세션은 여전히 reattach -S new; 이 상황에서 에이전트는 ~/.ssh/agent-screen값 과 공유됩니다 . 작업 전달 에이전트를 다시 가져 오려면 분리 한 후 다시 로그인하십시오. 그러면 동일한 서버 X${USER} = Xmyusername에서 코드가 호출되지 않습니다 sudo.


1

@apinstein이 내 .bashrc에 사용하는 변형을 사용하고 있습니다 .

case "$TERM" in
    screen)
           export SSH_AUTH_SOCK=~/.ssh/ssh_auth_sock
        ;;
         *)
           if [[ -n "$SSH_AUTH_SOCK" ]]; then
               ln -sf $SSH_AUTH_SOCK ~/.ssh/ssh_auth_sock
           fi
        ;;
esac

이것은 내 화면 세션에서 실행되는 모든 앱에서 작동합니다. 이것은 스크린 세션의 모든 새로운 쉘에서 작동합니다. 기존 쉘의 export SSH_AUTH_SOCK=~/.ssh/ssh_auth_sock경우 호스트 쉘에서 실행해야 작동합니다.

추신 : 이것은 @apinstein의 답변을 바탕으로 한 독립 답변으로 추가하여 죄송합니다. stackoverflow의 주석이 코드 블록을 지원하지 않기 때문에이 작업을 수행해야했습니다.


항상 symlink하고 항상 내 보내지 않는 이유는 무엇입니까?
Collin Anderson

@CollinAnderson 두 가지 행동. 하나는 화면 쉘 내에 있고 다른 하나는 일반 로그인 쉘 안에 있습니다. 로그인 쉘의 환경 변수는 ssh에 의해 설정되므로 심볼릭 링크가 있습니다. 스크린 세션 내에서이 작업을 수행하면 심볼릭 링크 루프가 발생합니다.
Sandip Bhattacharya

아, 맞아 $ SSH_AUTH_SOCK가 아직 링크가 아닌 경우에만 링크해야합니다. 내 게시물 참조 superuser.com/a/424588/134212
Collin Anderson

0

화면과 ssh-agent 친구만들자에 제안 된 대로이 간단한 라이너를 사용해 보았습니다 .

Target에 처음 로그인하면 한 번만 수행해야합니다.

ssh -o StrictHostKeyChecking=no -C <userid>@<server>

처음 화면 시작. 한 번만 수행해야합니다.

eval `ssh-agent`; /usr/bin/screen -D -R -h 10000
ssh-add

분리 또는 연결 해제 된 경우이 명령을 사용하여 로그인하여 종료 화면에 연결하십시오.

ssh -o StrictHostKeyChecking=no -C -t <userid>@<server> ssh-agent /usr/bin/screen -D -R -h 10000

0

이것들은 내가 조금 다르게하는 정말 좋은 답변입니다. 새 ssh 세션을 시작하고 화면을 다시 연결 한 후 SSH_AUTH_SOCK루트 bash 환경의 내용을 기반으로 환경 변수를 재설정 합니다. svn을 사용할 때 가끔 ssh-agent 액세스가 필요 하므로이 SSH_AUTH_SOCK쉘에서 필요에 따라 재설정하십시오 .

이것은 proc 파일 시스템을 사용하므로 리눅스마다 다릅니다. 나는 오직 나만 액세스 할 수있는 헤드리스 리눅스 박스에서만 이것을 테스트했다. 다른 환경에서 작동하려면 약간의 조정이 필요할 수있다.

SSH_AUTH_SOCK를 재설정하려면 (별칭으로 만들 수 있음).

$ . ~/bin/screen_auth.sh

screen_auth.sh는 다음과 같습니다

# Find the pid of putty's bash shell
tty=`who | awk '/[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+/ { print substr($2, 5) }'`
pid=`ps -t $tty | grep bash | awk '{print $1}'`
# Find the SSH_AUTH_SOCK variable in its enviornment
auth_sock=`xargs --null --max-args=1 echo < /proc/$pid/environ | grep SSH_AUTH_SOCK`
eval "export $auth_sock"

0

위의 모든 솔루션은 여러 SCREEN 세션 또는 여러 SSH 연결에서 경쟁 조건으로 인해 어려움을 겪고 있습니다. 내가 생각할 수있는 유일한 보편적 인 솔루션은 먼저 SSH_AUTH_SOCK to SCREEN 서버 프로세스를 푸시 screen -r한 다음 각 대화식 비 내장 명령 전에 BASH 세션으로 가져 오는 것입니다. 불행히도 SCREEN과 BASH는 이러한 종류의 문제를 인식하지 않고 설계되었으므로 제대로 구현하기가 다소 어렵습니다 (두 프로젝트 모두에 기능 요청을 게시하는 데 늦지는 않습니다). BASH 세션 에서이 문제를 극복하려고 시도했습니다.

설치하기 위해서:

  1. 두 스크립트를 모두 넣고 $HOME/bin실행 비트를 추가하십시오.
  2. PATH에서 $HOME/bin진행 되는지 확인하십시오 /usr/bin.

    PATH = $ HOME / bin : $ PATH

  3. 이것을 당신의 .bashrc:에 추가하십시오

    $ HOME / bin / screen-helper 설정 소스

이제 SSH 세션 내에서 SCREEN 세션을 생성하고 분리, 연결 해제, 연결 및 재 연결을 시도 할 수 있으며 ssh-add -l키를 올바르게 표시해야합니다.


영구 ssh-agent데몬 (여기서는 superuser.com/a/412052/376867 에서 제안 )은 경합 상태가 아니라 오래된 키 링이 발생합니다. 더 중요한 것은 모든 키를 화면 세션과 함께 원격 호스트에 두는 것 (또는 언급 된 게시물의 경우 재부팅 할 때까지 더 긴 시간)을 유지하는 것이 안전하지 않습니다.
midenok '11

0

나는 다른 답변을 훑어보고 내 것을 찾을 수 없었습니다. 여기 내가 사용하는 것이 있습니다. ~/.screenrc-wrapper다음 내용 으로 파일 을 작성하십시오 .

escape ^xx
bindkey ^Ad detach

그리고 이것을 당신의 ~/.bashrc(또는 ~/.zshrc사용한다면) 추가하십시오 :

  if echo $TERM | grep -v 'screen' && ! screen -x -SU wrapper; then
      if echo $TERM | grep -v 'screen' && ! screen -x -SU main; then
      screen -c ~/.screenrc-wrapper -SU wrapper ssh-agent screen -SU main
      fi
  fi

이 방법으로 두 개의 스크린 세션을 사용할 수 있습니다. 하나는 "래퍼"이고 다른 하나는 내부입니다. 이렇게하면 로그 아웃해도 ssh-agent가 계속 켜져 있습니다. 또 다른 좋은 기능은 창 설정을 기억한다는 것입니다. 분할 창을 사용하는 경우 매우 유용 할 수 있습니다.

dotfiles 에서이 기능을 컨텍스트에서 찾을 수 있습니다 .

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.