はじめに
業務で、sudo su
でroot
ユーザへ権限昇格した際に、あるコマンドにおいて文字化けしてしまうということが起きていた。sudo su -
でのroot
ユーザへ権限昇格だと正常にコマンドが実行できた。
このあたり理解が浅いのでまとめておく。
環境
Windows 11 Professional
WSL2 Ubuntu 24.04 LTS
sudo su について
コマンドの動作
現在のシェル環境をそのまま引き継ぎ、新しいユーザー(通常は root)としてシェルを起動する。
環境変数の挙動
元のユーザーの環境変数を引き継ぐ。
例として、$HOME
や $PATH
は元のユーザーの設定が維持される。このため、デフォルトの root ユーザーの設定は適用されない。
※正確には、/etc/sudoers
の env_keep
が有効であれば環境変数が設定される。
用途
環境を引き継いだまま一時的に権限を上げてコマンドを実行したい場合に便利である。しかし、意図しない環境変数が root の操作に影響を与えるリスクがある。
sudo su - について
コマンドの動作
新しいユーザー(通常は root)としてログインし、そのユーザーのデフォルト環境を完全にロードする。
環境変数の挙動
元のユーザーの環境変数はクリアされ、新しいユーザー(root)のデフォルト環境が読み込まれる。
例として、$HOME
は /root
に変更され、root ユーザー専用のパスや設定が適用される。
この際、/etc/profile
や /root/.bashrc
などの設定ファイルが読み込まれる。
用途
完全に root 環境で作業したい場合に推奨される。
root 専用の設定や環境が必要なタスク(システム管理、パッケージのインストールなど)を行う際に有効である。
違いについての例
sudo su
user@machine:~$ echo $HOME
/home/user
user@machine:~$ sudo su
root@machine:/home/user# echo $HOME
/home/user
$HOME
が元のユーザーのままとなる。
sudo su -
user@machine:~$ echo $HOME
/home/user
user@machine:~$ sudo su -
root@machine:~# echo $HOME
/root
$HOME
が /root
に切り替わる。
実際にやってみる
WSL2
の環境でやってみる。
kbushi
ユーザーがカレントユーザなので、これを sudo su
での昇格とsudo su -
での昇格で確認してみる。
kbushiユーザの $HOMEと$PATH
echo $HOME
/home/kbushi
echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/usr/lib/wsl/lib:/mnt/c/Program Files/Microsoft SDKs/Azure/CLI2/wbin:/mnt/c/Windows/system32:/mnt/c/Windows:/mnt/c/Windows/System32/Wbem:/mnt/c/Windows/System32/WindowsPowerShell/v1.0/:/mnt/c/Windows/System32/OpenSSH/:/mnt/c/Program Files/dotnet/:/mnt/c/Program Files (x86)/NVIDIA Corporation/PhysX/Common:/mnt/c/Program Files/Git/cmd:/mnt/c/Program Files/Microsoft SQL Server/150/Tools/Binn/:/mnt/c/Program Files/Microsoft SQL Server/Client SDK/ODBC/170/Tools/Binn/:/mnt/c/Program Files (x86)/Nodist/bin:/mnt/c/Program Files/NVIDIA Corporation/NVIDIA app/NvDLISR:/Docker/host/bin:/mnt/c/Users/pspkk/AppData/Local/Microsoft/WindowsApps:/mnt/c/Users/pspkk/AppData/Local/Programs/Microsoft VS Code/bin:/mnt/c/Users/pspkk/.dotnet/tools:/home/kbushi/.dotnet:/home/kbushi/.dotnet/tools
sudo suで実行
sudo su
root@kbushi:/home/kbushi# echo $HOME
/root
root@kbushi:/home/kbushi# echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
sudo su -で実行
sudo su -
root@kbushi:~# echo $HOME
/root
root@kbushi:~# echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
やってみたが、変わっていないようだった。sudo su
だと環境変数が切り替わるようだが、なぜ?
/etc/sudoersのenv_keep, secure_pathについて
/etc/sudoers
には、環境変数の保持 (env_keep
)が存在している。sudo
の設定ファイル(/etc/sudoers
)で、env_keep オプションによってどの環境変数を保持するかが制御されている。
そのため、この中でこの設定がされているかどうかを確認するのが良い。
※デフォルトでは、$PATH などが引き継がれることが一般的である。
また、secure_path
が設定されていると、sudo 実行時に $PATH
をこの値に強制的に設定するため、ここも確認をする。
下記を見てみると、secure_path
が設定されており、これが$PATH
に上書きするようなので、引き継ぎされないようだ。
#
# This file MUST be edited with the 'visudo' command as root.
#
# Please consider adding local content in /etc/sudoers.d/ instead of
# directly modifying this file.
#
# See the man page for details on how to write a sudoers file.
#
Defaults env_reset
Defaults mail_badpass
Defaults secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin"
# This fixes CVE-2005-4890 and possibly breaks some versions of kdesu
# (#1011624, https://bugs.kde.org/show_bug.cgi?id=452532)
Defaults use_pty
# This preserves proxy settings from user environments of root
# equivalent users (group sudo)
#Defaults:%sudo env_keep += "http_proxy https_proxy ftp_proxy all_proxy no_proxy"
# This allows running arbitrary commands, but so does ALL, and it means
# different sudoers have their choice of editor respected.
#Defaults:%sudo env_keep += "EDITOR"
# Completely harmless preservation of a user preference.
#Defaults:%sudo env_keep += "GREP_COLOR"
# While you shouldn't normally run git as root, you need to with etckeeper
#Defaults:%sudo env_keep += "GIT_AUTHOR_* GIT_COMMITTER_*"
# Per-user preferences; root won't have sensible values for them.
#Defaults:%sudo env_keep += "EMAIL DEBEMAIL DEBFULLNAME"
# "sudo scp" or "sudo rsync" should be able to use your SSH agent.
#Defaults:%sudo env_keep += "SSH_AGENT_PID SSH_AUTH_SOCK"
# Ditto for GPG agent
#Defaults:%sudo env_keep += "GPG_AGENT_INFO"
# Host alias specification
# User alias specification
# Cmnd alias specification
# User privilege specification
root ALL=(ALL:ALL) ALL
# Members of the admin group may gain root privileges
%admin ALL=(ALL) ALL
# Allow members of group sudo to execute any command
%sudo ALL=(ALL:ALL) ALL
# See sudoers(5) for more information on "@include" directives:
@includedir /etc/sudoers.d
Defaults env_reset
sudo コマンド実行時に、環境変数をリセットする。
一部の変数($PATH
など)はリセットされるか、secure_path
によって上書きされる。
Defaults secure_path="..."
sudo 実行時に $PATH
をこの値に強制的に設定する。
これにより、通常のユーザーが持つ $PATH
の内容は無視される。
sudo を使った場合、secure_path
に定義された値が $PATH
として使用されるため、sudo su
や sudo su -
を実行しても $PATH
はこの値が反映される。
環境変数を引き継ぎしつつ切り替えをする
確認するために、環境変数を引き継ぎできるようにしてみる。
/etc/sudoersの設定を変更する
sudo EDITOR=vim visudo
Defaults env_reset
Defaults mail_badpass
# Defaults secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin"
として保存する。
下記を実行する。
※sudo su
だと、どうやら$PATH
の環境変数が引継ぎされないようだった。
今回はsudo -i
で実行して試した結果となる。
sudo -i
root@kbushi:~# echo $HOME
/root
root@kbushi:~# echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/usr/lib/wsl/lib:/mnt/c/Program Files/Microsoft SDKs/Azure/CLI2/wbin:/mnt/c/Windows/system32:/mnt/c/Windows:/mnt/c/Windows/System32/Wbem:/mnt/c/Windows/System32/WindowsPowerShell/v1.0/:/mnt/c/Windows/System32/OpenSSH/:/mnt/c/Program Files/dotnet/:/mnt/c/Program Files (x86)/NVIDIA Corporation/PhysX/Common:/mnt/c/Program Files/Git/cmd:/mnt/c/Program Files/Microsoft SQL Server/150/Tools/Binn/:/mnt/c/Program Files/Microsoft SQL Server/Client SDK/ODBC/170/Tools/Binn/:/mnt/c/Program Files (x86)/Nodist/bin:/mnt/c/Program Files/NVIDIA Corporation/NVIDIA app/NvDLISR:/Docker/host/bin:/mnt/c/Users/pspkk/AppData/Local/Microsoft/WindowsApps:/mnt/c/Users/pspkk/AppData/Local/Programs/Microsoft VS Code/bin:/mnt/c/Users/pspkk/.dotnet/tools:/home/kbushi/.dotnet:/home/kbushi/.dotnet/tools:/snap/bin
環境変数を引き継ぎしつつ切り替えをする2
気になったので、$PATH
以外の環境変数で実験した。
一般ユーザで環境変数をexport
する。
export ICHI=1
env | grep ICHI
## 結果
ICHI=1
/etc/sudoers
を修正する。
Defaults env_reset
Defaults env_keep += "ICHI"
Defaults mail_badpass
# Defaults secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin"
sudo su
, sudo su -
, sudo -i
を試す。
sudo su
での実行
sudo su
root@kbushi:/home/kbushi# env | grep ICHI
ICHI=1
root@kbushi:/home/kbushi#
sudo su -
での実行
sudo su -
root@kbushi:~# env | grep ICHI
root@kbushi:~#
sudo -i
での実行
sudo -i
root@kbushi:~# env | grep ICHI
ICHI=1
root@kbushi:~#
結果として、sudo su
だと環境変数が引き継がれるようだった。
※sudo su
でのPATH
の環境変数が引き継がれないところについては、secure_path
以外にも設定している箇所があるのかもしれない…。
おまけ
su
について
su
で 特定のユーザに切り替えることもできる。
su
これだと、root
ユーザへの切り替え。
この場合は、root
ユーザのパスワードが必要になることに注意。
su
とsu -
も今回記載したsudo su
と sudo su -
と同じなのでここでは記載しない。
例えば、root
ユーザ以外の切り替えであれば、
# - なし
su user
# - あり
su user -
というように切り替えができる。-
のあり/なしでカレントユーザの環境変数が引き継がれるかどうかが決まるのでこの点に注意すること。
参考
sudo su とかしてる人はだいたいおっさん
https://zenn.dev/tmtms/articles/202105-sudo-susuとsudoの違い
https://qiita.com/aosho235/items/05d4a4f549016e41cde7sudo時の環境変数上書き / 引き継ぎについて
https://qiita.com/chroju/items/375582799acd3c5137c7
おわりに
sudo su
を何も考えずに気軽に使ってしまっていたので、このあたりちゃんと覚えておきたい。