🌏

sudo 実行時に設定される環境変数の仕組み

2024/12/07に公開

sudo 実行時の環境変数のセットのされ方について、知らなかったのでメモ。
間違いがありましたら、ご指摘いただけると助かります🙇‍♀️
※実行環境: Amazon Linux 2023(EC2)

1. 前提

環境変数は、ユーザーごとにそれぞれ保持しています。

  • xxxユーザーなら、xxxユーザーの環境変数を保持
  • rootユーザーなら、rootユーザーの環境変数を保持

以下のコマンドで、ユーザーごとの環境変数を一覧で確認できます。

$ env


2. sudo 実行時に環境変数はどう変わるか?

sudo は通常、コマンドを root 権限 で実行します。それなら、sudo を実行したときに使用される環境変数は、全部root ユーザーのものが使われていると思いきや、そういう訳ではありません。
以下、sudo 実行時に環境変数がどのように設定されるか、ざっくりルールをまとめてみました。

詳しくは、記事の最後に記載した参考リンクをご確認ください。


3. sudo 実行時の環境変数の処理のルール

ルール1. sudo 実行ユーザーの環境変数は基本的にリセットされる

sudo 実行時の環境変数の取り扱いは、/etc/sudoers で管理されています。
sudo 実行時に、 sudo 実行ユーザーの環境変数はリセットされます。これは/etc/sudoers にデフォルトで設定されているenv_resetオプションによるものです。

Defaults    env_reset

実行例

$ whoami
ec2-user

$ env | grep HOGE
HOGE=123

$ sudo env | grep HOGE # sudo実行時に、環境変数HOGEがリセットされているため何も表示されない


ルール2. 特定の環境変数は、rootの持っている値がsudo 実行ユーザーに上書きされる

sudo 実行ユーザーが保持する$HOME$MAIL$SHELL$LOGNAME$USERなどの特定の環境変数については、rootユーザーの持っている値で上書きされます。

例えば$HOME は、always_set_home オプションにより、rootの$HOME の値がsudo を実行ユーザーの$HOME にセットされます。

Defaults    always_set_home

実行例

$ env | grep HOME
HOME=/home/ec2-user

$ sudo env | grep HOME # sudoで実行すると、rootが持っているのと同じ$HOMEが出力される
HOME=/root

$ env | grep USER
USER=ec2-user

$ sudo env | grep USER # sudoで実行すると、rootが持っているのと同じ$USERが出力される
USER=root


ルール3. 指定した環境変数はsudo 実行したユーザーから引き継げる

ルール1で「sudo 実行ユーザーの環境変数はリセット」されると書きましたが、/etc/sudoersenv_keep で指定した環境変数はリセットされず、引き継ぐことができます。

Defaults    env_keep =  "COLORS DISPLAY HOSTNAME HISTSIZE KDEDIR LS_COLORS"
Defaults    env_keep += "MAIL QTDIR USERNAME LANG LC_ADDRESS LC_CTYPE"

実行例

$ env | grep MAIL
MAIL=/var/spool/mail/ec2-user

$ sudo env | grep MAIL # env_keepにMAILが設定されているので、sudo実行元ユーザーの環境変数が引き継がれる
MAIL=/var/spool/mail/ec2-user


4. その他

環境変数$PATH について

sudo実行時に使われるPATHは、secure_pathオプションで設定されています。

Defaults    secure_path = /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/var/lib/snapd/snap/bin

実行例

$ env | grep PATH
PATH=...(ec2-userで設定してあるPATHが表示)

$ sudo env | grep PATH
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/var/lib/snapd/snap/bin


sudo -i でrootの環境変数を取得する

-i オプションをつけてsudoを実行すると、rootでログインした時と同じ状態で、コマンドを実行できます。よって以下のように、rootの環境変数を取得することができます。

$ env | grep HOGE
HOGE=123

$ sudo env | grep HOGE # ルール1より、環境変数HOGEがリセットされているため何も表示されない

$ sudo -i env | grep HOGE # rootでログインして、env | grep HOGEを実行した時と同じ結果が取得できる
HOGE=789


参考リンク

章Command environment: ルール1~3
章SUDOERS OPTIONS: sudoresで設定できるオプション
https://man7.org/linux/man-pages/man5/sudoers.5.html

章ENVIRONMENT: sudo内の環境変数について
https://man7.org/linux/man-pages/man8/sudo.8.html

Discussion