¿Por qué las variables PATH son diferentes cuando se ejecutan a través de sudo y su?

40

En mi VM Fedora, cuando ejecuto mi cuenta de usuario, tengo /usr/local/binen mi ruta:

[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

Y del mismo modo cuando se ejecuta 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

Sin embargo, cuando se ejecuta vía sudo, este directorio no está en la ruta:

[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

¿Por qué la ruta sería diferente cuando se ejecuta vía sudo?

Justin Ethier
fuente
stackoverflow.com/questions/257616/sudo-changes-path-why
Ciro Santilli 新疆 改造 中心 法轮功 六四 事件

Respuestas:

37

Echa un vistazo a /etc/sudoers. El archivo predeterminado en Fedora (así como en RHEL, y también Ubuntu y similares) incluye esta línea:

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

Lo que garantiza que su ruta esté limpia cuando ejecute binarios en sudo. Esto ayuda a proteger contra algunas de las preocupaciones señaladas en esta pregunta . También es conveniente si no tiene /sbiny /usr/sbinen su propio camino.

mattdm
fuente
Ah, veo eso en mi archivo. Entonces, no es que quiera, pero si agrego /usr/local/binesta directiva , la vería en mi camino cuando la ejecute sudo, ¿verdad?
Justin Ethier
Solo lo intenté y ahora veo /usr/local/bin. ¡Muchas gracias por explicar esto!
Justin Ethier
¿Qué hay de agregar la ruta de sus usuarios para scripts y binarios, para que no tenga que escribir la ruta absoluta cuando debe, sudopor ejemplo, un script en su ~/bin(o cualquier ruta que use)? Acabo de hacer el cambio, ¿funciona, solo pensé que podría haber un lado negativo?
Emanuel Berg
@mattdm Sí, Ubuntu también, ya que me encontré con ese problema en Ubuntu Vivid cuando jugaba con VM. Lo mismo para Debian .
kenorb
9

El comando su -ejecutará el perfil de los usuarios raíz y tomará el entorno de ese usuario, incluida la ruta, etc., sudono lo hace.

Si desea sudocomportarse así su -, use la opción sudo -i [commandque ejecutará el perfil del usuario

Si desea su -comportarse así sudo, no use el guión, solo usesu [command]

Andrew Yochum
fuente
2

Puede verificar por qué (es diferente) ejecutando sudo sudo -V.

Por ejemplo, en Linux ejecuta:

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

Nota: en MacOS / BSD, basta con ejecutar: sudo sudo -V.

La lista anterior está restringida debido al complemento de política de seguridad predeterminado en algunas distribuciones de Linux.


Esto se explica más detalladamente en man sudoers:

Si secure_pathse establece la opción, su valor se usará para la PATHvariable de entorno.

secure_path- Ruta utilizada para cada comando ejecutado desde sudo. Si no confía en que las personas que ejecutan sudo tengan una PATHvariable de entorno sensata, puede usar esto.

Otro uso es si desea que la "ruta raíz" esté separada de la "ruta del usuario". Los usuarios del grupo especificado por la exempt_groupopción no se ven afectados por secure_path. Esta opción no está configurada por defecto.

Si ese es el caso, puede cambiar eso ejecutando sudo visudoy editando el archivo de configuración y modificando su secure_path(agregando una ruta adicional separada por :) o agregue su usuario exempt_group(para que no se vea afectado por las secure_pathopciones).

O para pasar el usuario PATHtemporal, puede ejecutar:

sudo env PATH="$PATH" my_command

y puedes verificar eso de la siguiente manera:

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

Ver también: ¿Cómo hacer sudopreservar $PATH?


Otra razón por la cual el entorno podría ser diferente sudoes porque podría tener la env_resetopción habilitada en su sudoersarchivo. Esto hace que los comandos se ejecuten con un nuevo entorno mínimo.

Por lo tanto, puede usar la env_keepopción (no recomendada por razones de seguridad ) para preservar las variables de entorno de su usuario:

Defaults        env_reset
Defaults        env_keep += "PATH PYTHONPATH"
kenorb
fuente
1

En la mayoría de los Linux, instalas programas a través de la administración de paquetes y obtienes actualizaciones de manera regular. Si instala algo que elude la administración del paquete, se instalará en / usr / local / bin (por ejemplo, o ... / sbin, / / ​​opt) y no recibirá actualizaciones periódicas.

Por lo tanto, supongo que los programas no se consideran tan seguros y no se ponen en la RUTA raíz de forma predeterminada.

usuario desconocido
fuente
+1 - Genial, me preguntaba por qué no estaba en el camino, y eso tiene sentido. Por lo que vale, estaba construyendo node.js desde cero para jugar con él, por lo que tiene sentido por qué se habría colocado allí y por sudoqué excluiría este directorio de forma predeterminada.
Justin Ethier
@Justin Ethier: fuera de tema, pero ver bugzilla.redhat.com/show_bug.cgi?id=634911
mattdm
1

Acabo de probar esto por mí mismo y no vi el comportamiento que estabas viendo: mi camino siguió siendo el mismo, por lo que tal vez la configuración de sudo es diferente. Si marca man sudoers, verá que hay una opción llamada secure_pathque se restablece PATH; parece que esta opción podría haberse habilitado.

Richard Downer
fuente
Interesante. Esto fue en Fedora 12, por lo que vale ...
Justin Ethier
1

Porque cuando lo usas sudo bash, bashno actúa como un shell de inicio de sesión. Intente nuevamente con sudo bash -ly debería ver el mismo resultado quesu - .

Si esto es correcto, entonces la diferencia de PATHmentiras en los archivos de configuración: /etc/profile, ~/.bash_profile, ~/.bash_login, ~/.profilese ejecuta (en ese orden) para un shell de entrada, mientras que ~/.bashrcse ejecuta para un shell interactivo no inicio de sesión.

phunehehe
fuente
0

Antigua pregunta, lo sé, pero me topé aquí justo ahora porque estaba investigando este problema exacto.

Por alguna razón /usr/local/binsolo estaba en la RUTA cuando se convirtió en root vía sudo su -. Cuando lo usaba sudo -ino estaba allí. Por supuesto, ahora sé que puedo agregarlo a / etc / sudoers, pero eso aún no explica por qué ya está allí despuéssu - . ¿De dónde vino esta parte de PATH?

Después de buscar y buscar mucho, encontré la respuesta:

La ruta predeterminada que contiene '/ usr / local / bin' en realidad está codificada en su (1).

Por lo tanto, ninguna configuración de pam, perfil, bashrc ni nada fue responsable de agregar selectivamente este elemento. Siempre estaba allí cuando se suhizo cargo. Y como sudono invocasu en absoluto pero usa su propia configuración, faltaba despuéssudo -i

Encontré que esto es cierto en RHEL6 y RHEL7. No revisé ninguna otra versión o distribución.

Oscar
fuente
No me pregunten cómo verifiqué esto ... De acuerdo, si insisten: edité hexadecimalmente una copia del subinario, la cambié /usr/local/binpor otra e invoqué la copia. Mi RUTA ahora contenía la cadena modificada ... Buenos niños y administradores de sistemas no perezosos, por supuesto, solo descarguen la fuente y verifiquen allí. ;-)
Oscar