Инструмент WinSCP способен выполнить sudo
на удаленной машине, чтобы выполнить как пользователь sudo. Это наводит меня на мысль, что это должно быть возможно и scp
с версией командной строки .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"
Единственная проблема в том, что, делая это таким образом, у меня есть много бремени для решения, которое было реализовано с использованием базы scp
. По этой и другим причинам я также не хочу использовать это решение.
Как я могу разрешить scp
обработку прямого копирования на удаленный компьютер с помощью sudo
изменения пользователя, чтобы получить доступ к его привилегиям?
решение1
Scp работает, создавая ssh-подключение к удаленному серверу, а затем используя это подключение для выполнения другой scp
команды на удаленной системе. Локальный экземпляр scp и удаленный экземпляр взаимодействуют через ssh-ссылку для отправки или получения файлов.
OpenSSH scp, в частности, создает строку команды scp для запуска на удаленной системе. Затем он запускает ssh для запуска этой команды. Окончательная вызываемая команда ssh эквивалентна следующей:
/path/to/ssh [ssh options...] "scp [scp options...]"
- /path/to/ssh — это обычно встроенный путь к программе ssh.
- [параметры ssh...] — один или несколько параметров программы ssh.
- «scp [параметры scp...]» — это один аргумент, содержащий команду scp и ее аргументы для запуска на удаленной системе.
OpenSSH scp не предоставляет много возможностей для изменения формы удаленной команды scp. Нет способа заставить ее вызывать что-то, кроме "scp", или вставить что-то вроде "sudo" перед частью "scp".
Как вы заметили, scp имеет возможность вызывать какую-то другую программу вместо ssh. Кто-то, кто знает, как это сделать, может написать программу-обертку ssh и заставить scp вызывать обертку вместо прямого вызова ssh. Обертке придется проверить свои аргументы командной строки, чтобы найти тот, который содержит команду scp, изменить команду по своему усмотрению, а затем вызвать ssh с измененными аргументами командной строки.
решение2
Как работает SCP
Внутреннее функционирование scp
зависит от двух недокументированных форм scp
, а именно scp -f
и scp -t
. По сути, это удаленные серверы, слушающие stdin и генерирующие данные через stdout. Эти процессы используют протокол, аналогичный тому, что делает sftp. Более подробную информацию можно найти наБлог Оракула.
При 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 [email protected]:/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 \
[email protected]:/tmp
Это отлично работает для отправки файла на удаленный компьютер. Однако, когда я извлекаю удаленный файл, он каким-то образом зависает. Когда я прерываю сеанс (control-c), я вижу, что передача прошла успешно, но у меня каким-то образом появляется дополнительный файл с именем "0". Интересно, может ли кто-нибудь мне с этим помочь?
Лучший вариант: sftp
Однако sftp гораздо лучше.
- у него есть
-S
опция - позволяющая задать всю командную строку ssh. У меня возникли проблемы с тем, чтобы разобраться и заставить ее работать. Подозреваю, что я не понимаю, как правильно привязать stdin/stdout из оболочки shell-ssh. - у него есть
-s
опция (в нижнем регистре) - позволяющая задать только подкоманду, отвечающую за настройку только удаленного сервера. Мне показалось, что так проще заставить это работать. - Вы можете задать удаленный путь, права доступа к удаленным файлам, выполнить операции put/get и т. д. в соответствии с руководствами по sftp.
В этом случае мы просто
sftp -s "sudo -u sudo-user -- /usr/libexec/openssh/sftp-server" [email protected]
Это дало мне счастливую sftp>
подсказку " "
Обратите внимание, что подпрограмма иногда располагается по разным путям, например /usr/libexec/openssh/sftp-server
. Я бы предложил выполнить парсинг из Subsystem sftp
строки " " внутри /etc/ssh/sshd_conf
файла?