Почему переменные PATH отличаются при запуске через sudo и su?

40

На моей виртуальной машине Fedora при работе с моей учетной записью у меня /usr/local/binна пути:

[justin@justin-fedora12 ~]$ env | grep PATH
 PATH=/usr/kerberos/sbin:/usr/kerberos/bin:/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/sbin:/home/justin/bin

И так же, когда работает su:

[justin@justin-fedora12 ~]$ su -
Password: 
[root@justin-fedora12 justin]# env | grep PATH
PATH=/usr/kerberos/sbin:/usr/kerberos/bin:/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/sbin:/home/justin/bin

Однако при запуске через sudoэтот каталог не находится в пути:

[root@justin-fedora12 justin]# exit
[justin@justin-fedora12 ~]$ sudo bash
[root@justin-fedora12 ~]# env | grep PATH
PATH=/usr/kerberos/sbin:/usr/kerberos/bin:/sbin:/bin:/usr/sbin:/usr/bin

Почему путь будет отличаться при запуске через sudo?

Джастин этир
источник
stackoverflow.com/questions/257616/sudo-changes-path-why
Сиро Сантилли 新疆 改造 中心 法轮功 六四 事件

Ответы:

37

Посмотрите на /etc/sudoers. Файл по умолчанию в Fedora (как и в RHEL, а также в Ubuntu и аналогичных) содержит следующую строку:

Defaults    secure_path = /sbin:/bin:/usr/sbin:/usr/bin

Что гарантирует, что ваш путь чист при запуске исполняемых файлов под sudo. Это помогает защитить от некоторых проблем, отмеченных в этом вопросе . Это также удобно, если у вас нет /sbinи /usr/sbinна вашем собственном пути.

mattdm
источник
Ах, я вижу это в моем файле. Итак, не то, что я хочу, но если бы я добавил /usr/local/binэту директиву, я бы увидел ее на своем пути при запуске через sudo, правильно?
Джастин Этьер
Я только что попробовал, и теперь я вижу /usr/local/bin. Большое спасибо за объяснение этого!
Джастин Этьер
А как насчет добавления пути ваших пользователей для скриптов и двоичных файлов, чтобы вам не приходилось писать абсолютный путь, когда вы должны, sudoнапример, скрипт в своем ~/bin(или любом другом пути, который вы используете)? Я только что внес изменения - это работает, только подумал, что это может быть оборотной стороной?
Эмануэль Берг
@mattdm Да, Ubuntu также, как я сталкивался с этой проблемой в Ubuntu Vivid при игре с VM. То же самое для Debian .
Кенорб
9

Команда su -выполнит профиль корневого пользователя и примет окружение этого пользователя, включая путь и т. Д., sudoЭтого не делает.

Если вы хотите sudoвести себя так, su -используйте опцию, sudo -i [commandкоторая будет выполнять профиль пользователя

Если вы хотите su -вести себя так sudo, не используйте дефис - просто используйтеsu [command]

Андрей Йохум
источник
2

Вы можете проверить, почему (это отличается), запустив sudo sudo -V.

Например, в Linux запустите:

$ sudo sudo -V | grep PATH
Value to override user's $PATH with: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

Примечание: В MacOS / BSD, просто запустите: sudo sudo -V.

Приведенный выше список ограничен из-за плагина политики безопасности по умолчанию в некоторых дистрибутивах Linux.


Это дополнительно объясняется в man sudoers:

Если secure_pathопция установлена, ее значение будет использоваться для PATHпеременной среды.

secure_path- Путь, используемый для каждой команды, запускаемой из sudo. Если вы не доверяете людям, работающим с sudo, иметь PATHпеременную среды, вы можете использовать это.

Другое использование, если вы хотите, чтобы «корневой путь» был отделен от «пути пользователя». Пользователи в группе, указанной exempt_groupпараметром, не затрагиваются secure_path. Эта опция не установлена ​​по умолчанию.

В этом случае вы можете изменить это, запустив sudo visudoи отредактировав файл конфигурации и изменив свой secure_path(добавив дополнительный путь, разделенный :) или добавив в него своего пользователя exempt_group(чтобы параметры не влияли на вас secure_path).

Или, чтобы пропустить PATHвременный пользователь , вы можете запустить:

sudo env PATH="$PATH" my_command

и вы можете проверить это:

sudo env PATH="$PATH" env | grep ^PATH

Смотрите также: Как сделать sudoконсерв $PATH?


Другая причина, по которой среда может отличаться sudo, заключается в том, что env_resetв вашем sudoersфайле может быть включена опция . Это заставляет команды выполняться в новой, минимальной среде.

Таким образом, вы можете использовать env_keepопцию (не рекомендуется из соображений безопасности ), чтобы сохранить переменные окружения вашего пользователя:

Defaults        env_reset
Defaults        env_keep += "PATH PYTHONPATH"
kenorb
источник
1

В большинстве linux вы устанавливаете программы через управление пакетами и регулярно получаете обновления. Если вы устанавливаете что-либо, обходящее управление пакетами, оно будет установлено в / usr / local / bin (например, или ... / sbin, или / opt) и не получит регулярных обновлений.

Поэтому я полагаю, что программы не считаются настолько безопасными и по умолчанию не помещаются в корень PATH.

неизвестный пользователь
источник
+1 - Круто, мне было интересно, почему это не было в пути, и это имеет смысл. Что бы это ни стоило, я создавал node.js с нуля, чтобы поиграться с ним, поэтому есть смысл, почему он был бы помещен туда и почему sudoисключил бы этот каталог по умолчанию.
Джастин Этьер
@Justin Ethier: не по теме, но смотрите bugzilla.redhat.com/show_bug.cgi?id=634911
mattdm
1

Я только что попробовал это для себя, и я не видел поведение, которое вы видели - мой путь остался прежним, так что, возможно, ваша конфигурация sudo отличается. Если вы проверите, man sudoersто увидите, что есть опция, secure_pathкоторая перезагружается PATH- похоже, эта опция была включена.

Ричард Даунер
источник
Интересный. Это было на Fedora 12, для чего это стоит ...
Джастин Этьер
1

Потому что, когда вы используете sudo bash, bashне действует как оболочка входа в систему. Попробуйте еще раз, sudo bash -lи вы увидите тот же результат, что и su -.

Если это верно, то разница в PATHложь в файлах конфигурации: /etc/profile, ~/.bash_profile, ~/.bash_login, ~/.profileвыполняются (в указанном порядке) для входа в оболочку, в то время как ~/.bashrcвыполняется для нерегистрированной интерактивной оболочки.

phunehehe
источник
0

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

По какой-то причине /usr/local/binбыл только в PATH при получении root через sudo su -. При использовании sudo -iего там не было. Конечно, теперь я знаю, что могу добавить его в / etc / sudoers, но это все еще не объясняет, почему оно уже там su -. Откуда взялась эта часть PATH?

После долгих поисков я нашел ответ:

Путь по умолчанию, содержащий «/ usr / local / bin», фактически жестко запрограммирован в su (1).

Поэтому никакая конфигурация pam, профиль, bashrc или что-либо еще не отвечали за выборочное добавление этого элемента. Он всегда был там, когда suвступил во владение. А так sudoкак не вызывает suвообще, но использует свою собственную конфигурацию, послеsudo -i

Я нашел это, чтобы быть правдой на RHEL6 и RHEL7. Я не проверял ни одну другую версию или дистрибутив.

Оскар
источник
Не спрашивайте меня, как я это проверил ... Хорошо, если вы настаиваете: я отредактировал копию suдвоичного файла, изменил ее /usr/local/binна что-то другое и вызвал копию. Мой PATH теперь содержит измененную строку ... Хорошие дети и не ленивые системные администраторы, конечно, просто скачайте исходный код и зарегистрируйтесь там. ;-)
Оскар