こんな状況に遭遇したことがある。同僚がサーバーでNginxのサービスを再起動する必要があったのに、root権限がなかった。一番簡単な解決策はrootのパスワードを教えることだが、セキュリティ的には最悪の方法だ。その時初めて、sudoがいかに重要かを実感した。
会社の古いCentOS 7サーバーでは、多くのことを最適化する必要があった。最初にやったことの一つが、sudo policyの全面的な見直しだった。それ以前は、ほぼ全員が制限なしでwheelグループに追加されていたからだ。
サーバーでの権限付与における実際の問題
チーム環境のLinuxサーバーで作業していると、すぐにこんな問題に直面する。誰が何をできるのか?開発者はコードをデプロイする必要があり、DevOpsはサービスを管理する必要があり、ジュニアのsysadminはログを確認する必要がある。しかし、誰も無制限のroot権限を持つべきではない。
Linuxはこの問題をsudo(superuser do)と設定ファイル/etc/sudoersによって解決している。rootパスワードを共有する代わりに、どのユーザーが、どのコマンドを、誰として、どのマシンで実行できるかを正確にコントロールできる。
sudo権限を付与する3つのアプローチ
方法1:sudoまたはwheelグループにユーザーを追加する
最も手軽で、最もよく知られた方法だ。コマンド1つで完了する。ただし注意点がある:この方法はフル権限のsudoを付与するため、コマンドの制限は一切ない。
# Ubuntu/Debian — "sudo"グループを使用
sudo usermod -aG sudo username
# CentOS/RHEL/Fedora — "wheel"グループを使用
sudo usermod -aG wheel username
# ユーザーがグループに所属しているか確認
id username
# groups: uid=1001(username) gid=1001(username) groups=1001(username),10(wheel)
グループに追加した後、新しいグループを有効にするためにユーザーは一度ログアウト/ログインし直す必要がある。
方法2:/etc/sudoersに直接ルールを追加する
Nginxの再起動だけを許可してシステム全体は許可しない、というような細かい制御が必要な場合は、この方法を選ぶ。
# sudoersを編集するには常にvisudoを使用 — ファイルを直接開いてはいけない
sudo visudo
# sudoersの基本構文:
# ユーザー ホスト=(実行ユーザー) コマンド
username ALL=(ALL) ALL
# nginxの再起動のみ許可
username ALL=(ALL) /usr/bin/systemctl restart nginx
# 複数のコマンドはカンマ区切りで指定
username ALL=(ALL) /usr/bin/systemctl restart nginx, /usr/bin/systemctl reload nginx
方法3:/etc/sudoers.d/に個別ファイルを作成する
すべてを1つの/etc/sudoersファイルに詰め込む代わりに、/etc/sudoers.d/の中にチームごとの個別ファイルを作成する。特定のユーザーの権限を剥奪したい場合は、そのファイルを削除するだけで済む。巨大な設定ファイルを探し回る必要はない。
# ユーザー/チーム専用の設定ファイルを作成
sudo visudo -f /etc/sudoers.d/devteam
# ファイルの内容:
# devteamグループ全体にデプロイ権限を付与
%devteam ALL=(ALL) /usr/bin/systemctl restart nginx, /usr/bin/systemctl restart php-fpm
# 注意:ファイルのパーミッションは0440にする必要がある
sudo chmod 0440 /etc/sudoers.d/devteam
各方法のメリット・デメリット比較
| 基準 | グループ(sudo/wheel) | /etc/sudoers編集 | /etc/sudoers.d/ |
|---|---|---|---|
| 使いやすさ | とても簡単 | 普通 | 普通 |
| 細かい制御 | なし(フル権限) | あり | あり |
| 複数ユーザーの管理 | 難しい | 難しい(1ファイルが肥大化) | 簡単(個別ファイル) |
| ミス時の安全性 | 低い | visudo未使用時は低い | より高い |
| 適した環境 | 個人開発 | 小規模サーバー、少数ユーザー | 本番環境、チーム |
方法1はフルsudoを付与するため、ユーザーはrootと同じことができる。方法2と3では、必要なコマンドだけに絞って制限できる。セキュリティの原則は最小権限(least privilege)だ。必要な権限だけを付与し、それ以上は与えない。
どの方法を選ぶべきか?
- 個人マシン/開発環境:方法1で十分。sudoグループへの追加で問題ない。
- 小規模サーバー、管理者が1〜2人:方法2。visudoでsudoersを直接編集する。
- 本番サーバー、複数チームがいる環境:方法3。チーム/ロールごとに
/etc/sudoers.d/の中に個別ファイルを作成し、監査や権限剥奪が容易になる。
本番環境では方法3をよく使っている。誰かの権限を剥奪する必要があれば、巨大なsudoersファイルを探し回る代わりに、その人のファイルを削除または名前変更するだけでいい。
実践的な導入ガイド
ステップ1:ユーザーとグループの作成(まだない場合)
# 新しいユーザーを作成
sudo useradd -m -s /bin/bash deployer
sudo passwd deployer
# チーム用グループを作成
sudo groupadd devteam
# ユーザーをグループに追加
sudo usermod -aG devteam deployer
ステップ2:制限付きsudoersルールの作成
sudo visudo -f /etc/sudoers.d/deployer
# 内容 — デプロイ関連のサービスのrestart/reloadのみ許可:
deployer ALL=(ALL) NOPASSWD: /usr/bin/systemctl restart nginx, \
/usr/bin/systemctl reload nginx, \
/usr/bin/systemctl restart php8.1-fpm, \
/usr/bin/systemctl status nginx
NOPASSWDは、そのコマンドを実行する際にパスワードの入力が不要になることを意味する。自動化やCI/CDスクリプトに便利だ。
ステップ3:エイリアスを使った高度な設定
コマンド数が増えてきたら(本番環境では5〜10コマンドは珍しくない)、Command Aliasを使ってすっきりまとめよう:
sudo visudo -f /etc/sudoers.d/webteam
# エイリアスの定義
Cmnd_Alias WEB_SERVICES = /usr/bin/systemctl restart nginx, \
/usr/bin/systemctl reload nginx, \
/usr/bin/systemctl restart php8.1-fpm
Cmnd_Alias VIEW_LOGS = /usr/bin/tail -f /var/log/nginx/error.log, \
/usr/bin/tail -f /var/log/nginx/access.log
# グループに権限を付与
%webteam ALL=(ALL) NOPASSWD: WEB_SERVICES
%webteam ALL=(ALL) NOPASSWD: VIEW_LOGS
ステップ4:設定の確認
# sudoers全体の構文チェック(実行はしない)
sudo visudo -c
# 期待される出力: /etc/sudoers: parsed OK
# /etc/sudoers.d/deployer: parsed OK
# 現在ログイン中のユーザーの権限を確認
sudo -l
# 特定ユーザーの権限を確認(root権限が必要)
sudo -lU deployer
# -lフラグでコマンドをテスト(実行はしない)
sudo -l -U deployer
便利な追加設定
# sudoのタイムアウト時間を変更(デフォルト15分、ここでは5分に設定)
# /etc/sudoersに追加:
Defaults timestamp_timeout=5
# 毎回パスワード入力を要求(タイムアウト = 0)
Defaults timestamp_timeout=0
# sudoで実行した全コマンドを専用ファイルに記録
Defaults logfile=/var/log/sudo.log
# レクチャー機能を有効化(初回sudo使用時に警告を表示)
Defaults lecture=always
よくあるミスと回避方法
ミス1:通常のエディタでsudoersを編集する(visudoを使わない)
/etc/sudoersをnanoやvimで直接開いて、誤った構文で保存してしまうと、sudoが完全に壊れてしまう。誰も使えなくなる。visudoは保存前に構文をチェックする。それがvisudoが存在する理由だ。
ミス2:sudoersで絶対パスを忘れる
# 誤り — sudoersでは常に絶対パスが必要
deployer ALL=(ALL) systemctl restart nginx
# 正しい
deployer ALL=(ALL) /usr/bin/systemctl restart nginx
# コマンドの正しいパスを調べる
which systemctl
# /usr/bin/systemctl
ミス3:sudoersのワイルドカードが悪用される
# 危険 — ユーザーが: sudo vim /etc/sudoers を実行できてしまう
deployer ALL=(ALL) /usr/bin/vim *
# より安全 — 特定ファイルのみ許可
deployer ALL=(ALL) /usr/bin/vim /var/www/html/config.php
sudoersのワイルドカードを使った権限昇格を実際に目撃したことがある。vim *の権限を持つユーザーが/etc/passwdを開いて編集してしまったのだ。sudoersのワイルドカードには細心の注意を払おう。
監査とモニタリング
設定が完了したら放置しない。誰がsudoを使って何をしているか把握するために、ログを有効にしよう:
# Ubuntu/DebianでsudoのログをUbuntu/Debianで確認
grep sudo /var/log/auth.log
# CentOS/RHELでsudoのログを確認
grep sudo /var/log/secure
# 出力例:
# Mar 15 10:23:45 server sudo: deployer : TTY=pts/1 ; PWD=/home/deployer ;
# USER=root ; COMMAND=/usr/bin/systemctl restart nginx
サーバーがjournald(systemdベース)を使用している場合は、次のコマンドも使える:
journalctl -u sudo --since "today"
# または特定ユーザーでフィルタリング:
journalctl SYSLOG_IDENTIFIER=sudo _UID=$(id -u deployer)
sudoを正しく設定することは、単なるセキュリティの話ではない。管理者にサービスの再起動のたびに連絡しなくても、チーム全体がスムーズに作業できるようになる。3つのことを覚えておこう:必要な権限だけを付与し、すべての操作をログに記録し、visudoを使う。例外はない。

