Girişte ssh-agent'ı başlat


262

Bir SSH takma adı kullanarak Bitbucket.com'dan çekerek uzak Git repo olarak bir sitem var. Sunucumda ssh-agent'ı manuel olarak başlatabilirim, ancak SSH üzerinden her giriş yaptığımda bunu yapmak zorundayım.

El ile ssh-ajan başlatmak:

eval ssh-agent $SHELL

Sonra ajan ekleyin:

ssh-add ~/.ssh/bitbucket_id

Sonra yaptığım zaman ortaya çıkıyor:

ssh-add -l

Ve ben gidiyorum. Bu işlemi otomatikleştirmenin herhangi bir yolu var, bu yüzden her giriş yaptığımda bunu yapmak zorunda değilim? Sunucu RedHat 6.2 (Santiago) çalıştırıyor.


2
Her giriş yaptığınızda yapmak istediğiniz her şey .profile (terminal girişleri) veya .xinitrc (GUI girişleri için) olmalıdır.
Barmar

1
Ah! .Bash_profile kullanıyordum ... .profile ve .bash_profile arasındaki fark nedir?
Pathsofdesign

1
Komutu neden bu şekilde çalıştırdığınızdan emin değilsiniz. bir alt işlem olarak ssh-agent <command>çalışır , bu nedenle yeni bir kabuk başlatıyorsunuz. Bence istiyorsun . <command>ssh-agenteval ssh-agent
Barmar

9
.bash_profilebash'a özgüdür, .profiletüm POSIX kabukları için geneldir. bashönce arar .bash_profile, sonra varsayılan .profile.
Barmar

5
ssh-agent"Standart" (POSIX uyumlu) bir kabuk için ortaya çıkmanın doğru yolu eval $(ssh-agent -s). Oturumu zaman koymak için de tavsiye edilir böylece Emin düzgün ajan kurtulmak yapmak zorunda da unutmayın trap 'kill $SSH_AGENT_PID' EXITGözlerinde farklı .profileajan başlar satırdan sonra.
kostix

Yanıtlar:


368

Lütfen bu makaleyi okuyun. Bunu çok faydalı bulabilirsiniz:

http://mah.everybody.org/docs/ssh

Yukarıdaki bağlantının bir gün kaybolması durumunda, aşağıdaki çözümün ana parçasını yakalıyorum:

Daniel Starin aracılığıyla Joseph M. Reagle'ın bu çözümü:

Bunu aşağıdakileri ekleyin: .bash_profile

SSH_ENV="$HOME/.ssh/agent-environment"

function start_agent {
    echo "Initialising new SSH agent..."
    /usr/bin/ssh-agent | sed 's/^echo/#echo/' > "${SSH_ENV}"
    echo succeeded
    chmod 600 "${SSH_ENV}"
    . "${SSH_ENV}" > /dev/null
    /usr/bin/ssh-add;
}

# Source SSH settings, if applicable

if [ -f "${SSH_ENV}" ]; then
    . "${SSH_ENV}" > /dev/null
    #ps ${SSH_AGENT_PID} doesn't work under cywgin
    ps -ef | grep ${SSH_AGENT_PID} | grep ssh-agent$ > /dev/null || {
        start_agent;
    }
else
    start_agent;
fi

Bu sürüm özellikle güzeldir, çünkü zaten ssh-agent'ı başlatıp açmadığınızı görecek ve bulamazsa, başlatacak ve ayarları kaydedecek, böylece bir sonraki başlatışınızda kullanılabilir olacaklar kabuk.


8
Makinenin yeniden başlatılması gerekli değildir. Geçerli kabuk oturumunuzda .bash_profilekullanarak yeniden yükleyebilirsiniz source ~/.bash_profile. Yine de yeni yapılandırma yükleneceğinden, makinenin yeniden başlatılması da çalışır.
Litmus

11
Kullanım SSH_ENV="$HOME/.ssh/env"(yani / çevre değil) Neden? sshd ~ / .ssh / ortam kullanır (bkz. sayfa: PermitUserEnvironment). Github bunu çözümlerinde de tavsiye ediyor - help.github.com/articles/…
Andrew Murphy

7
Bu komut dosyası ~ / .bashrc dosyama koyduğumda çalıştı (~ / .profile veya ~ / .bash_profile değil). Yerel bir konsolu ilk kez açtığımda parola ister, her şey daha fazla sormadan o noktadan itibaren çalışır. Şerefe.
andrew pate

3
ssh-agent.Bashrc dosyasına start komutunun eklenmesi scpkomutun çalışmamasına neden olur.
Dzanvu

5
Hala sinir bozucu ... ssh kullanmasanız bile, her giriş yaptığınızda bunu yapmak zorundasınız. Ssh her çağrıldığında bu yangını söndürmeniz gerekir ... ve ideal olarak, hangi ana makinelerin hangi anahtarların yüklenmesine neden olacağını yapılandırabilmeniz gerekir.
Erik Aronesty

99

Arch Linux'ta, aşağıdakiler gerçekten harika çalışır (tüm systemd tabanlı dağıtımlarda çalışmalıdır):

Aşağıdakileri yaparak bir sistem kullanıcısı hizmeti oluşturun ~/.config/systemd/user/ssh-agent.service:

[Unit]
Description=SSH key agent

[Service]
Type=simple
Environment=SSH_AUTH_SOCK=%t/ssh-agent.socket
ExecStart=/usr/bin/ssh-agent -D -a $SSH_AUTH_SOCK

[Install]
WantedBy=default.target

Kabuk, socket ( .bash_profile, .zshrc, ...) için bir ortam değişkenine sahip olacak şekilde ayarlayın :

export SSH_AUTH_SOCK="$XDG_RUNTIME_DIR/ssh-agent.socket"

Hizmeti etkinleştirin, böylece oturum açıldığında otomatik olarak başlatılır ve başlatılır:

systemctl --user enable ssh-agent
systemctl --user start ssh-agent

Yerel ssh yapılandırma dosyanıza aşağıdaki yapılandırma ayarını ekleyin ~/.ssh/config(SSH 7.2'den beri çalışır):

AddKeysToAgent  yes

Bu, ssh istemcisine anahtarı çalışan bir aracıya her zaman eklemesini söyleyecektir, bu nedenle önceden ssh eklemenize gerek yoktur.


3
Bu yorumu Ubuntu'da yapmaya çalışırken buldum. En azından sistemin nasıl çalışması gerektiğine dair bilgim göz önüne alındığında, yerleşik sistemlerle başlangıç ​​komut dosyalarına bir şey hack etmekten çok daha güzel oynuyor gibi görünüyor.
xiterion

Bunu Ubuntu 16.04 LTS'de denedim. Ne yazık ki, her kabuk süreci kendi bireysel ssh-agentsürecini istiyor . Belki de dokümanlarý okuduktan sonra bile bilgim yok.
Daisuke Aramaki

Ayrıca Type = simple komutunu da kullanabilirsiniz . wiki.archlinux.org/index.php/…
Hans-J. Schmid

2
yani bu çözüm temel olarak bir systemd hizmetini kurmak / yapılandırmak mı (sadece kullanıcı için)?
Trevor Boyd Smith

Bu, SSH_AGENT_PIDortam değişkenini ayarlamaz , ancak :(
MrMeszaros

73

Eski bir soru, ama benzer bir durumla karşılaştım. Yukarıdaki cevabın tam olarak neye ihtiyaç duyduğunu düşünmeyin. Eksik parça keychain; henüz yüklenmediyse kurun.

sudo apt-get install keychain

Ardından, aşağıdaki satırı ~/.bashrc

eval $(keychain --eval id_rsa)

Bu, ssh-agentçalışmıyorsa başlatılır, bağlıysa, ssh-agentortam değişkenlerini kabuğunuza yükler ve ssh anahtarınızı yükler.

Yüklemek istediğiniz id_rsaözel anahtarla değiştirin ~/.ssh.

Referans

/unix/90853/how-can-i-run-ssh-add-automatically-without-password-prompt


Anahtarlık verilen talimatlara göre benim için çalışmıyor. .Bash_profile dosyasına ekledim ve ssh her seferinde şifre istiyor. aynı kabuk içinde birden çok kez denedim. nafile. temel ssh-ajan yaklaşımına geri dönüyor
javadba

keychain --eval id_[yourid file]
Eval

4
StackOverflow yorum biçimlendirme nedeniyle bir çözüm araştırma 20 dakika geçirdim. Yukarıdaki xelber en Başına yorum, doğru çözümdür eval `keychain --eval id_[yourid file]`için .bashrc. Çalışan ssh aracısına erişim için geçerli kabuğa ortam değişkenlerini değerlendirmek için backticks gerekir.
James

2
Bu doğru ve basit bir çözümdür. Anahtarlık komutu yürütüldüğünde günlüğü görmek istemiyorsanız, -qsessiz mod için seçenek ekleyebilirsiniz . Keychain: funtoo.org/Keychain
Diki Ananta

4
Teşekkürler, bu en zarif çözüm.
greenspand

37

Kabul edilen çözümün aşağıdaki sakıncaları vardır:

  • sürdürmek karmaşıktır;
  • hatalara veya güvenlik ihlaline yol açabilecek depolama dosyasını değerlendirir;
  • aracıyı başlatır, ancak anahtarı kontakta bırakmaya yakın bir değerde durdurmaz.

Anahtarlarınız parola yazmayı gerektirmiyorsa, aşağıdaki çözümü öneririm. Aşağıdakileri .bash_profile sonuna ekleyin (anahtar listesini ihtiyaçlarınıza göre düzenleyin):

exec ssh-agent $BASH -s 10<&0 << EOF
    ssh-add ~/.ssh/your_key1.rsa \
            ~/.ssh/your_key2.rsa &> /dev/null
    exec $BASH <&10-
EOF

Aşağıdaki avantajlara sahiptir:

  • çok daha basit bir çözüm;
  • ajan oturumu bash oturumu sona erdiğinde biter.

Olası dezavantajları vardır:

  • etkileşimli ssh-addkomut sadece bir oturumu etkileyecektir, bu aslında çok alışılmadık durumlarda bir sorundur;
  • şifre girilmesi gerekiyorsa kullanılamaz;
  • başlatılan kabuk giriş yapmaz hale gelir (AFAIK hiçbir şeyi etkilemez).

Birkaç ssh-agentişlemin dezavantaj olmadığını unutmayın , çünkü daha fazla bellek veya CPU zamanı gerektirmezler.


Git Bash kullanarak Windows 10'da $ HOME dışındaki bir dizinde SSH anahtarları var. RSA'nın yolunu değiştirmek, bu işi yapmak için tek yapmam gereken şeydi. TYVM!
kayleeFrye_onDeck

7
"Anahtarlarınız parola yazmayı gerektirmiyorsa" anahtarı kontakta bırakmaya yakın bir şey olduğunu iddia ediyorum .
Bruno Bronosky

En azından ağ üzerinde bir yerde değil, kendi sunucunuzda.
midenok

1
"Ben senin anahtarları şifre yazmak gerektirmez" anahtar ateşleme bırakmak yakın eşdeğer olduğunu iddia ediyorum. "<- Nasıl olduğunu açıklayın ?? Anahtarlar parolalardan çok daha esnek olduğundan, iptal edilmesi çok daha kolaydır (ne? Yalnızca tam erişime sahip sudo kullanıcıları için anahtar mı kullanıyorsunuz? Tsk tsk). Birden çok kullanıcı profili için birden fazla anahtar kümesi. Herhangi bir şeyi otomatikleştirmek istiyorsanız (dağıtım veya uçtan uca kontroller gibi), o zaman iyi şanslar "düzenleme" sırasında sürekli olarak şifreleri yazarak.
Scott Prive

2
Bunu yapma. Şifresiz anahtarlar kötü bir uygulamadır.
user48678 28:17

26

Bunu kendinize ekleyin ~/.bashrc, ardından oturumu kapatmak için tekrar oturum açın.

if [ ! -S ~/.ssh/ssh_auth_sock ]; then
  eval `ssh-agent`
  ln -sf "$SSH_AUTH_SOCK" ~/.ssh/ssh_auth_sock
fi
export SSH_AUTH_SOCK=~/.ssh/ssh_auth_sock
ssh-add -l > /dev/null || ssh-add

Bu, yalnızca her yeniden başlatma işleminden sonra ilk kez giriş yaptığınızda bir parola girmelidir. Çalışmaya devam ssh-agentettiği sürece tekrar kullanmaya devam edecektir .


Birden fazla anahtarımız olsaydı ve onlar adlandırılmasaydı ne kullanırdık ~/.ssh/id_rsa? ssh-addYanıtınızın bir kısmı anahtarlar için varsayılan dosya adlarını bekliyor gibi görünüyor .
Gabriel Staples

Evet. Gerekirse dosya adlarını son satırın sonuna ekleyebileceğinizi düşünüyorum
Collin Anderson

Ama yine de bir komut dosyası otomatikleştirmek için şifre manuel olarak girmeden git şeyler çekemezsiniz? Bundan nasıl kaçınılır?
trainoasis

7

Bu yüzden yukarıda açıklanan yaklaşımları kullanırdım, ama son bash oturumum bittiğinde ajanın ölmesini tercih ederim. Bu diğer çözümlerden biraz daha uzun, ama benim tercih ettiğim yaklaşım. Temel fikir, ilk bash oturumunun ssh-agent'ı başlatmasıdır. Daha sonra her ek bash oturumu config dosyasını ( ~/.ssh/.agent_env) kontrol eder . Bu durumda ve çalışan bir oturum varsa, ortamı kaynaklayın ve soket dosyasına bir bağlantı oluşturun /tmp(orijinal soket dosyasıyla aynı dosya sisteminde olması gerekir). Bash oturumları kapandıkça, her biri kendi sabit bağlantısını siler. Kapatılacak son oturum, hardlinklerin 2 bağlantıya (hardlink ve orijinal) sahip olduğunu, işlemlerin kendi soketinin çıkarılması ve sürecin öldürülmesinin 0 ile sonuçlanacağını ve son bash oturumu kapandıktan sonra temiz bir ortam bırakacağını görecektir.

# Start ssh-agent to keep you logged in with keys, use `ssh-add` to log in
agent=`pgrep ssh-agent -u $USER` # get only your agents           
if [[ "$agent" == "" || ! -e ~/.ssh/.agent_env ]]; then
    # if no agents or environment file is missing create a new one
    # remove old agents / environment variable files
    kill $agent running
    rm ~/.ssh/.agent_env 

    # restart
    eval `ssh-agent` 
    echo 'export SSH_AUTH_SOCK'=$SSH_AUTH_SOCK >> ~/.ssh/.agent_env             
    echo 'export SSH_AGENT_PID'=$SSH_AGENT_PID >> ~/.ssh/.agent_env             
fi

# create our own hardlink to the socket (with random name)           
source ~/.ssh/.agent_env                                                    
MYSOCK=/tmp/ssh_agent.${RANDOM}.sock                                        
ln -T $SSH_AUTH_SOCK $MYSOCK                                                
export SSH_AUTH_SOCK=$MYSOCK                                                

end_agent()                                                                     
{
    # if we are the last holder of a hardlink, then kill the agent
    nhard=`ls -l $SSH_AUTH_SOCK | awk '{print $2}'`                             
    if [[ "$nhard" -eq 2 ]]; then                                               
        rm ~/.ssh/.agent_env                                                    
        ssh-agent -k                                                            
    fi                                                                          
    rm $SSH_AUTH_SOCK                                                           
}                                                                               
trap end_agent EXIT                                                             
set +x              

eğer bunu başka bir kabuğun (BASH'den sonra) girişinde BASH betiği olarak çalıştırırsak, o da çalışmalıdır, değil mi?
hoijui

7

Başka bir çözüm daha eklemek için: P, @spheenik ve @ collin-anderson çözümlerinin bir kombinasyonuyla gittim.

 # Ensure that we have an ssh config with AddKeysToAgent set to true
 if [ ! -f ~/.ssh/config ] || ! cat ~/.ssh/config | grep AddKeysToAgent | grep yes > /dev/null; then
     echo "AddKeysToAgent  yes" >> ~/.ssh/config
 fi
 # Ensure a ssh-agent is running so you only have to enter keys once
 if [ ! -S ~/.ssh/ssh_auth_sock ]; then
   eval `ssh-agent`
   ln -sf "$SSH_AUTH_SOCK" ~/.ssh/ssh_auth_sock
 fi
 export SSH_AUTH_SOCK=~/.ssh/ssh_auth_sock

Biraz daha zarif olabilir ama basit ve okunabilir. Bu çözüm:

  • olmasını sağlar AddKeysToAgent yestuşları kullanım otomatik eklenecektir böylece SSH config olduğunu
  • oturum açma sırasında herhangi bir parola girmenizi istemez (yine, ilk kullanımda bir kerelik parola girişi gerçekleşir)
  • henüz başlamadıysa ssh aracısını sessizce başlatır

Yorumlarınızı bekliyoruz :)


1
Bu benim için mükemmel çalıştı. Kubuntu'da .profile'a koydum.
Shai

1
AddKeysToAgent yesAyarı bilmek güzel . Teşekkürler.
Collin Anderson

3

Bunu sistem genişliğinde / etc / profile - veya kullanıcının yerel .profile veya _.bash_profile_) ekleyerek çözdüm:

# SSH-AGENT 
#!/usr/bin/env bash
SERVICE='ssh-agent'
WHOAMI=`who am i |awk '{print $1}'`

if pgrep -u $WHOAMI $SERVICE >/dev/null
then
    echo $SERVICE running.
else
    echo $SERVICE not running.
    echo starting
    ssh-agent > ~/.ssh/agent_env
fi
. ~/.ssh/agent_env

Bu, geçerli kullanıcı için çalışmıyorsa yeni bir ssh-agent başlatır veya çalışıyorsa ssh-agent env parametresini yeniden ayarlar.


Temsilcinin zaten çalışıp çalışmadığını nasıl anlatacağınızı söylediğiniz için teşekkür ederiz!
Mike Maxwell

Nasıl if pgrep -u $WHOAMI $SERVICE >/dev/nullçalışır?
Josh Desmond

3

Balık kabuğunun kullanıcıları aynı şeyi yapmak için bu komut dosyasını kullanabilir .

# content has to be in .config/fish/config.fish
# if it does not exist, create the file
setenv SSH_ENV $HOME/.ssh/environment

function start_agent                                                                                                                                                                    
    echo "Initializing new SSH agent ..."
    ssh-agent -c | sed 's/^echo/#echo/' > $SSH_ENV
    echo "succeeded"
    chmod 600 $SSH_ENV 
    . $SSH_ENV > /dev/null
    ssh-add
end

function test_identities                                                                                                                                                                
    ssh-add -l | grep "The agent has no identities" > /dev/null
    if [ $status -eq 0 ]
        ssh-add
        if [ $status -eq 2 ]
            start_agent
        end
    end
end

if [ -n "$SSH_AGENT_PID" ] 
    ps -ef | grep $SSH_AGENT_PID | grep ssh-agent > /dev/null
    if [ $status -eq 0 ]
        test_identities
    end  
else
    if [ -f $SSH_ENV ]
        . $SSH_ENV > /dev/null
    end  
    ps -ef | grep $SSH_AGENT_PID | grep -v grep | grep ssh-agent > /dev/null
    if [ $status -eq 0 ]
        test_identities
    else 
        start_agent
    end  
end

2

Bunun için ssh-ident aracını kullanıyorum.

Onun Gönderen adam sayfalık:

ssh-ident - ssh-agent'ı başlatın ve kullanın ve kimlikleri gerektiği gibi yükleyin.


1

Birçok kaynaktan denenmiş birkaç çözüm, ancak hepsi çok fazla sorun gibi görünüyordu. Sonunda en kolayını buldum :)

Henüz zsh ve oh-my-zsh hakkında bilginiz yoksa kurun. Bunu seveceksiniz :)

Sonra düzenle .zshrc

vim ~/.zshrc

pluginsbölümü bulun ve aşağıdaki ssh-agentgibi kullanmak üzere güncelleyin :

plugins=(ssh-agent git)

Ve hepsi bu! Sen gerekecek ssh-agentsize kabuk başlatmak ve çalışır her zaman


1

Cevaplarını çok beğendim. cygwin / linuxAna bilgisayarlardan çalışmayı çok daha kolay hale getirdi . Güvenli hale getirmek için başlangıç ​​ve bitiş işlevlerini birleştirdim.

SSH_ENV="$HOME/.ssh/.agent_env"

function start_agent {
    echo "Initialising new SSH agent..."

    eval `/usr/bin/ssh-agent`
    echo 'export SSH_AUTH_SOCK'=$SSH_AUTH_SOCK >> ${SSH_ENV}
    echo 'export SSH_AGENT_PID'=$SSH_AGENT_PID >> ${SSH_ENV}

    echo succeeded
    chmod 600 "${SSH_ENV}"
    . "${SSH_ENV}" > /dev/null
    /usr/bin/ssh-add;
}

# Source SSH settings, if applicable
if [ -f "${SSH_ENV}" ]; then
    . "${SSH_ENV}" > /dev/null
    #ps ${SSH_AGENT_PID} doesn't work under cywgin
    ps -ef | grep ${SSH_AGENT_PID} | grep ssh-agent$ > /dev/null || {
        start_agent;
    }
else
    start_agent;
fi

# create our own hardlink to the socket (with random name)
MYSOCK=/tmp/ssh_agent.${RANDOM}.sock
ln -T $SSH_AUTH_SOCK $MYSOCK
export SSH_AUTH_SOCK=$MYSOCK

end_agent()
{
    # if we are the last holder of a hardlink, then kill the agent
    nhard=`ls -l $SSH_AUTH_SOCK | awk '{print $2}'`
    if [[ "$nhard" -eq 2 ]]; then
        rm ${SSH_ENV}
        /usr/bin/ssh-agent -k
    fi
    rm $SSH_AUTH_SOCK
}
trap end_agent EXIT
set +x
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.