У меня есть скрипт, который устанавливает обратный туннель на конечной точке HostB
. Выглядит он так:
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
когда я запускаю его вручную, ./tun.sh
он работает, и я вижу на HostB, что пользователь A вошел в систему. Если я снова запускаю его на HostA, но с другой консоли, он работает так, как и ожидалось — он не запускает второй туннель.
Пока все хорошо.
Теперь я редактирую свой crontab так, чтобы он выглядел следующим образом:
crontab -l
# m h dom mon dow command
*/1 * * * * /home/userA/bin/tun.sh
Он запускает скрипт каждую минуту. Это должно быть нормально, так как скрипт завершается, если туннель уже установлен.
Однако теперь пользователь userA не входит в систему, как при запуске его вручную из консоли.
Тестовый код в верхней части скрипта подтверждает, что скрипт вызывается и имеет разрешение на выполнение /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]
По какой-то причине -V
пишет в stderr
и не stdout
, но это деталь. Главное здесь то, что скрипт выполняется каждую минуту.
Мой вопрос:почему не устанавливается SSH-туннель?
решение1
Спасибо @Andrew за указание на ssh-agent
. Насколько я понимаю, если кто-то хочет иметь возможность установить туннель без необходимости каждый раз вводить пароль, пароль должен быть сохранен или удален. Я решил удалить его. Для справки, вот некоторые исправления, основанные на полученных мной комментариях:
#!/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
кронтаб:
# m h dom mon dow command
*/1 * * * * /home/laptopuser/bin/establishTunnel.sh
скопируйте идентификатор вашего туннеля на vps:
ssh-copy-id -i /home/user/laptopuser/.ssh/id_rsa_tunnel vps.com
дождитесь запуска туннеля (см. sudo watch grep CRON /var/log/syslog
) и скопируйте свой обычный идентификатор, если вы еще не вошли~/.ssh/authorized_keys
ssh-copy-id vps.com -p 2200
В идеале туннель должен работать как выделенный пользователь как на VPS, так и на ноутбуке.
решение2
У меня была похожая проблема - туннель ssh работает, если запущен из скрипта, но не из crontab. ssh ищет ключи и known_hosts в $HOME/.ssh. Если вы запускаете скрипт из bash под пользователем tom, $HOME будет /home/tom. Если скрипт запущен из crontab, пользователь будет root, а $HOME будет /home/root (или undefined).
Решение: Определите HOME в вашем скрипте для пользователя, у которого есть ключи.
HOME=/home/tom