python - ¿Puedo evitar que la tela me pida una contraseña de sudo?
fabric (8)
Estoy utilizando Fabric para ejecutar comandos en un servidor remoto. El usuario con el que me conecto en ese servidor tiene algunos privilegios de sudo, y no requiere una contraseña para usar estos privilegios. Cuando SSH''ing en el servidor, puedo ejecutar sudo blah
y el comando se ejecuta sin pedir una contraseña. Cuando intento ejecutar el mismo comando a través de la función sudo
de Fabric, me piden una contraseña. Esto se debe a que Fabric construye un comando de la siguiente manera cuando usa sudo
:
sudo -S -p <sudo_prompt> /bin/bash -l -c "<command>"
Obviamente, mi usuario no tiene permiso para ejecutar /bin/bash
sin una contraseña.
He resuelto el problema usando run("sudo blah")
lugar de sudo("blah")
, pero me pregunto si hay una solución mejor. ¿Hay una solución para este problema?
En su /etc/sudoers
, podría agregar
user ALL=NOPASSWD: /bin/bash
... donde user
es tu nombre de usuario de Fabric.
Obviamente, solo puede hacer esto si tiene acceso de root, ya que /etc/sudoers
solo se puede escribir por root.
Obviamente, esto no es terriblemente seguro, ya que ser capaz de ejecutar /bin/bash
te deja abierto a prácticamente cualquier cosa, así que si no tienes acceso de root y tienes que pedirle a un administrador de sistemas que haga esto por ti, probablemente ganen ''t
En su archivo / etc / sudoers agregue
user ALL=NOPASSWD: some_command
donde usuario es sudo sudo y some_command el comando que desea ejecutar con fabric, luego en el script de estructura ejecute sudo con shell = False:
sudo(''some_command'', shell=False)
esto funciona para mi
Esta es la respuesta más directa a su pregunta: en realidad no tiene un problema; malinterpretas cómo funcionan Fabric run () y sudo ().
Su "solución alternativa" NO es una solución alternativa, es la respuesta 100% válida al problema.
Aquí hay un conjunto simple de reglas: 1) Use "ejecutar ()" cuando no espere un aviso. 2) use "sudo ()" cuando espere un aviso. (Esto debería ser cierto para todos o la mayoría de los comandos que requieren una solicitud, incluso si el ejecutable en cuestión no es Bash o Sudo).
Esta misma respuesta se aplica a las personas que intentan ejecutar comandos en "sudo". Incluso si sudoers tiene una configuración sin contraseña para el usuario actual en algún sistema, si usa sudo () en lugar de run (), forzará una solicitud (a menos que el código de Fabric ya contenga una contraseña o clave ENV).
Por cierto, el autor de Fabric respondió a mi pregunta, muy similar a su pregunta, en #IRC. Buen chico, uno de los héroes anónimos de código abierto por persistir en su trabajo Fabric y Paramiko.
... En mi entorno de prueba, siempre hay 1 nombre de usuario que tiene acceso completo sin contraseña a sudo. Escribir sudo echo hello
no me avisará. Además, ese usuario sudo está configurado con "! Requiretty" para que todos los comandos puedan ejecutarse sobre SSH (como SSH saltando entre hosts). Esto significa que simplemente puedo usar "run ()" para ejecutar "sudo something", pero es solo otro comando que se ejecuta sin un aviso. En lo que respecta a la seguridad, el trabajo de alguien es bloquear un host de producción pero no un host de prueba. (Si está siendo forzado a probar cosas por y no puede automatizar, ese es un gran problema).
Intenta pasar shell=False
a sudo. De esa manera / bin / bash no se agregará al comando sudo. sudo(''some_command'', shell=False)
De la línea 503 de fabric/operations.py :
if (not env.use_shell) or (not shell):
real_command = "%s %s" % (sudo_prefix, _shell_escape(command))
el bloque else se ve así:
# V-- here''s where /bin/bash is added
real_command = ''%s %s "%s"'' % (sudo_prefix, env.shell,
_shell_escape(cwd + command))
Noob de Linux aquí, pero encontré esta pregunta al intentar instalar el tejido de grafito en un AMI EC2. La tela siguió pidiendo una contraseña de root.
El truco evntual consistía en pasar el archivo de clave privada ssh al tejido.
fab -i key.pem graphite_install -H root@servername
Puedes usar:
fabric.api import env
# [...]
env.password = ''yourpassword''
Recientemente enfrenté este mismo problema y encontré confusa la answer de Crossfit_and_Beer.
Una forma compatible de lograrlo es mediante el uso de env.sudo_prefix
, como se documenta en este github commit (de este PR )
Mi ejemplo de uso:
env.sudo_prefix = ''sudo ''
También puedes usar contraseñas para múltiples máquinas:
from fabric import env
env.hosts = [''user1@host1:port1'', ''[email protected]'']
env.passwords = {''user1@host1:port1'': ''password1'', ''[email protected]'': ''password2''}
Ver esta respuesta: https://.com/a/5568219/552671