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


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

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

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

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

Вы знаете, как я могу справиться с этим?

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


136
2017-10-29 21:03


происхождения


Это больше похоже на вопрос для вашего поставщика виртуального сервера, или для разработчиков putty или winscp. - dobey
@dobey вы obviusly неправильно, это о привилегиях ubuntu! - Dimitris Sapikas
Почему это закрыто? Это совершенно правильный вопрос о копировании файлов с помощью scp - каждый веб-разработчик знаком с этой ситуацией - Sergey
Копирование защищенных файлов между серверами в одной строке? должен помочь. - Gilles
У меня аналогичная проблема. Я создаю файл (в данном случае HTML) на компьютере Windows и пытаюсь скопировать его с помощью WinSCP в папку / var / www / html / website. И в нем говорится, что есть проблема с разрешением. Поскольку я могу копировать в папку my / home, я скопировал файл в два этапа, но это не очень удобно :-) Я попытался добавить своего пользователя в группу www-data, но это не помогло. Любая идея, почему добавление пользователю к www-данным по-прежнему не позволяет пользователю копировать файл в папку, принадлежащую группе www-data? - JanezKranjski


ответы:


Вы правы, нет sudo при работе с scp, Обходным путем является использование 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, но эта функция отключена по какой-то причине, поэтому я бы настоятельно советовал вам не делать этого.


105
2017-10-29 22:22



я не получил первое решение, не могли бы вы быть более популярным? - Dimitris Sapikas
Я говорю свои собственные файлы, которые я имею в виду / var / www, я использую свой vps как веб-сервер .... в моей собственной папке у меня есть полный доступ - Dimitris Sapikas
Число рейнольдса первое решение. 1. scp -R mysite dimitris@myserver.com:/home/dimitris/ 2. ssh dimitris@myserver.com 3. sudo mv ~/mysite /var/www - это двухэтапный процесс, сначала вы scp файлы в домашний каталог, затем вы регистрируетесь через ssh и копируете / перемещаете файлы туда, где они должны быть - Sergey
hm .. он отлично работает! Спасибо :) - Dimitris Sapikas


Другой способ - скопировать с помощью tar + ssh вместо scp:

tar -c -C ./my/local/dir \
  | ssh dimitris@myserver.com "sudo tar -x --no-same-owner -C /var/www"

29
2017-10-03 18:56



Это лучший способ сделать это. - mttdbrd
Я не могу заставить этот метод работать успешно. Как написано, я получаю 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
@IBBoard: попробуйте решение Вот используя ssh -t: ssh -t dimitris@myserver.com "sudo tar -x --no-same-owner -C /var/www" - Alexander Bird
@AlexanderBird Хотя это работает во многих случаях, я не уверен, что он работает здесь, потому что мы пытаемся подключить tarball через соединение SSH. Видеть serverfault.com/questions/14389/... - IBBoard
Это то, что окончательно сработало для меня. У вас нет прав на удаленный файл, который вы хотите скопировать на локальный, выполните sudo tar, архивировать, изменять разрешения, используя chmod а также chown, а затем скопируйте его на локальный. Особенно, если это каталог. - forumulator


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

Скопировать на удаленный хост, используя анзибль-х copy модуль:

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

Выбор из удаленного хоста с использованием анзибль-х fetch модуль:

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 будучи судо.
  • 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

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


23
2018-02-15 07:03



Мне нравится этот ответ, но я рекомендую вам направить его по заданному вопросу в сравнении с более обобщенным комментарием перед повышением. что-то вроде ansible -i "hostname," all -u user --become -m copy -a ... - Mike D
@MikeD: как выглядят эти изменения? - erik.weathers
лучше, но это терпит неудачу, --module-name это правильное имя коммутатора. и с тех пор hostname это единственный хост в вашем инвентаре, вы можете просто сказать all - Mike D
Будет что-то вроде -i 'host,' быть допустимым синтаксисом? Я считаю, что при чтении команды легко потерять знаки препинания. (Для читателя я имею в виду, если не оболочку.) - mwfearnley
@mwfearnley: конечно, оболочка будет лечить -i 'host,' и такие же, как -i host, или -i "host,", В общем, я предпочитаю, чтобы эти призывы были как можно короче, чтобы они не были сложными, но вы должны быть свободны, чтобы сделать их такими подробными и ясными, насколько вам кажется необходимым для ясности. - erik.weathers


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

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

sudo chown -R dimitri:dimitri /home/dimitri

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


12
2017-10-29 23:07



Я использую это решение любым способом, но что, если бы я мог получить полный доступ к моей собственной файловой системе, я не хочу вводить sudo chow ... для каждого отдельного каталога: S - Dimitris Sapikas
Изменение права собственности на все системные файлы для удобства пользователя крайне не рекомендуется. Это позволяет любой ошибке в пользовательском пространстве, с которой вы можете столкнуться, серьезно подорвать безопасность вашей системы. Гораздо лучше изменить права собственности на файлы, которые нужно изменить или обновить с помощью SCP, но оставить все остальное, принадлежащее root (как и предполагалось). Тем не менее, -R в chown говорит, что он меняет права собственности на этот каталог, а все дочерние файлы и каталоги рекурсивно ... поэтому вы можете делать все, что вам нравится. - Bailey S
hmm .... это кажется работаю хорошо, спасибо! извините, я не могу повышать (система не позволяет мне делать ...) - Dimitris Sapikas


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


8
2017-11-15 10:14





Если вы используете инструменты 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 .

5
2017-11-21 16:52





Быстро:

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

5
2018-01-16 13:01



Этот ответ недооценен. Он прост, чист, читает или записывает корневой файл с помощью одной атомной операции и не требует ничего, что еще не гарантировано, если вы используете scp. Главный недостаток заключается в том, что он не копирует разрешения. Если вы хотите это, решение tar лучше. Это мощный метод, особенно в сочетании с магией xargs / bash для прохождения по траекториям. - markgo2k


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

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

но это требует некоторых сумасшедших вещей (что, кстати, автоматически делается по сценарию)

  1. сервер, файл которого отправляется, больше не будет запрашивать пароль при установлении подключения ssh к исходному компьютеру
  2. из-за необходимости отсутствия приглашения 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
2017-11-21 19:47



@Braiam да, конечно, извините за ссылку, сценарий довольно длинный, и это было причиной :) - test30