Sudo thay đổi PATH, nhưng thực hiện cùng một nhị phân


7

Có hai trình thông dịch Python được cài đặt:

[user@localhost ~]$ /usr/bin/python -V && /usr/local/bin/python -V
Python 2.4.3
Python 2.7.6

Sudo thay đổi PATH khi được thực thi:

[user@localhost ~]$ env | grep PATH && sudo env | grep PATH
PATH=/usr/kerberos/bin:/usr/local/bin:/usr/bin:/bin:/usr/X11R6/bin:/home/user/bin
PATH=/usr/bin:/bin

Tuy nhiên, Python chạy qua sudo giống như chạy trực tiếp:

[user@localhost ~]$ sudo python -V && python -V
Python 2.7.6
Python 2.7.6

Tôi dự kiến sudo pythonsẽ chạy /usr/bin/pythoncái duy nhất hiển thị trên bản sửa đổi PATH. Tại sao nó chạy /usr/local/bin/pythonthay thế?

Tôi đã hỏi câu hỏi này trong danh sách gửi thư của người dùng sudo nhưng chúng tôi không thể tìm thấy lý do cho hành vi này trong cuộc thảo luận với người duy trì sudo Todd C. Miller.

Để tham khảo:

[user@localhost ~]$ sudo -l
Matching Defaults entries for user on this host:
    requiretty, !visiblepw, env_reset, env_keep="COLORS DISPLAY HOSTNAME HISTSIZE INPUTRC KDEDIR LS_COLORS MAIL PS1 PS2 QTDIR USERNAME LANG LC_ADDRESS
    LC_CTYPE LC_COLLATE LC_IDENTIFICATION LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER LC_TELEPHONE LC_TIME LC_ALL LANGUAGE
    LINGUAS _XKB_CHARSET XAUTHORITY"

Runas and Command-specific defaults for user:


User user may run the following commands on this host:
    (ALL) NOPASSWD: ALL


[user@localhost ~]$ sudo sudo -V
Sudo version 1.7.2p1

Sudoers path: /etc/sudoers
nsswitch path: /etc/nsswitch.conf
ldap.conf path: /etc/ldap.conf
ldap.secret path: /etc/ldap.secret
Authentication methods: 'pam'
Syslog facility if syslog is being used for logging: authpriv
Syslog priority to use when user authenticates successfully: notice
Syslog priority to use when user authenticates unsuccessfully: alert
Ignore '.' in $PATH
Send mail if the user is not in sudoers
Use a separate timestamp for each user/tty combo
Lecture user the first time they run sudo
Require users to authenticate by default
Root may run sudo
Allow some information gathering to give useful error messages
Visudo will honor the EDITOR environment variable
Set the LOGNAME and USER environment variables
Length at which to wrap log file lines (0 for no wrap): 80
Authentication timestamp timeout: 5 minutes
Password prompt timeout: 5 minutes
Number of tries to enter a password: 3
Umask to use or 0777 to use user's: 022
Path to mail program: /usr/sbin/sendmail
Flags for mail program: -t
Address to send mail to: root
Subject line for mail messages: *** SECURITY information for %h ***
Incorrect password message: Sorry, try again.
Path to authentication timestamp dir: /var/run/sudo
Default password prompt: [sudo] password for %p: 
Default user to run commands as: root
Path to the editor for use by visudo: /bin/vi
When to require a password for 'list' pseudocommand: any
When to require a password for 'verify' pseudocommand: all
File containing dummy exec functions: /usr/libexec/sudo_noexec.so
File descriptors >= 3 will be closed before executing a command
Reset the environment to a default set of variables
Environment variables to check for sanity:
        TERM
        LINGUAS
        LC_*
        LANGUAGE
        LANG
        COLORTERM
Environment variables to remove:
        RUBYOPT
        RUBYLIB
        PYTHONINSPECT
        PYTHONPATH
        PYTHONHOME
        TMPPREFIX
        ZDOTDIR
        READNULLCMD
        NULLCMD
        FPATH
        PERL5DB
        PERL5OPT
        PERL5LIB
        PERLLIB
        PERLIO_DEBUG 
        JAVA_TOOL_OPTIONS
        SHELLOPTS
        GLOBIGNORE
        PS4
        BASH_ENV
        ENV
        TERMCAP
        TERMPATH
        TERMINFO_DIRS
        TERMINFO
        _RLD*
        LD_*
        PATH_LOCALE
        NLSPATH
        HOSTALIASES
        RES_OPTIONS
        LOCALDOMAIN
        CDPATH
        IFS
Environment variables to preserve:
        XAUTHORIZATION
        XAUTHORITY
        TZ
        PS2
        PS1
        PATH
        MAIL
        LS_COLORS
        KRB5CCNAME
        HOSTNAME
        HOME
        DISPLAY
        COLORS
Locale to use while parsing sudoers: C
Local IP address and netmask pairs:
        10.0.2.15 / 255.255.255.0
        fe80::a00:27ff:febb:56ce / ffff:ffff:ffff:ffff::


[user@localhost ~]$ sudo cat /etc/sudoers | grep -v -E '^#|^$'
Defaults    requiretty
Defaults   !visiblepw
Defaults    env_reset
Defaults    env_keep = "COLORS DISPLAY HOSTNAME HISTSIZE INPUTRC KDEDIR \
                        LS_COLORS MAIL PS1 PS2 QTDIR USERNAME \
                        LANG LC_ADDRESS LC_CTYPE LC_COLLATE LC_IDENTIFICATION \
                        LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC \
                        LC_PAPER LC_TELEPHONE LC_TIME LC_ALL LANGUAGE LINGUAS \
                        _XKB_CHARSET XAUTHORITY"
root    ALL=(ALL)       ALL
user    ALL=(ALL)       NOPASSWD: ALL


[user@localhost ~]$ which sudo && command -V sudo
/usr/bin/sudo
sudo is hashed (/usr/bin/sudo)

[user@localhost ~]$ cat /etc/redhat-release 
Red Hat Enterprise Linux Server release 5.10 (Tikanga)

1
Environment variables to preserve: ... PATHNghe có vẻ như một lời giải thích.
peterph

@peterph Vậy tại sao env hiển thị PATH khác nhau khi chạy với sudo?
Piotr Dobrogost

Bạn có thể gửi bài của bạn /etc/sudoers? Ngoài ra, bạn có thể xác minh bạn không có một bí danh được đặt cho sudo như alias='sudo -i'không? Bạn có thể kiểm tra với which sudo.
yoonix

Trong PATH của bạn, / usr / local / bin pre / usr / bin. Tôi nghĩ rằng bằng cách nào đó dự kiến ​​sẽ dừng tìm kiếm và chạy chương trình thực thi một khi nó được tìm thấy. Và vị trí nó được tìm thấy là / usr / local / bin lần đầu tiên. Tất nhiên trừ khi sudo của bạn được biên dịch với PATH mặc định khác
MelBurslan

1
@Mel_Burslan Và vị trí nó được tìm thấy là / usr / local / bin lần đầu tiên - Tôi không chắc ý của bạn ở đây là gì. Chạy sudo env | grep PATHrõ ràng cho thấy những gì PATHkhi hoạt động với sudo. Câu hỏi là tại sao sudo pythonkhông hành động theo điều này PATH?
Piotr Dobrogost

Câu trả lời:


6

Bạn đang bị lẫn lộn giữa PATHcái đang ở trong sudomôi trường thực thi thực tế và cái PATHnào sudođặt trong môi trường của chương trình mà nó chạy. Từ sudohướng dẫn:

Khi sudo chạy một lệnh, nó gọi fork (2), thiết lập môi trường thực thi như được mô tả ở trên và gọi cuộc gọi hệ thống thực thi trong tiến trình con.

Với execvebạn chỉ định môi trường mà bạn muốn tiến trình con có, nghĩa là nó có thể khác với tiến trình cha.

Thường secure_pathsẽ được đặt trong /etc/sudoers:

Secure_path

Đường dẫn được sử dụng cho mọi lệnh chạy từ sudo. Nếu bạn không tin tưởng những người đang chạy sudo có biến môi trường PATH lành mạnh, bạn có thể muốn sử dụng biến này. Một cách sử dụng khác là nếu bạn muốn có đường dẫn gốc của Google thì hãy tách biệt với đường dẫn người dùng của Google. Người dùng trong nhóm được chỉ định bởi tùy chọn miễn_group không bị ảnh hưởng bởi safe_path. Tùy chọn này không được đặt theo mặc định.

Nếu điều này được đặt, sudocả hai sẽ tìm kiếm lệnh trong này PATHvà đặt lệnh này trong môi trường của lệnh mà nó chạy. Nó cũng sẽ hiển thị trong đầu ra của sudo sudo -Vvới một dòng như:

Value to override user's $PATH with: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

Tuy nhiên trong trường hợp của bạn, điều này không được đặt, vì vậy sudosẽ sử dụng PATHtrong môi trường thực thi riêng của nó (trong trường hợp này được kế thừa từ trình bao cha). Mặc dù nó đã được cấu hình để bỏ qua thư mục hiện tại nếu điều này đã được đặt trong PATH:

Ignore '.' in $PATH

env_reset nằm trong chuỗi của bạn /etc/sudoers(và PATHkhông nằm trong env_keepchuỗi), PATHnên sudotập hợp trong lệnh mà nó gọi sẽ được xác định bởi PAMhoặc bởi /etc/environmentvà do đó khác với cách PATH sudosử dụng để tìm kiếm vị trí của nó:

Theo mặc định, tùy chọn env_reset được bật. Điều này khiến các lệnh được thực thi với môi trường mới, tối thiểu. Trên AIX (và các hệ thống Linux không có PAM), môi trường được khởi tạo với nội dung của tệp / etc / môi trường. Môi trường mới chứa các biến TATE, PATH, HOME, MAIL, SHELL, LOGNAME, USER, USERNAME và SUDO_ * ngoài các biến từ quy trình gọi được cho phép bởi các tùy chọn env_check và env_keep.

Để chạy pythontrong PATHtập hợp sudo, bạn nên làm một cái gì đó như thế này:

sudo env python -V

Bằng cách này, sudobản thân nó không phải là tìm kiếm lệnh, mà envsẽ có môi trường được thiết lập sudoenvsẽ tìm kiếm lệnh ở đó.


Nếu điều này được đặt, sudocả hai sẽ tìm kiếm lệnh trong này PATHvà đặt lệnh này trong môi trường của lệnh mà nó chạy. - điều này rõ ràng hơn nhiều so với ngắn gọn Path used for every command run from sudo.trong trang man sudoers.
Piotr Dobrogost

@Piotr, vâng, sudoerstrang người đàn ông thực sự không rõ ràng về điều này. Nếu bạn tìm kiếm thông qua tất cả các địa điểm PATHđược đề cập, bạn bắt đầu ghép lại những gì đang xảy ra.
Graeme

Tôi đã đăng một phần tiếp theo mà bạn có thể quan tâm - Sự không phù hợp giữa sys.executable và sys.version trong Python
Piotr Dobrogost

0

Câu trả lời của Graeme khá toàn diện, nhưng có hai điều, cần được nói rõ ràng mặc dù chúng không trả lời cho câu hỏi của bạn:

1. Nếu an toàn và bảo mật là mối quan tâm của bạn - đó là khi bạn sử dụng

(ALL) NOPASSWD: ALL

(không có vấn đề gì với người dùng) - hãy sử dụng secure_path. Mặt khác, một tập lệnh độc hại được đánh dấu là có thể thực thi được ở bất kỳ đâu trên hệ thống của bạn có thể tàn phá (không chỉ) máy cục bộ. Và tập lệnh không phải được đặt trực tiếp trên hệ thống của bạn - một hệ thống tệp mạng được gắn mà không noexeccó tác dụng.

2. Nếu an toàn và bảo mật thực sự là mối quan tâm của bạn, không sử dụng

(ALL) NOPASSWD: ALL

ở tất cả. Tôi không hoàn toàn chắc chắn ai đã nghĩ ra ý tưởng hoàn toàn ngu ngốc (từ rõ ràng hơn được tái định nghĩa) về việc sử dụng nó làm mặc định trước tiên, nhưng nó đơn giản là quá dễ dãi và nguy hiểm - ngay cả một lỗi đánh máy nhẹ cũng có thể làm hỏng (không chỉ) ngày của bạn. Chỉ định một số lệnh yêu cầu quyền root (hoặc sử dụng setcap) và cho phép truy cập vào các lệnh này. Rõ ràng, bất cứ điều gì như một cái vỏ (và sucho những người đã quen sudo su) hoặc bất kỳ trình thông dịch nào khác (Python, Perl, Ruby - bạn đặt tên cho nó) là không cần thiết. Bằng cách này, C có thể được giải thích cũng . Nó có thể phức tạp hơn một chút để thiết lập nếu bạn đang sử dụng các chương trình được thiết kế kém, mặc dù.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.