SSD Nodes Learn
ガイド Matt Connor著者 Matt Connor ・更新日 2026-07-24

サービスをroot以外で実行する方法とsystemdの設定

サービスをroot権限で実行すると、脆弱性が発見された際にサーバー全体の制御を奪われるリスクがあります。最小権限の原則に基づき、専用のシステムユーザーを作成するか、systemdのDynamicUser機能を利用して、被害範囲を最小限に抑える安全な設定方法を解説します。

なぜすべてを root で実行してはいけないのか

root はマシン上のあらゆる操作が可能です。すべてのファイルを読み取り、あらゆる設定を変更し、システム全体を削除できます。サービスを root として実行すると、その権限のすべてをサービスに渡すことになります。サービスに脆弱性があり、攻撃者に悪用された場合、攻撃者はそのサービスだけでなく root 権限を手にします。root 権限の取得は、サーバー全体の掌握を意味します。権限のないユーザーとして実行すれば、被害を食い止めることができます。制限されたアカウントで実行されているサービスにバグがあっても、攻撃者が操作できるのはそのアカウントがアクセスできる範囲のみであり、それは実質的に何も存在しない状態であるべきです。

これが最小権限の原則です。システムの各構成要素に対し、業務を遂行するために必要な最小限のアクセス権のみを付与します。これは、侵害が発生した際の被害範囲(blast radius)を制限するために最も効果的な習慣であり、現代のサーバーにおいて適用コストはほぼゼロです。

サービスごとに専用のアカウントを作成する

標準的な手法は、各サービスに対して個別のシステムユーザーを作成することです。そのユーザーは、そのサービスのファイルのみを所有し、ログインできないように設定します。Webアプリ用のシステムアカウントの例は以下の通りです。

sudo useradd --system --no-create-home --shell /usr/sbin/nologin appsvc

各フラグには重要な意味があります。--system は、人間がログインするためのものではなく、サービス用のアカウントであることを示します。--no-create-home は、不要なホームディレクトリの作成をスキップします。--shell /usr/sbin/nologin は、万が一攻撃者がアカウントを奪取しても、シェルを開けないようにすることを意味します。このアカウントは、プロセスとそのファイルを所有するためだけに存在します。

次に、そのユーザーには必要なファイルのみを付与し、それ以外は許可しません。

sudo chown -R appsvc:appsvc /opt/myapp

これで、サービスは自身のディレクトリの読み書きのみが可能になり、ディスク上の他の場所へ干渉することはできなくなります。もし脆弱性が悪用されても、攻撃者が変更できるファイルは /opt/myapp に限定されます。アカウントは引き続き、世界に公開されている(world-readable)ファイルは読み取れますが、システムの他の部分を変更することはできません。

systemd でそのユーザーとして実行する

アカウントを作成したら、systemd にそのユーザーでサービスを実行するよう指示します。unit ファイルでは、以下の1行で設定できます。

[Service]
ExecStart=/opt/myapp/bin/server
User=appsvc
Group=appsvc

User=appsvc を指定すると、プロセスは root ではなく、そのアカウントの制限された権限で開始されます。これは systemd でアプリケーションを実行する際の標準的かつ一般的な方法であり、すべての unit ファイルを作成する際に適用すべき手法です。

または DynamicUser でアカウント作成を省略する

systemd はさらに進んで、サービスが実行されている間だけ存在する使い捨てのユーザーを自動作成できます。DynamicUser=yes を設定すれば、アカウントの管理自体が不要になります。

[Service]
ExecStart=/opt/myapp/bin/server
DynamicUser=yes
StateDirectory=myapp

起動時に systemd は未使用のユーザー ID を割り当て、停止時にそれを解放します。また、サービスにはプライベートな /tmp(ファイルシステムの大部分を読み取り専用としたビュー)と、StateDirectory= が設定して渡す /var/lib/myapp 配下の書き込み可能な state ディレクトリが割り当てられます。自身の state ディレクトリのみを必要とする自己完結型のサービスの場合、DynamicUser=yes を使用するのが最も簡単な強力な隔離方法です。攻撃者の標的となる長期的なアカウント自体が存在しないためです。

手動での unit ファイル作成は手間がかかり、セキュリティ強化のディレクティブを正しく設定することが最も重要です。systemd のサービスとタイマーのガイド にある generator を使用すれば、これらのオプションを自動補完し、最初から正しい unit ファイルを作成できます。

他の対策との関係性

最小権限の原則は一つのレイヤーであり、他の対策を置き換えるのではなく、それらと組み合わせて機能します。デフォルト拒否のファイアウォール がサービスへの到達を制御し、権限のないユーザーでの実行が、侵害された際のサービスの動作を制御し、強化された SSH がそもそも攻撃者の侵入を防ぎます。これら単体では不十分ですが、組み合わせることで、一つのサービスのバグがサーバー全体の侵害につながるのを防ぐことができます。

次に進む前に、サーバー全体のセキュリティチェックリストを実行し、作業用のパーソナライズされたコピーを作成してください。

ToolVPS hardening checklist

FAQ

なぜサービスを root で実行してはいけないのですか?

root はマシン上のあらゆる操作ができるため、root で実行されているサービスが侵害されると、攻撃者はサービスだけでなくサーバー全体を掌握します。サービスは制限された権限のないアカウントで実行してください。root は管理作業のために取っておき、常時稼働するサービスはすべて制限されたユーザーで実行してください。

ログインできないユーザーを作成するにはどうすればよいですか?

sudo useradd --system --no-create-home --shell /usr/sbin/nologin NAME を実行してください。nologin シェルは、認証情報が盗まれても対話型セッションを開けないことを意味し、--system はサービス用アカウントであることを示し、--no-create-home は不要なホームディレクトリの作成をスキップします。chown を使用して、そのユーザーには自身のファイルのみを所有させてください。

systemd DynamicUser とは何ですか?

DynamicUser=yes は、サービスが実行されている間だけ存在する一時的なユーザーを systemd に作成させる設定です。これにより、長期的なアカウントを管理する必要がなくなります。また、サービスにはプライベートな /tmp(大部分が読み取り専用のファイルシステムビュー)と、管理された state ディレクトリが提供されます。使い捨ての低権限アイデンティティを使用して、自己完結型のサービスを実行するための最も簡単な方法です。

非 root ユーザーでの実行はファイアウォールの代わりになりますか?

いいえ。これらは保護する対象が異なります。権限のないユーザーでの実行は、侵害された際のサービスの動作を制限しますが、ファイアウォールはサービスへの通信自体を制限します。各レイヤーが他のレイヤーの不足を補うよう、両方を使用し、さらに SSH の強化も行ってください。

サービスユーザーはどのファイルの所有権を持つべきですか?

サービスが実際に必要とするファイルのみです。アカウントには、自身の作業ディレクトリとデータの所有権を与え、それ以外はすべて root の所有のままにしておいてください。推奨されるパターンは、アプリケーションディレクトリには sudo chown -R svc-app:svc-app /opt/svc-app を使用し、/etc 配下の設定ファイルは root が所有し、サービスには読み取り権限のみを与える構成です。目的は、プロセスが侵害されたとしても、攻撃者が変更できるファイルを自身のデータのみに限定することです。

#security#least-privilege#systemd#users#hardening#linux