Perché $ PATH di un comando remoto ssh differisce da quello di una shell interattiva?


20

Ho un utente che non ha apportato modifiche a $ PATH in nessun file dot: è esattamente l'impostazione predefinita del sistema. Da una shell di login:

$ 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

Esattamente come specificato in /etc/profile. Questo lo trovo piuttosto inaspettato:

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

Come ho detto, non c'è alcuna modifica di $ PATH ~/.bashrcné in /etc/bash.bashrc. No ~/.ssh/environmentneanche. L' ssh(1)dichiara che la variabile d'ambiente PATHè

Impostato sul PATH predefinito, come specificato durante la compilazione di ssh.

ma questo thread di StackOverflow e questo articolo della mailing list suggeriscono che dovrei essere in grado di influenzare $ PATH per un dato comando semplicemente modificando / etc / profile, uno dei file di avvio della shell, ecc.

Cosa sta succedendo qui?

Risposte:


16

Dalla ssh(1)pagina del manuale: "Se viene specificato un comando, viene eseguito sull'host remoto anziché su una shell di accesso."

Quindi, in breve, quando si accede effettivamente alla macchina bash viene avviato come shell di accesso e carica i file appropriati, quando ci si collega in remoto e si emette un comando, viene eseguito al posto di bash, il che significa che questi file NON vengono caricati. Puoi aggirare il problema usando su -l -co simili nella parte di comando di ssh.

In alcuni casi ho visto anche delle -tdiscussioni su ssh work (allocare tty).

Modifica 1 :
Penso che le informazioni sul PERCORSO che hai trovato, che il percorso predefinito (a meno che non lo sostituiamo) sia quello compilato in sshd. Mi sono assicurato che il mio / etc / profile, / etc / bash *, dotfile locali, ecc. Non contenessero alcuna informazione PATH, quindi ho effettuato l'accesso e avevo ancora un PATH. Ho cercato questo in sshd e l'ho trovato lì. Quindi è come dice la manpage:

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

Quindi aggiungo PATH=$PATH:/my/testall'inizio del mio .bashrcfile sul telecomando e ricontrollo:

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

Quindi posso assolutamente influenzarlo e il PATH predefinito è quello compilato in sshd. :)


Hmm, quella frase "eseguita sull'host remoto" significa molto di più di quello che dice, penso. Il bit più interessante, che mi mancava in precedenza, si trova nella sezione "AMBIENTE" della stessa manpage: "PATH Impostato sul PATH predefinito, come specificato durante la compilazione di ssh." Tranne questo suggerisce che dovrei essere in grado di influenzare il PERCORSO di un comando.
Troutwine,

Bene, il punto è che non è una shell di login, quindi non esegue / source / include i file di avvio allo stesso modo di una shell di login, quindi i miei suggerimenti per provarlo. Anche mettere le cose .bashrcpotrebbe funzionare, ma nel complesso ci proverei se PATH è importante. O perché non specificare solo percorsi completi se hai bisogno del modo 'comando' di eseguire ssh? :)
Mattias Ahnberg

Ho modificato leggermente il mio post. Ora, c'è una shell di login, una shell non di login e varianti interattive / non interattive della stessa. I comandi SSH vengono invocati nella shell dell'utente in forma non interattiva non di accesso. L' bash(1)INVOCAZIONE suggerisce che nessun file di avvio viene letto in questo modo, ma non riesco a trovare la documentazione su come ssh sta invocando la shell. Questo sembra in contrasto con le fonti collegate sopra, a meno che altri non abbiano il file di avvio / etc / ssh / sshrc che non ho. (Ci sono soluzioni alternative, ovviamente, ma il punto è capire esattamente come Debian SSHD gestisce i percorsi di default.)
troutwine

Se modifico il PERCORSO /etc/profilesul mio aggiornamento del percorso della casella remota per me, quindi ssh user@remotebox 'env'mi mostra il PERCORSO aggiornato. La stessa cosa vale se aggiungo export PATH=$PATH:/my/testpatha .bashrc (ma nel mio caso in cima al file prima di controllare le shell interattive ( -z "$PS1").
Mattias Ahnberg

Aggiornato con i miei test / risultati.
Mattias Ahnberg,

3

Sono stato in grado di ottenere ssh per eseguire comandi utilizzando il percorso remoto eseguendo:

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

Qui env può essere sostituito con qualsiasi comando tu voglia.

Ho chiavi autorizzate, quindi non avevo bisogno di una password per eseguire il comando o ssh.


3

Ho trovato una soluzione diversa per risolvere il problema. La mia preferenza personale è quella di creare nuovi file di configurazione invece di modificare quelli esistenti. In questo modo posso semplificare più facilmente le modifiche dalla configurazione predefinita.

Ecco i contenuti di /etc/profile.d/ssh_login.sh:

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

Usando dropbearal posto di openssh-server(questo dovrebbe funzionare anche con openssh), la variabile SSH_CONNECTION viene impostata automaticamente quando eseguo l'accesso in remoto. Ho creato una nuova configurazione del profilo della shell per rilevare gli accessi SSH, visualizzare alcune informazioni sullo schermo e, soprattutto, caricare le impostazioni globali dell'ambiente /etc/environmentper sostituire i valori compilati. Si noti che ciò riguarda solo le shell SSH interattive, non l'esecuzione dei comandi remoti.

In alternativa , se usi openssh e vuoi sempre caricare l'ambiente globale, indipendentemente dal fatto che si tratti di una shell interattiva, puoi inserire un link simbolico in ~/.ssh/questo modo:

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

Quindi è necessario abilitare l' PermitUserEnvironmentopzione in /etc/sshd/sshd_config. Fallo solo per utenti fidati, poiché ciò potrebbe consentire loro di aggirare le restrizioni di accesso in alcune configurazioni utilizzando meccanismi come LD_PRELOAD. Per man sshd_configulteriori informazioni, vedere in particolare come utilizzare i Matchblocchi per vincolare le opzioni a utenti / gruppi specifici.


0

Se vuoi caricare il percorso del profilo, prova:

#!/bin/bash -i

nella parte superiore della sceneggiatura. In questo modo la shell è in modalità interattiva durante l'esecuzione dello script.

Quando bash viene invocato come shell di login interattiva o come shell non interattiva con l'opzione --login, legge prima ed esegue i comandi dal file / etc / profile, se quel file esiste. Dopo aver letto quel file, cerca ~ / .bash_profile, ~ / .bash_login e ~ / .profile, in quell'ordine, e legge ed esegue i comandi dal primo che esiste ed è leggibile. L'opzione --noprofile può essere usata all'avvio della shell per inibire questo comportamento.

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

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.