Linux基礎

【初心者向け】sudoとsuの違い, コマンドが使えない場合の対処等

sudo と su

sudo (読み方 : すーどぅー) はコマンドの先頭につけることで、そのコマンドを root 権限で実行することができるコマンドです。別のコマンドとセットで使われ、一時的に root にユーザーになれるコマンドです。なので root で実行したいコマンド毎に sudo を付ける必要があります。

$ sudo useradd user1
$ sudo usermod -aG hoge user1

一方、su (読み方 : えすゆー) は単体で実行され、永続的に root ユーザーになれるコマンドです。一度 root になってしまえば以降はどのコマンドを実行しても root で実行されます。

$ su -
# useradd user1
# usermod -aG hoge user1

大きな使い分けは以上ですが、その他にも以下の違いがあります。

sudosu
求められるパスワード現在のユーザーの
パスワード
root のパスワード
コマンドを実行できる
ユーザー
/etc/sudoers で設定された
ユーザー・グループ
(wheel, sudo グループ等)
全ユーザー
細かい制御可能不可

sudo は /etc/sudoers の設定に従って使うことができます。デフォルトでは RedHat 系であれば wheel グループ、Debian/Ubuntu 系であれば sudo グループが sudoers に設定されているため、このグループに所属している一般ユーザーは sudo コマンドを使えます。

以下は RedHat 系 OS の /etc/sudoers のデフォルト設定の一部です。 wheel グループが sudo を使えることを意味しています。(% はグループであることを意味します。)

%wheel  ALL=(ALL)       ALL

OS インストール時に一般ユーザーを作るとき、「このユーザを管理者にする」にチェックを入れるなどをすると、このグループに所属することになります。

sudo su と su の違い

上表から分かる通り、sudo su では現在のユーザーのパスワードで root になることができます。ただし、そのユーザーは /etc/sudoers で許可設定されている必要があります。

一方、su は root のパスワードが求められますが、ユーザーに制限はありません。

sudo su が使えない場合の対処

su で root 権限になってから、sudo を使わせたい一般ユーザー (仮に user1) を適切なグループに所属させます。つまり、root のパスワードが無いとダメです。

[RedHat 系 (RockyLinux, Almalinux, CentOS, Fedora)]

$ su
# usermod -aG wheel user1

[Debian 系 (Ubuntu, Kali linux)]

$ su
# usermod -aG sudo user1

もちろん、これ以外に visudo を使って /etc/sudoers を設定変更する方法もあります。

sudo はなぜ必要なのか?

su で事足りるのではないかと思うかもしれませんが、su は root になることができた後はやりたい放題になってしまいます。つまり細かい制御ができず、0 か 1 かの扱いになってしまいます。

一方、sudo は細かい制御ができるので柔軟性が高く、セキュアにも設定できます。

例えば柔軟性で言うと、特定ユーザーについてはパスワードを求めない設定が可能です。

/etc/sudoers 設定例 その 1 : ansible ユーザーに全コマンドをパスワード無しで許可

以下を /etc/sudoers に記載すると、ansible ユーザーは全てのコマンドをパスワード無しで実行できます。

ansible  ALL=(ALL)    NOPASSWD: ALL

ALL=(ALL) の左側は sudo が使えるホストです。sudo はリモート接続元を識別して、特定の接続元ホストからのみ sudo を許可することができます。この例では ALL なので接続元の制限はありません。

ALL=(ALL) の右側の (ALL) は sudo でどのユーザーになれるかを意味しています。この例では全てのユーザーになれます。例えば (user1:group1) と書いてある場合はユーザー user1、グループ group1 になることができます。

実際の運用ではこの 2 つは ALL=(ALL) 以外の設定をするケースは少ないです。

前者については、多層防御の考えには反しますが、そもそも firewalld 等で IP レベルで不要な接続元を遮断するので必要性が薄いです。後者については、root になることを前提とするケースがほとんどであり、root になれればどのユーザーにもなれるので設定する意味がないです。

その後の NOPASSWD: はまさに「パスワード不要」であることを示しており、その後の ALL が対象コマンドです。

/etc/sudoers 設定例 その 2 : nginx ユーザーに useradd , usermod を許可

以下を /etc/sudoers に記載すると、nginx ユーザーは useradd, usermod コマンドをパスワード無しで実行できます。

nginx  ALL=(ALL)    NOPASSWD: /user/sbin/useradd, /user/sbin/usermod

これは例えば WebUI でユーザーを作るような PHP プログラムで Linux OS コマンドを呼び出す際に useradd と usermod だけをパスワード無しで使わせることができますが、それ以外には root 権限では実行できません。つまり最小権限の原則を実現するセキュアな設定が可能です。(php-fpm プロセスが nginx ユーザーで実行されている前提)

su と su - の違い

su だけで実行した場合はログインはし直さないため、環境変数は前のユーザーの状態から維持されます。以下の例だと user1 がいきなり root ユーザーに入れ替わるイメージです。exit すると user1 に戻ります。

[user1@localhost ~]$ su
パスワード:
[root@localhost user1]# env
~~~
USER=user1
~~~

一方、su - を実行した場合はログインしなおします。そのため ~/.bashrc や /etc/profile 等の初期化が実行され、環境変数も新たに更新されますし、カレントディレクトリもログイン直後のホームディレクトリ (/root) に切り替わります。このケースでは user1 のことはいったん放置して、新たに root ユーザーでログインするイメージです。exit すると user1 に戻ります。

[user1@localhost ~]$ su -
パスワード:
最終ログイン: 2023/11/11 (土) 22:36:49 JST 日時 pts/0
[root@localhost ~]# env
~~~
USER=root
~~~

あまり使い分けするケースは無いように思えます。

環境変数については以下を参照ください。

【図解】わかりやすい環境変数の仕組み~Windows/Linuxの実用例と確認コマンド~
環境変数とは 環境変数とは、OS が提供するデータ共有の仕組みであり、主にその ...

ちなみに、sudo su - は sudo -i と、sudo su は sudo -s と似た挙動をします。

コメント

タイトルとURLをコピーしました