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
それもあります)は、2番目ssh -A
またはForwardAgent
接続を開くと最初のソケットを上書きし、最初のソケットの前に2番目の接続を閉じると、唯一の良いソケットが失われます。
tmux
も同様に機能します。
~/.ssh/ssh_auth_sock_"$(hostname)"
シンボリックリンクに使用します。ホストごとに個別の認証ソケットを保持します。
「ssh -t some.machine screen -R」はbashを実行しないため、シンボリックリンクが作成される.bash_profileスクリプトを実行しません。
あなたが試すことができます:ssh -t some.machine bash -c "screen -R"
(もちろん、bashをシェルとして使用していると仮定します)
編集:その「答え」は実際には上記の最初の答えに対するコメントです :)
autosshが必要だと思います。私はもう何年も使用していますが、画面と組み合わせると、すべての端末セッションが完全に移植可能かつ透過的になります。単にラッピーを閉じ、新しい場所に移動し、ラッピーを開くと、すべての画面とネストされた画面が自動的に接続されます。もう考えもしません。
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) 'を、画面を再接続するために使用する正確なコマンドに適合させる必要がある場合があります。
私の方法の注意点:コンピューターで別の " screen "コマンドが実行されていると、状況が悪くなることがあります。
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
画面を起動/再接続せずにリモートサーバーにログインしただけの場合、2つの「ソケット」があり、1つscreen
は新しいシェルによって使用され、もう1つは新しいシェルによって使用されます。2つの「スタートアップ」セッションがあってはなりませんが、2つ目のセッションは引き続き使用できreattach -S new
ます。この状況では、エージェントは~/.ssh/agent-screen
値と共有されます。正常に機能する海貨業者を取り戻すには、切り離してから再度ログインします。これX${USER} = Xmyusername
によりsudo
、同じサーバーでコードが呼び出されないようになります。
.apashsteinが.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
、ホストシェルで実行して動作させる必要があります。
PSこれを独立した回答として追加してすみませんが、@ apinsteinの回答に基づいています。stackoverflowのコメントはコードブロックをサポートしないため、これを行う必要がありました。
画面とsshエージェントの友達を作りましょうで提案されているように、このシンプルなライナーを試しました。
Target.Needsへの初回ログインは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
これらはすべて本当に良い答えです。私は少し違うやり方でやっています。新しいsshセッションを開始して画面を再接続した後SSH_AUTH_SOCK
、ルートbash環境の内容に基づいて環境変数をリセットしました。私は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"
上記のすべてのソリューションは、競合状態(複数のSCREENセッションまたは複数のSSH接続のいずれか)の影響を受けます。私が考えることができる唯一の普遍的な解決策は、最初にSSH_AUTH_SOCKをSCREENサーバープロセスにプッシュしscreen -r
、次に各非ビルトインコマンドの前にBASHセッション内にプルすることです。残念ながら、SCREENとBASHはそのような問題を意識することなく設計されたため、適切に実装するのはかなり困難です(ただし、両方のプロジェクトに機能要求を投稿するのは遅くありません)。ここにあるBASHセッションでこの問題を克服しようとしました。
インストールする:
$HOME/bin
、実行可能ビットを追加します。PATHの$HOME/bin
前/usr/bin
にあることを確認してください:
PATH = $ HOME / bin:$ PATH
これをあなたのに追加してください.bashrc
:
source $ HOME / bin / screen-helper setup
これで、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
この方法では、2つのスクリーンセッションを使用します。1つは「ラッパー」で、もう1つは内側のセッションです。これにより、ログアウトしても後者が保持され、ssh-agentがオンのままになります。もう1つの便利な機能は、ウィンドウのセットアップを記憶することです。分割ウィンドウを使用する場合、非常に便利です。
この機能は、私のdotfilesのコンテキストで見つけることができます。