ssh-agent가 실행되는 동안 (ssh -A 에이전트 전달에서) 화면 세션을 시작하면 ssh-agent에 액세스하는 것이 좋습니다. 그러나 해당 세션에서 분리하고 로그 아웃 한 후 다시 로그인 (ssh-agent 전달을 사용하여) 한 다음 화면 세션에 다시 연결하면 ssh-agent 액세스가 작동하지 않습니다.
이 문제를 어떻게 해결할 수 있습니까?
ssh-agent가 실행되는 동안 (ssh -A 에이전트 전달에서) 화면 세션을 시작하면 ssh-agent에 액세스하는 것이 좋습니다. 그러나 해당 세션에서 분리하고 로그 아웃 한 후 다시 로그인 (ssh-agent 전달을 사용하여) 한 다음 화면 세션에 다시 연결하면 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 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는 쉘이 아니라 화면 구문이라고 생각합니다.
해결책은 원래이 게시물 에서 조정 되었지만 작동하지 않지만 올바른 아이디어가 있습니다.
나는 이것이 @ 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 -A
나 ForwardAgent
연결하면 첫 번째 소켓을 덮어 쓰며 첫 번째 소켓 전에 두 번째 연결을 닫으면 유일한 소켓이 손실됩니다.
tmux
잘 작동합니다 .
~/.ssh/ssh_auth_sock_"$(hostname)"
심볼릭 링크에 사용 하십시오. 각 호스트마다 별도의 인증 소켓을 유지합니다.
"ssh -t some.machine screen -R"은 bash를 실행하지 않으므로 symlink가 작성된 .bash_profile 스크립트를 실행하지 않습니다.
당신은 시도 할 수 있습니다 : ssh -t some.machine bash -c "screen -R"
(물론 bash를 bash로 사용한다고 가정)
편집 : 그 "답변"은 실제로 위에 주어진 첫 번째 대답 에 대한 주석입니다 :)
나는 당신이 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에 에이전트를 유지할 수있는 것이 있다고 생각합니다 ...
내가 사용하는 방법은 다음과 같습니다.
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) '을 적용해야 할 수도 있습니다.
내 방법에 대한주의 사항 : 컴퓨터에서 다른 " 화면 "명령이 실행 되면 문제가 발생할 수 있습니다.
sudo
.
저는 일반적으로 직장에서 다른 서버의 장기 (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
.
@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의 주석이 코드 블록을 지원하지 않기 때문에이 작업을 수행해야했습니다.
화면과 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
이것들은 내가 조금 다르게하는 정말 좋은 답변입니다. 새 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"
위의 모든 솔루션은 여러 SCREEN 세션 또는 여러 SSH 연결에서 경쟁 조건으로 인해 어려움을 겪고 있습니다. 내가 생각할 수있는 유일한 보편적 인 솔루션은 먼저 SSH_AUTH_SOCK to SCREEN 서버 프로세스를 푸시 screen -r
한 다음 각 대화식 비 내장 명령 전에 BASH 세션으로 가져 오는 것입니다. 불행히도 SCREEN과 BASH는 이러한 종류의 문제를 인식하지 않고 설계되었으므로 제대로 구현하기가 다소 어렵습니다 (두 프로젝트 모두에 기능 요청을 게시하는 데 늦지는 않습니다). BASH 세션 에서이 문제를 극복하려고 시도했습니다.
설치하기 위해서:
$HOME/bin
실행 비트를 추가하십시오.PATH에서 $HOME/bin
진행 되는지 확인하십시오 /usr/bin
.
PATH = $ HOME / bin : $ PATH
이것을 당신의 .bashrc
:에 추가하십시오
$ HOME / bin / screen-helper 설정 소스
이제 SSH 세션 내에서 SCREEN 세션을 생성하고 분리, 연결 해제, 연결 및 재 연결을 시도 할 수 있으며 ssh-add -l
키를 올바르게 표시해야합니다.
ssh-agent
데몬 (여기서는 superuser.com/a/412052/376867 에서 제안 )은 경합 상태가 아니라 오래된 키 링이 발생합니다. 더 중요한 것은 모든 키를 화면 세션과 함께 원격 호스트에 두는 것 (또는 언급 된 게시물의 경우 재부팅 할 때까지 더 긴 시간)을 유지하는 것이 안전하지 않습니다.
나는 다른 답변을 훑어보고 내 것을 찾을 수 없었습니다. 여기 내가 사용하는 것이 있습니다. ~/.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 에서이 기능을 컨텍스트에서 찾을 수 있습니다 .