¿Por qué el $ PATH de un comando remoto ssh difiere del de un shell interactivo?

20

Tengo un usuario que no ha realizado modificaciones en $ PATH en ningún archivo de puntos: es exactamente la configuración predeterminada del sistema. Desde un shell de inicio de sesión:

$ ssh example.com
user@example.com:~$ cat /tmp/hello.hs
#!/bin/bash

echo "$SHELL"
echo "$PATH"

user@example.com:~$ /tmp/hello.hs
/bin/bash
/usr/local/bin:/usr/bin:/bin

Exactamente como se especifica en /etc/profile. Esto me parece bastante inesperado:

$ ssh example.com '/tmp/hello.sh'
/bin/bash       
/usr/local/bin:/usr/bin:/bin:/usr/bin/X11:/usr/games

Como dije, no hay modificación de $ PATH en ~/.bashrc, ni en /etc/bash.bashrc. No ~/.ssh/environmenttampoco El ssh(1)declara que la variable de entorno PATHes

Establezca la RUTA predeterminada, como se especifica al compilar ssh.

pero este hilo de StackOverflow y este artículo de la lista de correo sugieren que debería poder influir en $ PATH para un comando dado simplemente modificando / etc / profile, uno de los archivos de inicio de shell, etc.

¿Que está pasando aqui?

trucha
fuente

Respuestas:

16

De ssh(1)la página del manual: "Si se especifica el comando, se ejecuta en el host remoto en lugar de un shell de inicio de sesión".

En resumen, cuando realmente inicia sesión en la máquina bash se inicia como un shell de inicio de sesión y carga los archivos apropiados, cuando se conecta de forma remota y emite un comando, se ejecuta en lugar de bash, lo que significa que estos archivos NO se cargan. Puede solucionarlo utilizando su -l -co similar en la parte de comando de ssh.

En algunos casos, también he visto -targumentos para el trabajo ssh (asignar tty).

Edición 1 :
creo que la información de RUTA que encontró, que la ruta predeterminada (a menos que la anulemos) es la compilada en sshd. Me aseguré de que mi / etc / profile, / etc / bash *, los archivos de puntos locales, etc. no tenían ninguna información de RUTA, luego inicié sesión y todavía tenía una RUTA. Busqué este en sshd y lo encontré allí. Así es como dice la página de manual:

ahnberg@remote$ strings /usr/sbin/sshd | grep -i x11 | grep bin
/usr/local/bin:/usr/bin:/bin:/usr/bin/X11:/usr/games

Luego agrego PATH=$PATH:/my/testa la parte superior de mi .bashrcarchivo en el control remoto y lo verifico nuevamente:

ahnberg@local$ ssh ahnberg@remote "env | grep PATH"
PATH=/usr/local/bin:/usr/bin:/bin:/usr/bin/X11:/usr/games:/my/test

Así que puedo influenciarlo absolutamente, y la RUTA predeterminada es la que se compila en sshd. :)

Mattias Ahnberg
fuente
Hmm, creo que esa frase "ejecutada en el host remoto" significa mucho más de lo que dice. La parte más interesante, que me perdí antes, viene en la sección 'AMBIENTE' de la misma página de manual: "RUTA Establecida en la RUTA predeterminada, como se especifica al compilar ssh". Excepto que esto sugiere que debería poder influir en la RUTA de un comando.
Troutwine
Bueno, el punto es que no es un shell de inicio de sesión, por lo que no se ejecuta / fuente / incluye los archivos de inicio de la misma manera que para un shell de inicio de sesión, de ahí mis sugerencias para probar. Poner las cosas también .bashrcpodría funcionar, pero en general lo solucionaría si PATH es importante. ¿O por qué no simplemente especificar nombres de ruta completos si necesita la forma 'comando' de ejecutar ssh? :)
Mattias Ahnberg
He editado mi publicación un poco. Ahora, hay un shell de inicio de sesión, un shell de no inicio de sesión y sus variantes interactivas / no interactivas. Los comandos SSH se invocan en el shell del usuario en forma no interactiva y sin inicio de sesión. La bash(1)INVOCACIÓN sugiere que no se leen archivos de inicio de esta manera, pero no puedo encontrar documentación sobre cómo ssh invoca el shell. Esto parece contrario a las fuentes vinculadas anteriores, a menos que otros tengan un archivo de inicio / etc / ssh / sshrc que yo no tenga. (Existen soluciones alternativas, por supuesto, pero el punto es comprender exactamente cómo Debian SSHD maneja las rutas por defecto)
Troutwine
Si modifico PATH en /etc/profilelas actualizaciones de ruta de mi cuadro remoto para mí, entonces ssh user@remotebox 'env'me muestra el PATH actualizado. Lo mismo ocurre si agrego export PATH=$PATH:/my/testpatha .bashrc (pero en mi caso en la parte superior del archivo antes de comprobar si hay shells interactivos ( -z "$PS1").
Mattias Ahnberg
Actualizado con mis pruebas / hallazgos.
Mattias Ahnberg
3

Pude hacer que ssh ejecutara comandos usando la ruta remota ejecutando:

ssh dist@d6 "bash --login -c 'env'"

Aquí env puede ser reemplazado con cualquier comando que desee.

Tengo claves autorizadas, así que no necesitaba una contraseña para ejecutar el comando o ssh.

Ian
fuente
3

Se me ocurrió una solución diferente para solucionar el problema. Mi preferencia personal es crear nuevos archivos de configuración en lugar de alterar los existentes. De esta manera, puedo facilitar el cambio de la configuración predeterminada.

Aquí están los contenidos de /etc/profile.d/ssh_login.sh:

#!/bin/sh
if [ "$SSH_CONNECTION" ]; then
    echo "User '$USER' logged in from '${SSH_CONNECTION%% *}'"
    . /etc/environment
fi

Utilizando dropbearen lugar de openssh-server(esto también debería funcionar con openssh), la variable SSH_CONNECTION se configura automáticamente cuando inicio sesión de forma remota. Creé una nueva configuración de perfil de shell para detectar inicios de sesión SSH, mostrar cierta información en la pantalla y, lo más importante, cargar la configuración del entorno global /etc/environmentpara reemplazar los valores compilados. Tenga en cuenta que esto solo afecta a los shells interactivos SSH, no a la ejecución remota de comandos.

Alternativamente , si usa openssh y siempre desea cargar el entorno global, independientemente de si se trata de un shell interactivo, puede colocar un enlace simbólico de ~/.ssh/esta manera:

ln -s /etc/environment ~/.ssh/environment

Entonces debe habilitar la PermitUserEnvironmentopción en /etc/sshd/sshd_config. Sin embargo, solo haga esto para usuarios confiables, ya que esto podría permitirles eludir las restricciones de acceso en algunas configuraciones utilizando mecanismos como LD_PRELOAD. Consulte man sshd_configpara obtener más información, específicamente cómo usar Matchbloques para restringir las opciones a usuarios / grupos específicos.

taquilato
fuente
0

Si desea que se cargue la ruta del perfil, intente:

#!/bin/bash -i

en la parte superior del guión. De esta forma, el shell está en modo interactivo cuando ejecuta el script.

Cuando se invoca bash como un shell de inicio de sesión interactivo o como un shell no interactivo con la opción --login, primero lee y ejecuta comandos del archivo / etc / profile, si ese archivo existe. Después de leer ese archivo, busca ~ / .bash_profile, ~ / .bash_login y ~ / .profile, en ese orden, y lee y ejecuta comandos del primero que existe y es legible. La opción --noprofile se puede usar cuando se inicia el shell para inhibir este comportamiento.

http://linux.die.net/man/1/bash

Adam Brand
fuente