Forzar a SSH a usar un shell específico

29

¿Hay alguna manera de obligar a SSH a usar un shell particular en el extremo remoto, independientemente de cuál sea el shell predeterminado del usuario?

He intentado soluciones similares a:

ssh host.domain.com /bin/bash -c 'complicated, multi-line command'

pero desafortunadamente, el shell predeterminado en el extremo remoto es responsable de analizar la parte del "comando complicado de varias líneas", y estoy teniendo dificultades para escapar lo suficiente como para que funcione tanto para los usuarios de shell Bash como para C.

plinehan
fuente

Respuestas:

8

No creo que esto sea posible, al menos con sistemas basados ​​en openssh. Si tiene la capacidad, una mejor solución podría ser crear un archivo de script de shell y luego ejecutarlo con el método que publicó. Tendría la ventaja de minimizar la cantidad de escape necesaria, pero dejaría un archivo que tendría que eliminarse (tal vez como el último paso del script).

sysadmin1138
fuente
1
Esto es lo que eventualmente hice, pero usando scp. Una gran idea.
plinehan
16

Use un heredoc:

ssh host.domain.com /bin/bash << EOF
big ugly commands
lots of them
EOF
Ignacio Vazquez-Abrams
fuente
¿No deberías usar "-s" para bash para leer comandos de stdin?
Weboide
No siempre es obligatorio.
Ignacio Vazquez-Abrams
Lo rechazaría si pudiera porque evita que los comandos tengan acceso a stdin y la pregunta era invocar un shell en particular.
Eric Woodruff
3
@EricWoodruff, ... invocar un shell particular (en este caso bash) es exactamente lo que muestra cómo hacer.
Charles Duffy el
1
FYI también puedes hacer cat /tmp/tempfile_containing_your_script ssh ${hostname} /bin/bash. Entonces, en lugar de un paso, tiene dos pasos: paso 1, copie el script en un archivo, paso 2, catel script en ssh.
Trevor Boyd Smith
10

Utilice inicios de sesión basados ​​en claves, no basados ​​en contraseña. Luego puede agregar una (lista de) "comandos forzados" a su clave ssh pública (en el campo "opciones" en el caso de SSH1) que está instalada en el servidor (en el archivo ~ / .ssh / Authorizedkeys para SSH1 , ~ / .ssh2 / autorización para SSH2).

Realice su comando forzado para que su shell deseado se llame ...

Más: puede asociar como máximo un comando forzado a una tecla determinada. Si necesita múltiples comandos forzados para diferentes propósitos, debe configurar diferentes teclas. (Por supuesto, puede poner varias cosas en una secuencia de comandos, que llama mediante un comando forzado. Pero tenga en cuenta que los comandos forzados siempre se ejecutan para una cuenta / clave determinada si el usuario inicia sesión, independientemente de si pidió algo diferente para ejecutar. Si aún desea respetar el comando original solicitado, eche un vistazo a cómo explotar la $SSH_ORIGINAL_COMMANDvariable ...

Lea sobre "comandos forzados" a través de Google .

Kurt Pfeifle
fuente
Buen material. Ese gráfico en la página de O'Reilly es muy agradable. Sin embargo, en mi caso particular, quiero poder forzar esto para cualquier usuario, no solo para los usuarios que han configurado sus claves correctamente. Tampoco tengo root en las máquinas del servidor, por lo que no puedo editar archivos como /etc/sshrc.
plinehan
Bueno, siempre es el servidor (o mejor: el que ejerce el control sobre el servidor) quien toma las decisiones cuando se conecta a su servicio ... El 'propietario' del servidor decide qué se puede hacer con él. - No puede forzar nada 'para ningún usuario' si no tiene mayores privilegios que ellos.
Kurt Pfeifle
Si el cliente puede ejecutar comandos arbitrarios, entonces el cliente también puede ejecutar un shell arbitrario como comando.
Eric Woodruff
@KurtPfeifle ese enlace a O'Reilly está roto
Brian Vandenberg
@BrianVandenberg: Gracias por la pista. Quité ese enlace ahora.
Kurt Pfeifle
2

Puede usar la -topción para forzar la asignación de un pseudo-tty para el programa que desea iniciar, como si estuviera ejecutando el shell estándar. Luego pase el shell que desea como un argumento simple y antiguo.

Con esta técnica, no solo puede usar cualquier shell instalado, sino que también puede abrir vim y otros programas que requieren un TTY, desde un solo comando. Lo cual es genial si estás escribiendo un script de shell que te conecta en algún lugar y abre un archivo en vim, htop o algo así.

me@my-machine $ ssh root@myhost -t bash
root@myhost:~# exit
Connection to myhost closed.
me@my-machine $ ssh root@myhost -t sh
# exit
Connection to myhost closed.
me@my-machine $ 

No estoy seguro de si se trata de un shell de inicio de sesión, pero hay opciones para hacer que bash actúe como un shell de inicio de sesión, por lo que su shell también puede tener eso.

Fábio Santos
fuente
1

Sorprendentemente veo diferentes resultados con lo siguiente:

correr en el tablero:

ssh eric@172.17.1.241 /bin/bash -c "echo <(cat)"                                              
sh: 1: Syntax error: "(" unexpected

vs bash:

ssh eric@172.17.1.241 '/bin/bash -c "echo <(cat)"'                                            
/dev/fd/63

Mostrar el comando entre comillas funciona como se esperaba.

Eric Woodruff
fuente
1
No es sorprendente en absoluto. El demonio ssh remoto se ejecuta efectivamente sh -c "$*". Por lo tanto, estás corriendo sh -c "/bin/bash -c echo <(cat)"; el echocomando en sí es el único argumento que se pasa -cy <(cat)es un argumento completamente diferente.
Charles Duffy el
0

Me enfrenté a una situación similar hace un tiempo, donde necesitaba usar ksh coprocess para sqlplus y solo tenía un ssh a través del cual las lecturas y escrituras deben tener lugar.

Una forma de hacerlo es canalizar todos sus comandos dependientes en una línea (use;) a / usr / bin / ksh en la máquina remota. por ejemplo:

host="user@host"

db_conn="ora_user/passwd"

a="select * from dual;"

frmt="set heading off echo off feedback off verify off pagesize 0 termout off"

var=$(ssh ${host} "echo 'sqlplus -silent /nolog |&; sql_pid=\$!; print -p \"conn ${db_conn}\"; print -p \"${frmt}\"; print -p \"${a}\"; print -p \"exit\"; wait \$sql_pid' > /remote_dir/kshcmd.txt; awk '{print \$0}' /remote_dir/kshcmd.txt | /usr/bin/ksh")
aws
fuente