sudo

sudo時の環境変数上書き / 引き継ぎについて

sudo 実行時、環境変数は変身ユーザーのもので基本的に上書きされると認識しているのだが、実際どう上書きされているのかとか、実行ユーザー側のものを引き継いで使いたい場合はどうしたらいいのかとか、よくわかってないので少し調べたメモ。

なお、以下では sudo で他のユーザーに成り替わることを「変身」と呼称する。日本語版のMan pageでも使われている用語であるため。また確認はCentOS 7で行なっている。

デフォルトの挙動

環境変数の扱いは基本的には /etc/sudoers で管理されている。デフォルトでは漠然と「変身ユーザーの環境変数が適用される」と考えていたが、具体的には env_reset が有効になっている。

env_reset

  • これを有効にしていると、変身後に「最小限の環境」が採用される。
  • 最小限の環境とは、/etc/environment で初期化され、TERM, PATH, HOME, MAIL, SHELL, LOGNAME, USER, USERNAME, SUDO_*がセットされたもの。
  • sudo の実行ユーザーからは env_keepenv_check にマッチするものが加わる。

というわけで、必ずしもすべての環境変数が上書きされているわけではない。 env_keepenv_check は以下の通り。

env_keep

  • env_reset 有効 時に、実行ユーザーから継承される環境変数を定義する。

env_check

  • 「安全」だとみなされない場合に、実行ユーザーから継承されない環境変数を定義する。
  • 「安全」とはTZ以外のすべての環境変数について、変数値に %/ を含まないこと。

ちなみに env_reset が無効な場合に適用されるオプションもある。

env_delete

  • env_reset 無効 時に、実行ユーザーから継承されない(削除される)環境変数を定義する。

これらのオプションで定義されている変数は、 sudoers が権限的に見られない場合でも、 sudo -V で確認ができる。

env_resetの無効化

では実行ユーザーの環境変数を、変身後も引き継ぎたい場合はどうするか。 Defaults env_reset をコメントアウトするなりして完全に無効化することもできなくはないが、それはセキュリティ的によろしくないので以下2パターンかと。

  • 上述の env_keep を使う。
  • sudo -E を使う。

env_keep を使う場合は全ユーザー共通の設定となってしまう。一方で sudo -E は、 -E オプションを指定した場合のみ env_reset が無効化されるため、選択権がある。というわけで後者が良さそう。

setenv

しかしながらデフォルトだと -E は使えない。使えるようにするには setenv オプションを有効にする必要がある。

ただし、これについても全ユーザーに対して有効化することは、Man pageで明確に非推奨とされている。以下のようにタグで設定するのがベター。

%hoge        ALL=(ALL)       SETENV: /usr/bin/fuga

$HOMEについて

sudo -E を使っても、 $HOME は実行ユーザーのものを維持できない場合がある。

これは always_set_home オプションがデフォルト有効になっているためで、これは常にsudoの -H オプションが使用された状態になる(つまり変身ユーザーの $HOME が使われる)。 $HOME 含めて実行ユーザーの環境を使いたい場合は、これを無効にしておく必要がある。

似たようなオプションに set_logname なんかもあったりする。

結論

  • Defaults env_reset はそのまま有効にしておく。
  • 必要な場合に限って SETENV タグを使い、 -E オプションを使えるようにする。
  • $HOME の上書きが必要な場合は Defaults always_set_home も外す。