82 votos

¿Cómo puedo ejecutar arbitrariamente complejas comando con sudo ssh?

Tengo un sistema que sólo puedo iniciar sesión en virtud de mi nombre de usuario (usuario), pero necesito ejecutar comandos como otro usuario (scriptuser). Hasta el momento, he llegado a la siguiente para ejecutar los comandos que necesito:

ssh -tq myuser@hostname "sudo -u scriptuser bash -c \"ls -al\""

Si, sin embargo, cuando intento ejecutar un más complejo de comando, como por ejemplo [[ -d "/tmp/Some directory" ]] && rm -rf "/tmp/Some directory" rápidamente me meten en problemas con cita. No estoy seguro de cómo me podría pasar este ejemplo de comando compleja a bash -c, cuando \" ya delimites de los límites del comando que estoy pasando (y por lo tanto no sé cómo citar /tmp/algo de directorio, que incluye espacios.

Hay una solución general lo que me permite pasar cualquier comando no importa cuán complejo/loco de la comilla es, o se trata de algún tipo de limitación que he llegado? Hay otros posibles, y tal vez más legible soluciones?

150voto

ThoriumBR Puntos 2198

Un truco que uso a veces es el uso de base64 para codificar los comandos, y la tubería de bash en el otro sitio:

MYCOMMAND=`base64 -w0 script.sh`
ssh user@remotehost "echo $MYCOMMAND | base64 -d | sudo bash"

Esto se codifican la secuencia de comandos, con comas, barras, cita y variables dentro de una cadena segura, y enviarlo a otro servidor. (-w0 es necesario desactivar el ajuste de línea, lo que ocurre en la columna de 76 por defecto). Por otro lado, base64 -d decodificar la secuencia de comandos y alimentar a bash para ser ejecutado.

Nunca he tenido ningún problema con ella, no importa la complejidad de la secuencia de comandos. Resuelve el problema con el escape, ya que usted no necesita para escapar nada. No se crea un archivo en el host remoto, y puede ejecutar muy scripts complicados con facilidad.

35voto

moebius_eye Puntos 576

Ver el -tt opción? Leer el ssh(1) manual.

ssh -tt root@host << EOF
sudo some # sudo shouldn't ask for a password, otherwise, this fails. 
lines
of
code 
but be careful with \$variables
and \$(other) \`stuff\`
exit # <- Important. 
EOF

Una cosa que me suelen hacer es usar vim y el uso de la :!cat % | ssh -tt somemachine truco.

10voto

Sybren Puntos 186

Creo que la solución más sencilla se encuentra en una modificación de @thanasisk del comentario.

Crear una secuencia de comandos, scp a la máquina, a continuación, ejecutarlo.

Tiene el guión rm sí en el inicio. El shell tiene abierto el archivo, así que ha sido cargado, y se puede eliminar sin problemas.

Haciendo las cosas en este orden (rm primera, otras cosas de segundo) se puede incluso ser eliminado cuando se produce un error en algún momento.

8voto

Tom Fenech Puntos 141

Usted puede utilizar el %q especificador de formato con printf a cuidar de la variable de escape para usted:

cmd="ls -al"
printf -v cmd_str '%q' "$cmd"
ssh user@host "bash -c $cmd_str"

printf -v escribe el resultado en una variable (en este caso, $cmd_str). Creo que esta es la manera más sencilla de hacerlo. No hay necesidad de transferir cualquier archivo o codificar la cadena de comando (por mucho que me guste el truco).

He aquí un ejemplo más complejo, demostrando que funciona para cosas como corchetes y signos:

$ ssh user@host "ls -l test"
-rw-r--r-- 1 tom users 0 Sep  4 21:18 test
$ cmd="[[ -f test ]] && echo 'this really works'"
$ printf -v cmd_str '%q' "$cmd"
$ ssh user@host "bash -c $cmd_str"
this really works

Yo no lo he probado con sudo pero debe ser tan simple como:

ssh user@host "sudo -u scriptuser bash -c $cmd_str"

Si lo desea, puede omitir un paso y evitar la creación de la variable intermedia:

$ ssh user@host "bash -c $(printf '%q' "$cmd")"
this really works

O incluso sólo de evitar la creación de una variable completamente:

ssh user@host "bash -c $(printf '%q' "[[ -f test ]] && echo 'this works as well'")"

5voto

jpcooper Puntos 41

¿Sabe usted que usted puede utilizar sudo para darle una shell donde se pueden ejecutar comandos como el usuario que ha elegido?

-i, --de inicio de sesión

Ejecutar el intérprete de comandos especificado por el usuario objetivo de la contraseña de entrada de base de datos como un shell de inicio de sesión. Esto significa que de inicio de sesión-archivos de recursos específicos, tales como .o de perfil .inicio de sesión va a ser leído por la consola. Si un comando se especifica, se pasa a la shell para la ejecución a través de la shell de la opción-c. Si no comando se especifica, un shell interactivo es ejecutado. sudo intentos para cambiar a ese directorio home del usuario antes de ejecutar el shell. La com‐ mand que se ejecuta con un entorno similar a la que el usuario recibe en el registro. El Comando de la sección de medio Ambiente en el sudoers(5) manual de docu‐ ments cómo la opción-i afecta el entorno en el que se ejecuta un comando cuando el sudoers política está en uso.

EnMiMaquinaFunciona.com

EnMiMaquinaFunciona es una comunidad de administradores de sistemas en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros sysadmin, hacer tus propias preguntas o resolver las de los demás.

Powered by: