Dlaczego $ PATH polecenia zdalnego ssh różni się od powłoki interaktywnej?

20

Mam użytkownika, który nie wprowadził żadnych zmian do zmiennej $ PATH w żadnym pliku kropkowym: jest to dokładnie domyślne ustawienie systemowe. Z powłoki logowania:

$ 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

Dokładnie jak określono w /etc/profile. To wydaje mi się raczej nieoczekiwane:

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

Tak jak powiedziałem, nie ma modyfikacji $ PATH w ~/.bashrc, ani w /etc/bash.bashrc. Nie ~/.ssh/environmentalbo. ssh(1)Deklaruje, że zmienna PATHjest

Ustaw domyślną ŚCIEŻKĘ, określoną podczas kompilacji ssh.

ale ten wątek z StackOverflow i ten artykuł z listy mailingowej sugerują, że powinienem mieć wpływ na $ PATH dla danego polecenia, po prostu modyfikując / etc / profile, jeden z plików startowych powłoki itp.

Co tu się dzieje?

pstrąg
źródło

Odpowiedzi:

16

Ze ssh(1)strony podręcznika: „Jeśli podano polecenie, jest ono wykonywane na zdalnym hoście zamiast powłoki logowania.”

Krótko mówiąc, kiedy faktycznie logujesz się na maszynę, bash jest uruchamiany jako powłoka logowania i ładuje odpowiednie pliki, kiedy łączysz się zdalnie i wydajesz polecenie, jest on uruchamiany zamiast bash, co oznacza, że ​​te pliki NIE ładują się. Możesz obejść to za pomocąsu -l -c lub podobnego w części poleceń ssh.

W niektórych przypadkach widziałem też -targument za działaniem ssh (alokuj tty).

Edycja 1 :
Myślę, że informacje o PATH, które znalazłeś, że domyślną ścieżką (chyba że ją zastąpimy) jest ścieżka skompilowana do sshd. Upewniłem się, że mój plik / etc / profile, / etc / bash *, lokalne pliki kropkowe itp. Nie zawierają żadnych informacji o PATH, a następnie zalogowałem się i nadal miałem PATH. Szukałem tego w sshd i znalazłem go tam. Tak mówi strona podręcznika:

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

Następnie dodaję zdalnie PATH=$PATH:/my/testdo samej góry mojego .bashrcpliku i sprawdzam ponownie:

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

Mogę więc mieć absolutny wpływ na to, a domyślna ŚCIEŻKA to ta wkompilowana w sshd. :)

Mattias Ahnberg
źródło
Hmm, ta fraza „wykonana na zdalnym hoście” oznacza o wiele więcej, niż myślę. Bardziej interesujący bit, który przegapiłem wcześniej, znajduje się w sekcji „ŚRODOWISKO” tej samej strony: „ŚCIEŻKA Ustaw domyślną ŚCIEŻKĘ, określoną podczas kompilacji ssh”. Z wyjątkiem tego sugeruje, że powinienem mieć wpływ na ŚCIEŻKĘ polecenia.
troutwine,
Chodzi o to, że nie jest to powłoka logowania, więc nie działa / source / włącza plików startowych w taki sam sposób, jak w przypadku powłoki logowania, stąd moje sugestie, aby wypróbować. Wrzucanie rzeczy też .bashrcmoże działać, ale ogólnie obejdę to, jeśli ŚCIEŻKA jest ważna. A może po prostu podać pełne nazwy ścieżek, jeśli potrzebujesz metody polecenia ssh? :)
Mattias Ahnberg,
Lekko zredagowałem swój post. Teraz jest powłoka logowania, powłoka niezalogowana oraz ich interaktywne / nieinteraktywne warianty. Polecenia SSH są wywoływane w powłoce użytkownika w nieinteraktywnej formie niezalogowanej. bash(1)INWOKACJA sugeruje, że żadne pliki startowe są odczytywane w ten sposób, ale nie mogę znaleźć dokumentację na temat jak ssh wywołując powłokę. Wydaje się to sprzeczne z powyższymi połączonymi źródłami, chyba że inni mają źródła plików startowych / etc / ssh / sshrc, których nie mam. (Oczywiście istnieją obejścia, ale chodzi o to, aby zrozumieć, jak Debian SSHD domyślnie obsługuje ścieżki.)
troutwine
Jeśli zmodyfikuję ŚCIEŻKĘ w /etc/profilemoich zdalnych aktualizacjach ścieżki do skrzynki, ssh user@remotebox 'env'pokaże mi zaktualizowaną ŚCIEŻKĘ. To samo dzieje się, jeśli dodam export PATH=$PATH:/my/testpathdo .bashrc (ale w moim przypadku na górze pliku przed sprawdzeniem interaktywnych powłok ( -z "$PS1").
Mattias Ahnberg
Zaktualizowałem o moje testy / ustalenia.
Mattias Ahnberg,
3

Byłem w stanie uzyskać ssh do uruchamiania poleceń przy użyciu ścieżki zdalnej, uruchamiając:

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

Tutaj env można zastąpić dowolnym poleceniem.

Mam autoryzowane klucze, więc nie potrzebowałem hasła, aby uruchomić polecenie lub ssh.

Ian
źródło
3

Wymyśliłem inne rozwiązanie, aby rozwiązać problem. Moje osobiste preferencje to tworzenie nowych plików konfiguracyjnych zamiast zmieniania istniejących. W ten sposób mogę łatwiej zrezygnować ze zmian z domyślnej konfiguracji.

Oto zawartość /etc/profile.d/ssh_login.sh:

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

Używając dropbearzamiast openssh-server(powinno to również działać z openssh), zmienna SSH_CONNECTION jest ustawiana automatycznie, gdy loguję się zdalnie. Utworzyłem nową konfigurację profilu powłoki, aby wykrywać logowania SSH, wyświetlać pewne informacje na ekranie i, co najważniejsze, ładować globalne ustawienia środowiska, /etc/environmentaby zastąpić skompilowane wartości. Pamiętaj, że dotyczy to tylko interaktywnych powłok SSH, a nie zdalnego wykonywania poleceń.

Alternatywnie , jeśli używasz openssh i zawsze chcesz załadować środowisko globalne, niezależnie od tego, czy jest to powłoka interaktywna, możesz umieścić dowiązanie symboliczne w ~/.ssh/następujący sposób:

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

Następnie musisz włączyć tę PermitUserEnvironmentopcję w /etc/sshd/sshd_config. Rób to jednak tylko dla zaufanych użytkowników, ponieważ może to umożliwić im ominięcie ograniczeń dostępu w niektórych konfiguracjach za pomocą mechanizmów takich jak LD_PRELOAD. Zobacz man sshd_configwięcej informacji, w szczególności jak używać Matchbloków w celu ograniczenia opcji dla określonych użytkowników / grup.

tachylatus
źródło
0

Jeśli chcesz załadować ścieżkę profilu, spróbuj:

#!/bin/bash -i

u góry skryptu. W ten sposób powłoka działa w trybie interaktywnym podczas uruchamiania skryptu.

Kiedy bash jest wywoływany jako interaktywna powłoka logowania lub jako nieinteraktywna powłoka z opcją --login, najpierw czyta i wykonuje polecenia z pliku / etc / profile, jeśli plik ten istnieje. Po odczytaniu tego pliku szuka ~ / .bash_profile, ~ / .bash_login i ~ / .profile, w tej kolejności, i odczytuje i wykonuje polecenia z pierwszego, który istnieje i jest czytelny. Opcji --noprofile można użyć, gdy powłoka zostanie uruchomiona w celu zahamowania tego zachowania.

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

Adam Brand
źródło