実行可能ファイルの場所が検索パスにない場合でも、フルパスなしで実行可能ファイルが見つかるのはなぜですか?

実行可能ファイルの場所が検索パスにない場合でも、フルパスなしで実行可能ファイルが見つかるのはなぜですか?

この質問は、実行可能ファイルを呼び出すときに記録された動作と実際の動作が一致しない理由を理解することです。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_pathPATH既知の良好な値にリセット
  • env_reset以下を含むほとんどの環境変数をリセットしますPATH(正確な動作は、以下を含む他のオプションと構成によって異なりますsecure_path)。

問題は、各リセットがどのような影響を与えるかです。

第二に、env_resetによって開始されたプログラムに影響を与えますsudo。一方、secure_pathそれsudo自体にも影響を与えます。利用できない場合は、sudoユーザーを使用(呼び出し)してPATHプログラムを見つけます。しかし:

  • プログラムを開始すると、
    • 有効な場合env_reset(デフォルト)
      • PATHはリセットによって免疫されません(例:による)env_keep
        • プログラムは次のように始まります。
          • リセット値はPATH
          • (およびその他の環境変数)

だから電話をかけたりwhich、他のことをするときは、それ自体が使用されているのをenv見ません。PATHsudo

関連情報