Ssh-agentの実行中に(ssh -Aエージェント転送から)screenセッションを開始した場合、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 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
ファイルを作成し、現在実行中のスクリーンセッションでエクスポートコマンドを実行します。
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
にもあります)は、2番目のssh -A
またはForwardAgent
接続すると、最初のソケットが上書きされ、最初の接続の前に2番目の接続を閉じると、正常なソケットだけが失われます。
「ssh -t some.machine screen -R」はbashを実行しないため、シンボリックリンクが作成されている.bash_profileスクリプトは実行されません。
あなたは試すことができます:ssh -t some.machine bash -c "screen -R"
(もちろん、シェルとしてbashを使用していると仮定します)
編集:その「答え」は実際には 上記の最初の答え へのコメントです:)
Autosshが必要だと思います。私はこれを何年も使用しており、画面と組み合わせることで、すべての端末セッションを完全にポータブルで透過的にします。 Lappyを閉じて新しい場所に移動し、Lappyを開くと、すべての画面とネストされた画面が自動的に接続されます。私はそれについてもう考えていません。
http://www.linux.com/archive/feature/1341
基本です...私は、指定されたホストの.screenrcでプロセスを自動化するために、lilスクリプトをRubyで作成しました。 (私の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 /画面の問題に役立ちます
最後に、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
}
正規表現 'screenr | DR)'を、画面を再接続するために使用する正確なコマンドに適合させる必要がある場合があります。
私の方法の警告:コンピューターで実行中の別の "screen"コマンドがある場合、問題が発生する可能性があります。
@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のコメントはコードブロックをサポートしないため、これを行う必要がありました。
私は通常、職場のさまざまなサーバーで長期間(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
画面を開始/再接続せずにリモートサーバーにログインするだけの場合、2つの「ソケット」があり、1つはscreen
で使用され、もう1つは新しいシェルで使用されます。 「スタートアップ」セッションは2つにすべきではありませんが、2番目のセッションはreattach -S new
を使用して開始できます。この状況では、エージェントは~/.ssh/agent-screen
値と共有されます。機能している転送エージェントを元に戻すには、デタッチし、再度ログインします。X${USER} = Xmyusername
は、同じサーバーのSudo
を通じてコードが呼び出されないようにします。
これらはすべて本当に良い答えです。新しいsshセッションを開始して画面を再接続した後、ルートbash環境の内容に基づいてSSH_AUTH_SOCK
環境変数をリセットします。私はsvnを使用しているときにssh-agentへのアクセスのみを必要とするため、これらのシェルで必要に応じてSSH_AUTH_SOCK
をリセットするだけです。
これはprocファイルシステムを使用するため、Linux固有です。私は、自分だけがアクセスできるヘッドレスLinuxボックスでのみこれをテストしました。他の環境で動作させるには、多少の調整が必要になる場合があります。
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"
私は他の答えをざっと見て、私のものを見つけることができませんでした。これが私が使うものです。次の内容のファイル~/.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
この方法では、2つのスクリーンセッションを使用します。1つは「ラッパー」で、もう1つは内部です。これにより、ログアウトした場合でも後者が存続し、ssh-agentがオンのままになります。もう1つの素晴らしい機能は、ウィンドウの設定を記憶することです。分割ウィンドウを使用する場合、非常に便利です。
この機能のコンテキストは、my dotfiles にあります。
画面とssh-agentの友達を作ろう で提案されているように、このシンプルな1ライナーを試してみました。
Targetへの初回ログイン。1回だけ実行する必要があります。
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
上記のすべてのソリューションは、(複数のSCREENセッションまたは複数のSSH接続のいずれかで)競合状態に悩まされています。私が考えることができる唯一の普遍的なソリューションは、最初にSSH_AUTH_SOCKをscreen -r
のSCREENサーバープロセスにプッシュしてから、各対話型の非組み込みコマンドの前に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
がキーを正しく表示するはずです。