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


Ich habe einen Ubuntu-Server, zu dem ich eine Verbindung über SSH herstelle.

Ich muss Dateien von meinem Rechner hochladen /var/www/ auf dem Server die Dateien in /var/www/ sind im Besitz von root.

Mit PuTTY, nachdem ich mich eingeloggt habe, muss ich tippen sudo su und mein Passwort zuerst, um Dateien ändern zu können /var/www/.

Aber wenn ich Dateien mit WinSCP kopiere, kann ich keine Dateien erstellen / ändern /var/www/, weil der Benutzer, mit dem ich mich verbinde, keine Berechtigungen für Dateien in hat /var/www/ und ich kann es nicht sagen sudo su wie ich es im Falle einer SSH-Sitzung mache.

Weißt du, wie ich damit umgehen könnte?

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


134
2017-10-29 21:03


Ursprung


Dies scheint eher eine Frage für Ihren virtuellen Serveranbieter oder für die Putty- oder Winscp-Entwickler zu sein. - dobey
@dobey du bist offensichtlich falsch, es geht um Ubuntu Privilegien! - Dimitris Sapikas
Warum ist das geschlossen? Dies ist eine absolut gültige Frage zum Kopieren von Dateien mit scp - jeder Webentwickler ist mit dieser Situation vertraut - Sergey
Geschützte Dateien zwischen Servern in einer Zeile kopieren? sollte helfen. - Gilles
Ich habe ein ähnliches Problem. Ich erstelle eine Datei (HTML in diesem Fall) auf Windows-Computer und versuche, sie mit WinSCP nach / var / www / html / Website-Ordner zu kopieren. Und es besagt, dass es ein Berechtigungsproblem gibt. Da ich in meinen / home-Ordner kopieren kann, habe ich die Datei in zwei Schritten kopiert, aber es ist nicht sehr praktisch :-) Ich habe versucht, meinen Benutzer zur www-Datengruppe hinzuzufügen, aber es hat nicht geholfen. Irgendeine Idee, warum das Hinzufügen zum Benutzer zu WWW-Daten immer noch nicht erlauben, eine Datei in einen Ordner zu kopieren, der von WWW-Datengruppe gehört? - JanezKranjski


Antworten:


Du hast Recht, es gibt keine sudo bei der Arbeit mit scp. Ein Workaround ist zu verwenden scp um Dateien in ein Verzeichnis hochzuladen, in dem dein Benutzer die Berechtigung hat, Dateien zu erstellen, logge dich dann über ssh ein und benutze es sudo Verschieben / Kopieren von Dateien an ihr endgültiges Ziel.

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 / Besitzrechte der Verzeichnisse zu ändern, in die Sie die Dateien hochladen, so dass Ihr nicht-privilegierter Benutzer in diese Verzeichnisse schreiben kann.

Im Allgemeinen arbeitet in der root account sollte eine Ausnahme sein, keine Regel - die Art, wie du deine Frage formulierst, lässt mich denken, dass du sie vielleicht etwas missbrauchst, was wiederum zu Problemen mit Berechtigungen führt - unter normalen Umständen brauchst du keine Super-Admin-Rechte greifen Sie auf Ihre eigenen Dateien zu.

Technisch können Sie Ubuntu so konfigurieren, dass Remote-Login direkt erlaubt wird root, aber diese Funktion ist aus einem bestimmten Grund deaktiviert, daher rate ich Ihnen dringend davon ab.


105
2017-10-29 22:22



Ich habe die erste Lösung nicht bekommen, könnten Sie bitte ein bisschen mehr speific sein? - Dimitris Sapikas
Wenn ich sage meine eigenen Dateien ich meine / var / www, verwende ich meine vps als Webserver .... auf meinem eigenen Ordner habe ich vollen Zugriff - Dimitris Sapikas
Re. die erste Lösung. 1. scp -R mysite dimitris@myserver.com:/home/dimitris/ 2. ssh dimitris@myserver.com 3. sudo mv ~/mysite /var/www - Es ist ein zweistufiger Prozess, zuerst Sie scp die Dateien zu Ihrem Home-Verzeichnis, dann melden Sie sich über ssh an und kopieren / verschieben Sie die Dateien dorthin, wo sie sein sollen - Sergey
hm .. es funktioniert gut! Danke :) - Dimitris Sapikas


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"

29
2017-10-03 18:56



Dies ist der beste Weg, dies zu tun. - mttdbrd
Ich kann diese Methode nicht erfolgreich ausführen. Wie geschrieben, bekomme ich sudo: sorry, you must have a tty to run sudo. Wenn ich "-t" hinzufüge, um ein TTY zuzuweisen, dann bekomme ich Pseudo-terminal will not be allocated because stdin is not a terminal.. Ich kann nicht sehen, dass dies ohne passwortloses Sudo funktioniert. - IBBoard
@IBBoard: Probieren Sie die Lösung aus Hier mit ssh -t: ssh -t dimitris@myserver.com "sudo tar -x --no-same-owner -C /var/www" - Alexander Bird
@AlexanderBird Während das in vielen Fällen funktioniert, bin ich mir nicht sicher, ob es hier funktioniert, weil wir versuchen, einen Tarball über die SSH-Verbindung zu pipen. Sehen serverfault.com/questions/14389/ ... - IBBoard
Das hat endlich für mich funktioniert. Sie haben keine Berechtigungen für eine Remote-Datei, die Sie in den lokalen Ordner kopieren möchten sudo tar, archiviere es, ändere Berechtigungen mit chmod und chown, und kopieren Sie es dann nach lokal. Vor allem, wenn es ein Verzeichnis ist. - forumulator


Sie können auch verwenden ansible um das zu erreichen.

Kopieren Sie den Remote-Host mit ansible copy Modul:

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

Abrufen vom Remote-Host mit ansible fetch Modul:

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 expandiert nach --becomeund der Standardwert --become-user ist root, mit dem Standardwert --become-method Sudo sein.
  • flat=yes Kopien gerade Die Datei kopiert nicht den gesamten Remotepfad, der zur Datei führt
  • Die Verwendung von Platzhaltern in den Dateipfaden wird von diesen Ansible-Modulen nicht unterstützt.
  • Kopieren eines Verzeichnisses ist unterstützt von der copy Modul, aber nicht bis zum fetch Modul.

Spezifische Aufforderung für diese Frage

Hier ist ein Beispiel, das spezifisch und vollständig spezifiziert ist, vorausgesetzt, das Verzeichnis auf Ihrem lokalen Host, das die zu verteilenden Dateien enthält, ist sourcedirund dass 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 der prägnanten Invokation:

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

P. S., mir ist klar, dass das Sagen "installiere einfach dieses fabelhafte Werkzeug" irgendwie ist Ton-taube Antwort. Aber ich habe es für möglich gehalten Super nützlich für die Verwaltung von Remote-Servern, so dass die Installation sicher weitere Vorteile bringt, als die Bereitstellung von Dateien.


21
2018-02-15 07:03



Ich mag die Antwort, aber ich empfehle, dass Sie es bei der gestellten Frage im Vergleich zu generalisierten Kommentaren vor der Aktualisierung ausrichten. etwas wie ansible -i "hostname," all -u user --become -m copy -a ... - Mike D
@MikeD: Wie sehen die obigen Änderungen aus? - erik.weathers
besser, aber es ist fehlgeschlagen, --module-name ist der korrekte Name des Switches. und seit hostname ist der einzige Host in Ihrem Inventar, können Sie einfach sagen all - Mike D
Würde so etwas mögen -i 'host,' gültige Syntax sein? Ich denke, es ist leicht, Satzzeichen zu verlieren, wenn man einen Befehl liest. (Für den Leser meine ich, wenn nicht die Schale.) - mwfearnley
@mwfearnley: Sicher, die Shell wird behandeln -i 'host,' und dasselbe wie -i host, oder -i "host,". Im Allgemeinen bevorzuge ich es, diese Aufrufe so kurz wie möglich zu halten, um sie davon abzuhalten, entmutigend zu sein, aber Sie sollten sich frei fühlen, sie so ausführlich und explizit zu machen, wie Sie es aus Gründen der Klarheit für nötig halten. - erik.weathers


Wenn du rennst sudo suAlle Dateien, die Sie erstellen, werden von root verwaltet, aber es ist nicht möglich, sich direkt als root mit ssh oder scp anzumelden. Es ist auch nicht möglich, sudo mit scp zu verwenden, so dass die Dateien nicht verwendbar sind. Beheben Sie dies, indem Sie die Eigentumsrechte an Ihren Dateien beanspruchen:

Angenommen, Ihr Benutzername war dimitri, könnten Sie diesen Befehl verwenden.

sudo chown -R dimitri:dimitri /home/dimitri

Ab dann, wie in anderen Antworten erwähnt, ist der "Ubuntu" Weg, Sudo, und nicht root Logins zu verwenden. Es ist ein nützliches Paradigma mit großen Sicherheitsvorteilen.


12
2017-10-29 23:07



Ich benutze diese Lösung irgendwie, aber was, wenn ich vollen Zugang zu meinem eigenen Dateisystem bekommen könnte, möchte ich nicht schreiben sudo chow ...für jedes einzelne Verzeichnis: S - Dimitris Sapikas
Es wird dringend davon abgeraten, die Eigentumsrechte für alle Systemdateien an den Benutzer zu übergeben, um Bequemlichkeit zu vermitteln. Es ermöglicht jedem Userspace-Bug, der auftreten könnte, die Sicherheit Ihres Systems zu beeinträchtigen. Es ist viel besser, den Besitz der Dateien zu ändern, die Sie ändern oder mit SCP aktualisieren müssen, aber alles andere im Besitz von root zu lassen (wie es sein sollte). Das sagte, der -R im chown teilt ihm mit, dass er den Besitz dieses Verzeichnisses und alle untergeordneten Dateien und Verzeichnisse rekursiv ändern soll ... damit Sie alles tun können, was Sie möchten. - Bailey S
hmm .... das scheint gut zu funktionieren, danke! Entschuldigung, ich kann nicht upvote (System erlaubt mir nicht zu tun ...) - Dimitris Sapikas


Vielleicht ist der beste Weg zu benutzen rsync (Cygwin/cwRsync in Windows) über SSH?

Zum Beispiel, um Dateien mit dem Besitzer hochzuladen www-data:

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

Wenn Sie in Ihrem Fall Root-Rechte benötigen, lautet der Befehl wie folgt:

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

Sehen: scp auf Remote-Server mit sudo.


8
2017-11-15 10:14





Wenn Sie die OpenSSH - Tools anstelle von PuTTY verwenden, können Sie dies tun, indem Sie das scp Dateiübertragung auf dem Server mit sudo. Stellen Sie sicher, dass Sie eine haben sshd Daemon läuft auf Ihrem lokalen Rechner. Mit ssh -R Sie können dem Server eine Möglichkeit geben, mit Ihrem Computer Kontakt aufzunehmen.

Auf Ihrer Maschine:

ssh -R 11111:localhost:22 REMOTE_USERNAME@SERVERNAME

Zusätzlich zur Anmeldung auf dem Server wird jede auf dem Port 11111 des Servers vorgenommene Verbindung zum Port 22 Ihres Computers weitergeleitet: dem Port, den Sie verwenden sshd hört zu.

Starten Sie auf dem Server die Dateiübertragung wie folgt:

cd /var/www/
sudo scp -P 11111 -r LOCAL_USERNAME@localhost:FOLDERNAME .

5
2017-11-21 16:52





Schnell Weg:

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

5
2018-01-16 13:01



Diese Antwort wird unterbewertet. Es ist einfach, sauber, liest oder schreibt eine Root-Datei mit einer einzigen atomaren Operation und benötigt nichts, was nicht garantiert ist, wenn Sie scp verwenden. Der Hauptnachteil ist, dass Berechtigungen nicht kopiert werden. Wenn Sie das wollen, ist die Teerlösung besser. Dies ist eine mächtige Technik, besonders wenn sie mit xargs / bash magic kombiniert wird, um Pfade zu durchlaufen. - markgo2k


Sie können das Skript, das ich geschrieben habe, von diesem Thema inspirieren:

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

aber das erfordert etwas verrücktes (was übrigens automatisch vom Skript erledigt wird)

  1. Der Server, an den die Datei gesendet wird, fragt beim Herstellen der SSH-Verbindung zum Quellcomputer nicht mehr nach dem Kennwort
  2. wegen der notwendigkeit des fehlens von sudo prompt auf dem server wird sudo nicht mehr nach dem passwort auf dem entfernten computer fragen, für den benutzer

Hier geht das 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

1
2017-11-21 19:47



@Braiam ja, sicher, entschuldigung für link, das skript ist ziemlich lang und das war der grund :) - test30


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 berechtigt zu sein, mit Ihrem Benutzer auf die Dateien zuzugreifen. Das ist ein bisschen fummelig, also habe ich ein Skript geschrieben, um dies zu unterstützen. Sie finden das Skript hier: https://github.com/sigmunau/sudoscp

oder hier:

#! / bin / bash
res = 0
von = 1 $
zu = 2 $
Verschiebung
Verschiebung
files = "$ @"
if test -z "$ from" -o -z "$ bis" -o -z "$ files"
dann
    echo "Verwendung: $ 0 (Datei) *"
    echo "Beispiel: $ 0 server1 server2 / usr / bin / myapp"
    Ausgang 1
fi

read -s -p "Passwort eingeben:" sudopassword
Echo ""
temp1 = $ (mktemp)
temp2 = $ (mktemp)
(echo "$ sudopassword"; echo "$ sudopassword" | ssh $ aus sudo -S tar c -P -C / $ files 2> $ temp1) | ssh $ zu sudo -S tar x -v -P -C / 2 > $ temp2
sourceres = $ {PIPESTATUS [0]}
wenn [$? -ne 0 -o $ sources -ne 0]
dann
    echo "Fehler!" > & 2
    echo "$ aus Ausgabe:"> & 2
    Katze $ temp1> & 2
    echo ""> & 2
    echo "$ zu Ausgabe:"> & 2
    Katze $ temp2> & 2
    res = 1
fi

rm $ temp1 $ temp2
exit $ res

1
2017-07-01 15:16



Willkommen bei Ask Ubuntu. Könnten Sie bitte das Skript in Ihre Antwort aufnehmen? Ich weiß, dass es unwahrscheinlich ist, aber wenn das Github-Repo jemals entfernt wurde oder sich die URL änderte, wäre die Antwort ungültig. Es ist besser, das Skript direkt einzubinden und den Github-Repo als Quelle zu belassen. - Michael Lindman