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.
Vous avez raison, il n'y a pas Sudo
lorsque vous travaillez avec scp
name__. Une solution de contournement consiste à utiliser scp
pour 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 Sudo
pour 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 root
devrait ê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 root
name__, mais cette fonctionnalité est désactivée pour une raison, je vous déconseille donc fortement de le faire.
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"
Vous pouvez également utiliser ansible
pour accomplir cela.
copy
de ansible :ansible -i Host, -b -m copy -a "src=SRC_FILEPATH dest=DEST_FILEPATH" all
fetch
de ansible :ansible -i Host, -b -m fetch -a "src=SRC_FILEPATH dest=DEST_FILEPATH flat=yes" all
REMARQUE:
-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 fichiercopy
name__, mais non par le fetch
module.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 sourcedir
et que le nom d'hôte de la cible distante est hostname
name__:
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.
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"
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é.
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
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 .
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)
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
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
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.