Mevcut bir ekrana yeniden eklerken ekranın mevcut ssh-ajanına otomatik olarak bağlanmasını nasıl sağlarsınız?


47

Eğer ssh-agent çalışırken bir ekran oturumu başlatırsanız (ssh-A agent yönünden), ssh-agent'a erişmek gayet iyi çalışır. Ancak, bu oturumdan ayrılırsanız, oturumu kapatın, tekrar oturum açın (ssh-agent yönlendirme ile) ve ekran oturumunuza yeniden ekleyin, ssh-agent erişimi çalışmıyor.

Bu nasıl düzeltilebilir?

Yanıtlar:


41

1) SSH rc betiğinizde (~ / .ssh / rc), kurallı bir konumdan "geçerli" SSH_AUTH_SOCK'a sembolik bir bağlantı kuracaksınız. İşte bash olarak nasıl yaparım (~ / .ssh / rc'nin içeriği):

#!/bin/bash
if test "$SSH_AUTH_SOCK" ; then
    ln -sf $SSH_AUTH_SOCK ~/.ssh/ssh_auth_sock
fi

(ve 755 ~ / .ssh / rc chmod olduğundan emin olun). "Test", eğer ssh-agent'ı çalıştırmıyorsanız (yani -A'sız ssh) görüntülememek için bir hatanın görünmesini engellemek içindir. Bu komutun ikinci yarısı, oturum açma anında kendisini "gerçek" SSH_AUTH_SOCK'a güncelleyen kanonik bir konumda bir sembolik bağlantı kurar. Bu, ssh'de bir kabuk kullanmaktan veya doğrudan bir komut çağırmaktan bağımsızdır, "ssh -t screen -RRD" ile de çalışır.

Not: ~ / .ssh / rc'nin varlığı sshd'nin davranışını değiştirir. Özellikle, xauth'u çağırmaz. Daha fazla bilgi ve bunun nasıl düzeltileceği hakkında bilgi için man sshd'ye bakınız.

Ayrıca, aşağıdaki tanılamalarla rsync-over-ssh'ı kıracak en kısa sürede "-v" kullanmamalısınız:

$ 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'nizde, SSH_AUTH_SOCK'u kanonik konuma geçersiz kılmanız gerekir:

setenv SSH_AUTH_SOCK $HOME/.ssh/ssh_auth_sock

Hangi kabuğu kullandığınızdan bağımsız olarak setenv kullandığınızı unutmayın; Setenv'in kabuk değil ekran sözdizimi olduğunu düşünüyorum.

İlk başta bu yazıdan uyarlanan, işe yaramayan, ancak doğru bir fikri olan çözüm.


Bu, önce giriş yaptığınızı ve ardından ekranı başlattığınızı varsayar. Sağ?
innaM

1
Başka bir yol nasıl olabilir? Giriş yapmadan ekranı nasıl başlatırsın?

1
Haklısın. Soru aptalca bir şekilde ifade edildi. Ancak giriş yapmanız, bir kabuk başlatmanız ve oradan başlangıç ​​ekranı açmanız mı gerekiyor? Sık sık "ssh -t some.machine screen -R" gibi bir şey yaparım.
innaM

1
Ah tamam. Ben sadece bunu denedim ve işe yaramadı (yani ssh-agent bağlı değil). Sanırım ssh bu şekilde kullanıldığında uygun soketleri kurmuyor. Belki biraz daha tartışma-foo bunu temizleyebilir mi?

SSH yuvaları kurar, sadece kabuğunu asla çalıştırmaz. Ancak bu ipucu o kadar kullanışlıdır ki, alışkanlıklarımı değiştirebilirim.
21'de

23

Sanırım @ sandip-bhattacharya'nın cevabının basitleştirilmesi olarak çalışıyor. Bunu ~/.bashrcdosyanıza koyun ve çalışmakta olan tüm ekran oturumlarında export komutunu çalıştırın.

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_SOCKOkur ( -S) ve sembolik bir link ( ! -h) değilse , bilinen yolda yeni bir sembolik link oluşturun. Her durumda, SSH_AUTH_SOCKbilinen yola işaret etmek için yeniden tanımlayın .

Bunu ! -hbirden çok kez çalıştırırsanız, dairesel bir referans oluşturmaktan kaçınır.

Ayrıca, kullanırsanız byobu, herhangi bir yapılandırma dosyasını düzenlemeye gerek kalmadan otomatik olarak yapar.

Bunda bulduğum tek hata ( byobubuna da sahip) bir saniye açarsanız ssh -Aya da ForwardAgentbağlantı kurarsanız, ilk soketin üzerine yazar ve ilk bağlantıdan önce ikinci bağlantıyı kapatırsanız, tek iyi soketinizi kaybedersiniz.


1
Bu da işe yarıyor tmux.
Dag Høidahl

Harika çalışıyor, ancak uzaktan monte edilmiş ev klasörlerini kullanırken kesiliyor. Bu durumda, ~/.ssh/ssh_auth_sock_"$(hostname)"sembolik bağlantınız için kullanın . Her ana bilgisayar için ayrı kimlik doğrulama soketleri tutar.
Kibber

4

"ssh -t some.machine screen -R" bash komutunu çalıştırmaz ve bu nedenle sembolik bağın oluşturulduğu .bash_profile komut dosyasını çalıştırmaz.

Deneyebilirsiniz: ssh -t some.machine bash -c "ekran -R"

(elbette kabuğunuz olarak bash kullandığınızı varsayarsak)

Düzenleme: Bu "cevap" aslında yukarıda verilen ilk cevaba bir yorumdur :)


"Yukarıda verilen ilk cevap", yanıtların oy verme sırasındaki değişiklik sırasını değiştirdiği gibi bir anlam ifade etmez.
rjmunro

3

Bence otomatik durmana ihtiyacın var. Yıllardır kullanıyorum ve ekranla birlikte bütün terminal oturumlarımı tamamen taşınabilir ve şeffaf hale getiriyor. Sadece lappy kapatın, yeni konuma gidin, lappy açın ve tüm ekranlarım ve iç içe ekranlar otomatik olarak bağlanıyor. Artık düşünmüyorum bile.

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

temeldir ... .screenrc'deki işlemi belirli bir ana bilgisayar için otomatik hale getirmek için bir lil betiği ovaladım. (ayrıca ssh iletimi de yapıyor, bu yüzden tüm bu farklı yerlerde bağlantımı sunucularım üzerinden tünelleyebiliyorum)

autossh dağıtımında, rscreen adlı bir program olmalı (ve .. var!)

#!/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"

Bu, ssh / screen problemlerinde yardımcı olmalı

Sonunda, ssh-ajanımı çalışır durumda tutmak için anahtarlık kullanıyorum, çünkü bir tür kabuk kafadayım ... OSX'in ajanını etrafta tutacak bir şeyi olduğunu düşünüyorum.


2

İşte kullandığım yöntem:

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

Genellikle tez komutlarıyla bir takma ad veya bir kabuk işlevi kurarım:

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
}

Ekranınızı yeniden bağlamak için kullandığınız komutların tümüne ' screen - (r | DR) ' normal ifadesini uyarlamanız gerekebilir .

  • İlk satır, SSH_AUTH_SOCK ortam değişkenini az önce girdiğiniz " screen -r " komutunun işlem alanında okur ve mevcut kabuğunuzdaki değeri günceller.
  • X11 bağlantılarını iletmek için " ssh -X " kullanıyorsanız ikinci satır gereklidir : DISPLAY değişkenini aynı şekilde günceller .

Benim yöntem ile bir uyarı: bilgisayarda çalışan başka bir " ekran " komutu varsa işler yanlış gidebilir .


Gereksiz kullanım için -1 sudo.
0xC0000022L

1

İşyerimde farklı sunucularda uzun süreli (6+ ay) oturumlar düzenliyorum. Bu yüzden tekrar tekrar takma ve uygulanabilir bir ssh yönlendirme ajanına sahip olmak sorunlu olmuştur. Sistemlerime kurduğum şey bu:

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

Uzak sunucuya yalnızca ekranı başlatıp / yeniden takmadan açmadan giriş yaparsam, biri screenyeni diğeri tarafından kullanılan iki "soket" olacaktır . İki "başlangıç" oturumu olmamalı, ancak ikinci bir oturum hala kullanmaya başlamış olabilir reattach -S new; Bu durumda, acente ~/.ssh/agent-screendeğeri ile paylaşılacaktır . Çalışan bir iletme aracısını geri almak için, sonra ayrılacağım ve tekrar giriş yapabileceğimden X${USER} = Xmyusernameemin olun. Kodun sudoaynı sunucuda aranmamasını sağlar.


1

@Pinstein'ın benim .bashrc için kullandığı şeyin bir varyasyonunu kullanıyorum .

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

Bu benim ekran oturumunda çalışan tüm uygulamalar için çalışıyor. Bu, ekran oturumunuzdaki tüm yeni mermiler için işe yarar. Mevcut kabuklar için çalışabilmesi export SSH_AUTH_SOCK=~/.ssh/ssh_auth_sockiçin ana bilgisayar kabuğu üzerinde çalıştırmanız gerekir .

PS Bunu bağımsız bir cevap olarak eklediğim için üzgünüm, oysa @ apinstein'ın cevabına dayandı. Stackoverflow'taki yorumlar kod bloklarını desteklemediğinden bunu yapmak zorunda kaldım.


Neden her zaman sembolik bağlantı ve her zaman ihracat yapmıyorsunuz?
Collin Anderson

@CollinAnderson İki farklı davranış. bir ekran kabuğu içinde bir tane ve normal giriş kabuğu içinde bir tane. oturum açma kabuğundaki ortam değişkeni ssh ve dolayısıyla oradaki sembolik bağlantı tarafından ayarlanır. Bunu bir ekran oturumu içinde yaparsak, bir sembolik bağ döngüsüne neden oluruz.
Sandip Bhattacharya

Ahh, doğru. Yalnızca $ SSH_AUTH_SOCK zaten bir bağlantı değilse, bağlantı kurmanız gerekir. Yazılarıma
Collin Anderson

0

Ekrandan ve ssh-agent arkadaşlarından yapalım'da önerildiği gibi bu basit astarı denedim ve bu benim için işe yarıyor.

Target.Ne'ye ilk kez giriş yapın.

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

Ekranı İlk kez başlatın. Sadece bir kez yapılması gerekenler.

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

Çıkarılmış veya bağlantısı kesilmişse, çıkış ekranına bağlanmak için daha sonra giriş yapmak için bu komutu kullanın.

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

0

Bunların hepsi gerçekten iyi cevaplar, biraz farklı yapıyorum. Yeni bir ssh oturumu başlatıp yeniden ekrana getirdikten SSH_AUTH_SOCKsonra, kök değişken ortamının içeriğine göre ortam değişkenini sıfırlarım . Sadece svn kullandığımda zaman zaman ssh-agent erişimi SSH_AUTH_SOCKgerekiyor, bu yüzden bu mermilerde gerekli olanı sıfırlıyorum.

Bu, proc dosya sistemini kullanır ve linux'a özgüdür. Bunu yalnızca benim tarafımdan erişilen başsız bir linux kutusunda test ettim, diğer ortamlarda çalışmasını sağlamak için biraz ince ayar yapmanız gerekebilir.

SSH_AUTH_SOCK öğesini sıfırlamak için (bu bir takma ad olabilir).

$ . ~/bin/screen_auth.sh

screen_auth.sh buna benziyor

# 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

Yukarıdaki tüm çözümler yarış koşullarından muzdariptir (çoklu EKRAN seanslarında veya çoklu SSH bağlantılarında). Aklıma gelen tek evrensel çözüm, önce SSH_AUTH_SOCK'u SCREEN sunucu işlemine itmek screen -rve sonra her etkileşimli yerleşik olmayan komuttan önce BASH oturumu içine çekmek. Ne yazık ki SCREEN ve BASH, bu tür problemlerin farkında olmadan tasarlanmıştı, bu yüzden düzgün şekilde uygulanması oldukça zor (her iki projeye de özellik isteği göndermek için asla geç değildir). Burada bulunabilecek BASH oturumları için bu sorunun üstesinden gelme girişimim:

Yüklemek:

  1. her iki komut dosyasını da yerleştirin $HOME/bin, yürütülebilir bit ekleyin;
  2. Bunun $HOME/binPATH'de daha önce olduğundan emin olun /usr/bin:

    PATH $ HOME / bin =: $ PATH

  3. Bunu da ekle .bashrc:

    kaynak $ HOME / bin / ekran yardımcı ayarları

Şimdi SSH oturumu içinde EKRAN oturumu oluşturmayı deneyebilir, ayırıp, bağlantısını kesebilir, bağlayabilir ve yeniden bağlayabilirsiniz ve umarım ssh-add -lanahtarlarınızı doğru göstermelisiniz.


Kalıcı ssh-agentarka plan programı (burada belirtildiği gibi superuser.com/a/412052/376867 ) yarış koşullarından muzdarip değil, eski anahtarlıktan muzdariptir. Daha da önemlisi, tüm anahtarlarınızı uzak ana bilgisayarda ekran oturumuyla birlikte (ya da söz konusu posta durumunda yeniden başlatılana kadar daha uzun süre) bırakmak çok güvenli değildir.
midenok

0

Diğer cevapları inceledim ve benimkini bulamadım. İşte kullandığım şey. ~/.screenrc-wrapperAşağıdaki içeriğe sahip bir dosya oluşturun :

escape ^xx
bindkey ^Ad detach

Ve bunu da ekleyin ~/.bashrc(veya ~/.zshrckullanıyorsanız):

  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

Bu şekilde iki ekran oturumu kullanırsınız - biri "sarmalayıcı" dır, bir tanesi içtir. Bu, oturumu kapattığınızda bile ikincisini canlı tutacak ve ssh-agent'ı açık tutacaktır. Bir başka güzel özellik, pencere kurulumunuzu hatırlayacağıdır - bölünmüş pencereler kullanıyorsanız, çok kullanışlı olabilir.

Sen benim içinde bağlamında bu özelliği bulabilirsiniz dotfiles .

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.