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

StackOverflow https://stackoverflow.com/questions/869589

  •  22-08-2019
  •  | 
  •  

Вопрос

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

ssh -nxv user@remotehost echo "hello world"

Когда я выполняю команду из командной строки, она работает нормально, но не работает, когда выполняется как часть crontab (код ошибки = 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 и любого другого компьютера, к которому подключаются сценарии.

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

Это было полезно?

Решение

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

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

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

Другие советы

keychain

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

sudo apt-get install keychain

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

Эта программа запустит ssh-agent если ни один из них не запущен, и предоставить сценарии оболочки, которые можно sourced и подключим текущую оболочку к этому конкретному 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

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

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

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

# 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-агент для автоматической аутентификации.

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

30 *  *   *   *     /usr/bin/whoami

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

Если вы попытаетесь посмотреть, какие клавиши используются в качестве пользователя 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-агента, указанный выше.Вот результирующая запись cron:

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

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

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

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

в кронтабе у меня было

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

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

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

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

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

* * * * * cd /path/to/script/; php doSomeJob.php
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top