Вопрос или проблема
У меня есть проблема в том, что rsync не устанавливает UID и GID, как ожидалось, и у меня есть ощущение, что rsync
следует запускать от root
на целевой машине.
Я не могу войти как root
по SSH, так как это отключено по соображениям безопасности. Пользователь на целевой машине может использовать sudo
.
Можно ли использовать rsync
с sudo
?
На целевой машине
- Узнайте путь к
rsync
:which rsync
- Отредактируйте файл
/etc/sudoers
:sudo visudo
(см. также: должен ли я использовать visudo?) - Добавьте строку
<имя_пользователя> ALL=NOPASSWD:<путь к rsync>
, где имя_пользователя — это имя входа пользователя, который будет использовать rsync для входа. Этот пользователь должен уметь использоватьsudo
Затем, на исходной машине укажите, что следует использовать sudo rsync
:
rsync ... --rsync-path="sudo rsync" ...
Использование без NOPASSWD
на целевой машине приведет к сообщению
sudo: no tty present and no askpass program specified
Мое решение — использовать --rsync-path="sudo rsync"
, если запрашивается пароль, вы можете использовать обходной путь, подобный этому:
rsync -avz --stats --rsync-path="echo <SUDOPASS> | sudo -Sv && sudo rsync" [email protected]:/ .
Однако лучше не вводить свой пароль в командной строке, где он будет храниться в истории терминала. Вместо этого вы можете использовать read -s
, чтобы запросить пароль, не показывая его:
read -s -p "Удаленный пароль sudo: " SUDOPASS && rsync -avz --stats --rsync-path="echo $SUDOPASS | sudo -Sv && sudo rsync" [email protected]:/ .
(Примечание: -p
для запроса не поддерживается во всех оболочках (например, zsh), если у вас возникает ошибка, вы можете опустить ее или вывести сообщение перед вводом вместо этого)
Вы можете заставить удаленный sudo запрашивать у вас пароль через X-windows. Вот как это сделать:
- Убедитесь, что
ssh-askpass
установлен на удаленном хосте (и что вы используете X-windows, конечно) - Убедитесь, что это записано в
/etc/sudo.conf
:
# Путь к программе помощнику askpass
Path askpass /usr/bin/ssh-askpass
-
Добавьте эти параметры к rsync:
-e "ssh -X" --rsync-path="sudo -A rsync"
ssh -X
перенаправит вашу информацию и порт X-windows на вашу
удаленную сессиюsudo -A
заставит sudo использовать ssh-askpass для запроса пароля
Решения, которые предлагают изменять /etc/sudoers
или echo
пароль в канал, не вызывали у меня доверия.
Вместо этого я добился успеха, используя ответ, опубликованный здесь. Моя небольшая модификация добавляет sudo
к вызову rsync на второй строке, чтобы иметь неограниченные права на запись на локальной машине.
stty -echo; ssh myUser@REMOTE_SERVER "sudo -v"; stty echo
sudo rsync -avze ssh --rsync-path="sudo rsync" myUser@REMOTE_SERVER:/REMOTE_PATH/ /LOCAL_PATH/
-
Первая строка проверяет учётные данные sudo пользователя и гарантирует, что временная метка sudo обновляется на удаленном хосте, позволяя выполнять последующие команды sudo без запроса пароля в течение короткого времени.
-
Вторая строка выполняет операцию rsync с привилегиями sudo как на локальном, так и на удаленном хосте.
Если нет доступа к файлу sudoers,
просто создайте обертку для команды ssh.
ssh_sudo:
{
echo $PASSWORD;
cat - ;
} | ssh $* &
Сначала это передает пароль процессу sudo клиента ssh для запуска rsync на удаленной стороне. Далее весь ввод, поступающий от локального rsync, перенаправляется в ssh.
Наконец, вызывайте rsync, например, так:
PASSWORD=<SUDOPASS> rsync -avzue ssh_sudo --rsync-path "sudo -S rsync" SRC DST
Я думаю, что аспект безопасности здесь не так уж плох, вам просто нужно сохранить пароль локально в виде переменной окружения. Чтение его из файла также должно работать…
При попытке решить эту же проблему в модуле ansible
synchronize
я наткнулся на этот вопрос и хотел бы привлечь внимание к решению https://askubuntu.com/a/1263657/874618 от Симона Шмида. Не могу сделать апвоут или комментарий с помощью своей учетной записи (недостаточно очков репутации), поэтому я размещаю это как другой ответ:
Решение Симона не только является самым безопасным, поскольку не требует изменений в sudoers
и передает пароль с помощью окружения (так что он не появится в файлах истории и журналах), но оно также работает без изменений на целевой машине, что очень удобно, если вы хотите rsync
на множество свежих машин и не хотите перенастраивать их только для этой команды.
Поиграв с этим немного, я смог встроить команды оболочки, используемые для обертки ssh
на хосте, так что теперь можно использовать всего одну строку rsync
:
PASSWORD=<SUDOPASS> rsync -avzue '/bin/sh -c "{ echo $PASSWORD; cat - ; } | ssh $0 $* &"' --rsync-path "sudo -S rsync" SRC DST
Счастливой синхронизации 😉
Ответ или решение
Для решения проблемы с использованием rsync
с правами sudo
на удаленной машине, когда доступ к root
через SSH отключен, следуйте приведенным ниже рекомендациям. Я объясню, как настроить sudo
и выполнить команду rsync
с необходимыми правами на целевой машине.
Шаг 1: Настройка sudo
на целевой машине
-
Определите путь к
rsync
:
Выполните команду:which rsync
Это даст вам путь к исполняемому файлу
rsync
, который вам понадобится для привилегийsudo
. -
Измените файл
/etc/sudoers
:
Откройте файл с правами администратора с помощью команды:sudo visudo
Это важно, чтобы избежать синтаксических ошибок.
-
Добавьте строку в файл
sudoers
:
Включите в файл следующую строку:<имя_пользователя> ALL=(ALL) NOPASSWD:<путь_к_rsync>
Замените
<имя_пользователя>
на имя пользователя, под которым будет выполнятьсяrsync
, и<путь_к_rsync>
на результат первой команды. Это позволяет пользователю запускатьrsync
от имениroot
без ввода пароля.
Шаг 2: Запуск rsync
с использованием sudo
На источнике выполните следующую команду rsync
, указав использование sudo
для команды rsync
на удаленной машине:
rsync ... --rsync-path="sudo rsync" ...
Это укажет rsync
на использование sudo
при выполнении на целевой машине, что позволит корректно установить UID и GID файлов.
Шаг 3: Работа с паролем sudo
При отсутствии NOPASSWD
в /etc/sudoers
, вы можете сталкиваться с ошибками, связанными с отсутствием терминала для запроса пароля. Вот несколько возможных способов обойти эту проблему:
-
Указать пароль непосредственно (не рекомендуется):
rsync ... --rsync-path="echo <SUDOPASS> | sudo -Sv && sudo rsync" ...
Но это небезопасно, так как пароль может остаться в истории терминала.
-
Использовать скрытый ввод пароля:
read -s -p "Пароль для sudo: " SUDOPASS && rsync ... --rsync-path="echo $SUDOPASS | sudo -S rsync" ...
Здесь
-s
гарантирует, что вводимый пароль не будет отображаться.
Шаг 4: Поддержка спрашивания пароля через X-windows
Если у вас есть доступ к графическому интерфейсу:
- Убедитесь, что
ssh-askpass
установлен на удаленной машине и, что вы используете X-windows. - В файле
/etc/sudo.conf
должно быть указано:# Путь к программе-спрашивателю пароля Path askpass /usr/bin/ssh-askpass
- Запустите
rsync
с параметрами:rsync -e "ssh -X" --rsync-path="sudo -A rsync" ...
Альтернативный способ: использование оболочки-обертки
Если вы не имеете доступа к редактированию sudoers
, создайте обертку для ssh
:
ssh_sudo() {
{
echo $PASSWORD;
cat -;
} | ssh "$@";
}
Затем выполните rsync
с использованием этой обертки:
PASSWORD=<SUDOPASS> rsync -avzue ssh_sudo --rsync-path="sudo -S rsync" SRC DST
Заключение
При следовании этим инструкциям вы сможете использовать rsync
с sudo
на целевой машине, что даст вам возможность управлять правами доступа к файлам корректно. Учтите, что передача паролей через командную строку не является наилучшей практикой, и всегда старайтесь избегать хранения паролей в истории терминала.