Linuxにおけるsudoとsudoersファイルの設定ガイド:ユーザーごとの安全な権限管理

Linux tutorial - IT technology blog
Linux tutorial - IT technology blog

こんな状況に遭遇したことがある。同僚がサーバーで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/sudoersnanovimで直接開いて、誤った構文で保存してしまうと、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を使う。例外はない。

Share: