2

Инструмент WinSCP может выполнить sudo на удаленной машине, чтобы выполнить scp от имени пользователя sudo. Это заставляет меня думать, что это должно быть возможно и с версией scp командной строки.

В тайне, как WinSCP выполняет это?

Я не хочу работать с решением с помощью пользовательской промежуточной директории. Файлы могут быть такими большими, что я должен публиковать их напрямую, используя пользователя sudo . В результате файл скопирован, но в мой локальный каталог, а не в каталог sudo.

Одним из решений может быть ручная передача по ssh:

tar zcvf -  MyBackups | ssh user@server "cat > /path/to/backup/foo.tgz"

Я думаю, что можно настроить sudo следующим образом:

cat local.txt | ssh user@server "sudo -u sudouser cat > ~/remote_file"

Единственная проблема заключается в том, что, делая это таким образом, я могу решить много проблем, которые были реализованы с использованием base scp . По этой и другим причинам я также не хочу использовать это решение.

Как я могу позволить scp обрабатывать прямое копирование на удаленный компьютер с помощью sudo чтобы изменить пользователя, чтобы я получил доступ к его привилегиям.

2 ответа2

1

Scp работает, устанавливая ssh-соединение с удаленным сервером, а затем использует это соединение для выполнения другой команды scp в удаленной системе. Локальный экземпляр scp и удаленный экземпляр обмениваются данными по каналу ssh для отправки или получения файлов.

В частности, OpenSSH scp создает командную строку scp для запуска в удаленной системе. Затем он запускает ssh для запуска этой команды. Вызываемая команда ssh является эквивалентом этого:

/path/to/ssh [ssh options...] "scp [scp options...]"
  • /path/to/ssh - это обычно встроенный путь к программе ssh.
  • [ssh options ...] - это одна или несколько опций для программы ssh.
  • scp [scp options ...] - это единственный аргумент, содержащий команду scp и ее аргументы для запуска в удаленной системе.

OpenSSH scp не предоставляет много возможностей для изменения формы удаленной команды scp. Нет способа заставить его вызвать что-то кроме "scp" или вставить что-то вроде "sudo" перед частью "scp".

Как вы заметили, у scp есть возможность вызывать какую-то другую программу, а не ssh. Кто-то, кто знал, как написать программу-оболочку ssh и заставить scp вызывать оболочку вместо непосредственного вызова ssh. Оболочка должна будет проверить свои аргументы командной строки, чтобы найти тот, который содержит команду scp, изменить команду по своему желанию, а затем вызвать ssh с измененными аргументами командной строки.

0

Как работает SCP

Внутренняя работа scp зависит от двух недокументированных форм scp - scp -f и scp -t . В основном это удаленные серверы, которые прослушивают стандартный ввод и генерируют данные через стандартный вывод. Эти процессы используют протокол, аналогичный тому, что делал бы sftp. Более подробную информацию можно найти в блоге Oracle .

Когда запускается scp , он сначала запускает сессию ssh для запуска scp -t или scp -f . Затем ваш локальный процесс scp будет связываться с удаленным процессом scp через stdout и stdin, переданные по каналу ssh (полностью зашифрованные), и будет служить stdin/stdout для вашего удаленного сеанса scp .

Как настроить

Команда scp предоставляет параметр -s который позволяет вам настроить программу, используемую для настройки удаленного сеанса scp . Ожидается, что он обработает все параметры, типичные для ssh . Чтобы помочь отладке, как это может выглядеть, мы устанавливаем фиктивную программу, которая просто выводит параметры:

/tmp/scp-dump.sh:

echo $0 $*

Мы выполним это следующим образом:

scp -S /tmp/scp-dump.sh /tmp/dump.txt me@server.com:/tmp

И соответственно мы получаем следующий вывод:

/home/me/dump.sh \
    -x -oForwardAgent=no \
    -oPermitLocalCommand=no \
    -oClearAllForwardings=yes \
    -l me -- server.com scp -t /tmp

Для удобства чтения добавлены разрывы строк с обратной косой чертой.

Это дает нам возможность изменить параметры и команды, прежде чем мы отправим их в команду ssh .

Настройка sudo

Теперь мы можем написать программу для изменения параметров по мере необходимости, запустить ssh и использовать измененную форму для запуска scp -t . Мы будем в основном собирать параметры, перехватывать те, которые мы хотим использовать внутри, только добавлять дополнительные и вносить изменения.

/tmp/scp-sudo.sh:

add_ssh_option() {
  local option
  if [ $# = 2 ]; then
    option="$1 \"$2\""
  else
    option="$1"
  fi
  if [ -z "${ssh_options}" ]; then
    ssh_options=${option}
  else
    ssh_options="${ssh_options} ${option}"
  fi
}

parse_options() {
  ssh_options=
  local option
  while [ $# > 0 ] ; do
    case $1 in
      -oSudoUser=* )
        SSH_SUDO_USER=${option##*=}
        shift
        ;;
      -l ) ssh_user=$2 ; shift 2 ;;
      -i ) add_ssh_option "$1" "$2" ; shift 2 ;;
      -- ) shift ; break ;;
      -* ) add_ssh_option "${1}" ; shift ;;
      *  ) break ;;
    esac
  done
  ssh_host=$1
  shift
  ssh_command="$*"
}

parse_options "$@"
# To avoid intererence with Standard-In, we change this to
# Strict:
add_ssh_option "-oStrictHostKeyChecking=yes"

if [ -z "${SSH_SUDO_USER}" ]; then
  # As before without sudo
  cat | ssh $ssh_options -l $ssh_user $ssh_host $ssh_command
  exit $?
else
  # Send standard-in to the customized "scp -t" sink.
  cat | ssh $ssh_options -l $ssh_user $ssh_host sudo -i -u ${SSH_SUDO_USER} $ssh_command
  exit $?
fi

Теперь мы можем использовать модифицированную форму scp:

scp -oSudoUser=other \
    -i /tmp/me-id_rsa \
    /tmp/scp-sudo.sh \
    /tmp/dump.txt \
    me@server.com:/tmp

Это прекрасно работает для отправки файла на удаленный. Однако, когда я получаю удаленный файл, он как-то зависает. Когда я прерываю сеанс (control-c), я вижу, что передача прошла успешно, но у меня есть какой-то дополнительный файл с именем "0". Интересно, кто-нибудь может мне помочь с этим?

Лучший вариант: sftp

Однако sftp намного лучше.

  1. у него есть опция -S позволяющая установить всю командную строку ssh. У меня были проблемы с выяснением и заставить его работать. Я подозреваю, что я не понимаю, как правильно связать stdin/stdout из оболочки shell-ssh.
  2. он имеет опцию -s (нижний регистр) - позволяет установить только подкоманду, отвечающую только за настройку удаленного сервера. Я нашел это проще, чтобы заставить его работать.
  3. Вы можете установить удаленный путь, права доступа к удаленным файлам, сделать как put/get, и так далее в соответствии с man-страницами для sftp.

В этом случае мы просто

sftp -s "sudo -u sudo-user -- /usr/libexec/openssh/sftp-server" me@server.com

Это дало мне счастливую подсказку " sftp> "

Обратите внимание, что подпрограмма иногда находится по разным путям, например /usr/libexec/openssh/sftp-server . Я хотел бы предложить синтаксический анализ строки " Subsystem sftp " из файла /etc/ssh/sshd_conf ?

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .