それマグで!

知識はカップより、マグでゆっくり頂きます。 takuya_1stのブログ

習慣に早くから配慮した者は、 おそらく人生の実りも大きい。

sudo時の$HOME/$USER の環境変数の継承について

はじめに

-E環境変数を引き継げるのだけれど、WSLでsudo したときに、Windowsアプリにroot を使ってほしくなく、単にファイルを書き換えたいだけという欲求が出てきたので調べた。結論としてはむやみにやるんじゃない。ってことですけどね。

Home環境変数を維持する。-E

次のように、特に明示しない限り、sudo時に $HOMEをそのままにする。

takuya $ sudo -E  sh -c 'echo $HOME'
/home/takuya
takuya $ sudo -H -E  sh -c 'echo $HOME'
/root

$HOMEが書き換わる仕組み

デフォルトの挙動を見ておく。 素の状態では、sudo 時に 環境変数はリセットされ、HOMEは rootが使われる。

takuya $ sudo sh -c 'echo $HOME'
/root

環境変数を持ち込む

環境変数を維持したまま、sudo を実行する。

sudo -E sh -c 'echo $HOME'
/home/takuya

$HOME以外の環境変数を書き換える -H -E

$HOMEは除外。他の環境変数は維持する。

sudo -E -H sh -c 'echo $HOME'
/root

sudoersとの関係

sudoersのデフォルト設定は次のとおりです。

Defaults        env_reset

env_reset 設定は、sudo時の無継承、環境変数を最小限*1で新規作成し利用する。

このenv_reset を無視した実行が -E

sudo -E

ただし、$HOMEは強制する。 -Eで変数を継承するが、HOME変数は持ち込ませない。

sudo  -E -H  # または -H -E (順不問)

sudoers と -E の関係

-Eを常に有効する 。設定で常に有効にする。

## !が否定。偽になる
Defaults       !env_reset

すると、-Eをつけなくても、環境変数は維持される。

takuya $ export A=123; sudo sh -c 'echo A=$A;echo $HOME'
A=123
/home/takuya

sudoers と -E -Hの関係

sudoers では -Eを常に有効が!env_reset-Halways_set_home に相当する。

環境変数を維持して、ただしHOME変数は持ち込ませない。

# 環境変数を維持
Defaults   !env_reset
# ただし、HOME変数は持ち込ませない。
Defaults   always_set_home 

すると、HOME変数が、持込拒否される。

takuya $ export A=123; sudo sh -c 'echo A=$A;echo $HOME'
A=123
/root

-u オプションと set_logname

ちなみに、-uでユーザー名の書き換えができます。

takuya $ sudo sh -c 'echo $USER:$HOME'
root:/root
takuya $ sudo  -u takuya sh -c 'echo $USER:$HOME'
takuya:/home/takuya

しかし、-uで書き換えたところで、管理者コマンドは実行できません。

takuya$ sudo -E -u takuya apt remove dnsutils
open (13: Permission denied) are you root?

-uset_logname相当なのですが。

sudoersに次のように、設定し、sudo時に$USERを無変更にさせます。

Defaults !set_logname

すると、sudoしても$USERはそのままです。

sudo -E sh -c 'echo $USER:$HOME'
takuya:/home/takuya

そして、-u と同じようにapt install はできませ・・・えええ・・・そのまま apt install はできちゃう・・・

takuya$ sudo -E sh -c 'echo $USER:$HOME'
takuya:/home/takuya
takuya$ sudo -E apt install dnsutils
Setting up dnsutils (1:9.11.5.P4+dfsg-5.1+deb10u5) ...

えええ・・・どうなってるんだ。sudoers怖いね。

sudoers 書き換えは自分の開発環境だけにすること

むやみに書き換えないこと。環境変数をむやみに変えてたりすると、思わぬバグを踏んで、セキュリティを台無しににするので、env_resetなど書き換えはできる限りやらず、

開発環境でも sudo -Eで使ったほうがいいです。

https://www.sudo.ws/alerts/env_add.html

http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-0106

Sudo 1.6.9 before 1.8.5, when env_reset is disabled, does not properly check environment variables for the env_delete restriction, which allows local users with sudo permissions to bypass intended command restrictions via a crafted environment variable.

今回実験に使ったsudoについて

takuya $ wsl --list --verbose
  NAME      STATE           VERSION
* Debian    Running         1
takuya $ cat /etc/debian_version
10.10
takuya $sudo --version
Sudo version 1.8.27
Sudoers policy plugin version 1.8.27
Sudoers file grammar version 46
Sudoers I/O plugin version 1.8.27

参考資料

*1:If set, sudo will run the command in a minimal environment containing the TERM, PATH, HOME, MAIL, SHELL, LOGNAME, USER, USERNAME and SUDO_* variables.