Почему ssh выходит из crontab, но удаляется при запуске из командной строки? - PullRequest
21 голосов
/ 15 мая 2009

У меня есть скрипт bash, который выполняет ssh на удаленной машине и выполняет там команду, например:

ssh -nxv user@remotehost echo "hello world"

Когда я выполняю команду из командной строки, она работает нормально, но не работает, когда выполняется как часть crontab (errorcode = 255 - не удается установить соединение SSH). Подробности:

...
Waiting for server public key.
Received server public key and host key.
Host 'remotehost' is known and matches the XXX host key.
...
Remote: Your host key cannot be verified: unknown or invalid host key.
Server refused our host key.
Trying XXX authentication with key '...'
Server refused our key.
...

При локальном выполнении я действую как root, crontab также работает как root. Выполнение 'id' из crontab и командной строки дает точно такой же результат:

$ id
> uid=0(root) gid=0(root) groups=0(root),...

Я делаю ssh с некоторого локального компьютера на компьютер, на котором работает crond. У меня есть ключ ssh и учетные данные для ssh на машине crond и любой другой машине, к которой подключаются сценарии.

PS. Пожалуйста, не спрашивайте / не жалуйтесь / не комментируйте, что выполнение чего-либо с правами root является неправильным / неправильным / и т. Д. - это не цель этого вопроса.

Ответы [ 5 ]

25 голосов
/ 04 августа 2013

keychain

решает это безболезненно. Это в репозиториях для Debian / Ubuntu:

sudo apt-get install keychain

и, возможно, для многих других дистрибутивов (похоже, это произошло от Gentoo).

Эта программа запустит ssh-agent, если ни один из них не запущен, и предоставит сценарии оболочки, которые могут быть source d, и подключит текущую оболочку к этой конкретной ssh-agent.

Для bash с закрытым ключом с именем id_rsa добавьте следующее к вашему .profile:

keychain --nogui id_rsa

Это запустит ssh-agent и добавит ключ id_rsa при первом входе в систему после перезагрузки. Если ключ защищен парольной фразой, он также запросит парольную фразу. Больше не нужно использовать незащищенные ключи! При последующих входах в систему он распознает агента и больше не запрашивает пароль.

Кроме того, добавьте следующее в качестве последней строки вашего .bashrc:

. ~/.keychain/$HOSTNAME-sh

Это позволит оболочке узнать, где связаться с агентом SSH, управляемым keychain. Убедитесь, что .bashrc получено из .profile.

Однако, похоже, что cron задания все еще не видят этого. В качестве исправления включите строку выше в crontab непосредственно перед фактической командой:

* * * * * . ~/.keychain/$HOSTNAME-sh; your-actual-command
9 голосов
/ 15 мая 2009

Я предполагаю, что обычно, когда вы выполняете ssh с локального компьютера на компьютер, на котором работает crond, ваш закрытый ключ загружается в ssh-agent и пересылается по соединению. Поэтому, когда вы выполняете команду из командной строки, она находит ваш закрытый ключ в ssh-agent и использует его для входа на удаленный компьютер.

Когда crond выполняет команду, он не имеет доступа к ssh-agent, поэтому не может использовать ваш закрытый ключ.

Вам нужно будет создать новый закрытый ключ для пользователя root на машине, на которой запущен crond, и скопировать его открытую часть в соответствующий файл authorized_keys на удаленной машине, на которую вы хотите, чтобы crond зарегистрировался.

4 голосов
/ 03 августа 2016

Не подвергайте свои ключи SSH без ключевой фразы. Вместо этого используйте ssh-cron , что позволяет планировать задачи с использованием агентов SSH.

1 голос
/ 30 ноября 2016

Итак, у меня была похожая проблема. Я пришел сюда и увидел разные ответы, но, поэкспериментировав, я понял, как это работает с sshkeys с парольной фразой, ssh-agent и cron.

Прежде всего, моя установка ssh использует следующий скрипт в моем скрипте bash init.

# JFD Added this for ssh
SSH_ENV=$HOME/.ssh/environment

    # start the ssh-agent
    function start_agent {
        echo "Initializing new SSH agent..."
        # spawn 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
    }


    if [ -f "${SSH_ENV}" ]; then
         . "${SSH_ENV}" > /dev/null
         ps -ef | grep ${SSH_AGENT_PID} | grep ssh-agent$ > /dev/null || {
            start_agent;
        }
   else
        start_agent;
   fi

Когда я вхожу в систему, я ввожу свою фразу-пароль один раз, и с этого момента она будет использовать ssh-agent для автоматической аутентификации.

Данные ssh-agent хранятся в .ssh / environment. Вот как будет выглядеть этот скрипт:

SSH_AUTH_SOCK=/tmp/ssh-v3Tbd2Hjw3n9/agent.2089; export SSH_AUTH_SOCK;
SSH_AGENT_PID=2091; export SSH_AGENT_PID;
#echo Agent pid 2091;

Что касается cron, вы можете настроить работу как обычного пользователя различными способами. Если вы запустите crontab -e как пользователь root, он установит пользователя cron. Если вы запустите crontab -u davis -e, он добавит задание cron в качестве имени пользователя davis. Аналогично, если вы запускаете от имени пользователя davis и выполняете crontab -e, это создаст задание cron, которое будет запускаться как userrid davis. Это можно проверить с помощью следующей записи:

30 *  *   *   *     /usr/bin/whoami

Это будет отправлять результат whoami каждые 30 минут пользователю davis. (Я сделал crontabe -e как пользователь Дэвис.)

Если вы попытаетесь увидеть, какие ключи используются в качестве пользователя davis, сделайте следующее:

36 *  *   *   *     /usr/bin/ssh-add -l

Не удастся, журнал, отправленный по почте, скажет

To: davis@xxxx.net
Subject: Cron <davis@hostyyy> /usr/bin/ssh-add -l

Could not open a connection to your authentication agent.

Решение состоит в том, чтобы установить скрипт env для ssh-agent выше. Вот результирующая запись cron:

55 10  *   *   *     . /home/davis/.ssh/environment; /home/davis/bin/domythingwhichusesgit.sh

Это запустит скрипт в 10:55. Обратите внимание на ведущие. в сценарии. В нем говорится, что этот сценарий следует запускать в моей среде, аналогичной сценарию .bash init.

0 голосов
/ 11 марта 2013

Вчера у меня была похожая проблема ...

У меня есть задание cron на одном сервере, которое запускает какое-то действие на другом сервере, используя ssh ... Проблема была в правах пользователя и ключах ...

в crontab у меня было

* * * * * php /path/to/script/doSomeJob.php

И он просто не работал (не имел разрешений). Я попытался запустить Cron от имени конкретного пользователя, который подключен к другому серверу

* * * * * user php /path/to/script/doSomeJob.php

Но без эффекта.

Наконец, я перехожу к сценарию, а затем выполняю php-файл, и это работает ..

* * * * * cd /path/to/script/; php doSomeJob.php
...