Автоматизация 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 смогут использовать уже загруженные и разблокированные ключи.

  1. В обычном терминальном сеансе загрузите ваш ssh-agent (это оставлено читателю как упражнение; я думаю, что в macOS он работает по умолчанию, или вы можете запустить ssh-add -t 24h ~/path/to/your.key).
  2. Получите ваше местоположение SSH_AUTH_SOCK с env | grep SSH_AUTH_SOCK
  3. Добавьте это в начало вашего 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. Соединение разрывается при закрытии или если сам процесс закрывает какой-либо из идентификаторов файла.

Другие вопросы по тегам