Mengapa variabel PATH berbeda ketika berjalan melalui sudo dan su?


40

Pada fedora VM saya, ketika menjalankan dengan akun pengguna saya, saya ada /usr/local/bindi jalur saya:

[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

Dan juga saat menjalankan 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

Namun, ketika dijalankan melalui sudo, direktori ini tidak ada di jalur:

[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

Mengapa jalurnya berbeda saat berjalan via sudo?



Jawaban:


37

Lihatlah /etc/sudoers. File default di Fedora (juga di RHEL, dan juga Ubuntu dan yang serupa) termasuk baris ini:

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

Yang memastikan bahwa jalur Anda bersih saat menjalankan binari di bawah sudo. Ini membantu melindungi dari beberapa masalah yang dicatat dalam pertanyaan ini . Ini juga nyaman jika Anda tidak memiliki /sbindan /usr/sbindi jalur Anda sendiri.


Ah, saya melihat itu di file saya. Jadi, bukan itu yang saya inginkan, tetapi jika saya menambahkan /usr/local/binke direktif ini maka saya akan melihatnya di jalur saya ketika menjalankan via sudo, kan?
Justin Ethier

Saya hanya mencobanya dan sekarang saya mengerti /usr/local/bin. Terima kasih banyak untuk menjelaskan ini!
Justin Ethier

Bagaimana dengan menambahkan jalur pengguna Anda untuk skrip dan binari, jadi Anda tidak perlu menulis path absolut ketika Anda harus sudomisalnya skrip di ~/bin(atau jalur apa pun yang Anda gunakan)? Saya baru saja membuat perubahan - itu berhasil, hanya berpikir mungkin ada sisi lain dari itu?
Emanuel Berg

@mattdm Ya, Ubuntu juga, ketika saya menemukan masalah itu di Ubuntu Vivid saat bermain dengan VM. Hal yang sama untuk Debian .
kenorb

9

Perintah ini su -akan mengeksekusi profil pengguna root dan mengambil lingkungan pengguna itu termasuk jalur dll. sudoTidak melakukan itu.

Jika Anda ingin sudobersikap seperti su -maka gunakan opsi sudo -i [commandyang akan mengeksekusi profil pengguna

Jika Anda ingin su -bersikap seperti sudoitu jangan gunakan tanda hubung - cukup gunakansu [command]


2

Anda dapat memeriksa mengapa (berbeda) dengan menjalankan sudo sudo -V.

Misalnya di Linux dijalankan:

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

Catatan: Pada MacOS / BSD, hanya menjalankan: sudo sudo -V.

Daftar di atas dibatasi karena plugin kebijakan keamanan default di beberapa distribusi Linux.


Ini dijelaskan lebih lanjut dalam man sudoers:

Jika secure_pathopsi diset, nilainya akan digunakan untuk PATHvariabel lingkungan.

secure_path- Path digunakan untuk setiap perintah yang dijalankan dari sudo. Jika Anda tidak percaya orang yang menjalankan sudo memiliki PATHvariabel lingkungan waras, Anda mungkin ingin menggunakan ini.

Penggunaan lain adalah jika Anda ingin memiliki "jalur root" terpisah dari "jalur pengguna". Pengguna dalam grup yang ditentukan oleh exempt_groupopsi tidak terpengaruh oleh secure_path. Opsi ini tidak diatur secara default.

Jika itu masalahnya, Anda dapat mengubahnya dengan menjalankan sudo visudodan mengedit file konfigurasi dan memodifikasi Anda secure_path(menambahkan jalur tambahan yang dipisahkan oleh :) atau menambahkan pengguna Anda ke exempt_group(sehingga Anda tidak akan terpengaruh oleh secure_pathopsi).

Atau untuk lulus PATHsementara dari pengguna , Anda dapat menjalankan:

sudo env PATH="$PATH" my_command

dan Anda dapat memeriksanya dengan:

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

Lihat juga: Bagaimana cara sudomelestarikan $PATH?


Alasan lain mengapa lingkungan bisa berbeda sudo, adalah karena Anda dapat env_resetmengaktifkan opsi di sudoersfile Anda . Ini menyebabkan perintah dijalankan dengan lingkungan minimal baru.

Jadi, Anda dapat menggunakan env_keepopsi (tidak disarankan karena alasan keamanan ) untuk melindungi variabel lingkungan pengguna Anda:

Defaults        env_reset
Defaults        env_keep += "PATH PYTHONPATH"

1

Di sebagian besar linux, Anda menginstal program melalui manajemen paket, dan mendapatkan pembaruan secara teratur. Jika Anda menginstal sesuatu yang mengelak dari manajemen paket, ia akan diinstal di / usr / local / bin (misalnya, atau ... / sbin, atau / opt) dan tidak mendapatkan pembaruan rutin.

Karena itu saya kira program-programnya tidak dianggap seaman itu, dan tidak memasukkan PATH ke root secara default.


+1 - Keren, saya bertanya-tanya mengapa itu tidak ada di jalan, dan itu masuk akal. Untuk apa nilainya, saya sedang membangun node.js dari awal untuk bermain-main dengannya, jadi masuk akal mengapa itu akan diletakkan di sana, dan mengapa sudomengecualikan direktori ini secara default.
Justin Ethier

@Justin Ethier: di luar topik, tetapi lihat bugzilla.redhat.com/show_bug.cgi?id=634911
mattdm

1

Saya baru saja mencoba ini untuk diri saya sendiri dan saya tidak melihat perilaku yang Anda lihat - jalur saya tetap sama, jadi mungkin konfigurasi sudo Anda berbeda. Jika Anda memeriksa, man sudoersAnda akan melihat ada opsi yang disebut secure_pathreset PATH- sepertinya opsi ini telah diaktifkan.


Menarik. Ini ada di Fedora 12, untuk apa nilainya ...
Justin Ethier

1

Karena ketika Anda menggunakan sudo bash, bashjangan bertindak sebagai shell login. Coba lagi dengan sudo bash -ldan Anda akan melihat hasil yang sama dengan su -.

Jika itu benar, maka perbedaan PATHterletak pada file konfigurasi: /etc/profile, ~/.bash_profile, ~/.bash_login, ~/.profiledieksekusi (agar) untuk login shell, sedangkan~/.bashrc dijalankan untuk shell interaktif non-login.


0

Pertanyaan lama, saya tahu, tetapi saya tersandung di sini karena saya sedang menyelidiki masalah yang sebenarnya ini.

Untuk beberapa alasan /usr/local/binhanya ada di PATH ketika menjadi root viasudo su - . Saat menggunakannya sudo -itidak ada di sana. Tentu saja sekarang saya tahu saya bisa menambahkannya ke / etc / sudoers, tetapi itu masih tidak menjelaskan mengapa itu sudah ada setelahnya su -. Dari mana asal bagian PATH ini?

Setelah banyak memahami dan mencari, saya menemukan jawabannya:

Path default yang mengandung '/ usr / local / bin' sebenarnya hardcoded di su (1).

Jadi tidak ada konfigurasi pam, profil, bashrc atau apa pun yang bertanggung jawab untuk menambahkan elemen ini secara selektif. Itu selalu ada di sana ketika sumengambil alih. Dan karena sudotidak memintasu sama sekali tetapi menggunakan konfigurasi sendiri, itu hilang setelahsudo -i

Saya menemukan ini benar di RHEL6 dan RHEL7. Saya tidak memeriksa versi atau distribusi lainnya.


Jangan tanya saya bagaimana saya memverifikasi ini .. Oke, jika Anda bersikeras: Saya hex-edited salinan subiner, berubah /usr/local/binmenjadi sesuatu yang lain dan meminta salinannya. PATH saya sekarang berisi string yang dimodifikasi ... Anak-anak yang baik dan sysadmin yang tidak malas tentu saja mengunduh sumbernya dan memeriksa di sana. ;-)
Oscar
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.