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
sudo vi /etc/sudoers や sudo nano /etc/sudoers で直接編集した場合、構文ミスをそのまま保存できてしまう。エラーが入ると sudo 自体が使えなくなり、root パスワードがなければ復旧に root シェルが必要になる。
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 で自動読み込みされる。パーミッションは 0440(root: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"