sudoとperlと環境変数 - 環境変数削除への対策を考えてみる
前回のエントリ「sudoとperlと環境変数 - cipher」は予想外のアクセス数が発生し、過去最高のアクセス数。
解決方法は次回!とは言ったものの、下手な事書けない、と少し時間がかかりましたが、続きです。
まずは前回のおさらいから。
sudoコマンドは、セキュリティ上の理由により不要な環境変数を削除します。sudoのマニュアルによれば、デフォルトではTERM, PATH, HOME, SHELL, LOGNAME, USER, USERNAME以外の環境変数を全て削除します。
つまり、Perlモジュールの読み込みパスを環境変数PERL5LIBで指定しても、sudoコマンドでPerlスクリプトを実行する時はそのパスは使われないという事です。そして、たいていの場合、必要なモジュールが見つからずスクリプトの実行はエラーになることでしょう。
$ sudo perl script_nameの様なコマンド手順の場合には、環境変数が消されている事を考慮する必要が有ります。
引き継がれる環境変数は、sudoコマンドの設定ファイル「sudoers」に書かれている設定に依存します。
自分の環境で消されてしまう環境変数を確認したい場合は、
$ env
$ sudo envとコマンド投入して、結果を見比べてみて下さい。
なお、設定ファイル「sudoers」は、当たり前ですが管理者以外は見る事ができません。管理者権限が有る人は、visudoコマンドで内容を見る事も、編集する事もできます。
さて、解決方法に入る前にまずは注意事項。
セキュリティに唯一絶対の万能な対策は有り得ません。ケースバイケースで環境やアプリの特性に応じて対策は変える必要が有ります。
そもそも環境変数PERL5LIBを予め設定しているようなOSは有りません。環境変数を設定しているという事は、何らかの環境カスタマイズが行われています。管理者、又は自分自身で、何らかの理由が有って設定が追加されているはずです。
その利用する環境のカスタマイズ目的と、想定されるアプリ利用者によって対処方法は変わってきます。その事を念頭に置いて、以下の内容を読んで下さい。
では順番に見ていきましょう。4つほど考えてみました。しかし、最初の二つは推奨しない方法です。残り二つは「これなら自分の使い方だったら、いいかな?」と思われる方法です。
rootでログインする →推奨しないsudoersの設定を変更する → 推奨しない
sudoコマンドに環境変数を渡す
Perlの実行コマンドで-Iオプションを使う
最初からrootでログインするか、suコマンドで後からrootになってしまえば、sudoコマンドによる環境変数の削除とは無縁です。rootとして、環境変数PERL5LIBを設定すれば良いのです。
rootを使わないようにsudoコマンドを使っているハズなので、これは本末転倒。推奨しません。
また、Mac OS Xや、Ubuntuの様に元々rootでのログインを許していない環境も最近は多いですしね。
sudoコマンドの設定ファイル「sudoers」に、削除しない環境変数を個別に指定する事ができます。
Defaults env_keep += "PERL5LIB"と書けば、環境変数PERL5LIBは削除されません。
しかし、元々sudoコマンドが環境変数を削除するのは、攻撃者による不正なモジュールパス設定が有効にならない様にするための措置です。その考え方から行けば、OSやディストリビューションが設定している物以外にenv_keepを安易に増やすのは推奨されません。
sudoコマンドと実行したいコマンドの間に環境変数の設定を記述すると、その環境変数は有効になります。
$ sudo PERL5LIB=/path/to/lib perl script_nameとすると、設定した明示的に権限の有る人が妥当なパスを指定する事になるので、許容できる方法です。
今度はPerl自身の引数としてモジュールのパスを渡す方法です。Perlとしてはお馴染みの方法です。
$ sudo perl -I/path/to/lib script_name
こちらも、明示的に権限の有る人が妥当なパスを指定する事になるので、許容できる方法です。
あまり色々なコマンドに引数や設定が散らばると、トラブった時に解析が嫌なので、最後のPerl自身の引数としてパスを渡すのが、良いようです。
とはいえ、一番良いのは一般ユーザーの権限のままで実行できる設計にできないんだっけ?という所をもう一度問いかけ直す事かもしれませんが...。

コメントする