既存の画面に再接続するときに、現在のssh-agentに自動的に接続する画面を取得するにはどうすればよいですか?


48

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はシェルではなく画面構文だと思います。

解決策はもともとこの投稿から適応したものですが、機能しませんが、正しい考えを持っています。


これは、最初にログインしてから画面を開始することを前提としています。右?
イナム2009年

1
どうすれば他の方法になりますか?ログインせずにどのように画面を起動しますか?

1
あなたが正しい。質問は愚かな方法で表現されました。しかし、ログインしてシェルを起動し、そこから起動画面を表示する必要がありますか?私はよく「ssh -t some.machine screen -R」のようなことをします。
インナ2009年

1
わかった まあ、私はこれを試してみただけで機能しません(つまり、ssh-agentが接続されていません)。この方法で使用した場合、sshは適切なソケットをセットアップしないと思います。たぶんもっと引数-fooがそれをきれいにすることができますか?

SSHはソケットを設定しますが、シェルを起動することはありません。しかし、このヒントはとても便利なので、自分の習慣を変えるだけかもしれません。
インナ2009年

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それもあります)は、2番目ssh -AまたはForwardAgent接続を開くと最初のソケットを上書きし、最初のソケットの前に2番目の接続を閉じると、唯一の良いソケットが失われます。


1
これtmuxも同様に機能します。
ダグホイダール

うまく機能しますが、リモートでマウントされたホームフォルダーを使用すると壊れます。その場合、~/.ssh/ssh_auth_sock_"$(hostname)"シンボリックリンクに使用します。ホストごとに個別の認証ソケットを保持します。
Kibber

4

「ssh -t some.machine screen -R」はbashを実行しないため、シンボリックリンクが作成される.bash_profileスクリプトを実行しません。

あなたが試すことができます:ssh -t some.machine bash -c "screen -R"

(もちろん、bashをシェルとして使用していると仮定します)

編集:その「答え」は実際には上記の最初の答えに対するコメントです :)


「上記の最初の回答」とは、投票などで回答の順序が変わることを意味するものではありません。参照している回答からの共有リンクを含めてください。
rjmunro

3

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には、エージェントを維持するための何かがあると思います...


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環境変数を読み取り、現在のシェルの値を更新します。
  • 2行目は、「ssh -X」を使用してX11接続を転送する場合に必要です。同じ方法でDISPLAY変数を更新します。

私の方法の注意点:コンピューターで別の " screen "コマンドが実行されていると、状況が悪くなることがあります。


-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

画面を起動/再接続せずにリモートサーバーにログインしただけの場合、2つの「ソケット」があり、1つscreenは新しいシェルによって使用され、もう1つは新しいシェルによって使用されます。2つの「スタートアップ」セッションがあってはなりませんが、2つ目のセッションは引き続き使用できreattach -S newます。この状況では、エージェントは~/.ssh/agent-screen値と共有されます。正常に機能する海貨業者を取り戻すには、切り離してから再度ログインします。これX${USER} = Xmyusernameによりsudo、同じサーバーでコードが呼び出されないようになります。


1

.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のコメントはコードブロックをサポートしないため、これを行う必要がありました。


常にシンボリックリンクでなく、常にエクスポートしないのはなぜですか?
コリンアンダーソン

@CollinAnderson 2つの異なる動作。1つはスクリーンシェル内、もう1つは通常のログインシェル内です。ログインシェルの環境変数はsshによって設定されるため、そこでのシンボリックリンクが設定されます。スクリーンセッション内でこれを行うと、シンボリックリンクループが発生します。
サンディップバタチャリア

ああ、そう。リンクする必要があるのは、$ SSH_AUTH_SOCKがまだリンクでない場合のみです。私の投稿を参照してくださいsuperuser.com/a/424588/134212
コリンアンダーソン

0

画面と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

0

これらはすべて本当に良い答えです。私は少し違うやり方でやっています。新しい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"

0

上記のすべてのソリューションは、競合状態(複数のSCREENセッションまたは複数のSSH接続のいずれか)の影響を受けます。私が考えることができる唯一の普遍的な解決策は、最初にSSH_AUTH_SOCKをSCREENサーバープロセスにプッシュしscreen -r、次に各非ビルトインコマンドの前にBASHセッション内にプルすることです。残念ながら、SCREENとBASHはそのような問題を意識することなく設計されたため、適切に実装するのはかなり困難です(ただし、両方のプロジェクトに機能要求を投稿するのは遅くありません)。ここにあるBASHセッションでこの問題を克服しようとしました。

インストールする:

  1. 両方のスクリプトをに入れ$HOME/bin、実行可能ビットを追加します。
  2. PATHの$HOME/bin/usr/binにあることを確認してください:

    PATH = $ HOME / bin:$ PATH

  3. これをあなたのに追加してください.bashrc

    source $ HOME / bin / screen-helper setup

これで、SSHセッション内でSCREENセッションを作成し、デタッチ、切断、接続、再アタッチを試みることができssh-add -l、キーが正しく表示されるはずです。


永久ssh-agentデーモン(ここで提案されているsuperuser.com/a/412052/376867)は、競合状態ではなく、古いキーリングの影響を受けることに注意してください。さらに重要なことは、すべてのキーをスクリーンセッションとともにリモートホストに残すこと(または、前述の投稿の場合は再起動するまでさらに長くすること)はあまり安全ではありません。
midenok 14年

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

この方法では、2つのスクリーンセッションを使用します。1つは「ラッパー」で、もう1つは内側のセッションです。これにより、ログアウトしても後者が保持され、ssh-agentがオンのままになります。もう1つの便利な機能は、ウィンドウのセットアップを記憶することです。分割ウィンドウを使用する場合、非常に便利です。

この機能は、私のdotfilesのコンテキストで見つけることができます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.