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

У меня есть сервер Ubuntu, к которому я подключаюсь по SSH.

Мне нужно загрузить файлы со своего устройства в /var/www/ на сервере, файлы в /var/www/ принадлежат root.

Используя PuTTY, после входа в систему мне нужно сначала набрать sudo su и мой пароль, чтобы иметь возможность изменять файлы в /var/www/.

Но когда я копирую файлы с помощью WinSCP, я не могу создать / изменить файлы в /var/www/, потому что у пользователя, к которому я подключаюсь, нет прав на файлы в /var/www/, и я не могу сказать, sudo su как и в случае ssh-сессии.

Знаете ли вы, как я мог справиться с этим?

Если бы я работал на своей локальной машине, я бы позвонил gksudo nautilus, но в этом случае у меня есть только терминальный доступ к машине.

172
задан 31 October 2012 в 13:35

11 ответов

Вы правы, при работе с scp нет sudo. Обходной путь - использовать scp для загрузки файлов в каталог, где у вашего пользователя есть права на создание файлов, затем войти в систему через ssh и использовать sudo для перемещения / копирования файлов в их конечное место назначения.

scp -r folder/ user@server.tld:/some/folder/you/dont/need/sudo
ssh user@server.tld
 $ sudo mv /some/folder /some/folder/requiring/perms 
# YOU MAY NEED TO CHANGE THE OWNER like:
# sudo chown -R user:user folder

Другим решением было бы изменить разрешения / владельца каталогов, в которые вы загружаете файлы, чтобы ваш непривилегированный пользователь мог писать в эти каталоги.

Как правило, работа в учетной записи root должна быть исключением, а не правилом - то, как вы формулируете свой вопрос, заставляет меня думать, что, возможно, вы немного злоупотребляете им, что, в свою очередь, приводит к проблемам с разрешениями - при нормальных условиях. обстоятельства, когда вам не нужны привилегии супер-администратора для доступа к вашим собственным файлам.

Технически, вы можете настроить Ubuntu для разрешения удаленного входа непосредственно как root, но эта функция по какой-то причине отключена, поэтому я настоятельно рекомендую вам не делать этого.

0
ответ дан 31 October 2012 в 13:35

Можно также использовать ansible выполнять это.

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

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

Выборка из удаленного хоста с помощью ansible's fetch модуль:

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

Примечание:

  • Запятая в -i HOST, синтаксис не является опечаткой. Это - способ использовать ansible, не нуждаясь в файле материально-технических ресурсов.
  • -b заставляет действия с сервером быть сделанными как корень. -b расширяется до --become, и значение по умолчанию --become-user корень, со значением по умолчанию --become-method быть sudo.
  • flat=yes копии просто файл, не копирует целое удаленное продвижение пути в файл
  • Используя подстановочные знаки в путях к файлам не поддерживается этими ansible модулями.
  • Копирование каталога поддерживается 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

P.S., я понимаю, что высказывание "просто устанавливает этот невероятный инструмент", своего рода ответ без слуха. Но я нашел, что ansible супер полезен для администрирования удаленных серверов, так установки, это, конечно, даст Вам другие преимущества вне развертывающихся файлов.

26
ответ дан 31 October 2012 в 13:35

Другой способ - копировать, используя tar + ssh вместо scp:

tar -c -C ./my/local/dir \
  | ssh dimitris@myserver.com "sudo tar -x --no-same-owner -C /var/www"
0
ответ дан 31 October 2012 в 13:35

Быстрый способ

С сервера на локальный компьютер:

ssh user@server "sudo cat /etc/dir/file" > /home/user/file

С локального компьютера на сервер:

cat /home/user/file | ssh user@server "sudo tee -a /etc/dir/file"
0
ответ дан 31 October 2012 в 13:35

Может быть, лучший способ - использовать 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

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

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

См .: scp на удаленный сервер с sudo [ 114].

0
ответ дан 31 October 2012 в 13:35

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

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

sudo chown -R dimitri:dimitri /home/dimitri

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

0
ответ дан 31 October 2012 в 13:35

Если вы используете инструменты 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 .
0
ответ дан 31 October 2012 в 13:35

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

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

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

  1. сервер, в который отправляется файл, больше не будет просить пароль при установлении соединения SSH к исходному компьютеру
  2. из-за necessarility отсутствия подсказки 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
ответ дан 31 October 2012 в 13:35

Можно объединить ssh, sudo и например, tar для передачи файлов между серверами не имея возможности для входа в систему как корень и не наличие разрешения получить доступ к файлам с пользователем. Это немного трудно, таким образом, я записал сценарий для помощи этому. Можно найти сценарий здесь: 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
ответ дан 31 October 2012 в 13:35

Вот измененная версия ответа Willie Wheeler, который передает файл (файлы) через 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 страницы справочника:

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

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

Вы заметите, что я не выполнил 'чтение' с-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
ответ дан 31 October 2012 в 13:35

Я знаю, что вопрос старый, но времена меняются, и некоторые методы тоже. На всякий случай кто-то все еще ищет упрощенный способ сделать это.

Предположения

  1. Ваш пользователь на сервере — sudoers.
  2. Вы используете Windows 10.
  3. Файлы в /var/www должны принадлежать пользователю:группе www-data:www-data

Концепция

Концепция заключается в объединении удаленных команд через ssh и scp передающих файлов без использования графических интерфейсов, таких как PuTTy или WinSCP. Эти команды можно запустить либо из Командной строки, либо из PowerShell. Существует пять основных задач, которые необходимо выполнить:

  1. Настройка среды
  2. Перенос файлов на сервер
  3. Установка разрешений для удаленных файлов
  4. Перенос между удаленными папками
  5. Очистка

Задачи 3–5 можно выполнять в Единственный шаг. Если вы планируете делать это часто, выход из настройки среды позволит вам пропустить задачи 1 и 5.

Настройка среды

У вас может уже быть папка, которую вы можете использовать в качестве временного хранилища для переноса. Если нет, вы можете запустить:

ssh user@server.tld "mkdir ~/wwwtemp"

В зависимости от настроек вашего сервера вам может быть предложено ввести или не ввести пароль/фразу пользователя для аутентификации сеанса ssh.

После аутентификации сеанса будет выполнена команда mkdir ~/wwwtemp, затем сеанс ssh завершится, и вы вернетесь к своему приглашению (Командная строка или PowerShell).

Перенос файлов на сервер

Следующее, что нужно сделать, это перенести файлы с локальной машины Windows на сервер Ubuntu, используя scp следующим образом:

scp -R local\path user@server.tld:~/wwwtemp/

В зависимости от метода аутентификации вашего сервера, вы можете или не должны вводить пароль/парольную фразу.

Разрешения и конечное назначение файлов

После завершения передачи файла вы можете выполнить серию команд через ssh следующим образом:

ssh -t user@server.tld "sudo chown -R www-data:www-data ~/wwwtemp  && sudo mv -R ~/wwwtemp/* /var/www/ && sudo rmdir ~/wwwtemp"

Опять же, в зависимости от метода аутентификации вашего сервера вам может быть предложено ввести или не ввести пароль/парольную фразу. Независимо от вашего метода аутентификации, sudo запросит у вас пароль пользователя. Если, конечно, вы не отключили требование пароля, когда пользователь запускает chown mv и rmdir. См. этот вопрос, чтобы узнать, как это сделать.

Этот шаг охватывает задачи 3-5:

  1. sudo chown -R www-data:www-data ~/wwwtemp рекурсивно устанавливает нужные права доступа к файлам, которые вы только что загрузили.
  2. sudo mv -R ~/wwwtemp/* /var/www/ рекурсивно перемещает содержимое временного репозитория в его конечный пункт назначения.
  3. sudo rmdir ~/wwwtemp удаляет временный репозиторий. Здесь необходимо использовать sudo, так как мы изменили владельца каталога в задаче 3.

Конечно, && разделяет каждую команду. Команды будут выполняться последовательно. Если вы планируете сохранить репозиторий wwwtemp, последнюю команду в последовательности можно опустить.

Примечания

Вы можете опустить && sudo rmdir ~/wwwtemp в конце окончательной командной строки ssh, если хотите продолжать использовать временный репозиторий в будущем. Это также означает, что вы можете пропускать первую команду ssh каждый раз, когда хотите передавать файлы на сервер таким образом.

0
ответ дан 4 June 2020 в 17:37

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

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