Я работаю с двумя экземплярами Ubuntu на AWS (для доступа к которым я использую ключ PEM).
Я настроил rsync для обоих экземпляров, и он работает, если я использую пользователя по умолчанию, которым является ubuntu@ipaddress. Однако если я попытаюсь использовать rsync с другим пользователем ( sudo su - jenkins
например, я набираю команду или даже набираю ее sudo
перед командой rsync), то я получаю следующую ошибку.
Permission denied (publickey).
rsync: connection unexpectedly closed (0 bytes received so far) [Receiver]
rsync error: unexplained error (code 255) at io.c(226) [Receiver=3.1.0]
Шаги, которые я предпринял:
Я попытался создать ключ SSH (используя ssh-keygen), войдя в систему как пользователь, jenkins
и добавил его в authorized_keys
файл в обоих каталогах /home/ubuntu/.ssh/authorized_keys
(откуда я запускаю rsync) и даже $JENKINS_HOME/.ssh/authorized_keys
(откуда я пытался запустить rsync).
Я даже попробовал сделать то же самое с помощью клавиши PEM, но это тоже не сработало.
Вот что я пытаюсь сделать
rsync -avuh --delete -e ssh jenkins@ipaddress:/var/lib/jenkins/* /var/lib/jenkins
А вот с ключевым файлом
rsync -avuh --delete -e 'ssh -i path/to/key.pem' [email protected]:/var/lib/jenkins/* /var/lib/jenkins
PS: Единственная причина, по которой я не хочу запускать его от имени пользователя Ubuntu, заключается в том, что я влип failed: Permission denied (13)
во многие вещи (так как файлы принадлежат jenkins).
Конечная цель:
Я пытаюсь постоянно сохранять резервную копию экземпляра Jenkins вместе с основным экземпляром, выполняя cronjob:
*/30 * * * * /usr/bin/rsync -avuh --delete -e ssh root@jenkinsprimary:/var/lib/jenkins/* /var/lib/jenkins
решение1
Необходимо различать 2 вещи:
- ВОЗустанавливает SSH-соединение.
- которыйудаленный пользователь владеет файламикоторые вы хотите скопировать.
Обзор
(srcmachine) (rsync) (destmachine)
srcuser -- SSH --> destuser
|
| sudo su jenkins
|
v
jenkins
Предположим, вы хотите выполнить rsync:
- От:
- Машина:
srcmachine
- Пользователь:
srcuser
- Каталог:
/var/lib/jenkins
- Машина:
- К:
- Машина:
destmachine
- Пользователь:
destuser
комуустановить SSH-соединение. - Каталог:
/tmp
- Владелец конечных файлов:
jenkins
.
- Машина:
Решение
rsync --rsync-path 'sudo -u jenkins rsync' -avP --delete /var/lib/jenkins destuser@destmachine:/tmp
Пояснения
--rsync-path=PROGRAM specify the rsync to run on the remote machine
Хитрость заключается в том, чтобы указать, что нужно запустить программу rsync
на удаленной машине под другим пользователем ( jenkins
), а не под тем, кто устанавливает SSH-соединение ( destuser
).
Требования
SSH-доступ
(srcmachine) (rsync) (destmachine)
srcuser -- SSH --> destuser
[~/.ssh/id_rsa] [~/.ssh/authorized_keys] <-- "id_rsa.pub" inside
[~/.ssh/id_rsa.pub]
Не забудьте ограничить разрешения на ~/.ssh
:
chmod 700 ~/.ssh
sudoer дляdestuser
Должен destuser
иметь привилегию делать sudo -u jenkins rsync
.
В общем случае мы устанавливаем destuser
как член sudoers
. Для этого на root
@ destmachine
:
cat > /etc/sudoers.d/destuser << EOF
destuser ALL=(ALL) NOPASSWD:ALL
EOF
Чтобы протестировать его заранее rsync
, вы можете войти в destuser
@ destmachine
и выполнить следующее:
sudo su jenkins
echo $USER
Если он возвращается:
jenkins
это означает, что вы вошли в систему как jenkins
пользователь, и это означает, что ваша rsync
команда также будет работать, поскольку jenkins
работает привилегия escalade.
Примечание о плохом решении: установите SSH-соединение с конечным пользователем.jenkins
Почему бы нам просто не сделать это?
(srcmachine) (rsync) (destmachine)
srcuser -- SSH --> jenkins
[~/.ssh/id_rsa] [~/.ssh/authorized_keys] <-- "id_rsa.pub" inside
[~/.ssh/id_rsa.pub]
поскольку jenkins
это учетная запись «службы», что означает, что она запускает службу, которая предоставляет порт ( 80
или около того) для внешнего HTTP-доступа, и это означает, что ВОЗМОЖНО нарушение безопасности через службу Jenkins по HTTP для получения доступа.
Вот почему у нас есть www-data
пользователь и ему подобные, чтобы запускать разные сервисы. В случае, если их взломают с портов, которые они выставляют, они не смогут сделать многого:
- для них все доступно только для чтения.
- за исключением написания на
/var/log/THE_SERVICE
.
Таким образом, предоставление jenkins
пользователю доступа по SSH подвергает его поверхностной атаке (и это касается доступа по SSH root
!!).
Более того, если вы хотите выполнить rsync от имени другого пользователя ( root
, www-data
, и т. д.), вам придется скопировать свой открытый ключ SSH в эти учетные записи (хлопотно).
Хорошее решение.: Вам следует установитьКак можно меньше SSH-доступов к учетным записям пользователей(destuser
) чтоМОЖЕТ эскалироватьна нужную вам учетную запись «службы» ( jenkins
, root
, и т. д.).
решение2
У меня была похожая проблема с rsyncing как у другого пользователя. Решил ее запуском следующей команды:
rsync -avu -e "ssh -i my-key -o StrictHostKeyChecking=no -l user-i-want-to-use-in-rsync" ./local_dir remote_host:remote-host-dir
Обратите внимание, что, возможно, вам придется поиграться с ключами, чтобы иметь возможность запустить rsync от имени другого пользователя.
решение3
sudo -u jenkins -i rsync ...
сбез кавычек.
Эта -i
опция позволяет sudo
запустить команду в среде пользователя, включая ключи ssh .profile
и .bash_profile
т. д.
От sudo
мужчины:
-i, --login
Запустить оболочку, указанную записью базы данных паролей целевого пользователя, как оболочку входа. Это означает, что файлы ресурсов, специфичные для входа в систему, такие как
.profile
,.bash_profile
или.login
будут прочитаны оболочкой. Если указана команда, она передается оболочке для выполнения через-c
параметр оболочки. Если команда не указана, выполняется интерактивная оболочка.sudo
пытается перейти в домашний каталог этого пользователя перед запуском оболочки. Команда запускается в среде, похожей на ту, которую пользователь получит при входе в систему. Обратите внимание, что большинство оболочек ведут себя по-разному, когда указана команда, по сравнению с интерактивным сеансом; подробности см. в руководстве по оболочке. В разделе «Среда команд» в руководствеsudoers(5)
описывается, как-i
параметр влияет на среду, в которой выполняется команда, когда используется политика sudoers.
решение4
У меня похожая проблема.
Я решаю ее с помощью cron. Но cron должен работать с определенным пользователем (например: jenkins)
Просто сделайте задание cron:
$ crontab -u jenkins -e
затем заполните cron нужными вам данными.
*/2 * * * * sh /home/user/scp.sh 2>&1 >> /home/user/errmail.log