sudoers 設定入門 - 安全に権限を委譲する

sudoers 設定入門 - 安全に権限を委譲する

sudoers とは何か?

/etc/sudoers は「誰が・誰として・何を実行できるか」を定義するファイルで、sudo コマンドの権限委譲ルールをすべて管理している。直接編集は禁止であり、必ず visudo を使う。

結論(実務の型)

  • visudo 以外で sudoers を編集しない(シンタックスエラーで sudo が完全ロックされる)
  • 権限委譲はできる限り特定コマンドに限定する(ALL は最終手段)
  • NOPASSWD は CI/CD や特定の自動化にのみ使う

対象環境

  • OS:Ubuntu 22.04 / 24.04(Debian 系全般に準拠)
  • sudo がインストール済みであること(デフォルトで入っている)

なぜ visudo を使うのか?

visudo は構文検査付きのエディタラッパーで、保存時にシンタックスエラーを検出し、エラーがあると上書きしない。これにより sudo が壊れた状態で保存されるのを防ぐ。

$ sudo visudo

デフォルトエディタは nano(Ubuntu では EDITOR 環境変数で変更可能)。

$ sudo EDITOR=vim visudo

sudoers の構文

基本形

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

最も基本的な例:

alice ALL=(ALL:ALL) ALL

各フィールドの意味:

フィールド 値の例 意味
ユーザー alice 適用対象ユーザー
ホスト ALL 全ホストで有効
実行ユーザー (ALL:ALL) root を含む全ユーザー/グループ
コマンド ALL すべてのコマンド

グループへの委譲

行頭に % を付けるとグループを指定できる。

%sudo ALL=(ALL:ALL) ALL
%wheel ALL=(ALL) ALL

Ubuntu では %sudo グループ、CentOS/RHEL では %wheel グループが sudo 権限を持つのが慣例。

特定コマンドへの権限委譲

ALL を使わず、必要なコマンドだけを列挙するのが最も安全な設定

# nginx の再起動だけ許可
bob ALL=(root) /usr/bin/systemctl restart nginx

# 複数コマンドはカンマ区切り
carol ALL=(root) /usr/bin/systemctl restart nginx, /usr/bin/systemctl status nginx

コマンドはフルパスで記述する(which nginx で確認)。

/usr/bin/vim などのエディタを許可すると、vim から :!sh でシェルを呼び出せるため 事実上 root 権限全取得になる。エディタは原則禁止。

NOPASSWD 設定

パスワード入力なしで実行できる設定。CI/CD パイプラインやデプロイスクリプトで使う。

# 特定コマンドのみ NOPASSWD
deploy ALL=(root) NOPASSWD: /usr/bin/systemctl restart myapp

# グループ全体に NOPASSWD(非推奨・注意して使う)
%automation ALL=(ALL) NOPASSWD: ALL

NOPASSWD の注意点

  • スクリプトが悪用された場合、パスワードなしで root 権限が使われる
  • 特定コマンドのみに絞ること。NOPASSWD: ALL は最小限の用途に限定する
  • /var/log/auth.log で sudo の使用履歴を監視する

include ディレクトリ(推奨構成)

大規模環境や複数サービスの管理では、/etc/sudoers.d/ 配下に個別ファイルを置く構成が推奨される。

# 専用ファイルを作成(visudo -f で構文検査付き)
$ sudo visudo -f /etc/sudoers.d/deploy-user

ファイル内容例:

# /etc/sudoers.d/deploy-user
deploy ALL=(root) NOPASSWD: /usr/bin/systemctl restart myapp, /usr/bin/systemctl status myapp

/etc/sudoers.d/ 配下のファイルは /etc/sudoers 末尾の #includedir /etc/sudoers.d で自動読み込みされる。パーミッションは 0440root:root)でないと読み込まれない点に注意。

$ sudo chmod 0440 /etc/sudoers.d/deploy-user
$ sudo chown root:root /etc/sudoers.d/deploy-user

権限の確認と動作テスト

自分の sudo 権限を確認

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

別ユーザーとして実行

$ sudo -u www-data whoami
www-data

設定を確認してから本番実行

# コマンドを実行せずに権限確認
$ sudo -l -U bob

Defaults で動作を調整する

Defaults エントリで sudo のデフォルト動作を変更できる。

# パスワードキャッシュを無効化(毎回入力を要求)
Defaults timestamp_timeout=0

# sudo 実行時に現在の PATH を引き継がない(デフォルト・安全)
Defaults env_reset

# 特定ユーザーにのみ適用
Defaults:bob timestamp_timeout=5
オプション 意味
timestamp_timeout=N sudo キャッシュの有効期間(分)。0 で毎回要求
env_reset 環境変数をリセット(デフォルト有効)
logfile=/var/log/sudo.log ログの出力先を指定
passwd_tries=N パスワード試行回数(デフォルト 3)

よくある設定ミスと対処

sudo: /etc/sudoers is world writable が出る

$ sudo chmod 0440 /etc/sudoers

/etc/sudoers のパーミッションは 0440(読み取り専用)である必要がある。

visudo で編集後に変更が反映されない

  • sudo -k でキャッシュをクリアしてから再度実行する
  • グループ変更後は newgrp sudo またはログアウト/ログインが必要

sudo: command not found になる

env_reset が有効で /usr/local/bin 等が PATH に含まれないケース。

Defaults secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"

次に読む