この質問は、実行可能ファイルを呼び出すときに記録された動作と実際の動作が一致しない理由を理解することです。Sudo。いつ。 。 。いつ安全な道オプションを有効にすると(マイシステムのデフォルト)、検索パスは期待どおりに機能します。ただし、オプションを無効にすると奇妙なことが発生します。/usr/local/bin
実行可能ファイルの場所が検索パスにない場合でも、完全修飾パス名なしで実行可能ファイルにアクセスできます。
システムメッセージ
現在、私のシステムに次のソフトウェアがインストールされています。
## Yeah... still haven't migrated to Alma
[me@localhost ~]$ cat /etc/centos-release
CentOS Linux release 8.5.2111
[me@localhost ~]$ bash --version | head -1
GNU bash, version 4.4.20(1)-release (x86_64-redhat-linux-gnu)
[me@localhost ~]$ sudo --version
Sudo version 1.8.29
Sudoers policy plugin version 1.8.29
Sudoers file grammar version 46
Sudoers I/O plugin version 1.8.29
[me@localhost ~]$ ssh -V
OpenSSH_8.0p1, OpenSSL 1.1.1k FIPS 25 Mar 2021
PAMは私のシステムでPATH変数の値を設定または更新しません。
[me@localhost ~]$ grep --recursive 'pam_env\.so' /etc/pam.d
/etc/pam.d/fingerprint-auth:auth required pam_env.so
/etc/pam.d/smartcard-auth:auth required pam_env.so
/etc/pam.d/su:auth required pam_env.so
/etc/pam.d/password-auth:auth required pam_env.so
/etc/pam.d/system-auth:auth required pam_env.so
[me@localhost ~]$ sudo cat /etc/security/pam_env.conf /etc/environment | grep PATH
# be useful to be set: NNTPSERVER, LESS, PATH, PAGER, MANPAGER .....
#PATH DEFAULT=${HOME}/bin:/usr/local/bin:/bin\
私の/etc/sudoers
ファイルが設定されました安全な道すべてのsudoerの値:
[me@localhost ~]$ sudo grep --recursive secure_path /etc/sudoers /etc/sudoers.d
/etc/sudoers:Defaults secure_path = /sbin:/bin:/usr/sbin:/usr/bin
Bashのデフォルト値は次のPATH値です。
[me@localhost ~]$ env --ignore-environment bash -c 'echo $PATH'
/usr/local/bin:/usr/bin
最後に、システムにSSHで接続しましたが、/etc/ssh/sshd_config
ファイルに次の行が含まれていました。
[me@localhost ~]$ sudo grep PATH /etc/sshd_config
# This sshd was compiled with PATH=/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin
コピープロセス
複製するには、まずダミースクリプトを作成し、次の場所にインストールします/usr/local/bin
。
[me@localhost ~]$ cat > dummy <<EOF
#!/usr/bin/bash
echo 'Found!'
EOF
[me@localhost ~]$ sudo install --owner=root --group=root --mode=755 dummy /usr/local/bin
未使用時に検索パスが期待どおりに機能することを確認しました。Sudo:
## The /usr/local/bin location is part of my search path
[me@localhost ~]$ echo $PATH
/home/me/.local/bin:/home/me/bin:/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin
## This is expected
[me@localhost ~]$ dummy
Found!
そして使用Sudo、これは驚くべきことではありません。
## Sudo's secure_path value
[me@localhost ~]$ sudo --user=other env | grep PATH
PATH=/usr/bin:/bin:/usr/sbin:/sbin
## This is expected
[me@localhost ~]$ sudo --user=other which dummy
which: no dummy in (/sbin:/bin:/usr/sbin:/usr/bin)
## This too, of course
[me@localhost ~]$ sudo --user=other dummy
sudo: dummy: command not found
## Indeed, a fully qualified path name is required
[me@localhost ~]$ sudo --user=other /usr/local/bin/dummy
Found!
その後、無効にしました。安全な道(ここで気をつけて!ビジュド提案)、その行にコメントを付けるか、次の行を含むファイルを/etc/sudoers
作成します。/etc/sudoers.d/local
# Disable secure_path if set
Defaults !secure_path
これを防ぐ必要がありますSudo--preserve-env
、スイッチと共に呼び出されると、PATH環境変数を次の値にオーバーライドします。安全な道。期待どおりに動作します。
ただし、スイッチを使用せずにスイッチを使用--preserve-env
する完全なログインシーケンスがプロンプトされず(したがってBashの起動ファイルを取得できません)、PATHがPAM環境ファイルに割り当てられていないと、--login
奇妙なことが起こります。
## Not sure where this PATH value is from, neither from sudo's secure_path option
## (not set), PAM environment files (contain no assignment to PATH), Bash startup
## scripts (not sourced), nor Bash or sshd default PATH values (no match).
[me@localhost ~]$ sudo --user=other env | grep PATH
PATH=/usr/bin:/bin:/usr/sbin:/sbin
## Regardless, this is expected
[me@localhost ~]$ sudo --user=other which dummy
which: no dummy in (/usr/bin:/bin:/usr/sbin:/sbin)
## But wait! What?!?
[me@localhost ~]$ sudo --user=other dummy
Found!
それでは、どのようにwhich dummy
文句を言うのですか?偽検索パスに存在せず、パスdummy
プレフィックスなしでメソッドを直接呼び出すことなく検索できますか?
関連文書
以下は、この問題を調査しながら見つけたさまざまな関連情報への参照です。
Sudo ドキュメントには次のように記載されています。安全な道オプション:
sudo で実行される各コマンドに使用されるパス。 sudoを実行している人が通常のPATH環境変数を持っていることを信頼していない場合は、この方法を使用できます。別の用途は、「ユーザーパス」から「ルートパス」を分離したい場合です。 Except_groupオプションで指定されたグループのユーザーは、secure_pathの影響を受けません。このオプションはデフォルトでは設定されていません。
~によるとpam_envマニュアルページのドキュメントでは、/etc/environment
と/etc/security/pam_env.conf
のみ~/.pam_environment
で表示する必要があります。pam_envデフォルト以外のファイル名を指定しない限り、デフォルトはモジュールです。私のシステムではそうではありません。これらのファイルのどれもPATH値を設定または更新しません。
Bashのマニュアルページは次のように述べています。
PATH コマンドの検索パスです。これは、シェルがコマンドを検索するコロンで区切られたディレクトリのリストです(以下のコマンドの実行を参照)。 PATH値の長さが0の(空の)ディレクトリ名は、現在のディレクトリを表します。空のディレクトリ名は、2 つの隣接するコロン、または先頭または末尾のコロンとして表示できます。デフォルトのパスはシステムによって異なり、bashをインストールした管理者が設定します。一般的な値は「/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin」です。
gnu.orgのBashドキュメントページ(https://www.gnu.org/software/bash/manual/html_node/Bash-Startup-Files.html) さまざまな起動ファイルのソース時間を記述します。上記のデモでは、--login
新しいシェルを作成--interactive
または呼び出さないため、これらのファイルをインポートしないでください。Sudoスイッチで--login
。
このサーバーエラーの答え(https://serverfault.com/questions/833762/where-does-the-bash-path-on-centos-7-get-usr-local-bin-from#answer-838552) Bash の PATH 変数のデフォルト値を記述します。これはCentOS 7のBashに対する答えですが、CentOS 8パッケージのバージョンのBashにはまだ関係しています。受け入れられる答えに応じて、bashソースコードは次のconfig-top.h
ようになります。
/* The default value of the PATH variable. */
#ifndef DEFAULT_PATH_VALUE
#define DEFAULT_PATH_VALUE \
"/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin:."
#endif
/* The value for PATH when invoking `command -p'. This is only used when
the Posix.2 confstr () function, or CS_PATH define are not present. */
#ifndef STANDARD_UTILS_PATH
#define STANDARD_UTILS_PATH \
"/bin:/usr/bin:/sbin:/usr/sbin:/etc:/usr/etc"
#endif
答え1
env_reset
私はあなたが間の相互作用を見たことがあると確信していますsecure_path
。
有効にした後:
secure_path
PATH
既知の良好な値にリセットenv_reset
以下を含むほとんどの環境変数をリセットしますPATH
(正確な動作は、以下を含む他のオプションと構成によって異なりますsecure_path
)。
問題は、各リセットがどのような影響を与えるかです。
第二に、env_reset
によって開始されたプログラムに影響を与えますsudo
。一方、secure_path
それsudo
自体にも影響を与えます。利用できない場合は、sudo
ユーザーを使用(呼び出し)してPATH
プログラムを見つけます。しかし:
- プログラムを開始すると、
- 有効な場合
env_reset
(デフォルト)PATH
はリセットによって免疫されません(例:による)env_keep
。- プログラムは次のように始まります。
- リセット値は
PATH
- (およびその他の環境変数)
- リセット値は
- プログラムは次のように始まります。
- 有効な場合
だから電話をかけたりwhich
、他のことをするときは、それ自体が使用されているのをenv
見ません。PATH
sudo