Ssh-agent и crontab - есть ли хороший способ встретить их?
Я написал простой script, который каждую ночь отправляет svn активности журналам нашим разработчикам. До сих пор я запускал его на том же компьютере, что и репозиторий svn, поэтому мне не нужно было беспокоиться об аутентификации, я мог бы просто использовать стиль svn file:///address.
Теперь я запускаю script на домашнем компьютере, обращаясь к удаленному репозиторию, поэтому мне пришлось перейти на svn + ssh://paths. Когда ssh-key хорошо настроен, мне никогда не нужно вводить пароли для доступа к хранилищу svn при нормальных обстоятельствах.
Однако crontab не имел доступа к моим ssh-keys/ssh-agent. Я прочитал об этой проблеме несколько мест в Интернете, и она также упоминается здесь без разрешения:
Почему ssh не работает из crontab, но выполняется при выполнении из командной строки?
Моим решением было добавить это в начало script:
### TOTAL HACK TO MAKE SSH-KEYS WORK ###
eval `ssh-agent -s`
Это похоже на работу с MacOSX 10.6.
Мой вопрос: насколько это ужасно, и есть ли лучший способ?
Ответы
Ответ 1
Когда вы запускаете ssh-agent -s, он запускает фоновый процесс, который вам нужно будет убить позже. Итак, минимум - это изменить ваш хак на что-то вроде:
eval `ssh-agent -s`
svn stuff
kill $SSH_AGENT_PID
Однако я не понимаю, как работает этот хак. Просто запуск агента без запуска ssh-add не будет загружать какие-либо ключи. Возможно, что ssh-агент MacOS ведет себя по-другому, чем его справочная страница, говорит он.
Ответ 2
Кроме того...
Если у вашего ключа есть passhphrase, keychain спросит вас один раз (действителен, пока вы не перезагрузите компьютер или не закроете ssh-agent).
keychain - это то, что вам нужно! Просто установите его и добавьте следующий код в свой .bash_profile:
keychain ~/.ssh/id_dsa
Итак, используйте код ниже в script для загрузки переменных среды ssh-agent:
. ~/.keychain/$HOSTNAME-sh
Примечание: keychain также генерирует код для команд csh и fish.
Скопированный ответ https://serverfault.com/questions/92683/execute-rsync-command-over-ssh-with-an-ssh-agent-via-crontab
Ответ 3
У меня была аналогичная проблема. Мой script (который полагался на ssh-ключи) работал, когда я запускал его вручную, но не выполнялся при запуске crontab.
Вручную определяя соответствующий ключ с помощью
ssh -i /path/to/key
не работает.
Но в конце концов я узнал, что SSH_AUTH_SOCK был пуст, когда crontab запускал SSH. Я не был точно уверен, почему, но я просто
env | grep SSH
скопировал возвращаемое значение и добавило это определение в голову моего crontab.
SSH_AUTH_SOCK="/tmp/value-you-get-from-above-command"
Я не понимаю, что происходит здесь, но это устранило мою проблему. Теперь crontab работает гладко.
Ответ 4
Один из способов восстановления pid и socket для запуска ssh-agent будет.
SSH_AGENT_PID=`pgrep -U $USER ssh-agent`
for PID in $SSH_AGENT_PID; do
let "FPID = $PID - 1"
FILE=`find /tmp -path "*ssh*" -type s -iname "agent.$FPID"`
export SSH_AGENT_PID="$PID"
export SSH_AUTH_SOCK="$FILE"
done
Это, конечно, предполагает, что у вас установлен pgrep в системе и работает только один ssh-agent, или в случае нескольких из них он получит тот, который pgrep находит последним.
Ответ 5
Мое решение - основано на пра - немного улучшено, чтобы убить процесс даже при ошибке script:
eval `ssh-agent`
function cleanup {
/bin/kill $SSH_AGENT_PID
}
trap cleanup EXIT
ssh-add
svn-stuff
Обратите внимание, что я должен называть ssh-add на моей машине (научный linux 6).
Ответ 6
Чтобы настроить автоматизированные процессы без автоматического взлома паролей/парольных фраз, я использую отдельный IdentityFile, который не имеет парольной фразы, и ограничиваю записи author_keys целевых машин с префиксом from="automated.machine.com"...
т.д.
Я создал общедоступный закрытый набор ключей для отправляющего компьютера без ключевой фразы:
ssh-keygen -f .ssh/id_localAuto
(Хит возврата, когда будет предложено ввести фразу-пароль)
Я установил запись RemoteAuto Host в .ssh/config
:
Host remoteAuto
HostName remote.machine.edu
IdentityFile ~/.ssh/id_localAuto
и remote.machine.edu:.ssh/authorized_keys с:
...
from="192.168.1.777" ssh-rsa ABCDEFGabcdefg....
...
Тогда ssh не требуется внешняя аутентификация авторизации, предоставляемая ssh-agent или keychain, поэтому вы можете использовать такие команды как:
scp -p remoteAuto:watchdog ./watchdog_remote
rsync -Ca remoteAuto/stuff/* remote_mirror
svn svn+ssh://remoteAuto/path
svn update
...
Ответ 7
Предполагая, что вы уже настроили настройки SSH и что script отлично работает с терминалом, использование keychain - это, безусловно, самый простой способ гарантировать, что script отлично работает в crontab.
Так как keychain не входит в большинство производных Unix/Linux, выполните пошаговую процедуру.
1. Загрузите соответствующий пакет rpm в зависимости от вашей версии ОС от http://pkgs.repoforge.org/keychain/. Пример для CentOS 6:
wget http://pkgs.repoforge.org/keychain/keychain-2.7.0-1.el6.rf.noarch.rpm
2. Установите пакет:
sudo rpm -Uvh keychain-2.7.0-1.el6.rf.noarch.rpm
3. Создайте файлы ключей для вашего SSH-ключа, они будут расположены в каталоге ~/.keychain. Пример для id_rsa:
keychain ~/.ssh/id_rsa
4. Добавьте следующую строку в свой script где-нибудь перед первой командой, использующей аутентификацию SSH:
source ~/.keychain/$HOSTNAME-sh
Я лично старался избегать использования дополнительных программ для этого, но все остальное, что я пробовал, не помогло. И это сработало отлично.
Ответ 8
Вдохновленный некоторыми другими ответами здесь (особенно vpk), я придумал следующую запись crontab, которая не требует внешнего script:
PATH=/usr/bin:/bin:/usr/sbin:/sbin
* * * * * SSH_AUTH_SOCK=$(lsof -a -p $(pgrep ssh-agent) -U -F n | sed -n 's/^n//p') ssh hostname remote-command-here
Ответ 9
Вот решение, которое будет работать, если вы не можете использовать keychain, и если вы не можете запустить ssh-agent из вашего script (например, потому что ваш ключ защищен паролем).
Запустить это один раз:
nohup ssh-agent > .ssh-agent-file &
. ssh-agent-file
ssh-add # you'd enter your passphrase here
В script вы работаете из cron:
# start of script
. ${HOME}/.ssh-agent-file
# now your key is available
Конечно, это позволяет любому, кто может читать "~/.ssh-agent-file" и соответствующий сокет, использовать ваши учетные данные ssh, поэтому используйте их с осторожностью в любой многопользовательской среде.
Ответ 10
Ваше решение работает, но оно будет вызывать новый процесс агента каждый раз, как уже было указано другим ответом.
У меня возникли аналогичные проблемы, и я нашел этот blogpost полезным, а также оболочку script Уэйн Уокер, упомянутую в блоге на github.
Удачи!