Domanda Come faccio a copiare i file che richiedono l'accesso root con scp?


Ho un server Ubuntu a cui mi sto connettendo usando SSH.

Ho bisogno di caricare i file dalla mia macchina in /var/www/ sul server, i file in /var/www/ sono di proprietà di root.

Usando PuTTY, dopo aver effettuato l'accesso, devo digitare sudo su e la mia password prima di poter modificare i file in /var/www/.

Ma quando copio file usando WinSCP, non posso creare creare / modificare file in /var/www/, perché l'utente con cui mi sto collegando non ha le autorizzazioni per i file in /var/www/ e non posso dire sudo su come faccio in caso di una sessione ssh.

Sai come potrei affrontare questo?

Se stavo lavorando sulla mia macchina locale, chiamerei gksudo nautilus ma in questo caso ho solo accesso al terminale della macchina.


134
2017-10-29 21:03


origine


Questo sembra più una domanda per il tuo fornitore di server virtuale, o per gli sviluppatori di mastice o winscp. - dobey
@dobey hai ragionevolmente sbagliato, si tratta di privilegi di ubuntu! - Dimitris Sapikas
Perché è chiuso? Questa è una domanda perfettamente valida sulla copia dei file con scp - ogni sviluppatore web conosce questa situazione - Sergey
Copia di file protetti tra server in una riga? dovrebbe aiutare. - Gilles
Ho un problema simile. Creo un file (HTML in questo caso) su un computer Windows e provo a copiarlo con WinSCP nella cartella / var / www / html / website. E dice che c'è un problema di autorizzazione. Perché posso copiare nella mia cartella / home ho copiato il file in due passaggi, ma non è molto comodo :-) Ho provato ad aggiungere il mio utente al gruppo www-data, ma non è stato d'aiuto. Qualche idea sul perché l'aggiunta di utenti a www-data non permetta ancora all'utente di copiare un file nella cartella di proprietà di www-data group? - JanezKranjski


risposte:


Hai ragione, non c'è sudo quando si lavora con scp. Una soluzione alternativa è da utilizzare scp per caricare file in una directory in cui l'utente ha le autorizzazioni per creare file, quindi accedere tramite ssh e utilizzare sudo spostare / copiare i file nella loro destinazione finale.

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

Un'altra soluzione potrebbe essere quella di modificare le autorizzazioni / la proprietà delle directory in cui si stanno caricando i file, in modo tale che l'utente non privilegiato sia in grado di scrivere su tali directory.

In generale, lavorando nel root l'account dovrebbe essere un'eccezione, non una regola: il modo in cui formuli la tua domanda mi fa pensare che forse ti stai abusando un po ', che a sua volta porta a problemi con le autorizzazioni: in circostanze normali non hai bisogno di privilegi di super-amministratore per accedi ai tuoi file.

Tecnicamente, puoi configurare Ubuntu per consentire l'accesso remoto direttamente come root, ma questa funzione è disabilitata per un motivo, quindi ti consiglio caldamente di farlo.


105
2017-10-29 22:22



Non ho avuto la prima soluzione, potresti per favore essere un po 'più spesifico? - Dimitris Sapikas
Quando dico i miei file intendo / var / www, sto usando il mio vps come web server .... sulla mia cartella ho pieno accesso - Dimitris Sapikas
Ri. la prima soluzione. 1. scp -R mysite dimitris@myserver.com:/home/dimitris/ 2. ssh dimitris@myserver.com 3. sudo mv ~/mysite /var/www - È un processo in 2 fasi, prima tu scp i file nella directory home, quindi accedi tramite ssh e copia / sposta i file dove dovrebbero essere - Sergey
hm .. funziona bene! grazie :) - Dimitris Sapikas


Un altro metodo è copiare usando tar + ssh invece di 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



Questo è il modo migliore per farlo. - mttdbrd
Non riesco a ottenere questo metodo per funzionare correttamente. Come scritto ottengo sudo: sorry, you must have a tty to run sudo. Se aggiungo "-t" per allocare un TTY, allora ottengo Pseudo-terminal will not be allocated because stdin is not a terminal.. Non riesco a vederlo funzionare senza sudo senza password. - IBBoard
@ IBBoard: prova la soluzione Qui usando ssh -t: ssh -t dimitris@myserver.com "sudo tar -x --no-same-owner -C /var/www" - Alexander Bird
@AlexanderBird Sebbene funzioni in molti casi, non sono sicuro che funzioni qui perché stiamo provando a reindirizzare un tarball sulla connessione SSH. Vedere serverfault.com/questions/14389/... - IBBoard
Questo è quello che alla fine ha funzionato per me. Non si dispone delle autorizzazioni per un file remoto che si desidera copiare in locale, fare a sudo tar, archivialo, cambia i permessi usando chmod e chowne quindi copiarlo in locale. Soprattutto se si tratta di una directory. - forumulator


Puoi anche usare ansible per realizzare questo.

Copia su host remoto utilizzando ansible di copy modulo:

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

Recupera dall'host remoto usando ansible di fetch modulo:

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

NOTA:

  • La virgola in -i HOST, la sintassi non è un refuso. È il modo di usare ansible senza bisogno di un file di inventario.
  • -b fa sì che le azioni sul server vengano eseguite come root. -b si espande a --becomee il valore predefinito --become-user è root, con il valore predefinito --become-method essere sudo.
  • flat=yes copie appena il file, non copia l'intero percorso remoto che porta al file
  • L'utilizzo di caratteri jolly nei percorsi dei file non è supportato da questi moduli ansibili.
  • Copia di una directory è supportato dal copy modulo, ma non dal fetch modulo.

Invocazione specifica per questa domanda

Ecco un esempio specifico e completamente specificato, assumendo che la directory sul tuo host locale che contiene i file da distribuire sia sourcedire che il nome host del target remoto è hostname:

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

Con l'invocazione concisa essere:

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

P.S., mi rendo conto che dire "basta installare questo favoloso strumento" è una specie di a risposta tono-sordo. Ma ho trovato che è impossibile essere super utile per amministrare server remoti, quindi installarlo ti porterà sicuramente altri vantaggi oltre alla distribuzione dei file.


21
2018-02-15 07:03



Mi piace questa risposta, ma ti consiglio di indirizzarla alla domanda posta rispetto a commenti più generalizzati prima di andare a votare. qualcosa di simile a ansible -i "hostname," all -u user --become -m copy -a ... - Mike D
@ Mike: come appaiono le modifiche precedenti? - erik.weathers
meglio ma non funziona, --module-name è il nome dell'interruttore corretto. e da allora hostname è l'unico host nel tuo inventario, puoi solo dire all - Mike D
Sarebbe qualcosa di simile -i 'host,' essere sintassi valida? Penso che sia facile perdere la punteggiatura come quella durante la lettura di un comando. (Per il lettore intendo, se non la shell.) - mwfearnley
@ mwfearnley: certo, la shell tratterà -i 'host,' e lo stesso di -i host, o -i "host,". In generale, preferisco mantenere queste invocazioni il più brevi possibile per evitare che siano scoraggianti, ma dovresti sentirti libero di renderlo verboso ed esplicito come ritieni necessario per chiarezza. - erik.weathers


Quando corri sudo su, tutti i file che crei saranno di proprietà di root, ma per impostazione predefinita non è possibile accedere direttamente come root con ssh o scp. Inoltre, non è possibile usare sudo con scp, quindi i file non sono utilizzabili. Risolvi questo problema rivendicando la proprietà sui tuoi file:

Supponendo che il tuo nome utente fosse dimitri, potresti usare questo comando.

sudo chown -R dimitri:dimitri /home/dimitri

Da quel momento in poi, come menzionato in altre risposte, il modo "Ubuntu" è usare sudo e non i login di root. È un paradigma utile, con grandi vantaggi in termini di sicurezza.


12
2017-10-29 23:07



sto usando questa soluzione in qualsiasi modo, ma cosa succede se potrei ottenere l'accesso completo al mio file system, non voglio digitare sudo chow ... per ogni singola directory: S - Dimitris Sapikas
Cambiare la proprietà di tutti i file di sistema all'utente per il passaggio di convenienza è altamente sconsigliato. Consente a qualsiasi bug dello spazio utente che potresti incontrare compromettere seriamente la sicurezza del tuo sistema. È molto meglio cambiare la proprietà dei file che devi modificare o aggiornare da SCP, ma lasciare tutto il resto di proprietà di root (come dovrebbe essere). Detto questo, il -R in chown dice di cambiare la proprietà di quella directory e tutti i file e le directory dei bambini in modo ricorsivo ... così puoi fare tutto quello che vuoi. - Bailey S
hmm .... sembra funzionare bene, grazie! scusa non posso andare avanti (il sistema non mi permette di fare ...) - Dimitris Sapikas


Potrebbe essere il modo migliore è quello di utilizzare rsync (Cygwin/cwRsync in Windows) su SSH?

Ad esempio, per caricare file con il proprietario www-data:

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

Nel tuo caso, se hai bisogno dei privilegi di root, il comando sarà così:

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

Vedere: scp al server remoto con sudo.


8
2017-11-15 10:14





Se usi gli strumenti OpenSSH invece di PuTTY, puoi farlo avviando il scp trasferimento di file sul server con sudo. Assicurati di avere un sshd daemon in esecuzione sul computer locale. Con ssh -R puoi dare al server un modo per contattare la tua macchina.

Sulla tua macchina:

ssh -R 11111:localhost:22 REMOTE_USERNAME@SERVERNAME

Oltre ad accedere al server, questo inoltrerà ogni connessione effettuata sulla porta 11111 del server alla porta 22 della tua macchina: la porta tua sshd sta ascoltando.

Sul server, avvia il trasferimento del file in questo modo:

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

5
2017-11-21 16:52





Modo rapido:

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

5
2018-01-16 13:01



Questa risposta è sottovalutata. È semplice, pulito, legge o scrive un file di root con una singola operazione atomica e non richiede nulla che non sia già garantito per essere presente se si utilizza scp. Lo svantaggio principale è che non copia i permessi. Se lo vuoi, la soluzione tar è migliore. Questa è una tecnica potente, in particolare se combinata con la magia xargs / bash per attraversare percorsi .. - markgo2k


Puoi usare lo script che ho scritto ispirato a questo argomento:

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

ma questo richiede alcune cose pazzesche (che è fatto automaticamente da script)

  1. il server a cui viene inviato il file non chiederà più la password mentre stabilisce la connessione SSH al computer di origine
  2. a causa della necessità di mancanza di prompt sudo sul server, sudo non chiederà più la password sulla macchina remota, per l'utente

Ecco la sceneggiatura:

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 sì, certo, scusa per il link, la sceneggiatura è piuttosto lunga e questa è stata la ragione :) - test30