Я часто делаю резервные копии на локальном диске, который хочу ежедневно синхронизировать с удаленным сервером.
Целевой сервер настроен только для доступа по ключу SSH (без пароля). Поскольку мой основной ключ SSH для этого сервера защищен парольной фразой, ясоздал второй ключ SSH (не защищенный парольной фразой) + пользователя для использования при автоматическом резервном копировании- таким образом, мне не нужно присутствовать, чтобы ввести свою парольную фразу при запуске cron.
Я использую cron и rsync, и все команды работают по отдельности, но при совместном использовании дают сбой.
Самое большее, чего я добился при устранении неполадок, это работа
env -i sh -c "rsync -lrstRO --delete --exclude 'lost+found' /Backups/auto-daily-backups/./ [email protected]:/backups/desktop/"
который возвращает ошибку
Permission denied (publickey).
rsync: connection unexpectedly closed (0 bytes received so far) [sender]
rsync error: unexplained error (code 255) at io.c(226) [sender=3.1.0]
Есть ли какие-нибудь советы по дальнейшему устранению этой неполадки?
Вот что я уже попробовал, но у меня больше нет идей:
- Cron определенно работает
ps aux | grep cron
Ничего необычного в /var/log/syslog
Sep 7 13:22:01 desktop CRON[6735]: (tom) CMD (sh /home/tom/Documents/Scripts/offsite-backup)
SSH в терминале на удаленном сервере в качестве резервного пользователя работает
ssh [email protected]
- Запуск команды в Терминале работает отлично.
rsync -lrstRO --delete --exclude 'lost+found' /Backups/auto-daily-backups/./ [email protected]:/backups/desktop/
Указание пути к ключу backups-user вручную не дает никакого эффекта
rsync -lrstRO --delete --exclude 'lost+found' -e 'ssh -i /home/tom/.ssh/backups-only' /Backups/auto-daily-backups/./ [email protected]:/backups/desktop/
Замена неработающей команды простой тестовой командой работает
echo "Hello world" > ~/Desktop/test.txt
Крики/ругательства на компьютер не дали никакого эффекта (но мне стало временно лучше).
Редактировать 1:
Вот мой файл crontab и скрипт, который он вызывает.
...
# m h dom mon dow command
MAILTO=""
* * * * * sh /home/tom/Documents/Scripts/offsite-backup
и
#!/bin/bash
rsync -lrstRO --delete --exclude 'lost+found' /Backups/auto-daily-backups/./ [email protected]:/backups/desktop/
Редактировать 2:
Просто для ясности, /var/log/auth.log
на целевом сервере есть строка Sep 11 08:23:01 <hostname> CRON[24421]: pam_unix(cron:session): session closed for user root
Это сбивает с толку, потому что я больше не запускаю cron каждую минуту локально, но новая запись все еще появляется каждую минуту в журналах сервера. Файлы Crontab длявсепользователи (включая root) на сервере пусты и ничего не делают.
Кроме того, пользователь 'backups-only' был создан только на сервере и с ограниченными правами, с выделенным ключом SSH, скопированным на мой настольный компьютер. Я предполагаю, что это правильный путь, потому что все работает при запуске команд вручную.
Файл crontab, размещенный выше, предназначен для меня, пользователя 'tom' на моем настольном компьютере. Я хочу, чтобы он вызывал скрипт, который должен входить на сервер как пользователь 'backups-only'. Я только что попробовал запустить скрипт резервного копирования (а не команду внутри него), и он успешно подключился и заработал. Я запустил его на своем настольном компьютере как пользователь 'tom', тот же пользователь, который создал задание cron, которое не работает. Вот вывод из журнала сервера, соответствующий этому успешному входу
Sep 11 08:35:31 <hostname> sshd[25071]: error: Could not load host key: /etc/ssh/ssh_host_ed25519_key
Sep 11 08:35:32 <hostname> sshd[25071]: Accepted publickey for backups-only from <desktop IP> port 54242 ssh2: RSA e2:e6:07:27:c1:continues...
Sep 11 08:35:32 <hostname> sshd[25071]: pam_unix(sshd:session): session opened for user backups-only by (uid=0)
Sep 11 08:35:32 <hostname> systemd-logind[638]: New session 12 of user backups-only.
Sep 11 08:36:00 <hostname> sshd[25133]: Received disconnect from <desktop IP>: 11: disconnected by user
Sep 11 08:36:00 <hostname> sshd[25071]: pam_unix(sshd:session): session closed for user backups-only
решение1
Поскольку из командной строки все работает нормально, ошибка Permission denied (publickey)
означает, что часть SSH rsync
использует файл идентификации, отличный от указанного имени пользователя.
Откомментарий Янав исходном вопросе мы можем указать файл идентификации в rsync
команде, используя -e 'ssh -i /path/to/identity.file' ...
.
Использование приведенной ниже команды для запуска новой среды в cron и указание полного пути к файлу, по-видимому, решает проблему:
env -i sh -c "rsync -lrstRO --delete --exclude 'lost+found' -e 'ssh -i /home/tom/.ssh/backups-only' /Backups/auto-daily-backups/./ [email protected]:/backups/desktop/"
Я все еще очень заинтересован в этом открытии. Вероятно, это связано с cron, тем фактом, что он запускается с минимальными переменными окружения, и ssh-agent. Я настрою тот же сценарий через пару дней, чтобы протестировать его и отчитаться.
решение2
Я только что решил проблему, которая держала меня в напряжении.
Невозможно подключиться в RSYNC через SSH, несмотря на указание идентификатора для SSH... Ничего не делается... Rsync выдает сообщение «отказано в доступе», а ssh сообщает мне «read_passphrase: невозможно открыть /dev/tty: нет устройства или адреса такого типа»
Но я прочитал пост, в котором объяснялось, что у crontab есть своя собственная среда, которая не совпадает с root. Я уже знал это, но не понимал, какое влияние это может оказать на SSH при использовании SSH-AGENT
Но мой обмен ключами SSH выполняется с помощью PassPhrase... поэтому, если среда отличается и мой RSYNC через SSH ожидает парольную фразу, которую невозможно ввести => отладочная информация SSH также указывает на ошибку:
"debug1: read_passphrase: невозможно открыть /dev/tty: нет такого устройства или адреса" => Ну да, нет TTY = нет парольной фразы = не разрешено
На моей машине я использую "Keychain" для запуска агента SSH, чтобы мне не приходилось вводить пароль каждый раз при попытке удаленного подключения. Keychain генерирует файл, содержащий следующую информацию
SSH_AUTH_SOCK = /tmp/ssh-PWg3yHAARGmP/agent.18891; экспорт SSH_AUTH_SOCK; SSH_AGENT_PID = 18893; экспорт SSH_AGENT_PID;
==> Команда SSH-AGENT возвращает ту же информацию.
Итак, в конечном итоге, именно эта информация, связанная с текущим сеансом, позволяет проводить будущие аутентификации текущего сеанса без необходимости ввода парольной фразы, поскольку это уже было сделано ранее и запомнено...
==> Решение есть...достаточно в скрипте, запускаемом crontab, и "источнике" файла, содержащего эту информацию, или сделать это в командной строке ds the crontab ...
пример: 14 09 * * *. /home/foo/.keychain/foo.serveur.org-sh && scp -vvv -P 22 /tmp/mon_fic/toto.sh[email protected]:. >> / var / log / check_connexion.log 2> & 1 или используйте команду "source /home/foo/keychain/foo.server.org-sh" в скрипте, который запускает соединение с использованием SSH.
=> С этим источником больше не о чем беспокоиться. Информация SSH_AUTH_SOCK и SSH_AGENT_PID загружается в среду Crontab и поэтому известна, RSYNC через SSH работает без проблем.
Это отнимало у меня много времени, но теперь это работает :)
решение3
Предупреждение для тех, кто использует SSH Agent Forwarding:
Если вы видите такое поведение при отладке скрипта на удаленном хосте, это происходит потому, что даже с этим -e "ssh -i /path/to/key"
флагом ssh будет использовать ваш локальный (перенаправленный) ключ, а не тот, что на сервере.
Конкретный пример: у меня есть скрипт на сервере разработки, который извлекает данные из "сервера данных" с помощью rsync через ssh. Когда я захожу на сервер разработки и запускаю его, все хорошо, но при запуске из cron я получаю сообщение об отказе в доступе. Добавив немного детализации в процесс SSH (flag -vv
), я заметил следующее:
debug2: key: /home/nighty/.ssh/id_rsa (0x562d8b974820),
debug2: key: /home/juanr/.ssh/id_rsa (0x562d8b962930), explicit
debug1: Authentications that can continue: publickey,password
debug1: Next authentication method: publickey
debug1: Offering RSA public key: /home/nighty/.ssh/id_rsa
debug2: we sent a publickey packet, wait for reply
debug1: Server accepts key: pkalg ssh-rsa blen 279
debug2: input_userauth_pk_ok: fp 1a:19:08:9f:80:16:b1:db:55:42:9a:52:b2:49:9b:0a
debug1: Authentication succeeded (publickey).
Меня подсказало то, что по чистой случайности у меня на локальном хосте («nighty») и на сервере разработки («juanr») разные имена пользователей.
Обратите внимание, как он помечает ключ на сервере разработки как «явный», но по-прежнему использует пересланный ключ с моего ноутбука для входа в систему. Выполнение ssh-copy-id
на этом этапе ничего не решает, потому что он просто переустанавливает пересланный ключ, а не тот, что с сервера разработки. Если вы используете ssh-copy-id с пересылкой агента, вам нужно указать, какой ключ устанавливать с помощью флага -i: ssh-copy-id -i ~/.ssh/id_rsa.pub user@host
.
решение4
Вы уже пробовали старый трюк с очисткой файлов hosts? Я имею в виду:
rm ~/.ssh/known_hosts
Стоит попробовать, так как ssh перестроит его, и вы избавитесь от устаревших вещей. Конечно, вы также можете удалить части, принадлежащие данному IP / хосту.
Дополнительные вопросы: Ваше задание cron выполняется под вашим UID или от имени пользователя cron или root?