呼び出し側のシェルがsudoで使用されるのを防ぐ方法

呼び出し側のシェルがsudoで使用されるのを防ぐ方法

CentOS 6.5でsudo-1.8.6を実行しています。私の質問は簡単です。 SHELLがユーザー環境からsudo環境に伝播するのを防ぐ方法は?

多くの場合、人々は別の方向に行きます。彼らは環境変数を保存したいです。しかし、ユーザー"zabbix"のシェルが/sbin/nologinsudoを介してコマンドを実行しようとしたときに問題が発生しました。 Sudoは、/sbin/nologinルートがサブシェルを実行できないように維持されます。(更新:この部分は正しいですが、SHELL環境変数ではありません。問題は/ etc / passwdから抽出したシェル値です。)

問題を説明するテストが含まれています。実際のユースケースではありませんが、呼び出すユーザーのSHELLが保存されていることだけを示しています。ユーザーとして実行されるプログラムがありますzabbix。呼び出します(プログラミング方法でdaemonとして実行されるため、/usr/bin/sudo -u root /tmp/doitパスワードファイルのシェルはそれをブロックしません)。以下のみを含むシェルスクリプトです。zabbix/sbin/nologin/tmp/doit

#!/bin/sh
env > /tmp/outfile

(明らかにモードは755です。)outfile私が見ることができる限りそれSHELLはです/sbin/nologin。しかし、この時点では、スクリプトはsudoを介してrootとして実行されているので、古いユーザーの環境変数はありませんか?

これは私の/ etc / sudoersです:

デフォルトは必須です。
デフォルト値!visiblepw

デフォルトは Always_set_home
デフォルト値 env_reset
デフォルト値 env_keep="カラー表示ホスト名 HISTSIZE INPUTRC KDEDIR LS_COLORS"
デフォルト値 env_keep += "MAIL PS1 PS2 QTDIR ユーザー名 LANG LC_ADDRESS LC_CTYPE"
デフォルト値 env_keep += "LC_COLLATE LC_IDENTIFICATION LC_MEASURMENT LC_MESSAGES"
デフォルト env_keep += "LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER LC_TELEPHONE"
デフォルト値 env_keep += "LC_TIME LC_ALL LANGUAGE LINGUAS _XKB_CHARSET XAUTHORITY"
デフォルトの secure_path = /sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin:/usr/local/sbin

## ルートがどこからでもコマンドを実行できるようにする
ルートオール=(すべて)すべて

#includedir /etc/sudoers.d

これは私のものです/etc/sudoers.d/zabbix

既定値: zabbix !requiretty

zabbix ALL=(ルート) NOPASSWD: /tmp/doit

編集:追加情報:

sudo を実行するプロセスは、zabbix_agentdZabbix モニタリングソフトウェアからインポートされます。ファイルには次/etc/zabbix/zabbix_agentd.d/userparameter_disk.confの項目があります。

UserParameter=example.disk.discovery,/usr/local/bin/zabbix_raid_discovery

/usr/local/bin/zabbix_raid_discoveryPythonスクリプトです。簡単にこれを行うように修正しました。

print subprocess.check_output(['/usr/bin/sudo', '-u', 'root', '/tmp/doit'])

/tmp/doitこれを行う:

#!/bin/sh
環境 >> /tmp/outfile

Zabbixサーバーで次のコマンドを実行してスクリプトを実行します/usr/local/bin/zabbix_raid_discovery

zabbix_get -s クライアント_ホスト名 -k 'example.disk.discovery'

その後、確認すると/tmp/outfile次のようになります。

SHELL=/sbin/nologin
用語=Linux
ユーザー=ルート
SUDO_USER=ザビックス
Sudo_UID=497
ユーザー名=ルート
パス=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin:/usr/local/sbin
メール=/var/mail/root
パスワード=/
LANG=en_US.UTF-8
SLVL=1
SUDO_COMMAND=/tmp/doit
ホームページ=/ルートディレクトリ
ログ名=ルート
SUDO_GID=497
_=/空/環境

そのSHELLセリフが本当に酷いですね。ファイルはrootが所有しているため、rootが作成したことがわかりますが、シェルは呼び出すユーザー(zabbix)から来ます。

答え1

答えはsudoバグがあるということです。まず、解決策:私はこれを私の中に入れました/etc/sudoers.d/zabbix file

zabbix ALL=(ルート) NOPASSWD: /bin/env SHELL=/bin/sh /usr/local/bin/zabbix_raid_discovery

次に、zabbix_raid_discoveryジョブ内でサブコマンドを呼び出します。

この問題を解決するためのパッチはsudo 1.8.15でリリースされる予定です。管理者Todd Millerの言葉:

それはただ「いつもこんな感じでした」いいえ
これは確かに妥当な理由です。次の違いが原因で動作する必要があります。
文書と一致します。

 - トッド

diff -r adb927ad5e86 プラグイン/sudoers/env.c
--- a/plugins/sudoers/env.c 2015年10月6日火曜日-0600
+++ b/plugins/sudoers/env.c 2015年10月6日火曜日10:04:03 -0600
@@-939,8+939,6@@
            CHECK_SETENV2("ユーザー名", runas_pw->pw_name,
                ISSET(didvar、DID_USERNAME)、true);
        }その他{
- if (!ISSET(didvar, DID_SHELL))
- CHECK_SETENV2("SHELL", sudo_user.pw->pw_shell, false, true);
            / * def_set_lognameの場合は、後でLOGNAMEを設定します。 */
            if(!def_set_logname){
                if(!ISSET(didvar、DID_LOGNAME))
@@-984,6 +982,8 @@
            if (!env_should_delete(*ep)) {
                if (strncmp(*ep, "SUDO_PS1=", 9) == 0)
                    ps1 = * ep + 5;
+ else if (strncmp(*ep, "SHELL=", 6) == 0)
+ SET(didvar、DID_SHELL);
                そうでない場合 (strncmp(*ep, "PATH=", 5) == 0)
                    SET(didvar、DID_PATH);
                そうでない場合 (strncmp(*ep, "TERM=", 5) == 0)
@@-1039,7+1039,9@@
     if(ホームページリセット)
        CHECK_SETENV2("ホーム", runas_pw->pw_dir, true, true);

- /* $TERM と $PATH が設定されていない場合のデフォルト値を提供します。 */
+ / *設定されていない場合は、$ SHELL、$ TERM、および$ PATHのデフォルト値を指定します。 */
+ if (!ISSET(didvar, DID_SHELL))
+ CHECK_SETENV2("SHELL", runas_pw->pw_shell, false, false);
     if(!ISSET(didvar、DID_TERM))
        CHECK_PUTENV("TERM=不明", false, false);
     if(!ISSET(didvar、DID_PATH))

答え2

問題は私が問題だと思ったことでしたが、問題はSHELL変数に発生したのではなく、sudoが実際に何をしたのかにあることがわかりました。たとえば、

-bash-4.1$ whoami
テスト友達
-bash-4.1$ grep testdude /etc/passwd
testdude:x:1001:10:テスト友達:/tmp:/bin/bash
-bash-4.1$ sudo 環境
[sudo] testdudeのパスワード:
...
シェル=/bin/bash
...

今まではそんなに良くなった。 ...しかし、問題は、ドキュメントとは異なり、sudoが呼び出し側の受信者ではなく呼び出し側のシェルを使用することです。実際に/ etc / passwdを編集してシェルを変更すると、sudoが代わりに呼び出し元のシェルに従うことがわかりますSHELL

-bash-4.1$ grep root /etc/passwd
ルート:x:0:0:ルート:/ルート:/bin/bash
-bash-4.1$ sudo sed -i -e '/testdude/s/bash/sh/' /etc/passwd
-bash-4.1$ grep testdude /etc/passwd
testdude:x:1001:10:テスト友達:/tmp:/bin/sh
-bash-4.1$ sudo 環境
...
シェル=/bin/sh
...
-bash-4.1$ エクスポート SHELL=/完全/意味なし/パス
-bash-4.1$ sudo 環境
...
シェル=/bin/sh
...

sudo -i初期ログインをシミュレートしたくないため使用できません。sudo -ssudoersファイルに正しいコマンドがある場合は機能します。ただし、予想される動作(マンページ: " The new environment contains the TERM, PATH, HOME, MAIL, SHELL, LOGNAME, USER, USERNAME and SUDO_* variables"に反映されているように)は、シェルが呼び出し側の受信者のものです。 sudo env のPATH, HOME,LOGNAME変数 を見るとUSERroot の内容を見ることができます。SHELLまた、ルートシェルでなければなりません。

関連情報