2026年8月15日

2026年8月15日

sudoの設定でコマンド実行を制限する方法(sudoersの安全な書き方)

sudo の権限は「全部許可」か「なし」の二択ではなく、ユーザーごとに実行できるコマンドを絞れます。この記事では、/etc/sudoers.d/ に設定ファイルを置き、デプロイ用ユーザーに「Nginx の再読み込みと PHP-FPM の再起動だけ」を許可する例を通して、sudoers の書き方、抜け穴になりやすいコマンド、ログの残し方、締め出されたときの復旧方法までを説明します。

なぜコマンドを制限するのか

WordPress サーバーでは、デプロイの自動化や制作会社との共同作業のために、root 以外のユーザーへ管理操作を任せる場面がよくあります。そのユーザーに ALL=(ALL) ALL を与えると、パスワードが漏れたり SSH 鍵が盗まれたりしたときに、サーバー全体が乗っ取られます。

必要なコマンドだけを許可しておけば、万一アカウントが悪用されても被害の範囲を小さくできます。これは「最小権限の原則」と呼ばれる考え方です。

ただし、sudo の制限は書き方を誤ると簡単に抜けられます。後半の「抜け穴になりやすいコマンド」は特に注意して読んでください。

作業前の準備:締め出されないために

sudoers の書式を誤ると、sudo そのものが使えなくなり、管理者が root 権限を取れなくなることがあります。作業前に次の準備をします。

  • root 権限のシェルを1つ開いたままにする:sudo -i で root になったターミナルを残し、別のターミナルで設定と確認を行います。
  • コンソール接続を確認する:VPS の管理画面から使えるコンソールや、レスキューモードの起動方法を確認しておきます。
  • 設定ファイルを直接エディタで開かない:書式チェック付きの visudo を使います。

1. visudo で sudoers.d にファイルを作る

/etc/sudoers 本体を書き換えるより、/etc/sudoers.d/ に用途ごとのファイルを置くほうが管理しやすく、OS の更新で上書きされる心配もありません。多くのディストリビューションでは、/etc/sudoers の末尾に sudoers.d を読み込む指定が入っています(@includedir /etc/sudoers.d または古い書式の #includedir)。

sudo visudo -f /etc/sudoers.d/deploy

visudo は保存時に書式をチェックし、誤りがあれば保存前に警告します。sudoers.d 内のファイル名に . を含めたり、~ で終わらせたりすると読み込まれない仕様があるため、deploy のような単純な名前にします。

2. 特定のコマンドだけを許可する

基本の書式は「ユーザー ホスト=(実行ユーザー) コマンド」です。

# /etc/sudoers.d/deploy
Cmnd_Alias WEB_RELOAD = /usr/bin/systemctl reload nginx, \
                        /usr/bin/systemctl restart php8.3-fpm

deploy ALL=(root) WEB_RELOAD

書くときのポイントは次のとおりです。

  • コマンドはフルパスで書く:パスは command -v systemctl で確認します。ディストリビューションによって /usr/bin と /bin のどちらかが異なる場合があります。
  • 引数まで書く:/usr/bin/systemctl reload nginx と書けば、その引数の組み合わせだけが許可されます。/usr/bin/systemctl だけを書くと、あらゆる引数(stop、disable、edit など)が許可されます。
  • 引数なしだけを許可したい場合:コマンドの後に "" を書くと、引数を付けた実行が拒否されます。
  • Cmnd_Alias でまとめる:許可するコマンドに名前を付けておくと、後から読む人が意図を理解しやすくなります。

保存したら、ファイルの権限と書式を確認します。

sudo chmod 0440 /etc/sudoers.d/deploy
sudo visudo -c

visudo -c は sudoers 本体と読み込まれる全ファイルの書式をまとめて検査します。

3. 許可された内容を確認する

設定したユーザーで、何が許可されているかを確認します。

# deploy ユーザーとして実行
sudo -l

# 管理者が他のユーザーの許可内容を確認
sudo -l -U deploy

続けて、許可したコマンドが実行でき、許可していないコマンドが拒否されることを実際に試します。拒否されたときは「deploy is not allowed to run sudo as root」のようなメッセージが表示されます。

4. パスワードなし実行は対象を絞る

CI やデプロイツールから自動で実行する場合は、パスワード入力を省く NOPASSWD が必要になることがあります。

deploy ALL=(root) NOPASSWD: WEB_RELOAD

NOPASSWD は「許可したコマンドだけ」に付けます。NOPASSWD: ALL は、そのユーザーの SSH 鍵を持っている人に無条件で root 権限を渡すのと同じです。

なお、sudoers は後に書いた規則が優先されます。ユーザー個別の規則より後に、そのユーザーが所属するグループ(%sudo や %wheel)の規則が来ると、個別の制限が上書きされたように見えることがあります。制限したいユーザーは管理者グループに入れないのが安全です。

5. 抜け穴になりやすいコマンド

コマンドを1つに絞っていても、そのコマンドが別のプログラムを起動できる場合、root のシェルを取られます。代表的なものは次のとおりです。

  • エディタやページャー:vi、vim、nano、less、more などは、内部から外部コマンドを実行できます。ファイル編集を許可したい場合は、後述の sudoedit を使います。
  • ワイルドカード:/usr/bin/systemctl restart * のような指定は、想定外の引数(複数のユニット名や別のオプション)を許してしまいます。
  • 汎用のツール:find(-exec)、tar、rsync、git、python、php など、引数でコマンド実行やファイル上書きができるものは、制限の意味がほぼなくなります。
  • 書き換え可能なスクリプト:sudo で許可したスクリプトを、そのユーザー自身が編集できると、中身を書き換えて任意のコマンドを実行されます。スクリプトの所有者は root にし、ユーザーに書き込み権限を与えないでください。

WordPress の運用でよくあるのが WP-CLI の許可です。

deploy ALL=(www-data) /usr/local/bin/wp

実行ユーザーを root ではなく www-data にしている点はよいのですが、WP-CLI には wp eval や wp shell など任意の PHP を実行できるサブコマンドがあり、実質的に www-data の権限を丸ごと渡すことになります。どこまで任せるかを理解したうえで設定してください。

NOEXEC タグを付けると、許可したコマンドから別のプログラムを起動することを妨げられる場合がありますが、仕組み上すべてのプログラムに効くわけではありません。補助的な対策と考えてください。

ファイル編集は sudoedit で許可する

特定の設定ファイルの編集を許可したい場合は、エディタではなく sudoedit を指定します。

deploy ALL=(root) sudoedit /etc/nginx/conf.d/example.conf

sudoedit はファイルを一時的にコピーし、ユーザー自身の権限でエディタを起動してから、保存時に元の場所へ書き戻します。エディタ自体は root で動かないため、エディタ経由でシェルを取られる心配がありません。

6. sudo の実行記録を残す

制限と合わせて、誰が何を実行したかを記録しておきます。sudo の実行記録は通常、Ubuntu/Debian では /var/log/auth.log、RHEL 系では /var/log/secure か journald に残ります。

sudo journalctl _COMM=sudo --since today

専用のログファイルに分けたい場合や、端末の割り当てを強制したい場合は、Defaults で指定します。

# /etc/sudoers.d/00-defaults
Defaults use_pty
Defaults logfile="/var/log/sudo.log"
Defaults timestamp_timeout=5

timestamp_timeout は、一度パスワードを入力した後に再入力なしで sudo を使える時間(分)です。短くすると、席を離れた端末を悪用されるリスクが減ります。sudoers の設定変更そのものを記録したい場合は、auditd で /etc/sudoers と /etc/sudoers.d/ を監視する方法があります。

7. 締め出されたときの復旧

sudo が使えなくなった場合の対処は、環境によって次のように分かれます。

  • root のシェルが残っている:そのシェルで visudo -f を使って誤ったファイルを修正します。
  • root のパスワードを設定している:su - で root になり、修正します。
  • Ubuntu で polkit が使える:pkexec visudo で修正できる場合があります(環境によっては使えません)。
  • どれも使えない:VPS のコンソールからレスキューモードやシングルユーザーモードで起動し、ディスクをマウントして修正します。手順は事業者ごとに異なるため、マニュアルを確認してください。

sudo のバージョンによって使える書式や Defaults の項目が異なります(2026年10月現在)。sudo -V でバージョンを確認し、man sudoers の記述を正としてください。

まとめ

  • sudoers は visudo で編集し、/etc/sudoers.d/ に用途ごとのファイルを置く
  • コマンドはフルパスと引数まで書き、ワイルドカードは避ける
  • visudo -c で書式、sudo -l -U ユーザー名 で許可内容を確認する
  • NOPASSWD は許可したコマンドだけに付け、管理者グループとの重複に注意する
  • エディタ・汎用ツール・書き換え可能なスクリプトは抜け穴になる。編集は sudoedit で許可する
  • 作業前に root のシェルとコンソール接続を確保し、締め出されたときの復旧手段を用意しておく

お気軽にご相談ください

お見積りへ お問い合わせへ
▲