Warum unterscheidet sich das $ PATH eines ssh-Remote-Befehls von dem einer interaktiven Shell?

20

Ich habe einen Benutzer, der keine Änderungen am $ PATH in Dot-Dateien vorgenommen hat: Dies ist genau die Standardeinstellung des Systems. Aus einer Login-Shell:

$ 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

Genau wie in angegeben /etc/profile. Das finde ich eher unerwartet:

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

Wie gesagt, es gibt keine Modifikation von $ PATH in ~/.bashrcoder in /etc/bash.bashrc. Nein auch ~/.ssh/environmentnicht. Das ssh(1)deklariert, dass die Umgebungsvariable PATHist

Stellen Sie den Standard-PFAD ein, wie er beim Kompilieren von ssh angegeben wurde.

Aber dieser Thread von StackOverflow und dieser Mailinglisten- Artikel legen nahe, dass ich in der Lage sein sollte, den $ PATH-Wert für einen bestimmten Befehl zu beeinflussen , indem ich einfach / etc / profile, eine der Shell-Startdateien usw. ändere.

Was ist hier los?

Forellenwein
quelle

Antworten:

16

Von der ssh(1)Manualpage: "Wenn ein Befehl angegeben ist, wird er auf dem Remote-Host anstelle einer Login-Shell ausgeführt."

Kurz gesagt, wenn Sie sich tatsächlich bei der Maschine anmelden, wird Bash als Anmeldeshell gestartet und lädt die entsprechenden Dateien. Wenn Sie eine Remoteverbindung herstellen und einen Befehl ausgeben, wird Bash anstelle von Bash ausgeführt, was bedeutet, dass diese Dateien NICHT geladen werden. Sie können es umgehen, indem Sie su -l -cim Befehlsteil von ssh o.ä. verwenden.

In einigen Fällen habe ich auch -tArgumente für die ssh-Arbeit (die Zuweisung von tty) gesehen.

Edit 1 :
Ich denke, die PATH-Informationen, die Sie gefunden haben, dass der Standardpfad (sofern wir ihn nicht überschreiben) derjenige ist, der in sshd kompiliert wurde. Ich habe sichergestellt, dass meine / etc / profile, / etc / bash *, lokalen Punktedateien usw. keine PATH-Informationen enthalten. Dann habe ich mich angemeldet und hatte immer noch einen PATH. Ich habe diesen in sshd gesucht und dort gefunden. So heißt es in der Manpage:

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

Dann füge ich PATH=$PATH:/my/testganz oben auf meiner .bashrcRemote-Datei hinzu und überprüfe sie erneut:

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

Ich kann also absolut Einfluss darauf nehmen, und standardmäßig ist PATH derjenige, der in sshd kompiliert wurde. :)

Mattias Ahnberg
quelle
Hmm, dieser Ausdruck "auf dem entfernten Host ausgeführt" bedeutet viel mehr, als er sagt, denke ich. Das interessantere Bit, das ich zuvor übersehen habe, befindet sich im Abschnitt 'ENVIRONMENT' derselben Manpage: "PATH Auf den Standard-PATH setzen, wie er beim Kompilieren von ssh angegeben wurde." Außer dies legt nahe, dass ich in der Lage sein sollte, den Pfad eines Befehls zu beeinflussen.
Forellenwein
Nun, der Punkt ist, dass es sich nicht um eine Anmeldeshell handelt, daher werden die Startdateien nicht auf die gleiche Weise ausgeführt / source / include wie bei einer Anmeldeshell, daher meine Vorschläge zum Ausprobieren. Das Einfügen von Dingen .bashrckönnte auch funktionieren, aber insgesamt würde ich es umgehen, wenn PATH wichtig ist. Oder warum nicht einfach vollständige Pfadnamen angeben, wenn Sie die 'command'-Methode zum Ausführen von ssh benötigen? :)
Mattias Ahnberg
Ich habe meinen Beitrag leicht bearbeitet. Jetzt gibt es eine Login-Shell, eine Nicht-Login-Shell und interaktive / nicht interaktive Varianten davon. SSH-Befehle werden in der Shell des Benutzers in nicht interaktiver Form ohne Anmeldung aufgerufen. Der bash(1)Aufruf schlägt vor, dass keine Startdateien auf diese Weise gelesen werden, aber ich kann keine Dokumentation darüber finden, wie ssh die Shell aufruft. Dies scheint im Widerspruch zu den oben genannten Quellen zu stehen, es sei denn, andere haben / etc / ssh / sshrc-Startdateien, die ich nicht besitze. (Es gibt natürlich Workarounds, aber es geht
darum
Wenn ich PATH in /etc/profilemeinen Remote-Box-Pfad-Updates für mich ändere, ssh user@remotebox 'env'wird mir der aktualisierte PATH angezeigt. Dasselbe gilt, wenn ich export PATH=$PATH:/my/testpath.bashrc hinzufüge (in meinem Fall jedoch oben in der Datei, bevor nach interaktiven Shells -z "$PS1"
gesucht wird
Aktualisiert mit meinen Tests / Ergebnissen.
Mattias Ahnberg
3

Ich konnte ssh dazu bringen, Befehle über den Remote-Pfad auszuführen, indem ich Folgendes ausführte:

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

Hier kann env durch einen beliebigen Befehl ersetzt werden.

Ich habe autorisierte Schlüssel und benötige daher kein Passwort, um den Befehl oder ssh auszuführen.

Ian
quelle
3

Ich habe eine andere Lösung gefunden, um das Problem zu beheben. Ich persönlich bevorzuge es, neue Konfigurationsdateien zu erstellen, anstatt vorhandene zu ändern. Auf diese Weise kann ich Änderungen von der Standardkonfiguration leichter entfernen.

Hier sind die Inhalte von /etc/profile.d/ssh_login.sh:

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

Mit dropbearanstelle von openssh-server(dies sollte auch mit openssh funktionieren) wird die Variable SSH_CONNECTION automatisch gesetzt, wenn ich mich remote anmelde. Ich habe eine neue Shell-Profilkonfiguration erstellt, um SSH-Anmeldungen zu erkennen, einige Informationen auf dem Bildschirm anzuzeigen und vor allem die globalen Umgebungseinstellungen von /etc/environmentzu laden , um die kompilierten Werte zu ersetzen. Bitte beachten Sie, dass dies nur interaktive SSH-Shells betrifft, nicht die Remote-Befehlsausführung.

Alternativ , wenn Sie OpenSSH verwenden und immer die globale Umwelt geladen werden soll, unabhängig davon , ob es sich um eine interaktive Shell, können Sie einen symbolischen Link in setzen ~/.ssh/wie folgt aus :

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

Dann müssen Sie die PermitUserEnvironmentOption in aktivieren /etc/sshd/sshd_config. Tun Sie dies jedoch nur für vertrauenswürdige Benutzer, da diese in einigen Konfigurationen Zugriffsbeschränkungen mithilfe von Mechanismen wie LD_PRELOAD umgehen können. Bitte beachten Sie man sshd_configfür weitere Informationen, insbesondere , wie die Verwendung MatchBlock Einschränkung Optionen für bestimmte Benutzer / Gruppen.

Tachylatus
quelle
0

Wenn Sie möchten, dass der Profilpfad geladen wird, versuchen Sie Folgendes:

#!/bin/bash -i

am oberen Rand des Skripts. Auf diese Weise befindet sich die Shell beim Ausführen des Skripts im interaktiven Modus.

Wenn bash als interaktive Anmeldeshell oder als nicht interaktive Shell mit der Option --login aufgerufen wird, werden zuerst Befehle aus der Datei / etc / profile gelesen und ausgeführt, sofern diese Datei vorhanden ist. Nach dem Lesen dieser Datei sucht sie in dieser Reihenfolge nach ~ / .bash_profile, ~ / .bash_login und ~ / .profile und liest und führt Befehle von der ersten Datei aus, die vorhanden und lesbar ist. Die Option --noprofile kann verwendet werden, wenn die Shell gestartet wird, um dieses Verhalten zu unterbinden.

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

Adam Brand
quelle