Почему $ PATH удаленной команды ssh отличается от интерактивной оболочки?

20

У меня есть пользователь, который не вносил никаких изменений в $ PATH в любых точечных файлах: это точно настройка системы по умолчанию. Из оболочки входа в систему:

$ 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

Точно так же, как указано в /etc/profile. Это я нахожу довольно неожиданным:

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

Как я уже сказал, в $ PATH нет ни изменений ~/.bashrc, ни изменений /etc/bash.bashrc. Нет ~/.ssh/environmentтоже. ssh(1)Заявляет , что переменная среды PATHявляется

Установите значение PATH по умолчанию, как указано при компиляции ssh.

но этот поток из StackOverflow и статья в списке рассылки предполагают, что я должен иметь возможность влиять на $ PATH для данной команды, просто изменив / etc / profile, один из файлов запуска оболочки и т. д.

Что тут происходит?

troutwine
источник

Ответы:

16

Со ssh(1)страницы руководства: «Если указана команда, она выполняется на удаленном хосте вместо оболочки входа в систему».

Короче говоря, когда вы фактически входите в систему, bash запускается как оболочка для входа и загружает соответствующие файлы, когда вы подключаетесь удаленно и запускаете команду, она запускается вместо bash, что означает, что эти файлы НЕ загружаются. Вы можете обойти это с помощью su -l -cили подобным в командной части ssh.

В некоторых случаях я видел -tаргумент в пользу работы ssh (allocate tty).

Редактировать 1 :
Я думаю, что информация PATH, которую вы нашли, что путь по умолчанию (если мы не переопределяем его) - это путь, скомпилированный в sshd. Я убедился, что в моих / etc / profile, / etc / bash *, локальных точечных файлах и т. Д. Не было никакой информации о PATH, затем я вошел в систему и все еще имел PATH. Я искал это в sshd и нашел его там. Так что, как говорится в справочной странице:

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

Затем я добавляю PATH=$PATH:/my/testв самый верх моего .bashrcфайла на удаленном компьютере и проверяю его снова:

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

Так что я могу абсолютно на это повлиять, и по умолчанию PATH компилируется в sshd. :)

Маттиас Анберг
источник
Хм, эта фраза «выполняется на удаленном хосте» означает гораздо больше, чем говорит, я думаю. Более интересный момент, который я пропустил ранее, содержится в разделе «ENVIRONMENT» на той же man-странице: «PATH Установите значение PATH по умолчанию, как указано при компиляции ssh». Кроме того, это предполагает, что я должен иметь возможность влиять на PATH команды.
Troutwine
Дело в том, что это не оболочка входа в систему, поэтому она не запускает / source / включает файлы запуска так же, как для оболочки входа в систему, поэтому я предлагаю попробовать. Вложение вещей .bashrcтоже может сработать, но в целом я бы обошел это, если важен PATH. Или почему бы просто не указать полные пути, если вам нужен командный способ запуска ssh? :)
Маттиас Анберг
Я немного отредактировал свой пост. Теперь есть оболочка входа в систему, оболочка без входа в систему и ее интерактивные / неинтерактивные варианты. Команды SSH вызываются в оболочке пользователя в неинтерактивной форме без входа в систему. bash(1)ВЫЗОВ предполагает , что никакие загрузочные файлы не читаются таким образом, но я не могу найти документацию по каким SSH является вызовом оболочки. Кажется, это противоречит приведенным выше ссылкам, если только у других нет источника загрузки файла / etc / ssh / sshrc, которого у меня нет. (Конечно, есть обходные пути, но суть в том, чтобы точно понять, как Debian SSHD обрабатывает пути по умолчанию.)
troutwine
Если я изменяю PATH в /etc/profileсвоих обновлениях пути удаленного ящика для меня, то ssh user@remotebox 'env'показывает мне обновленный PATH. То же самое происходит, если я добавляю export PATH=$PATH:/my/testpathв .bashrc (но в моем случае вверху файла перед проверкой на наличие интерактивных оболочек ( -z "$PS1").
Маттиас Анберг
Обновлено с моими тестами / выводами.
Маттиас Анберг
3

Я смог заставить ssh запускать команды, используя удаленный путь, выполнив:

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

Здесь env можно заменить любой командой, которая вам нужна.

У меня есть авторизованные ключи, поэтому мне не нужен пароль для запуска команды или ssh.

Ян
источник
3

Я придумал другое решение, чтобы решить проблему. Мое личное предпочтение - создавать новые файлы конфигурации, а не изменять существующие. Таким образом, я могу легче исключить изменения из конфигурации по умолчанию.

Вот содержание /etc/profile.d/ssh_login.sh:

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

Использование dropbearвместо openssh-server(это также должно работать с openssh), переменная SSH_CONNECTION автоматически устанавливается, когда я вхожу удаленно. Я создал новую конфигурацию профиля оболочки для обнаружения входов SSH, отображения некоторой информации на экране и, что наиболее важно, загрузки глобальных параметров среды /etc/environmentдля замены скомпилированных значений. Обратите внимание, что это влияет только на интерактивные оболочки SSH, а не на удаленное выполнение команд.

В качестве альтернативы , если вы используете openssh и всегда хотите загрузить глобальную среду, независимо от того, является ли она интерактивной оболочкой, вы можете поместить символическую ссылку ~/.ssh/следующим образом:

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

Затем вам нужно включить PermitUserEnvironmentопцию в /etc/sshd/sshd_config. Делайте это только для доверенных пользователей, поскольку это может позволить им обойти ограничения доступа в некоторых конфигурациях, используя такие механизмы, как LD_PRELOAD. Пожалуйста, смотрите man sshd_configдля получения дополнительной информации, в частности, как использовать Matchблоки для ограничения параметров для конкретных пользователей / групп.

tachylatus
источник
0

Если вы хотите загрузить путь к профилю, попробуйте:

#!/bin/bash -i

в верхней части сценария. Таким образом, оболочка находится в интерактивном режиме при запуске скрипта.

Когда bash вызывается как интерактивная оболочка входа в систему или как неинтерактивная оболочка с параметром --login, она сначала читает и выполняет команды из файла / etc / profile, если этот файл существует. После прочтения этого файла он ищет ~ / .bash_profile, ~ / .bash_login и ~ / .profile в указанном порядке, а также читает и выполняет команды из первой, которая существует и доступна для чтения. Опция --noprofile может использоваться, когда оболочка запущена, чтобы запретить это поведение.

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

Адам Бранд
источник