У меня есть сервер Ubuntu, к которому я подключаюсь по SSH.
Мне нужно загрузить файлы со своего устройства в /var/www/
на сервере, файлы в /var/www/
принадлежат root
.
Используя PuTTY, после входа в систему мне нужно сначала набрать sudo su
и мой пароль, чтобы иметь возможность изменять файлы в /var/www/
.
Но когда я копирую файлы с помощью WinSCP, я не могу создать / изменить файлы в /var/www/
, потому что у пользователя, к которому я подключаюсь, нет прав на файлы в /var/www/
, и я не могу сказать, sudo su
как и в случае ssh-сессии.
Знаете ли вы, как я мог справиться с этим?
Если бы я работал на своей локальной машине, я бы позвонил gksudo nautilus
, но в этом случае у меня есть только терминальный доступ к машине.
Вы правы, при работе с 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
, но эта функция по какой-то причине отключена, поэтому я настоятельно рекомендую вам не делать этого.
Можно также использовать 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,
синтаксис не является опечаткой. Это - способ использовать ansible, не нуждаясь в файле материально-технических ресурсов.-b
заставляет действия с сервером быть сделанными как корень. -b
расширяется до --become
, и значение по умолчанию --become-user
корень, со значением по умолчанию --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
P.S., я понимаю, что высказывание "просто устанавливает этот невероятный инструмент", своего рода ответ без слуха. Но я нашел, что ansible супер полезен для администрирования удаленных серверов, так установки, это, конечно, даст Вам другие преимущества вне развертывающихся файлов.
Другой способ - копировать, используя tar + ssh вместо scp:
tar -c -C ./my/local/dir \
| ssh dimitris@myserver.com "sudo tar -x --no-same-owner -C /var/www"
Быстрый способ
С сервера на локальный компьютер:
ssh user@server "sudo cat /etc/dir/file" > /home/user/file
С локального компьютера на сервер:
cat /home/user/file | ssh user@server "sudo tee -a /etc/dir/file"
Может быть, лучший способ - использовать 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
Когда вы запускаете sudo su
, все созданные вами файлы будут принадлежать пользователю root, но по умолчанию невозможно напрямую войти в систему как root с помощью ssh или scp. Также невозможно использовать sudo с scp, поэтому файлы нельзя использовать. Исправьте это, заявив право собственности на ваши файлы:
Предполагая, что ваше имя пользователя dimitri, вы можете использовать эту команду.
sudo chown -R dimitri:dimitri /home/dimitri
С этого момента, как уже упоминалось в других ответах, «Ubuntu» использует sudo, а не root-логины. Это полезная парадигма с большими преимуществами безопасности.
Если вы используете инструменты 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 .
Можно использовать сценарий, который я записал быть вдохновленным этой темой:
touch /tmp/justtest && scpassudo /tmp/justtest remoteuser@ssh.superserver.com:/tmp/
но это требует некоторого сумасшедшего материала (который является btw., автоматически сделанным сценарием),
Здесь идет сценарий:
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
Можно объединить 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
Вот измененная версия ответа 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" к моей локальной машине для демонстрации.
Я знаю, что вопрос старый, но времена меняются, и некоторые методы тоже. На всякий случай кто-то все еще ищет упрощенный способ сделать это.
/var/www
должны принадлежать пользователю:группе www-data:www-data
Концепция заключается в объединении удаленных команд через ssh
и scp
передающих файлов без использования графических интерфейсов, таких как PuTTy
или WinSCP
. Эти команды можно запустить либо из Командной строки
, либо из PowerShell
. Существует пять основных задач, которые необходимо выполнить:
Задачи 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:
sudo chown -R www-data:www-data ~/wwwtemp
рекурсивно устанавливает нужные права доступа к файлам, которые вы только что загрузили. sudo mv -R ~/wwwtemp/* /var/www/
рекурсивно перемещает содержимое временного репозитория в его конечный пункт назначения. sudo rmdir ~/wwwtemp
удаляет временный репозиторий. Здесь необходимо использовать sudo
, так как мы изменили владельца каталога в задаче 3. Конечно, &&
разделяет каждую команду. Команды будут выполняться последовательно. Если вы планируете сохранить репозиторий wwwtemp
, последнюю команду в последовательности можно опустить.
Вы можете опустить && sudo rmdir ~/wwwtemp
в конце окончательной командной строки ssh
, если хотите продолжать использовать временный репозиторий в будущем. Это также означает, что вы можете пропускать первую команду ssh
каждый раз, когда хотите передавать файлы на сервер таким образом.