Como posso executar o ssh-add automaticamente, sem um prompt de senha?

248

Quero me comunicar entre vários computadores na minha rede (Ethernet estática), através do SSH. Para fazer isso, eu preciso executar o ssh-add toda vez que fizer login em uma máquina específica, como posso fazê-lo para que seja configurado uma vez e não solicite a senha sempre que eu fizer login ou reinicializar minha maquina?

Sei que existe uma maneira de adicionar algumas linhas ao bash_profilearquivo, mas ainda preciso digitar a senha toda vez que reinicializo / efetuo login em uma máquina específica.

if [ -z "$SSH_AUTH_SOCK" ] ; then
    eval `ssh-agent -s`
    ssh-add
fi
zdun8
fonte
semelhante a esta pergunta stackoverflow.com/questions/18880024/start-ssh-agent-on-login
steampowered

Respostas:

348

Este é um exemplo típico de uma troca entre segurança e conveniência. Felizmente, existem várias opções. A solução mais apropriada depende do cenário de uso e do nível de segurança desejado.

chave ssh com senha, não ssh-agent

Agora a senha deve ser inserida toda vez que a chave é usada para autenticação. Embora essa seja a melhor opção do ponto de vista de segurança, ela oferece a pior usabilidade. Isso também pode levar à escolha de uma frase secreta fraca para diminuir o fardo de inseri-la repetidamente.

chave ssh com senha, com ssh-agent

Adicionar o seguinte a ~/.bash_profileiniciará automaticamente ssh-agente carregará as teclas ssh no login:

if [ -z "$SSH_AUTH_SOCK" ] ; then
  eval `ssh-agent -s`
  ssh-add
fi

Agora, a senha deve ser inserida em cada login. Embora um pouco melhor do ponto de vista da usabilidade, isso tem a desvantagem que ssh-agentsolicita a senha, independentemente de a chave ser usada ou não durante a sessão de login. Cada novo login também gera uma ssh-agentinstância distinta que permanece sendo executada com as chaves adicionadas na memória, mesmo após o logout, a menos que seja explicitamente eliminado.

Para interromper o ssh_agentlogout, adicione o seguinte a~/.bash_logout

if [ -n "$SSH_AUTH_SOCK" ] ; then
  eval `/usr/bin/ssh-agent -k`
fi

ou o seguinte para ~/.bash_profile

trap 'test -n "$SSH_AUTH_SOCK" && eval `/usr/bin/ssh-agent -k`' 0

É ssh-agentpossível evitar a criação de várias instâncias criando um soquete de comunicação persistente para o agente em um local fixo no sistema de arquivos, como na resposta de Collin Anderson . Essa é uma melhoria em relação à criação de várias instâncias de agentes, no entanto, a menos que a chave descriptografada seja eliminada explicitamente e ainda permaneça na memória após o logout.

Nas áreas de trabalho, os ssh-agents incluídos no ambiente da área de trabalho, como o Agente SSH do Gnome Keyring , podem ser uma abordagem melhor, pois normalmente podem ser feitos para solicitar a senha na primeira vez que a chave ssh é usada durante uma sessão de login e armazene a chave privada descriptografada na memória até o final da sessão.

chave ssh com senha, com ssh-ident

ssh-identé um utilitário que pode gerenciar ssh-agentem seu nome e carregar identidades conforme necessário. Ele adiciona chaves apenas uma vez, conforme necessário, independentemente de quantos terminais, ssh ou sessões de login que requerem acesso a um ssh-agent. Também pode adicionar e usar um agente diferente e um conjunto diferente de chaves, dependendo do host ao qual está conectado ou do diretório em que o ssh é chamado. Isso permite isolar chaves ao usar o encaminhamento de agente com hosts diferentes. Também permite usar várias contas em sites como o GitHub.

Para habilitar ssh-ident, instale-o e adicione o seguinte alias ao seu ~/bash_profile:

alias ssh='/path/to/ssh-ident'

chave ssh com senha, com keychain

keychainé um pequeno utilitário que gerencia ssh-agentem seu nome e permite ssh-agentque permaneça em execução quando a sessão de login terminar. Nos logins subsequentes, keychainserá conectado à ssh-agentinstância existente . Na prática, isso significa que a senha deve ser inserida apenas durante o primeiro login após uma reinicialização. Nos logons subseqüentes, a chave não criptografada da ssh-agentinstância existente é usada. Isso também pode ser útil para permitir a autenticação RSA / DSA cronsem senha em trabalhos sem chaves ssh sem senha.

Para habilitar keychain, instale-o e adicione algo como o seguinte a ~/.bash_profile:

eval `keychain --agents ssh --eval id_rsa`

Do ponto de vista da segurança, ssh-idente keychainsão piores do que ssh-agentcasos limitados ao tempo de vida de uma sessão particular, mas eles oferecem um alto nível de conveniência. Para melhorar a segurança de keychain, algumas pessoas adicionam a --clearopção à sua ~/.bash_profilechamada de chaveiro. Ao fazer isso, as frases de acesso devem ser digitadas novamente no login, conforme descrito acima, mas os crontrabalhos ainda terão acesso às chaves não criptografadas após o logout do usuário. A keychain página wiki tem mais informações e exemplos.

chave ssh sem senha

Do ponto de vista da segurança, essa é a pior opção, pois a chave privada é totalmente desprotegida caso seja exposta. Essa é, no entanto, a única maneira de garantir que a senha não precise ser digitada novamente após uma reinicialização.

ssh-key com senha, com ssh-agent , passando senha para a ssh-add partir do script

Embora possa parecer uma idéia simples passar a senha ssh-addde um script, por exemplo echo "passphrase\n" | ssh-add, isso não é tão direto quanto parece ssh-add não ler a senha stdin, mas é aberto /dev/ttydiretamente para leitura .

Isso pode ser contornado com expectuma ferramenta para automatizar aplicativos interativos. Abaixo está um exemplo de script que adiciona uma chave ssh usando uma frase secreta armazenada no script:

#!/usr/bin/expect -f
spawn ssh-add /home/user/.ssh/id_rsa
expect "Enter passphrase for /home/user/.ssh/id_rsa:"
send "passphrase\n";
expect "Identity added: /home/user/.ssh/id_rsa (/home/user/.ssh/id_rsa)"
interact

Observe que, como a senha é armazenada em texto sem formatação no script, do ponto de vista da segurança, isso não é melhor do que ter uma chave ssh sem senha. Se essa abordagem for usada, é importante garantir que o expectscript que contém a frase secreta tenha permissões adequadas definidas, tornando-a legível, gravável e executável apenas pelo proprietário da chave.

Thomas Nyman
fonte
1
Ok, mas quando coloco seu código em ~ / .bash_profile, tenho que digitar a senha toda vez que faço login, também não quero isso. Não estou preocupado com segurança. eco "passar \ n" | ssh-add não funciona
zdun8
3
@ user1607072 Sim, é assim que o ssh-agentsnippet ~/.bash_profilese comporta, conforme explicado na resposta. Você pode querer olhar para o keychainutilitário. Com keychaina necessidade de digitar a senha no primeiro login após a reinicialização, os logins subseqüentes keychainserão conectados a uma ssh-agentinstância existente com a chave descriptografada na memória. Além disso, há a opção de gerar uma chave ssh sem uma senha, mas isso não é recomendado.
Thomas Nyman
3
@ user1607072 Embora eu sugira fortemente uma das abordagens mais seguras, existe uma maneira de passar a senha para ssh-addum script. O motivo echo "pass\n" | ssh-addnão funciona é que ssh-addnão lê a senha stdin, mas abre /dev/ttydiretamente para leitura. Atualizada a resposta para incluir uma solução alternativa para isso, usando um utilitário chamado expect.
Thomas Nyman
1
@ user1607072 Pode ser um pouco exagerado para o seu caso de uso, mas o Kerberos em combinação com o suporte ssh GSSAPI também pode ser usado para logins ssh sem senha. O método de autenticação correspondente no ssh é chamado gssapi-with-mic. Isso geralmente é usado em redes maiores, mas é claro que se você tiver interesse, vale a pena investigar.
Thomas Nyman
1
@ ErickBrown: Já respondeu aqui . A unidade SSH Agent deve ser parada no logout se o usuário permanecer desabilitado no gerenciador de login do systemd . Se a permanência do usuário estiver ativada, a instância do usuário systemd e a unidade SSH Agent permanecerão em execução, mesmo após o fechamento da última sessão de login.
Thomas Nyman
93

Adicione isso ao seu e ~/.bashrc, em seguida, efetue logout e entre novamente para entrar em vigor.

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

Isso deve solicitar apenas uma senha na primeira vez que você fizer login após cada reinicialização. Ele continuará reutilizando o mesmo ssh-agentenquanto permanecer em execução.

Collin Anderson
fonte
1
muito puro, desta forma você só tem um ssh-agente de execução (: Vários agentes como na segunda solução de @ thomasNyman parece um risco de segurança para mim ...
drevicko
1
Depois de pesquisar em vários sites e ler várias soluções, este aqui parece ser o mais claro, direto ao ponto. Muito agradável. +1
Dr. Beco
1
é melhor fazer isso: `alias ssh = ssh-check-agent" e fazer com que a versão do agente de verificação faça o acima. Dessa forma: a) você só recebe um agente eb) você só recebe o agente se precisar
Erik Aronesty
2
Eu acho que -s é o padrão, então já estamos fazendo isso.
Collin Anderson
1
ssh-add -lretorna um código de saída de 0 quando o agente tem identidades e 1 quando ele não para que você pode cortar grep para fora do último comando e usossh-add -l > '/dev/null' || ssh-add
Grant Humphries
16

Não está intimamente relacionado à pergunta do OP, mas pode ser útil para outros: já que 7.2.0 ssh (1) tem uma opção que permite adicionar uma chave ao ssh-agent na primeira autenticação; a opção é AddKeysToAgente pode ser definida como yes, no, ask, ou confirm, em todo o sistema ou em seu pessoal .ssh/configde arquivo.

Referência: https://www.openssh.com/txt/release-7.2

Guilherme Salazar
fonte
2
Aplicável àqueles que são novos no .ssh/configarquivo: isso se aplica a sshqualquer coisa que use sshpor trás dele, por exemplo scp, e pode ser feito por host.
Seof
Ele ainda me pede senha sempre que eu faço login e tento git pull, por exemplo.
trainoasis
@ trainosis O problema é que você provavelmente não possui uma instância do ssh-agent em execução para manter as chaves descriptografadas na memória para uso futuro. Você só precisa digitar a senha de uma determinada chave uma vez por sessão de login ao usar o ssh-agent.
eestrada 13/08
7

ssh-agent armazena em cache várias chaves ssh desbloqueadas, para que você possa protegê-las com senhas, mas sem precisar digitá-las todas as vezes.

Para armazenar em cache as chaves desbloqueadas, obviamente é necessário desbloqueá-las. Para desbloquear chaves bloqueadas com uma senha, obviamente é necessário conhecê-las.

Qualquer método que não exija autorização de um ser humano (por exemplo, "digitando uma senha") não apenas tornará seu sistema inseguro; também tornará sem sentido todo o propósito do agente ssh.

Dito tudo isso, você pode simplesmente usar chaves ssh que não são protegidas por senha (pressione Enterquando solicitado por uma senha durante a geração de chaves). Como não há senha, ssh-agentnão é necessário solicitar uma para (não) armazená-la em cache.

umläute
fonte
Concordo que, desde que suas chaves tenham permissão apenas de usuário, há pouca vantagem do ssh-agent sobre chaves sem permissão. Eu gosto de ssh em um servidor de login e, em seguida, esse servidor tem um monte de chaves sem permissão, cada uma das quais só pode ser usada para desbloquear um outro servidor. o servidor de login não faz mais nada, por isso é muito mais difícil hackear / falsificar, etc ... os outros servidores não têm acesso por senha, são apenas chave.
Erik Aronesty
5

Aqui está uma solução alternativa para automatizar sua senha SSH.

  1. Crie um script de uma linha que imprima sua senha na saída padrão, por exemplo:

     echo 'echo MY_SSH_PASSWORD' > ~/.print_ssh_password && chmod 700 ~/.print_ssh_password
    

    Importante: Certifique-se de copiar o espaço inicial para impedir o armazenamento de sua senha no seu histórico .

E use um dos métodos abaixo.

  • usando uma abordagem de entrada padrão:

    cat ~/.ssh/id_rsa | SSH_ASKPASS=~/.print_ssh_password ssh-add -
    
  • ou abordagem de pipe nomeado :

    1. Crie um canal nomeado (você também pode tentar uma substituição de processo ):

      mkfifo --mode 0600 ~/.ssh_fifo
      
    2. Execute ssh-addespecificando o programa usado para a autenticação:

      cat ~/.ssh/id_rsa >~/.ssh_fifo | SSH_ASKPASS=~/.print_ssh_password ssh-add ~/.ssh_fifo
      

    Veja: man ssh-addpara ler mais sobre SSH_ASKPASS.

kenorb
fonte
2
O echo my_passphraseé um grande buraco de segurança. Primeiro, depois de digitar, a senha está em texto não criptografado no arquivo de histórico de qualquer shell que você usar. E os argumentos da segunda linha de comando são legíveis mundialmente no Unix ( ps -ef). Nunca coloque senhas nos argumentos da linha de comando!
ceving 24/08/16
1
A adição de espaço extra à frente resolve o problema com o arquivo de histórico. Adicionado informação extra.
kenorb
@kenorb: Isso não resolve o maior problema da senha visível na pssaída. De qualquer forma, o arquivo de histórico geralmente é legível apenas pelo usuário proprietário, mas as linhas de comando são legíveis por todos os usuários em um sistema.
Thomas Nyman
4

Não vou recomendar o ssh-add (que precisa abrir um ssh-agent) no login. Isso ocorre porque você não pode controlar quando a seção ssh-agent termina e pode criar risco de segurança quando não precisar usar os arquivos de chave em uma seção de login.

Em vez disso, recomendo escrever um script que abra o sub-shell da seção do ssh-agent, com todos os arquivos-chave adicionados automaticamente e seja chamado quando necessário para usar o ssh. Se você pode adotar isso, continue a ler.

Você teria duas opções:

  1. Remova todas as frases secretas de suas chaves, que possuem segurança fraca se seus arquivos de chave forem roubados. (portanto, não recomendado )

  2. Use a mesma senha para suas chaves. Quando você ssh-add keyfile1 keyfile2 ...precisar digitar a senha apenas uma vez, por seção.

Nos dois casos, você pode escrever o arquivo de script "ssh_keys_section.sh" como abaixo:

#!/bin/bash
# This script run a ssh-agent on a sub-shell and automatically ssh-add all keyfiles at once.
# This agent ends when you type `exit` to close the sub-shell.
exec ssh-agent bash -c "ssh-add /path/to/keyfile1 /path/to/keyfile2 ...; exec bash"

Observações:

  • Comando para alterar ou excluir a senha: ssh-keygen -p -f keyfile
  • Dentro do sub-shell, você pode até dividir mais terminais que compartilham as mesmas chaves desbloqueadas, usando talvez um comando como /path/to/yourterminal &(depende do SO)
Johnny Wong
fonte
Por exemplo, no Windows no Cygwin, /path/to/yourterminal &==>mintty &
Johnny Wong
2
if [ ! -S ${HOME}/.ssh/ssh_auth_sock ]; then
  eval $(ssh-agent)
  ln -sf "${SSH_AUTH_SOCK}" ${HOME}/.ssh/ssh_auth_sock
fi
export SSH_AUTH_SOCK=${HOME}/.ssh/ssh_auth_sock

ssh_keys=$(find -E ~/.ssh -type f -regex '.*(rsa$|pem)')
ssh_agent_keys=$(ssh-add -l | awk '{key=NF-1; print $key}')

for k in "${ssh_keys}"; do
    for l in "${ssh_agent_keys}"; do
        if [[ ! "${k}" = "${l}" ]]; then
            ssh-add "${k}" > /dev/null 2>&1
        fi
    done
done
Diego Roberto Dos Santos
fonte
2

Eu costumava usar o script mencionado por steampowered, fiz o abaixo agora, porque ele não deixa os arquivos por aí.

Trabalhando zshapenas no shell.

#!/bin/sh

AGENT_BIN=`which ssh-agent`
AGENT_ADD_BIN=`which ssh-add`
AGENT_PID=`ps -fe | grep ${AGENT_BIN} | awk -vuser=$USER -vcmd="$AGENT_BIN" '$1==user && $8==cmd{print $2;exit;}'`
if [ -z "$AGENT_BIN" ]; then
    echo "no ssh agent found!";
    return
fi
if [ "" -eq "$AGENT_PID" ]; then
    if read -sq "YN?Do you want to unlock your ssh keys?"; then
        echo ""
        output=`$AGENT_BIN | sed 's/echo/#echo/g'`
        eval $output
        $AGENT_ADD_BIN
    fi
else
    for f in "/proc/"*
    do
        cmdline=`cat "$f/cmdline"`
        if [ "${AGENT_BIN}" -ef "${cmdline}" ]; then
            export SSH_AUTH_SOCK=`cat $f/net/unix | grep --binary-file=text -oP '((/[^/]*?)+/ssh-[^/]+/agent\.\d+$)'`
            export SSH_AGENT_PID=${f##*/}
            break;
        fi
    done
fi
rmc
fonte
1
SSH_ENV="$HOME/.ssh/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

Dando crédito aqui: https://www.cygwin.com/ml/cygwin/2001-06/msg00537.html

Esta solução também é recomendada aqui: http://mah.everybody.org/docs/ssh

a vapor
fonte
1

A solução de logon único para SSH poderia me levar a pam_ssh.

De acordo com este artigo , o conceito é:

Se você trabalha com várias máquinas baseadas em * nix via ssh, provavelmente está cansado de constantemente digitar sua senha toda vez que quiser acessar outra caixa. Existe uma maneira segura de permitir que você acesse todas as máquinas às quais você tem acesso ssh, sem precisar digitar outra senha (diferente daquela com a qual você se conectou originalmente).


Na verdade, é bastante simples de fazer, você basicamente cria um par de chaves pública / privada para se autenticar em outras máquinas e, em seguida, solicita ao PAM um agente para carregar suas chaves após o logon, fornecendo uma solução de conexão única para acessar todo o seu controle remoto máquinas Este guia orientará você na configuração.

Não verifiquei se isso realmente funcionaria.

Michael
fonte
0

Adicione isso ao seu ~/.bashrcarquivo:

ssh-add -L|grep identities > /dev/null && ssh-add /path/to/ssh/private/key
Abukamel
fonte
Não vejo como isso se relaciona com a pergunta, que é sobre não ser solicitada a senha nos logins subseqüentes.
Chris Baixo
0

Para adicionar uma chave (possivelmente sem senha) e garantir que ssh-addela não solicite uma senha, independentemente do que seja, mesmo quando executada no X :

DISPLAY= ssh-add -k /path/to/key </dev/null &>/dev/null

O status de saída indica sucesso ou falha.

Keith Cascio
fonte
0

Se você estiver executando o cavalo-marinho como seu gerenciador de senhas ... Qual você provavelmente é; D

Outra solução que atinge o objetivo que você está procurando é simplesmente adicionar as chaves ssh ao cavalo-marinho para desbloqueio automático no login. O principal benefício disso é que você nunca precisará digitar uma senha para as chaves depois de fazer login no gdm, ou qualquer que seja o seu login, mesmo que as chaves tenham uma senha. Isso requer a chave privada e a chave pública. Eles também DEVEM seguir uma convenção de nomenclatura para cavalos-marinhos. O padrão é aceitável (id_rsa para chave privada e id_rsa.pub para chave pública ... Realmente qualquer coisa que seja privatekeyname e privatekeyname.pub )

Para adicionar sua chave ssh ao cavalo-marinho para desbloqueio automático no login; (no fedora25, não tenho certeza de onde o caminho está em outras distros, embora seja provavelmente muito parecido)

/lib64/seahorse/seahorse-ssh-askpass /path/to/keys/here

Pra mim foi

/lib64/seahorse/seahorse-ssh-askpass ~/.ssh/id_rsa

(o cavalo marinho assumirá automaticamente que a chave pública no meu caso era id_rsa.pub)

Após executar o comando, o cavalo-marinho abrirá um pequeno e bonito campo de senha gtk para inserir a senha da chave privada. ou deixe em branco se você gerou a chave sem uma senha.

O cavalo marinho não avisa se tudo correu bem. Você precisará tentar ssh na máquina de destino. Então o cavalo-marinho solicitará que você desbloqueie a chave com uma senha graficamente (ISSO SÓ ACONTECERÁ UMA VEZ) novamente, mas desta vez deve parecer um pouco diferente; P (essa também é a parte em que o cavalo-marinho faz um cavalo-marinho para adicionar ssh à magia, acredito ) e ofereça a OPÇÃO para desbloquear a chave no login, você deve marcar esta opção para atingir seu objetivo.

Só porque eu não li todas as respostas, eu recomendaria desfazer o que todos lhe disseram para fazer com o ssh-add antes de tentar esta resposta. Fazer isso de outra forma pode resultar em algo ruim acontecendo com suas chaves, idk.

enconn
fonte
0

Aqui está o script definitivo.

Atualize $ PASSW e copie e cole no seu Terminal

# <sshpass> via typinator
# Updated: 2017-01-18_21h36
#
# apt-get update -y; apt-get install expect -qy

# Pass this value to ssh-add
PASSW="myfancypass123"

# Define a name for this script
THIS_SCRIPT="$(date +%Y-%m-%d_%H-%M-%S-%N)".sh

# Create a fresh directory to work from / Clean up
rm -rf ~/temp; mkdir -p ~/temp; cd ~/temp; ls -la


# Output our bash script file - BEGIN
cat <<< '
#!/bin/bash

set -u     # Stop if an unbound variable is referenced
set -e     # Stop on first error
export HISTIGNORE="expect*";

# Normal CMDs
echo && echo "The process should take about 10 seconds:" && echo
eval "$(ssh-agent -s)"; sleep 0.5;

# Define VAR passed when this bash-script was launched
password="$@"

# Launch the expect magic
expect -c "
    spawn ssh-add /root/.ssh/id_rsa
    expect "?assword:"
    send \"$password\r\"
    expect "?password:"
    send \"$password\r\"
    expect eof"

export HISTIGNORE="";
export password="";
' > $THIS_SCRIPT
# Output our bash script file - END


# Ensure we are in the right path
cd ~/temp; ls -la; sleep 1;

# Run the bash script
chmod +x ./$THIS_SCRIPT; ./$THIS_SCRIPT "$PASSW"; unset password;

# Clean up
rm -rf ~/temp; mkdir -p ~/temp; cd ~/temp; ls -la
Pascal Andy
fonte
0

A melhor maneira de saber é usar um script de login do PAM que adaptei do trabalho anterior, porque não encontrei uma resposta satisfatória nesta pergunta.

Sua senha é armazenada criptografada com a senha do sistema e uma função de derivação pesada. No login, sua senha do sistema é usada para descriptografar sua senha e adicioná-la ao agente.

https://github.com/capocasa/systemd-user-pam-ssh

A vantagem sobre todas as outras soluções apresentadas é que ela combina segurança equivalente à execução manual do ssh-add na inicialização, sem nenhum esforço. Ele não requer ferramentas extras e possui uma dependência extra que já está instalada por padrão na maioria dos sistemas (OpenSSL).

cmc
fonte
0

Minha configuração no macOS é a seguinte (no .zshrcou .bash_profilepara o pessoal do bash):

# Kill then Load the ssh-agent and set the necessary env variables it outputs
sshRestart() {
    # if all else fails
    # pkill -u $(whoami) ssh-agent;

    if [ -n "$SSH_AUTH_SOCK" ] ; then
        eval `/usr/bin/ssh-agent -k`
    fi
    eval `ssh-agent -s`
    ssh-add ~/.ssh/YOUR_KEY_FILE
    echo "Restarted SSH agent"
}

if [ -z "$SSH_AUTH_SOCK" ] || [[ $SSH_AUTH_SOCK == *"/private/tmp/"* ]] ; then
    eval `ssh-agent -s` > /dev/null 2>&1
    ssh-add ~/.ssh/YOUR_KEY_FILE > /dev/null 2>&1
fi

A || [[ $SSH_AUTH_SOCK == *"/private/tmp/"* ]]parte é necessária no MacOS porque o valor padrão é /private/tmp/com.apple.launchd.SOMETHINGHERE/Listeners. Caso contrário, a resposta abrangente do @Thomas Nyman falha porque $SSH_AUTH_SOCKé sempre definida como algo.

Em seguida, em .zlogout(ou .bash_logoutpara pessoas do bash):

if [ -n "$SSH_AUTH_SOCK" ] ; then
    eval `/usr/bin/ssh-agent -k`
fi

Testado no macOS Mojave 10.14.5

Sam
fonte