Использование rsync с sudo на целевой машине

Вопрос или проблема

У меня есть проблема в том, что rsync не устанавливает UID и GID, как ожидалось, и у меня есть ощущение, что rsync следует запускать от root на целевой машине.

Я не могу войти как root по SSH, так как это отключено по соображениям безопасности. Пользователь на целевой машине может использовать sudo.

Можно ли использовать rsync с sudo?

На целевой машине

  1. Узнайте путь к rsync: which rsync
  2. Отредактируйте файл /etc/sudoers: sudo visudo (см. также: должен ли я использовать visudo?)
  3. Добавьте строку <имя_пользователя> 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. Вот как это сделать:

  1. Убедитесь, что ssh-askpass установлен на удаленном хосте (и что вы используете X-windows, конечно)
  2. Убедитесь, что это записано в /etc/sudo.conf:
# Путь к программе помощнику askpass
Path askpass /usr/bin/ssh-askpass
  1. Добавьте эти параметры к 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 на целевой машине

  1. Определите путь к rsync:
    Выполните команду:

    which rsync

    Это даст вам путь к исполняемому файлу rsync, который вам понадобится для привилегий sudo.

  2. Измените файл /etc/sudoers:
    Откройте файл с правами администратора с помощью команды:

    sudo visudo

    Это важно, чтобы избежать синтаксических ошибок.

  3. Добавьте строку в файл 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

Если у вас есть доступ к графическому интерфейсу:

  1. Убедитесь, что ssh-askpass установлен на удаленной машине и, что вы используете X-windows.
  2. В файле /etc/sudo.conf должно быть указано:
    # Путь к программе-спрашивателю пароля
    Path askpass /usr/bin/ssh-askpass
  3. Запустите 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 на целевой машине, что даст вам возможность управлять правами доступа к файлам корректно. Учтите, что передача паролей через командную строку не является наилучшей практикой, и всегда старайтесь избегать хранения паролей в истории терминала.

Оцените материал
Добавить комментарий

Капча загружается...