Автоматизация ssh-соединения с помощью crontab
Я изо всех сил пытался crontab автоматизировать процесс git push с помощью ssh, и было сложно установить ключ с помощью агента ssh. Начиная с базового скрипта для тестирования агента:
# set paths (all examples)
source /etc/profile
export PATH=$PATH:/Users/myusername/.ssh
eval "$(ssh-agent)" > ssh_agent.txt
/usr/bin/ssh-add -l >> ssh_agent.txt
.. который выводит следующее:
Agent pid 16062
The agent has no identities.
Таким образом, агент активен. Теперь, чтобы добавить ключ и проверить, зарегистрирован ли он у агента. В iTerm2 вручную это работает нормально:
/usr/bin/ssh-add /Users/myusername/.ssh/id_rsa
2048 [key fingerprint] /Users/myusername/.ssh/id_rsa (RSA)
Я пытаюсь повторить это внутри задания crontab, используя этот скрипт:
/usr/bin/ssh-add /Users/myusername/.ssh/id_rsa
/usr/bin/ssh-add -l >> ssh_agent.txt
.. какие отчеты The agent has no identities
подать, и следующие через "You have mail in /var/mail/myusername"
:
[email metadata]
Enter passphrase for /Users/myusername/.ssh/id_rsa:
Таким образом, ключ пытается загрузить, но ловит в приглашении пароля. Здесь я хочу использовать expect
чтобы дать ему фразу-пароль, как описано в этом ответе unix.stackexchange (похоже, он должен работать в OSX):
#!/usr/bin/expect -f
/usr/bin/ssh-add /Users/myusername/.ssh/id_rsa
expect "Enter passphrase for /Users/myusername/.ssh/id_rsa:"
send "mypassphrase\n";
interact
Ответ об ошибке почты:
Enter passphrase for /Users/myusername/.ssh/id_rsa:
couldn't read file "Enter passphrase for /Users/myusername/.ssh/id_rsa:": no such file or directory
/Users/myusername/test/crontest.sh: line 17: send: command not found
/Users/myusername/test/crontest.sh: line 18: interact: command not found
Поэтому я попробовал альтернативную конфигурацию на основе этого SO ответа:
#!/usr/bin/expect -f
expect -c "
/usr/bin/ssh-add /Users/myusername/.ssh/id_rsa
expect \"Enter passphrase for /Users/myusername/.ssh/id_rsa: \"
send \"mypassphrase\n\";
interact
"
.. и получите следующий почтовый отчет об ошибке:
invalid command name "/usr/bin/ssh-add"
while executing
"/usr/bin/ssh-add /Users/myusername/.ssh/id_rsa"
Could not open a connection to your authentication agent.
Я не понимаю, проблема здесь - агент ssh работает, и ключ кажется доступным, так что же это за проблема с соединением? Я пробовал другие конфигурации для expect
безуспешно. Очень благодарен за помощь.
2 ответа
Я бы не рекомендовал бегать ssh-add
или же expect
в задании cron, поскольку его чрезмерно сложно запускать в ограниченной среде, которую использует cron для выполнения своих заданий, и я бы предпочел не хранить пароли в crontab.
Вместо того чтобы использовать ваш обычный ключ SSH, я бы создал новый ключ, который будет использоваться только для запуска команды, которую вы хотите запустить с помощью cron. Я бы настроил ключ без ключевой фразы и изменил бы его владельца / разрешения (0600) так, чтобы к нему мог обращаться только эффективный идентификатор пользователя, под которым запускается задание cron, т. Е. Идентификатор пользователей, чей crontab находится в процессе обработанный.
В вашем конкретном случае конкретная команда git push
поэтому новый ключ должен быть загружен на ваш сервер git. Большинство серверов git должны иметь возможность принимать несколько открытых ключей SSH.
В целом, для автоматизированных процессов лучше всего создавать конкретные ключи без парольных фраз. Затем на удаленном SSH-сервере настраивается ограниченный набор разрешенных команд, добавляя пары параметров к его строке вauthorized_keys
файл, например,
command="automated-task.sh",client=my.local.host,no-pty,no-agent-forwarding,no-port-forwarding ssh-rsa AAA…public…part…of…specific…keypair automated_user@server
Отказ от ответственности: у меня больше опыта работы с GNU/Linux, чем с OS X, но AFAIK приведенная выше информация должна относиться ко всем *nix системам.
Этот ответ имеет другое рабочее решение:
Если вы используете ssh-add
чтобы добавить свой ключ (и) в агент ssh, вы можете добавить SSH_AUTH_SOCK
переменная окружения вашего crontab, и команды ssh смогут использовать уже загруженные и разблокированные ключи.
- В обычном терминальном сеансе загрузите ваш ssh-agent (это оставлено читателю как упражнение; я думаю, что в macOS он работает по умолчанию, или вы можете запустить
ssh-add -t 24h ~/path/to/your.key
). - Получите ваше местоположение SSH_AUTH_SOCK с
env | grep SSH_AUTH_SOCK
- Добавьте это в начало вашего crontab, например,
SSH_AUTH_SOCK=/Users/USER/.ssh/ssh_auth_sock
,
Если вы не загрузили или не аутентифицировали ключи, команды crontab ssh все равно не будут работать, но для меня это нормально, так как 99% времени у меня загружены ключи.
Альтернативный ответ
Я просто подумала, что присмотрюсь к твоему expect
сценарии и я заметил, что они пропускают spawn
команда:
#!/usr/bin/expect -f
spawn /usr/bin/ssh-add /Users/myusername/.ssh/id_rsa
expect "Enter passphrase for /Users/myusername/.ssh/id_rsa:"
send "mypassphrase\n";
interact
От expect
руководство:
spawn [args] программа [args]
создает новый процесс, запускающий программу args. Его stdin, stdout и stderr связаны с Expect, так что они могут быть прочитаны и записаны другими командами Expect. Соединение разрывается при закрытии или если сам процесс закрывает какой-либо из идентификаторов файла.