呼び出し側のシェルがsudoで使用されないようにする方法


8

CentOS 6.5でsudo-1.8.6を実行しています。私の質問は非常に単純です。SHELLがユーザーの環境からsudo環境に伝播するのを防ぐにはどうすればよいですか?

通常、人々は逆の方向に進んでいます-彼らは環境変数を保存したいのです。しかし、シェルが/sbin/nologinsudo経由でコマンドを実行しようとするユーザー「zabbix」という問題が発生しています。Sudoは/sbin/nologinrootがサブシェルを実行できないようにを維持しています。(更新:この部分は正しいですが、SHELL環境変数ではありません。問題となっているのは、/ etc / passwdからプルされているシェル値です。)

問題を説明するテストを含めます。これは実際の使用例ではありませんが、呼び出し元のユーザーのシェルが保持されていることを示しています。ユーザーとして実行するプログラムがありますzabbix。呼び出します/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 = "COLORS DISPLAY HOSTNAME HISTSIZE INPUTRC KDEDIR LS_COLORS"
デフォルトenv_keep + = "MAIL PS1 PS2 QTDIR USERNAME LANG LC_ADDRESS LC_CTYPE"
デフォルトenv_keep + = "LC_COLLATE LC_IDENTIFICATION LC_MEASUREMENT 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

## rootがどこでもコマンドを実行できるようにする 
ルートALL =(ALL)ALL

#includedir /etc/sudoers.d

そしてこれが私の/etc/sudoers.d/zabbixです:

デフォルト:zabbix!requiretty

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

編集:もう少し情報:

sudoを実行するプロセスはzabbix_agentd、Zabbix監視ソフトウェアからのものです。/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
env >> / tmp / outfile

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

zabbix_get -s client_hostname -k 'example.disk.discovery'

次に、を確認する/tmp/outfileと、次のように表示されます。

SHELL = / sbin / nologin
TERM = linux
USER = root
SUDO_USER = zabbix
SUDO_UID = 497
USERNAME = root
PATH = / sbin:/ bin:/ usr / sbin:/ usr / bin:/ usr / local / bin:/ usr / local / sbin
MAIL = / var / mail / root
PWD = /
LANG = en_US.UTF-8
SHLVL = 1
SUDO_COMMAND = / tmp / doit
HOME = / root
LOGNAME = root
SUDO_GID = 497
_ = / bin / env

そのSHELL行は本当に私を悩ませます。ファイルはrootが所有しているので、rootユーザーが作成していることがわかりますが、シェルは呼び出し元ユーザー(zabbix)からのものです。


sudo env SHELL=/bin/sh shあなたのシステムのSHELL変数としてプロンプトで/ binに/ shのセットを提供?

@adonis-更新された質問を参照してください。ところで、あなたはとてもハンサムです。
マイクS

@BinaryZebraは-はい、私は知っているenv_deleteが、私は、問題の核心は、env_resetのデフォルトの動作があることであることに同意し...causes commands to be executed with a new, minimal environment.、我々はそうmanページによると、PAMを持つLinuxシステムを持っていますThe new environment contains the ... SHELL ... (variable)/etc/sudoers上記の私のファイルからわかるように、は許可さSHELLれていませんenv_keep。したがってSHELL、保持するべきではありません。rootユーザーのが必要SHELLです。
マイクS

@BinaryZebra- ファイルに追加zabbix ALL=(root) NOPASSWD: /bin/env SHELL=/bin/sh /tmp/doit *しまし/etc/sudoers/zabbixたが、適切なシェルがあります。おかげで、私は今回避策を持っています。問題は、なぜそれを含める必要があるのか​​ということです。呼び出し元のシェルを渡すのは危険な(そして壊れた)ようですが、sudoを変更するように設定されている場所が見つかりません。私は走りましたfind /etc/sudoers /etc/sysconfig -type f -exec grep env_ {} \;、そして、赤い旗を見つけません。文字列/etc/sudoersのみが含まれenv_ます。したがって、sudoersフラグが妨害しているとは思いません...
Mike S

マイク:最初のレベル:シンプルsudo bashはbashシェルをrootとして開始し、SHELL変数を/ etc / passwordからの値に設定する必要があります。SHELLがに設定されている(または保持されている)と報告し/sbin/nologinます。これはセキュリティ上の問題であり、rootによって起動されたシェルは、ユーザーが設定した環境変数によって制御されてはなりません。それはあなたが調査しなければならないものです。

回答:


5

それから答えはそれsudoがバグを持っているということです。まず、回避策:これを私の中に入れます/etc/sudoers.d/zabbix file

zabbix ALL =(root)NOPASSWD:/ bin / env SHELL = / bin / sh / usr / local / bin / zabbix_raid_discovery

そして今から呼び出されるサブコマンド zabbix_raid_discovery仕事。

これを修正するパッチはsudo 1.8.15にあります。メンテナのTodd Millerから:

これは「いつもそういう風に」のほんの一例です。ありません
本当に良い理由です。以下の違いは動作をするはずです
ドキュメントと一致します。

 -トッド

diff -r adb927ad5e86 plugins / sudoers / env.c
--- a / plugins / sudoers / env.c Tue Oct 06 09:33:27 2015 -0600
+++ b / plugins / sudoers / env.c Tue Oct 06 10:04:03 2015 -0600
@@ -939,8 +939,6 @@
            CHECK_SETENV2( "USERNAME"、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;
+それ以外の場合(strncmp(* ep、 "SHELL ="、6)== 0)
+ SET(didvar、DID_SHELL);
                else if(strncmp(* ep、 "PATH ="、5)== 0)
                    SET(didvar、DID_PATH);
                それ以外の場合(strncmp(* ep、 "TERM ="、5)== 0)
@@ -1039,7 +1039,9 @@
     if(reset_home)
        CHECK_SETENV2( "HOME"、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 = unknown"、false、false);
     if(!ISSET(didvar、DID_PATH))

素晴らしいマイク!、探偵の仕事をありがとう。

マイク、あなたは(将来の)パッチへのリンクを張ることは可能ですか?

@BinaryZebra Diffはこちらです:sudo.ws/repos/sudo/rev/b77adbc08c91まだパッチが表示されていません。
マイクS

マイク:あなたは間違った木に吠えていると思います。ここでの重要なポイントProvide default values for $SHELL, $TERM and $PATH if not set.は次のとおり... if not set.です。値セットはsudoによって保持されます。誰がシェルを設定していますか?

@BinaryZebra-それは私がそれを読む方法ではありません。SHELLは設定されていません(デフォルトではenv_resetによって)。設定されていないため、古いコードはsudo_userのpwエントリを使用するように言っています。新しいコードでは、runasユーザーのpwエントリを使用するように指示されています。
マイクS

4

問題はどこに問題があると思ったのかということでしたが、問題はSHELL変数に何が起こるかではなく、sudoが実際に行うことであることがわかりました。例えば:

-bash-4.1 $ whoami
testdude
-bash-4.1 $ grep testdude / etc / passwd
testdude:x:1001:10:Test dude:/ tmp:/ bin / bash
-bash-4.1 $ sudo env
[sudo] testdudeのパスワード: 
...
SHELL = / bin / bash
...

ここまでは順調ですね。...しかし問題は、ドキュメントとは異なり、sudoが呼び出し先ではなく呼び出し元のシェルを使用することです。実際、/ etc / passwdを編集してシェルを変更すると、sudoが呼び出し側のシェルではなく、次のようになっていることがわかりますSHELL

-bash-4.1 $ grep root / etc / passwd
root:x:0:0:root:/ root:/ 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:Test dude:/ tmp:/ bin / sh
-bash-4.1 $ sudo env
...
SHELL = / bin / sh
...
-bash-4.1 $エクスポートSHELL = / completely / meaningless / path
-bash-4.1 $ sudo env
...
SHELL = / bin / sh
...

sudo -i最初のログインをシミュレートしたくないので使用できません。sudo -ssudoersファイルに適切なコマンドがあれば動作します。ただし、予想される動作(manページ: " The new environment contains the TERM, PATH, HOME, MAIL, SHELL, LOGNAME, USER, USERNAME and SUDO_* variables"に反映)は、シェルが呼び出し先になることです。あなたが見ればPATHHOMELOGNAME、とUSERはsudo envをのための変数は、rootのものが表示されます。SHELLルートのシェルでもあるはずです。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.