J'utilise Fabric pour exécuter des commandes sur un serveur distant. L'utilisateur avec lequel je me connecte sur ce serveur dispose de certains privilèges Sudo et n'a pas besoin d'un mot de passe pour utiliser ces privilèges. Lors de la connexion SSH au serveur, je peux exécuter Sudo blah
Et la commande s'exécute sans demander de mot de passe. Lorsque j'essaie d'exécuter la même commande via la fonction Sudo
de Fabric, on me demande un mot de passe. Cela est dû au fait que Fabric crée une commande de la manière suivante lors de l'utilisation de Sudo
:
Sudo -S -p <Sudo_Prompt> /bin/bash -l -c "<command>"
De toute évidence, mon utilisateur n'est pas autorisé à exécuter /bin/bash
Sans mot de passe.
J'ai contourné le problème en utilisant run("Sudo blah")
au lieu de Sudo("blah")
, mais je me suis demandé s'il y avait une meilleure solution. Existe-t-il une solution de contournement à ce problème?
Essayez de passer Shell=False
À Sudo. De cette façon,/bin/bash ne sera pas ajouté à la commande Sudo. Sudo('some_command', Shell=False)
De la ligne 503 de fabric/operations.py :
if (not env.use_Shell) or (not Shell):
real_command = "%s %s" % (Sudo_prefix, _Shell_escape(command))
le bloc else ressemble à ceci:
# V-- here's where /bin/bash is added
real_command = '%s %s "%s"' % (Sudo_prefix, env.Shell,
_Shell_escape(cwd + command))
Vous pouvez utiliser:
fabric.api import env
# [...]
env.password = 'yourpassword'
C'est la réponse la plus directe à votre question: vous n'avez pas réellement de problème; vous vous méprenez sur le fonctionnement de Fabric run () et Sudo ().
Votre "solution de contournement" n'est PAS une solution de contournement, c'est la réponse 100% valide au problème.
Voici un ensemble simple de règles: 1) Utilisez "run ()" lorsque vous ne vous attendez pas à une invite. 2) utilisez "Sudo ()" lorsque vous vous attendez à une invite. (cela devrait être vrai pour toutes ou la plupart des commandes nécessitant une invite, même si l'exécutable en question n'est pas Bash ou Sudo).
Cette même réponse s'applique aux gens qui essaient d'exécuter des commandes sous "Sudo". Même si sudoers a une configuration sans mot de passe pour l'utilisateur actuel sur un système, si vous utilisez Sudo () au lieu de run (), vous forcerez une invite (sauf si le code Fabric contient déjà un mot de passe ou une clé ENV).
BTW, l'auteur de Fabric a répondu à ma question - très similaire à votre question - dans #IRC. Nice guy, l'un des héros méconnus de l'open source pour avoir persisté dans son travail Fabric et Paramiko.
... Dans mon environnement de test, il y a toujours 1 nom d'utilisateur qui a un accès complet sans mot de passe à Sudo. Taper Sudo echo hello
ne me demandera pas. De plus, cet utilisateur Sudo est configuré avec "! Cela signifie que je peux simplement utiliser "run ()" avec pour exécuter "Sudo something", mais c'est juste une autre commande qui s'exécute sans invite. En ce qui concerne la sécurité, c'est le travail de quelqu'un de verrouiller un hôte de production mais pas un hôte de test. (Si vous êtes obligé de tester des choses par et et ne pouvez pas automatiser, c'est un énorme problème).
Dans votre fichier/etc/sudoers, ajoutez
user ALL=NOPASSWD: some_command
où user est votre utilisateur Sudo et some_command la commande que vous souhaitez exécuter avec fabric, puis sur le script fabric exécutez Sudo avec Shell = False:
Sudo('some_command', Shell=False)
ça marche pour moi
Dans ton /etc/sudoers
fichier, vous pouvez ajouter
user ALL=NOPASSWD: /bin/bash
... où user
est votre nom d'utilisateur Fabric.
Évidemment, vous ne pouvez le faire que si vous avez un accès root, comme /etc/sudoers
n'est accessible en écriture que par root.
De toute évidence, ce n'est pas très sûr, car pouvoir exécuter /bin/bash
vous laisse essentiellement ouvert à tout, donc si vous n'avez pas d'accès root et devez demander à un administrateur système de le faire pour vous, ils ne le feront probablement pas.
Noob Linux ici, mais j'ai trouvé cette question en essayant d'installer du tissu graphite sur une AMI EC2. Fabric a continué à demander un mot de passe root.
L'astuce consistait à passer le fichier de clé privée ssh à fabric.
fab -i key.pem graphite_install -H root@servername
Vous pouvez également utiliser des mots de passe pour plusieurs machines:
from fabric import env
env.hosts = ['user1@Host1:port1', '[email protected]']
env.passwords = {'user1@Host1:port1': 'password1', '[email protected]': 'password2'}
Voir cette réponse: https://stackoverflow.com/a/5568219/552671
J'ai récemment rencontré ce même problème et j'ai trouvé Crossfit_and_Beer réponse déroutant.
Un moyen pris en charge pour y parvenir consiste à utiliser env.Sudo_prefix
, comme documenté par cette validation github (à partir de ce PR )
Mon exemple d'utilisation:
env.Sudo_prefix = 'Sudo '