CentOS 6.5でsudo-1.8.6を実行しています。私の質問は簡単です。 SHELLがユーザー環境からsudo環境に伝播するのを防ぐ方法は?
多くの場合、人々は別の方向に行きます。彼らは環境変数を保存したいです。しかし、ユーザー"zabbix"のシェルが/sbin/nologin
sudoを介してコマンドを実行しようとしたときに問題が発生しました。 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_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_discovery
Pythonスクリプトです。簡単にこれを行うように修正しました。
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 -s
sudoersファイルに正しいコマンドがある場合は機能します。ただし、予想される動作(マンページ: " The new environment contains the TERM, PATH, HOME, MAIL, SHELL, LOGNAME, USER, USERNAME and SUDO_* variables
"に反映されているように)は、シェルが呼び出し側の受信者のものです。 sudo env のPATH
, HOME
,LOGNAME
変数 を見るとUSER
root の内容を見ることができます。SHELL
また、ルートシェルでなければなりません。