Как скопировать файлы, требующие доступа root с помощью scp?

Вам нужно ввести эти строки в терминал, который вы можете открыть, нажав CtrlAltT.

Вы также можете вставить их с помощью Ctrl Shift Alt [!d2 ].

То, что делает команда, - это вызов исполняемого файла TICKR два раза. Амперсанд & позволит вам сделать это - все в одной строке.

Если вы хотите, чтобы эти экземпляры выдержали после того, как окно терминала было закрыто, прикрепите их к nohup:

[F1]
1
задан 31 October 2012 в 15:35

9 ответов

Другим методом является копирование с использованием tar + ssh вместо scp:

tar -c -C ./my/local/dir \
  | ssh dimitris@myserver.com "sudo tar -x --no-same-owner -C /var/www"
26
ответ дан 25 May 2018 в 04:56
  • 1
    Это лучший способ сделать это. – mttdbrd 30 March 2015 в 23:31
  • 2
    Я не могу заставить этот метод работать успешно. Как написано, я получаю sudo: sorry, you must have a tty to run sudo. Если я добавляю " -t " для выделения TTY, я получаю Pseudo-terminal will not be allocated because stdin is not a terminal.. Я не вижу, как это работает без пароля. – IBBoard 26 October 2015 в 20:35
  • 3
    @IBBoard: попробуйте решение здесь , используя ssh -t: ssh -t dimitris@myserver.com "sudo tar -x --no-same-owner -C /var/www" – Alexander Bird 18 August 2016 в 18:21
  • 4
    @AlexanderBird Хотя это работает во многих случаях, я не уверен, что он работает здесь, потому что мы пытаемся подключить tarball через соединение SSH. См. serverfault.com/questions/14389/… – IBBoard 19 August 2016 в 22:36

Вы также можете использовать ansible для выполнения этого.

Скопировать на удаленный хост с помощью модуля copy ansible:

ansible -i HOST, -b -m copy -a "src=SRC_FILEPATH dest=DEST_FILEPATH" all

Извлечь из удаленного хоста с помощью ansible's copy module :

ansible -i HOST, -b -m fetch -a "src=SRC_FILEPATH dest=DEST_FILEPATH flat=yes" all

ПРИМЕЧАНИЕ:

Запятая в синтаксисе -i HOST, не является опечаткой. Это способ использования без необходимости файла инвентаря. -b заставляет действия на сервере выполняться как root. -b расширяется до --become, а по умолчанию --become-user является root, а по умолчанию --become-method является sudo. flat=yes копирует только файл, не копирует весь удаленный путь, ведущий к файлу. Использование подстановочных знаков в пути к файлам не поддерживается этими незаменимыми модулями. Копирование каталога поддерживается модулем copy, но не модулем fetch.

Конкретный вызов для этого вопроса

Вот пример, который является конкретным и полностью указанным, предполагая, что каталог на вашем локальном хосте, содержащий файлы, которые будут распространены, sourcedir, и что имя удаленной цели - hostname:

cd sourcedir && \
ansible \
   --inventory-file hostname, \ 
   --become \
   --become-method sudo \
   --become-user root \
   --module-name copy \
   --args "src=. dest=/var/www/" \
   all

С кратким вызовом:

cd sourcedir && \
ansible -i hostname, -b -m copy -a "src=. dest=/var/www/" all

PS, я понимаю, что высказывание «просто установите этот сказочный инструмент» является своего рода тон-глухой ответ. Но я считаю, что для администрирования удаленных серверов очень удобно, поэтому установка его, несомненно, принесет вам другие преимущества, помимо развертывания файлов.

19
ответ дан 25 May 2018 в 04:56
  • 1
    Мне нравится этот ответ, но я рекомендую вам направить его по заданному вопросу в сравнении с более обобщенным комментарием перед повышением. что-то вроде ansible -i "hostname," all -u user --become -m copy -a ... – Mike D 16 February 2016 в 23:30
  • 2
    @MikeD: как выглядят эти изменения? – erik.weathers 19 February 2016 в 07:08
  • 3
    лучше, но он терпит неудачу, --module-name - это правильное имя коммутатора. и поскольку hostname является единственным узлом в вашем инвентаре, вы можете просто сказать all – Mike D 20 February 2016 в 00:40
  • 4
    Будет ли что-то вроде -i 'host,' корректным синтаксисом? Я считаю, что при чтении команды легко потерять знаки препинания. (Для читателя я имею в виду, если не оболочку.) – mwfearnley 10 June 2016 в 18:37
  • 5
    @mwfearnley: конечно, оболочка будет обрабатывать -i 'host,' и такую ​​же, как -i host, или -i "host,". В общем, я предпочитаю, чтобы эти призывы были как можно короче, чтобы они не были сложными, но вы должны быть свободны, чтобы сделать их такими подробными и ясными, насколько вам кажется необходимым для ясности. – erik.weathers 15 June 2016 в 06:00

Когда вы запустите sudo su, любые созданные вами файлы будут принадлежать root, но по умолчанию невозможно напрямую войти в систему с правами root с помощью ssh или scp. Также невозможно использовать sudo с scp, поэтому файлы не могут использоваться. Исправьте это, заявив право собственности на ваши файлы:

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

sudo chown -R dimitri:dimitri /home/dimitri

С этого момента, как упоминалось в других ответах, «Ubuntu» - использовать sudo, а не root-логины. Это полезная парадигма с большими преимуществами безопасности.

12
ответ дан 25 May 2018 в 04:56
  • 1
    Я использую это решение любым способом, но что, если бы я мог получить полный доступ к моей собственной файловой системе, я не хочу набирать sudo chow ... для каждого отдельного каталога: S – Dimitris Sapikas 30 October 2012 в 15:47
  • 2
    Изменение права собственности на все системные файлы для удобства пользователя крайне не рекомендуется. Это позволяет любой ошибке в пользовательском пространстве, с которой вы можете столкнуться, серьезно подорвать безопасность вашей системы. Гораздо лучше изменить права собственности на файлы, которые нужно изменить или обновить с помощью SCP, но оставить все остальное, принадлежащее root (как и предполагалось). Тем не менее, -R в chown сообщает, что он меняет права собственности на этот каталог, а все файлы и каталоги детей - рекурсивно ... поэтому вы можете делать все, что захотите. – Bailey S 30 October 2012 в 23:48
  • 3
    hmm .... это кажется работаю хорошо, спасибо! извините, я не могу повышать (система не позволяет мне делать ...) – Dimitris Sapikas 31 October 2012 в 01:05

Лучше всего использовать rsync (Cygwin / cwRsync в Windows) через SSH?

Например, чтобы загрузить файлы с владельцем www-data:

rsync -a --rsync-path="sudo -u www-data rsync" path_to_local_data/ login@srv01.example.com:/var/www

В вашем случае, если вам нужны привилегии root, команда будет выглядеть так:

rsync -a --rsync-path="sudo rsync" path_to_local_data/ login@srv01.example.com:/var/www

Смотрите: scp на удаленный сервер с sudo.

7
ответ дан 25 May 2018 в 04:56

Если вы используете инструменты OpenSSH вместо PuTTY, вы можете выполнить это, инициировав передачу файла scp на сервере с помощью sudo. Убедитесь, что на вашем локальном компьютере установлен демон sshd. С помощью ssh -R вы можете дать серверу возможность связаться с вашей машиной.

На вашем компьютере:

ssh -R 11111:localhost:22 REMOTE_USERNAME@SERVERNAME

В дополнение к регистрации на сервере, это будет перенаправлено каждое соединение, сделанное на порте сервера 11111, на порт вашего компьютера 22: прослушивает порт, на который вы слушаете sshd.

На сервере запустите передачу файлов следующим образом:

cd /var/www/
sudo scp -P 11111 -r LOCAL_USERNAME@localhost:FOLDERNAME .
3
ответ дан 25 May 2018 в 04:56

Быстро:

ssh user@server "sudo cat /etc/dir/file" > /home/user/file
3
ответ дан 25 May 2018 в 04:56
  • 1
    Этот ответ недооценен. Он прост, чист, читает или записывает корневой файл с помощью одной атомной операции и не требует ничего, что еще не гарантировано, если вы используете scp. Главный недостаток заключается в том, что он не копирует разрешения. Если вы хотите это, решение tar лучше. Это мощный метод, особенно в сочетании с магией xargs / bash для прохождения по траекториям. – markgo2k 16 May 2018 в 21:12

Вы можете использовать написанный мной сценарий, вдохновленный этой темой:

touch /tmp/justtest && scpassudo /tmp/justtest remoteuser@ssh.superserver.com:/tmp/

, но для этого требуется какой-то сумасшедший материал (который автоматически создается скриптом)

сервер, к которому отправляется этот файл, больше не будет запрашивать пароль при установлении подключения ssh к исходному компьютеру из-за необходимости отсутствия приглашения sudo на сервере, sudo больше не будет запрашивать пароль на удаленной машине, для пользователя

Здесь идет скрипт:

interface=wlan0
if [[ $# -ge 3 ]]; then interface=$3; fi
thisIP=$(ifconfig | grep $interface -b1 | tail -n1 | egrep -o '[0-9.]{4,}' -m1 | head -n 1)
thisUser=$(whoami)
localFilePath=/tmp/justfortest
destIP=192.168.0.2
destUser=silesia
#dest 
#destFolderOnRemoteMachine=/opt/glassfish/glassfish/
#destFolderOnRemoteMachine=/tmp/

if [[ $# -eq 0 ]]; then 
echo -e "Send file to remote server to locatoin where root permision is needed.\n\tusage: $0 local_filename [username@](ip|host):(remote_folder/|remote_filename) [optionalInterface=wlan0]"
echo -e "Example: \n\ttouch /tmp/justtest &&\n\t $0 /tmp/justtest remoteuser@ssh.superserver.com:/tmp/ "
exit 1
fi

localFilePath=$1

test -e $localFilePath 

destString=$2
usernameAndHost=$(echo $destString | cut -f1 -d':')

if [[ "$usernameAndHost" == *"@"* ]]; then
destUser=$(echo $usernameAndHost | cut -f1 -d'@')
destIP=$(echo $usernameAndHost | cut -f2 -d'@')
else
destIP=$usernameAndHost
destUser=$thisUser
fi

destFolderOnRemoteMachine=$(echo $destString | cut -f2 -d':')

set -e #stop script if there is even single error

echo 'First step: we need to be able to execute scp without any user interaction'
echo 'generating public key on machine, which will receive file'
ssh $destUser@$destIP 'test -e ~/.ssh/id_rsa.pub -a -e ~/.ssh/id_rsa || ssh-keygen -t rsa'
echo 'Done'

echo 'Second step: download public key from remote machine to this machine so this machine allows remote machine (this one receiveing file) to login without asking for password'

key=$(ssh $destUser@$destIP 'cat ~/.ssh/id_rsa.pub')
if ! grep "$key" ~/.ssh/authorized_keys; then
echo $key >> ~/.ssh/authorized_keys
echo 'Added key to authorized hosts'
else
echo "Key already exists in authorized keys"
fi

echo "We will want to execute sudo command remotely, which means turning off asking for password"
echo 'This can be done by this tutorial http://stackoverflow.com/a/10310407/781312'
echo 'This you have to do manually: '
echo -e "execute in new terminal: \n\tssh $destUser:$destIP\nPress enter when ready"
read 
echo 'run there sudo visudo'
read
echo 'change '
echo '    %sudo   ALL=(ALL:ALL) ALL'
echo 'to'
echo '    %sudo   ALL=(ALL:ALL) NOPASSWD: ALL'
echo "After this step you will be done."
read

listOfFiles=$(ssh $destUser@$destIP "sudo ls -a")

if [[ "$listOfFiles" != "" ]]; then 
echo "Sending by executing command, in fact, receiving, file on remote machine"
echo 'Note that this command (due to " instead of '', see man bash | less -p''quotes'') is filled with values from local machine'
echo -e "Executing \n\t""identy=~/.ssh/id_rsa; sudo scp -i \$identy $(whoami)@$thisIP:$(readlink -f $localFilePath) $destFolderOnRemoteMachine"" \non remote machine"
ssh $destUser@$destIP "identy=~/.ssh/id_rsa; sudo scp -i \$identy $(whoami)@$thisIP:$(readlink -f $localFilePath) $destFolderOnRemoteMachine"
ssh $destUser@$destIP "ls ${destFolderOnRemoteMachine%\\\\n}/$(basename $localFilePath)"
if [[ ! "$?" -eq 0 ]]; then echo "errror in validating"; else echo -e "SUCCESS! Successfully sent\n\t$localFilePath \nto \n\t$destString\nFind more at http://arzoxadi.tk"; fi
else
echo "something went wrong with executing sudo on remote host, failure"

fi
ENDOFSCRIPT
) | sudo tee /usr/bin/scpassudo && chmod +x /usr/bin/scpassudo
1
ответ дан 25 May 2018 в 04:56
  • 1
    @Braiam да, конечно, извините за ссылку, сценарий довольно длинный, и это было причиной :) – test30 22 November 2013 в 07:42

Вы можете комбинировать ssh, sudo и eg tar для передачи файлов между серверами без возможности входа в систему с правами root и не имеющих доступа к файлам с вашим пользователем. Это немного затруднительно, поэтому я написал сценарий, чтобы помочь этому. Вы можете найти скрипт здесь: https://github.com/sigmunau/sudoscp

или здесь:

#! /bin/bash res=0 from=$1 to=$2 shift shift files="$@" if test -z "$from" -o -z "$to" -o -z "$files" then echo "Usage: $0 (file)*" echo "example: $0 server1 server2 /usr/bin/myapp" exit 1 fi read -s -p "Enter Password: " sudopassword echo "" temp1=$(mktemp) temp2=$(mktemp) (echo "$sudopassword";echo "$sudopassword"|ssh $from sudo -S tar c -P -C / $files 2>$temp1)|ssh $to sudo -S tar x -v -P -C / 2>$temp2 sourceres=${PIPESTATUS[0]} if [ $? -ne 0 -o $sourceres -ne 0 ] then echo "Failure!" >&2 echo "$from output:" >&2 cat $temp1 >&2 echo "" >&2 echo "$to output:" >&2 cat $temp2 >&2 res=1 fi rm $temp1 $temp2 exit $res
1
ответ дан 25 May 2018 в 04:56
  • 1
    Добро пожаловать в Ask Ubuntu. Не могли бы вы включить сценарий в свой ответ? Я знаю, что это маловероятно, но если репозиторий github был когда-либо удален или URL-адрес изменился, то ответ был бы недействительным. Лучше всего включить скрипт и оставить репозиторий github в качестве источника. – Michael Lindman 1 July 2015 в 18:25

Вот измененная версия ответа Вилли Уилера, которая передает файл (ы) через tar, но также поддерживает передачу пароля sudo на удаленном хосте.

(stty -echo; read passwd; stty echo; echo $passwd; tar -cz foo.*) \
  | ssh remote_host "sudo -S bash -c \"tar -C /var/www/ -xz; echo\""

Немного лишней магии здесь это опция -S для sudo. На странице sudo man:

-S, --stdin Введите запрос стандартной ошибки и прочитайте пароль со стандартного ввода вместо использования терминального устройства. За паролем должен следовать символ новой строки.

Теперь мы действительно хотим, чтобы выход tar включался в ssh и перенаправлял stdin ssh в stdout tar, удаляя любой способ передать пароль в sudo из интерактивного терминала. (Мы можем использовать функцию ASKPASS от sudo на удаленном конце, но это еще одна история.) Мы можем получить пароль в sudo, хотя, предварительно захватив его и добавив его в выход tar, выполнив эти операции в подоболочке и выполнив вывод подоболочка в ssh. Это также имеет дополнительное преимущество, не оставляя переменную среды, содержащую наш пароль, свисающий в нашей интерактивной оболочке.

Вы заметите, что я не выполнил 'read' с параметром -p для печати приглашения. Это связано с тем, что запрос пароля от sudo удобно передавать обратно в stderr нашей интерактивной оболочки через ssh. Вы можете задаться вопросом: «Как выполняется sudo, поскольку он работает внутри ssh справа от нашей трубы?» Когда мы выполняем несколько команд и обрабатываем вывод одного в другое, родительская оболочка (в этом случае интерактивная оболочка) выполняет каждую команду в последовательности сразу после выполнения предыдущего. Поскольку каждая команда за трубой выполняется, родительская оболочка присоединяет (перенаправляет) stdout левой стороны к stdin правой части. Выход затем становится входным, когда он проходит через процессы. Мы можем увидеть это в действии, выполнив всю команду и опираясь на группу процессов (Ctrl-z), прежде чем вводить наш пароль, а затем просматриваем дерево процессов.

$ (stty -echo; read passwd; stty echo; echo $passwd; tar -cz foo.*) | ssh 
remote_host "sudo -S bash -c \"tar -C /var/www/ -xz; echo\""
[sudo] password for bruce: 
[1]+  Stopped                 ( stty -echo; read passwd; stty echo; echo 
$passwd; tar -cz foo.* ) | ssh remote_host "sudo -S bash -c \"tar -C 
/var/www/ -xz; echo\""

$ pstree -lap $$
bash,7168
  ├─bash,7969
  ├─pstree,7972 -lap 7168
  └─ssh,7970 remote_host sudo -S bash -c "tar -C /var/www/ -xz; echo"`

Наша интерактивная оболочка - PID 7168, наша подоболочка - PID 7969, а наш процесс ssh - PID 7970.

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

Примечание. Я просто добавил запись файла хоста для «remote_Host» на свой локальный компьютер для демонстрации.

0
ответ дан 25 May 2018 в 04:56

Другие вопросы по тегам:

Похожие вопросы: