Подтвердить что ты не робот

Почему ssh не работает из crontab, но выполняется при выполнении из командной строки?

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

ssh -nxv [email protected] 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.
...

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

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

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

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

4b9b3361

Ответ 1

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

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

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

Ответ 2

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

Ответ 3

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

Ответ 4

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

Во-первых, моя настройка ssh использует script в моем bash init script.

# 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. Вот что будет выглядеть script:

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, он настроит root cron. Если вы запустите crontab -u davis -e, он добавит задание cron как userid davis. Аналогично, если вы запустите как пользователь davis и сделаете crontab -e, он создаст задание cron, которое будет работать как userid davis. Это можно проверить со следующей записью:

30 *  *   *   *     /usr/bin/whoami

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

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

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

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

To: [email protected]
Subject: Cron <[email protected]> /usr/bin/ssh-add -l

Could not open a connection to your authentication agent.

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

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

Это запустит script в 10:55. Обратите внимание на лидерство. в script. Он говорит, чтобы запустить этот script в моей среде, подобный тому, что находится в .bash init script.

Ответ 5

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

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

в crontab у меня был

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

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

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

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

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

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