Wie kopiere ich Dateien, die Root-Zugriff benötigen, mit scp?

140

Ich habe einen Ubuntu-Server, zu dem ich mich mit SSH verbinde.

Ich muss Dateien von meinem Computer in /var/www/ auf dem Server hochladen. Die Dateien in /var/www/ gehören root .

Wenn Sie PuTTY verwenden, muss ich nach dem Anmelden zuerst sudo su und mein Kennwort eingeben, um Dateien in /var/www/ ändern zu können.

Wenn ich jedoch Dateien mit WinSCP kopiere, kann ich keine Dateien in /var/www/ erstellen / ändern, da der Benutzer, mit dem ich verbunden bin, keine Berechtigungen für Dateien in /var/www/ hat und ich kann es nicht sagen sudo su wie bei einer SSH-Sitzung.

Wissen Sie, wie ich damit umgehen könnte?

Wenn ich an meinem lokalen Rechner arbeite, würde ich gksudo nautilus anrufen, aber in diesem Fall habe ich nur Terminalzugriff auf den Rechner.

    
Dimitris Sapikas 29.10.2012, 22:03
quelle

10 Antworten

106

Sie haben Recht, es gibt kein sudo , wenn Sie mit scp arbeiten. Sie können dieses Problem umgehen, indem Sie scp verwenden, um Dateien in ein Verzeichnis hochzuladen, in dem Ihr Benutzer über die Berechtigung zum Erstellen von Dateien verfügt. Melden Sie sich dann über ssh an und verwenden Sie sudo , um Dateien an das endgültige Ziel zu verschieben / zu kopieren.

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

Eine andere Lösung wäre, die Berechtigungen / den Besitz der Verzeichnisse zu ändern, in die Sie die Dateien hochladen, damit Ihr nicht privilegierter Benutzer in diese Verzeichnisse schreiben kann.

Im Allgemeinen sollte das Arbeiten mit dem Konto root eine Ausnahme und keine Regel sein - die Art, wie Sie Ihre Frage formulieren, lässt mich denken, dass Sie sie vielleicht ein bisschen missbrauchen, was wiederum zu Problemen mit Berechtigungen führt - im Normalfall Unter Umständen benötigen Sie keine Super-Admin-Berechtigungen, um auf Ihre eigenen Dateien zuzugreifen.

Technisch können Sie Ubuntu so konfigurieren, dass die Remote-Anmeldung direkt als root zugelassen wird. Diese Funktion ist jedoch aus einem bestimmten Grund deaktiviert. Ich würde Ihnen daher dringend raten, dies nicht zu tun.

    
Sergey 29.10.2012, 23:22
quelle
29

Eine andere Methode ist das Kopieren mit tar + ssh anstelle von scp:

tar -c -C ./my/local/dir \
  | ssh dimitris@myserver.com "sudo tar -x --no-same-owner -C /var/www"
    
Willie Wheeler 03.10.2014 20:56
quelle
23

Sie können auch ansible verwenden, um dies zu erreichen.

Mit dem Modul copy von ansible auf den Remote-Host kopieren :

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

Rufen Sie mit einem Modul fetch von ansible vom entfernten Host ab:

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

HINWEIS:

  • Das Komma in der -i HOST, -Syntax ist kein Tippfehler. Auf diese Weise können Sie ansible verwenden, ohne eine Inventardatei zu benötigen.
  • -b bewirkt, dass die Aktionen auf dem Server als root ausgeführt werden. -b erweitert sich auf --become und der Standardwert --become-user ist root, wobei der Standardwert --become-method sudo ist.
  • flat=yes kopiert nur die Datei, kopiert nicht den gesamten entfernten Pfad, der zu der Datei führt,
  • Die Verwendung von Platzhaltern in den Dateipfaden wird von diesen verfügbaren Modulen nicht unterstützt.
  • Das Kopieren eines Verzeichnisses wird vom Modul copy unterstützt, jedoch nicht vom Modul fetch .

Spezifische Aufruf für diese Frage

Hier ist ein Beispiel, das spezifisch und vollständig angegeben ist, vorausgesetzt, das Verzeichnis auf Ihrem lokalen Host, das die zu verteilenden Dateien enthält, ist sourcedir , und der Hostname des Remote-Ziels ist hostname :

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

Mit dem prägnanten Aufruf:

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

P., ich merke, dass das Sprichwort "einfach dieses fabelhafte Werkzeug installieren" eine Art von tonlose Antwort. Ich habe jedoch festgestellt, dass er für die Verwaltung von Remote-Servern super nützlich ist. Durch die Installation von Remix-Servern können Sie also andere Vorteile erzielen als die Bereitstellung von Dateien.

    
erik.weathers 15.02.2016 08:03
quelle
12

Wenn Sie sudo su ausführen, werden alle von Ihnen erstellten Dateien im Besitz von root. Standardmäßig können Sie sich jedoch nicht direkt als root mit ssh oder scp anmelden. Es ist auch nicht möglich, sudo mit scp zu verwenden, sodass die Dateien nicht verwendet werden können. Beheben Sie dies, indem Sie den Besitz Ihrer Dateien beanspruchen:

Wenn Sie davon ausgehen, dass Ihr Benutzername "dimitri" war, können Sie diesen Befehl verwenden.

sudo chown -R dimitri:dimitri /home/dimitri

Von da an, wie in anderen Antworten erwähnt, ist die "Ubuntu" -Methode Sudo und keine Root-Logins. Es ist ein nützliches Paradigma mit großen Sicherheitsvorteilen.

    
trognanders 30.10.2012 00:07
quelle
8

Der beste Weg ist die Verwendung von rsync ( Cygwin / cwRsync in Windows) über SSH?

So laden Sie beispielsweise Dateien mit dem Eigentümer www-data hoch:

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

In Ihrem Fall lautet der Befehl folgendermaßen:

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

Siehe: scp zum Remote-Server mit Sudo .

    
Alexey Vazhnov 15.11.2016 11:14
quelle
7

Schnell weg:

ssh user@server "sudo cat /etc/dir/file" > /home/user/file
    
Anderson Lira 16.01.2017 14:01
quelle
5

Wenn Sie die OpenSSH-Tools anstelle von PuTTY verwenden, können Sie dies erreichen, indem Sie die scp -Dateiübertragung auf dem Server mit sudo initiieren. Stellen Sie sicher, dass auf Ihrem lokalen Computer ein sshd -Dämon ausgeführt wird. Mit ssh -R können Sie dem Server die Möglichkeit geben, mit Ihrem Computer Kontakt aufzunehmen.

Auf Ihrem Computer:

ssh -R 11111:localhost:22 REMOTE_USERNAME@SERVERNAME

Zusätzlich zum Anmelden am Server werden alle auf dem Server-Port 11111 hergestellten Verbindungen an Port 22 Ihres Computers weitergeleitet: Der Port, auf dem Ihr sshd wartet.

Starten Sie die Dateiübertragung auf dem Server folgendermaßen:

cd /var/www/
sudo scp -P 11111 -r LOCAL_USERNAME@localhost:FOLDERNAME .
    
bergoid 21.11.2016 17:52
quelle
1

Sie können ein von mir geschriebenes Skript verwenden, das von diesem Thema inspiriert wird:

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

aber das erfordert ein paar verrückte Sachen (was übrigens automatisch per Skript erledigt wird)

  1. Server, an den die Datei gesendet wird, werden nicht mehr nach einem Kennwort gefragt, während die ssh-Verbindung zum Quellcomputer hergestellt wird
  2. Da der Sudo-Prompt auf dem Server nicht unbedingt erforderlich ist, fragt Sudo auf dem Remote-Computer nicht mehr nach dem Kennwort für den Benutzer

Hier geht es zum Skript:

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
    
test30 21.11.2013 20:47
quelle
1

Sie können ssh, sudo und z. B. tar kombinieren, um Dateien zwischen Servern zu übertragen, ohne sich als root anmelden zu können und nicht die Berechtigung zum Zugriff auf die Dateien mit Ihrem Benutzer zu haben. Dies ist etwas fummelig, deshalb habe ich ein Skript geschrieben, um dies zu unterstützen. Sie finden das Skript hier: link

oder hier:

#! /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
    
sigmunda 01.07.2015 17:16
quelle
0

Hier ist eine modifizierte Version von Willie Wheelers Antwort, die die Datei (en) über tar überträgt, aber auch die Weitergabe eines Kennworts an sudo auf dem Remote-Host unterstützt.

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

Das kleine Extra an Magie ist die Option -S für Sudo. Von der Sudo-Manpage:

  

-S, --stdin                    Schreiben Sie die Eingabeaufforderung in den Standardfehler und lesen Sie das Kennwort aus der Standardeingabe, anstatt das Endgerät zu verwenden. Dem Passwort muss ein Zeilenvorschubzeichen folgen.

Jetzt möchten wir, dass die Ausgabe von tar in ssh geleitet wird, und das stdin von ssh auf das stdout von tar umleitet, so dass das interaktive Terminal keine Möglichkeit hat, das Kennwort an sudo zu übergeben. (Wir könnten Sudos ASKPASS-Funktion für das entfernte Ende verwenden, aber das ist eine andere Geschichte.) Wir können das Kennwort zwar in sudo eingeben, indem Sie es vorab erfassen und der tar-Ausgabe voranstellen die subshell in ssh. Dies hat auch den zusätzlichen Vorteil, dass keine Umgebungsvariable, die unser Kennwort enthält, in unserer interaktiven Shell hängen bleibt.

Sie werden feststellen, dass ich mit der Option -p nicht "read" ausgeführt habe, um eine Eingabeaufforderung zu drucken. Dies liegt daran, dass die Kennwortabfrage von sudo bequem über ssh an den stderr unserer interaktiven Shell zurückgegeben wird. Sie fragen sich vielleicht, "wie wird Sudo ausgeführt, wenn es in ssh rechts von unserer Pipe läuft?" Wenn wir mehrere Befehle ausführen und die Ausgabe eines Befehls an einen anderen übergeben, führt die übergeordnete Shell (in diesem Fall die interaktive Shell) jeden Befehl unmittelbar nach der Ausführung des vorherigen Befehls aus. Wenn jeder Befehl hinter einer Pipe ausgeführt wird, hängt (leitet) die übergeordnete Shell den Standardausschnitt der linken Seite an den Standardausschnitt der rechten Seite an. Die Ausgabe wird dann zur Eingabe, wenn sie Prozesse durchläuft. Wir können dies in Aktion sehen, indem wir den gesamten Befehl ausführen und die Prozessgruppe (Strg-z) im Hintergrund ausführen, bevor Sie unser Kennwort eingeben und dann den Prozessbaum anzeigen.

$ (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"'

Unsere interaktive Shell ist PID 7168, unsere Subshell ist PID 7969 und unser SSH-Prozess ist PID 7970.

Der einzige Nachteil ist, dass read Eingaben akzeptiert, bevor sudo Zeit hat, die Eingabeaufforderung zurückzusenden. Bei einer schnellen Verbindung und einem schnellen Remote-Host werden Sie dies nicht bemerken, aber wenn einer der beiden langsamer ist. Jede Verzögerung wirkt sich nicht auf die Eingabeaufforderung aus. Es erscheint möglicherweise nur, nachdem Sie mit der Eingabe begonnen haben.

Hinweis: Ich habe einfach einen Host-Dateieintrag für "remote_Host" zu meinem lokalen Rechner für die Demo hinzugefügt.

    
Bruce 06.05.2017 12:17
quelle

Tags und Links