Eu tenho um script que estabelece um túnel reverso em um endpoint HostB
. Se parece com isso:
cat tun.sh
#!/usr/bin/env bash
# Test code
/usr/bin/ssh -V 1> /home/userA/bin/tun.stdout 2> /home/userA/bin/tun.stderr
# Establish tunnel
createTunnel() {
/usr/bin/ssh -R *:19999:localhost:22 userB@hostB
}
# Do nothing if tunnel is already established
/usr/bin/ssh -p 19999 userA@hostB true
if [[ $? -ne 0 ]]; then
createTunnel
fi
quando eu o executo manualmente ./tun.sh
, ele funciona e posso ver no HostB que o usuárioA está logado. Se eu executá-lo novamente no HostA, mas em outro console, ele funciona como esperado - ele não inicia um segundo túnel.
Tudo até agora está bem.
Agora edito meu crontab para ficar assim:
crontab -l
# m h dom mon dow command
*/1 * * * * /home/userA/bin/tun.sh
Ele executa o script a cada minuto. Isso deve funcionar, pois o script termina se o túnel já estiver estabelecido.
No entanto, agora o usuárioA não faz login como quando eu o executo manualmente no console.
O código de teste na parte superior do script confirma que o script está sendo chamado e que tem permissão para executar /usr/bin/ssh
:
~/bin$ ls
tun.sh tun.stderr tun.stdout
~/bin$ cat tun.stderr
OpenSSH_5.3p1 Debian-3ubuntu7, OpenSSL 0.9.8k 25 Mar 2009
~/bin$ cat tun.stdout
[empty]
Por algum motivo -V
escreve para stderr
e não stdout
, mas isso é um detalhe. O ponto principal aqui é que o script está sendo executado a cada minuto.
Minha pergunta é:por que o túnel SSH não está estabelecido?
Responder1
Obrigado a @Andrew por apontar para ssh-agent
. Pelo que posso ver, se alguém quiser estabelecer o túnel sem ter que digitar uma senha todas as vezes, a senha deve ser armazenada ou removida. Eu optei por removê-lo. Para que conste, aqui estão algumas limpezas com base nos comentários que recebi:
#!/usr/bin/env bash
# Establish tunnel
createTunnel() {
/usr/bin/ssh -i /home/laptopuser/.ssh/id_rsa_tunnel -R 2200:localhost:22 [email protected]
}
# Do nothing if tunnel is already established
/usr/bin/ssh -i /home/user/laptopuser/.ssh/id_rsa_tunnel -p 2200 [email protected] true
if [[ $? -ne 0 ]]; then
createTunnel
fi
crontab:
# m h dom mon dow command
*/1 * * * * /home/laptopuser/bin/establishTunnel.sh
copie o ID do seu túnel para o vps:
ssh-copy-id -i /home/user/laptopuser/.ssh/id_rsa_tunnel vps.com
espere até que o túnel esteja em execução (veja sudo watch grep CRON /var/log/syslog
) e copie seu id normal se você ainda não o tiver feito~/.ssh/authorized_keys
ssh-copy-id vps.com -p 2200
Idealmente, o túnel seria executado como usuário dedicado tanto no vps quanto no laptop.
Responder2
Eu tive um problema semelhante - o túnel ssh funciona se executado a partir do script, mas não do crontab. ssh procura chaves e hosts_conhecidos em $HOME/.ssh. Se você estiver executando o script do bash sob o usuário tom, $HOME será /home/tom. Se o script for executado a partir do crontab, o usuário será root e $HOME será /home/root (ou indefinido).
Solução: Defina HOME em seu script para o usuário que possui as chaves.
HOME=/home/tom