web-dev-qa-db-fra.com

Comment copier des fichiers nécessitant un accès root avec scp?

J'ai un serveur Ubuntu auquel je me connecte via SSH.

Je dois télécharger des fichiers de ma machine dans /var/www/ sur le serveur. Les fichiers de /var/www/ appartiennent à root.

À l’aide de PuTTY, une fois connecté (e), je dois d’abord saisir Sudo su et mon mot de passe pour pouvoir modifier les fichiers dans /var/www/.

Mais lorsque je copie des fichiers à l'aide de WinSCP, je ne peux pas créer/modifier de fichiers dans /var/www/, car l'utilisateur avec lequel je me connecte n'a pas d'autorisations sur les fichiers dans /var/www/ et je ne peux pas dire Sudo su comme je le fais en cas de. une session SSH.

Savez-vous comment je pourrais gérer cela?

Si je travaillais sur ma machine locale, j'appellerais gksudo nautilus mais dans ce cas, je n'ai qu'un accès terminal à la machine.

158
Dimitris Sapikas

Vous avez raison, il n'y a pas Sudolorsque vous travaillez avec scpname__. Une solution de contournement consiste à utiliser scppour télécharger des fichiers dans un répertoire dans lequel votre utilisateur est autorisé à créer des fichiers, puis vous connecter via ssh et utiliser Sudopour déplacer/copier des fichiers vers leur destination finale.

scp -r folder/ [email protected]:/some/folder/you/dont/need/Sudo
ssh [email protected]
 $ Sudo mv /some/folder /some/folder/requiring/perms 
# YOU MAY NEED TO CHANGE THE OWNER like:
# Sudo chown -R user:user folder

Une autre solution serait de modifier les autorisations/la propriété des répertoires dans lesquels vous téléchargez les fichiers, afin que votre utilisateur non privilégié puisse écrire dans ces répertoires.

Généralement, travailler dans le compte rootdevrait être une exception, pas une règle - la façon dont vous formulez votre question me fait penser que vous en abusez peut-être un peu, ce qui entraîne des problèmes d'autorisations - dans des circonstances normales, ce n'est pas le cas besoin des privilèges de super administrateur pour accéder à vos propres fichiers.

Techniquement, vous pouvez configurer Ubuntu pour autoriser la connexion à distance directement en tant que rootname__, mais cette fonctionnalité est désactivée pour une raison, je vous déconseille donc fortement de le faire.

119
Sergey

Une autre méthode consiste à copier en utilisant tar + ssh au lieu de scp:

tar -c -C ./my/local/dir \
  | ssh [email protected] "Sudo tar -x --no-same-owner -C /var/www"
34
Willie Wheeler

Vous pouvez également utiliser ansiblepour accomplir cela.

Copier vers l'hôte distant à l'aide de module copyde ansible :

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

Récupération de l'hôte distant à l'aide de module fetchde ansible :

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

REMARQUE:

  • La virgule dans la syntaxe -i Host, n'est pas une faute de frappe. C'est la façon d'utiliser ansible sans avoir besoin d'un fichier d'inventaire.
  • -b provoque les actions sur le serveur en tant que root. -b se développe en --become, et le --become-user par défaut est la racine, avec le --become-method par défaut étant Sudo.
  • flat=yes copie seulement le fichier, ne copie pas le chemin d'accès distant complet menant au fichier
  • L'utilisation de caractères génériques dans les chemins de fichiers n'est pas prise en charge par ces modules ansible.
  • La copie d’un répertoire est prise en charge par par le module copyname__, mais non par le fetchmodule.

Invocation spécifique pour cette question

Voici un exemple spécifique et entièrement spécifié, en supposant que le répertoire de votre hôte local contenant les fichiers à distribuer est sourcediret que le nom d'hôte de la cible distante est hostnamename__:

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

Avec l'invocation concise étant:

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

P.S., je me rends compte que dire "viens d'installer ce fabuleux outil" est une sorte de réponse sourde et tonale. Mais j’ai trouvé ansible super utile pour l’administration de serveurs distants; son installation vous apportera donc d’autres avantages que le simple déploiement de fichiers.

25
erik.weathers

moyen rapide

Du serveur à la machine locale:

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

De la machine locale au serveur:

cat /home/user/file | ssh user@server "Sudo tee -a /etc/dir/file"
19
Anderson Lira

Lorsque vous exécutez Sudo su, tous les fichiers que vous créez seront la propriété de root, mais il n'est pas possible par défaut de se connecter directement en tant que root avec ssh ou scp. Il n’est pas possible non plus d’utiliser Sudo avec scp, les fichiers ne sont donc pas utilisables. Corrigez cela en revendiquant la propriété de vos fichiers:

En supposant que votre nom d’utilisateur soit dimitri, vous pouvez utiliser cette commande.

Sudo chown -R dimitri:dimitri /home/dimitri

À partir de là, comme indiqué dans d’autres réponses, la méthode "Ubuntu" consiste à utiliser Sudo et non les connexions à la racine. C'est un paradigme utile, avec de grands avantages en termes de sécurité.

12
trognanders

Peut-être que le meilleur moyen est d'utiliser rsync ( Cygwin / cwRsync dans Windows) sur SSH?

Par exemple, pour télécharger des fichiers avec le propriétaire www-data:

rsync -a --rsync-path="Sudo -u www-data rsync" path_to_local_data/ [email protected]:/var/www

Dans votre cas, si vous avez besoin de privilèges root, la commande sera comme ceci:

rsync -a --rsync-path="Sudo rsync" path_to_local_data/ [email protected]:/var/www

Voir: scp sur un serveur distant avec Sudo .

9
Alexey Vazhnov

Si vous utilisez les outils OpenSSH au lieu de PuTTY, vous pouvez le faire en lançant le transfert de fichier scp sur le serveur avec Sudo. Assurez-vous qu'un démon sshd est en cours d'exécution sur votre ordinateur local. Avec ssh -R, vous pouvez donner au serveur un moyen de contacter votre ordinateur.

Sur votre machine:

ssh -R 11111:localhost:22 REMOTE_USERNAME@SERVERNAME

En plus de vous connecter au serveur, cela transférera chaque connexion établie sur le port 11111 du serveur vers le port 22 de votre ordinateur: le port sur lequel votre sshd est à l'écoute.

Sur le serveur, démarrez le transfert de fichier comme ceci:

cd /var/www/
Sudo scp -P 11111 -r LOCAL_USERNAME@localhost:FOLDERNAME .
5
bergoid

Vous pouvez utiliser le script que j'ai écrit en s'inspirant de ce sujet:

touch /tmp/justtest && scpassudo /tmp/justtest [email protected]:/tmp/

mais cela nécessite des trucs déjantés (ce qui est d'ailleurs fait automatiquement par script)

  1. le serveur auquel le fichier est envoyé ne demandera plus de mot de passe lors de l'établissement d'une connexion SSH à l'ordinateur source
  2. en raison de la nécessité du manque d’invitation de Sudo sur le serveur, Sudo ne demandera plus de mot de passe sur la machine distante, pour l’utilisateur.

Voici le script:

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 [email protected]:/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
test30

Vous pouvez combiner ssh, Sudo et, par exemple, tar pour transférer des fichiers entre serveurs sans pouvoir vous connecter en tant que root et ne pas avoir l'autorisation d'accéder aux fichiers avec votre utilisateur. C'est un peu délicat, alors j'ai écrit un script pour aider ceci. Vous pouvez trouver le script ici: https://github.com/sigmunau/sudoscp

ou ici:

 #! /bin/bash
res=0
from=$1
to=$ 2[.____.HERshift[.____.HERshift
files="$@ "
 if test -z" $ de "-o -z" $ à "-o -z" $ fichiers "
 puis 
 echo" Utilisation: $ 0 (fichier) * Exemple "
 echo": $ 0 server1 server2 /usr/bin/myapp"
 exit 1 
 fi 
 
 read -s -p "Entrée Mot de passe: "sudopassword 
 Echo" "
 Temp1 = $ (mktemp) 
 Temp2 = $ (mktemp) 
 (Echo" $ sudopassword "; echo" $ sudopassword "| ssh $ de Sudo -S tar c -P -C/$ fichiers 2> $ temp1) | ssh $ vers Sudo -S tar x -v -P -C/2> $ temp2 
 sourceres = $ {PIPESTATUS [0]} 
 Si [$? -ne 0 -o $ sourceres -ne 0] 
 puis 
 écho "échec!" > & 2 
 Echo "$ from output:"> & 2 
 Cat $ temp1> & 2 
 Echo ""> & 2 
 Echo "$ to output:"> & 2 
 cat $ temp2> & 2 
 res = 1 
 fi 
 
 rm $ temp1 $ temp2 
 sortie $ res 
1
sigmunda

Voici une version modifiée de la réponse de Willie Wheeler qui transfère le ou les fichiers via tar, mais prend également en charge la transmission d'un mot de passe à Sudo sur l'hôte distant.

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

Le peu de magie supplémentaire ici est l'option -S de Sudo. De la page de manuel Sudo:

-S, --stdin Ecrit l'invite sur l'erreur standard et lit le mot de passe à partir de l'entrée standard au lieu d'utiliser le terminal. Le mot de passe doit être suivi d'un caractère de nouvelle ligne.

Nous voulons maintenant que la sortie de tar soit acheminée vers ssh, ce qui redirige le stdin de ssh vers la sortie standard de tar, supprimant ainsi tout moyen de transmettre le mot de passe à Sudo à partir du terminal interactif. (Nous pourrions utiliser la fonction ASKPASS de Sudo sur le site distant, mais ceci est une autre histoire.) Nous pouvons toutefois entrer le mot de passe dans Sudo en le capturant à l'avance et en le ajoutant à la sortie du fichier tar en effectuant ces opérations dans un sous-shell et en transférant la sortie du fichier. le sous-shell dans SSH. Cela présente également l’avantage supplémentaire de ne pas laisser une variable d’environnement contenant notre mot de passe suspendu dans notre shell interactif.

Vous remarquerez que je n'ai pas exécuté 'read' avec l'option -p pour imprimer une invite. En effet, l'invite de mot de passe de Sudo est facilement renvoyée à stderr de notre shell interactif via ssh. Vous vous demandez peut-être "comment l'exécution de Sudo est-elle exécutée dans la mesure où il fonctionne à l'intérieur de ssh, à droite de notre pipe?" Lorsque nous exécutons plusieurs commandes et que nous transmettons la sortie de l'une à l'autre, le Shell parent (le shell interactif dans ce cas) exécute chaque commande dans la séquence immédiatement après l'exécution de la précédente. Lorsque chaque commande derrière un canal est exécutée, le Shell parent attache (redirige) la sortie standard du côté gauche au stdin du côté droit. La sortie devient alors une entrée à mesure qu'elle passe par des processus. Nous pouvons le voir en action en exécutant l'intégralité de la commande et en mettant en arrière-plan le groupe de processus (Ctrl-z) avant de saisir notre mot de passe, puis en affichant l'arbre de processus.

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

Notre shell interactif est le PID 7168, notre sous-shell est le PID 7969 et notre processus SSH est le PID 7970.

Le seul inconvénient est que read acceptera les entrées avant que Sudo ait le temps de renvoyer son invite. Sur une connexion rapide et un hôte distant rapide, vous ne le remarquerez pas, mais vous pourriez le faire si l'un ou l'autre est lent. Tout retard n'affectera pas la possibilité d'entrer dans l'invite; il se peut qu’il apparaisse une fois que vous avez commencé à taper.

Remarque J'ai simplement ajouté une entrée de fichier hôte pour "remote_Host" à ma machine locale pour la démo.

0
Bruce