sudo/suの使い分け - 権限昇格の安全な方法

sudo/suの使い分け - 権限昇格の安全な方法

この記事でできるようになること

  • sudo と su を目的に応じて使い分けられる
  • sudo が推奨される理由をセキュリティ観点で説明できる
  • visudo で sudoers を安全に編集できる

前提知識(先に読むと理解しやすい記事)

この記事で身につくこと

  • sudosu を、目的に応じて使い分けられるようになります。
  • なぜ su より sudo が推奨されるのかを、セキュリティ観点で説明できるようになります。
  • sudoers の基本設定を、自分で安全に書けるようになります。
  • よくある事故パターンとその回避策が分かるようになります。

想定読者:Ubuntu でサーバを触りはじめ、sudo を「おまじない」として打っている人。

先に用語を整理する

初めて出てくる言葉を、ここで一度だけ定義します。

  • 権限昇格とは、今のユーザーでは許されていない操作を、より強い権限で実行することです。「特権昇格」「privilege escalation」とも呼びます。
  • root(ルート)とは、システム上で何でもできる管理者ユーザーの名前です。「スーパーユーザー」とも呼びます。
  • ログインシェルとは、ログイン時に読み込まれる設定(.profile.bashrc)を反映した状態のシェルです。同じユーザーでも、ログインシェルかどうかで PATH などの環境変数が変わります。
  • 環境変数とは、シェルが持っている設定値です。PATH(コマンドを探す場所の一覧)や HOME(ホームディレクトリ)が代表例です。
  • sudoers とは、誰にどのコマンドを許可するかを書いた設定ファイル /etc/sudoers のことです。
  • visudo とは、sudoers を構文チェック付きで編集する専用コマンドです。
  • NOPASSWD とは、sudoers に書ける指定で、パスワード入力を省略して実行を許可する設定です。

結論(実務の型)

  • 1コマンドだけ root 権限が必要sudo command
  • root として複数操作する(やむを得ない場合のみ)sudo -i
  • 別ユーザーとして1コマンド実行sudo -u username command
  • su - は root パスワードが必要。Ubuntu のデフォルトでは root パスワードが無効なため使えない

前提(対象環境)

  • OS:Ubuntu(または Debian 系)
  • 作業ユーザーが sudo グループに追加済み

1. sudo と su の違いは何か?

sudo(substitute user do)と su(switch user)は、どちらも権限昇格のためのコマンドだが、仕組みが根本的に異なる。

項目 sudo su
認証 自分のパスワード 切り替え先のパスワード
root パスワード 不要 必要(su - の場合)
操作ログ /var/log/auth.log に記録 記録が弱い
権限範囲 /etc/sudoers で細かく制御 root に全権限を渡す
Ubuntu デフォルト 使用可能 root パスワード無効で使えない

sudoユーザーごとに許可コマンドを限定できる点がセキュリティ上の強みだ。root パスワードをチームで共有する必要もない。

2. sudo の使い方

2-1. 基本形:1コマンドだけ実行

$ sudo command

例:

$ sudo apt update
$ sudo systemctl restart nginx

2-2. root のログインシェルを起動する

$ sudo -i

sudo -i は root の環境変数と .profile を読み込んだ状態でシェルを起動する。長時間の root 作業が必要な場合に使う。

root シェルを起動したままにしないこと。作業が終わったら exit で抜ける。

2-3. 別ユーザーとして実行する

$ sudo -u username command

例:www-data ユーザーとしてコマンドを実行:

$ sudo -u www-data php /var/www/html/artisan cache:clear

2-4. 権限昇格の持続時間

sudo は初回認証後、デフォルト 15 分間はパスワードなしで再実行できる。タイムアウトを即座にリセットする場合:

$ sudo -k

現在の自分の sudo 権限を確認する:

$ sudo -l
User alice may run the following commands on hostname:
    (ALL : ALL) ALL

(ALL : ALL) ALL は「どのユーザーとしても、どのコマンドでも実行できる」という意味。特定コマンドだけ許可されている場合は、そのコマンドのパスが列挙される。

3. su の使い方

3-1. su - でログインシェルを起動

$ su - [username]

- オプション(-l / --login と同義)は、切り替え先ユーザーのログイン環境(ホームディレクトリ・環境変数・PATH)を再現する。

$ su - deploy    # deploy ユーザーのログインシェルを起動

3-2. su と su - の違い

$ su username    # NG:現在の環境変数をそのまま引き継ぐ
$ su - username  # OK:ログイン時と同じ環境を再現

su username- なし)は現在の環境変数を引き継ぐため、切り替え先のユーザー環境が正しく再現されない。特に PATH が混在して command not found になる事故が多い。

3-3. Ubuntu で su が使えない理由

Ubuntu のデフォルトでは root アカウントのパスワードが無効化されている。su - で root に切り替えようとすると認証に失敗する。

$ su -
Password:
su: Authentication failure   # root パスワードが無効

Ubuntu で root シェルが必要な場合は sudo -i を使う。

4. なぜ sudo が推奨されるのか?

sudo が推奨される理由はセキュリティモデルの違いにある。

操作ログが残る: sudo を実行するたびに /var/log/auth.log に「誰が・何時・何のコマンドを実行したか」が記録される。

# rsyslog がある環境(Ubuntu 22.04 など)
$ sudo grep sudo /var/log/auth.log | tail -3

# journald のみの環境(Ubuntu 24.04 の既定インストールなど)
$ sudo journalctl -t sudo -n 3
May 31 10:30:01 hostname sudo: alice : TTY=pts/0 ; PWD=/home/alice ; USER=root ; COMMAND=/usr/bin/apt update

Ubuntu 24.04 は既定インストールで rsyslog を含まないため、/var/log/auth.log が存在しない構成がある。その場合はログが journald に集約されているため journalctl 側を使う。

「誰が」「どのディレクトリで」「どのコマンドを」実行したかが 1 行に残る。障害時に操作を追跡できるのは、この記録があるからだ。

最小権限の原則: sudoers でコマンドを個別に許可できるため、特定ユーザーに必要最低限の権限だけを付与できる。

root パスワード不要: チームメンバーに root パスワードを教える必要がない。個人の資格情報で認証が完結する。

5. sudoers の設定(visudo)

5-1. visudo で安全に編集する

/etc/sudoers必ず visudo コマンドで編集する。visudo はファイルを保存する前に構文チェックを行い、設定ミスでシステムにアクセスできなくなる事故を防ぐ。

$ sudo visudo

5-2. 基本的な書式

# ユーザー  ホスト=(実行ユーザー) コマンド
alice  ALL=(ALL) ALL

# NOPASSWD:パスワードなしで特定コマンドを許可
deploy ALL=(ALL) NOPASSWD: /usr/bin/systemctl restart nginx

5-3. グループに対して許可する

# %グループ名 で指定
%admin ALL=(ALL) ALL
%deploy ALL=(ALL) NOPASSWD: /usr/bin/systemctl

5-4. drop-in ファイルで管理する(推奨)

大規模環境では sudoers 本体を直接編集せず、/etc/sudoers.d/ 配下にファイルを置く方法が推奨される。

$ sudo visudo -f /etc/sudoers.d/deploy
deploy ALL=(ALL) NOPASSWD: /usr/bin/systemctl restart nginx

6. よくある事故パターン

NOPASSWD を全コマンドに設定する

# 危険:何でもパスワードなしで実行できる
alice ALL=(ALL) NOPASSWD: ALL

開発環境の「楽さ」のために設定したまま本番に持ち込むと深刻なリスクになる。このユーザーのセッションを奪われた時点で、攻撃者はパスワードを知らずに root 相当の操作ができる。許可は特定コマンドのみに限定すること。

visudo を使わずに sudoers を編集する

直接 vi /etc/sudoers で編集して構文ミスを起こすと、sudo が動作不能になる。visudo は保存時に構文チェックを行うため、必ず使うこと。

su username で環境変数が混在する

# NG:PATH が現在のシェルの設定を引き継ぐ
$ su deploy

# OK:deploy のログイン環境を再現
$ su - deploy

トラブルシューティング

症状: alice is not in the sudoers file. This incident will be reported.

原因: そのユーザーが sudo グループ(RHEL 系では wheel)に所属していない。

確認:

id -nG
alice

sudo が含まれていなければ権限がない。

対処: 別の管理者権限を持つユーザーから追加してもらう。

sudo usermod -aG sudo alice    # 管理者側で実行

追加後は、対象ユーザーがログアウトして再ログインするまで反映されない。管理者が誰もいない場合は、物理コンソールからリカバリモードで起動して修正する。

症状: sudo: unable to resolve host <hostname>

原因: /etc/hostname の名前が /etc/hosts に登録されていない。sudo 自体は動くが、毎回この警告が出る。

確認:

hostname
grep "$(hostname)" /etc/hosts

対処: /etc/hosts127.0.0.1 の行に現在のホスト名を追記する。編集前にコピーを取っておくと戻せる。

sudo cp /etc/hosts /etc/hosts.bak
sudo nano /etc/hosts
127.0.0.1   localhost myhost

症状: sudo: no tty present and no askpass program specified

原因: cron やスクリプトなど端末のない環境で、パスワード入力を求める sudo を実行した。

確認: 実行元が cron / systemd / CI などの非対話環境かどうかを確認する。

対処: そのコマンドだけを sudoers で NOPASSWD 指定する(対象は絶対パスで限定)。

sudo visudo -f /etc/sudoers.d/deploy
deploy ALL=(ALL) NOPASSWD: /usr/bin/systemctl restart nginx

症状: 3 incorrect password attempts

原因: パスワードを 3 回間違えた。sudo は 3 回失敗で試行を打ち切る。

確認: 入力しているのが root のパスワードではなく自分のパスワード かを確認する。sudo は自分のパスワードを要求する。

対処: もう一度 sudo を実行して自分のパスワードを入力する。忘れた場合は別の管理者に sudo passwd alice でリセットしてもらう。

作業完了チェックリスト

  • [ ] 1 コマンドだけなら sudo command、複数操作なら sudo -i を選べた
  • [ ] root シェルでの作業後、exit で抜けた
  • [ ] sudoers の編集は visudo 経由で行った
  • [ ] NOPASSWD を書く場合、対象コマンドを絶対パスで限定した
  • [ ] sudo -l で自分に許可されている操作を確認した

次に読む

この記事を共有

次の一手