- systemd は強力なサービス管理機能を提供するが、デフォルト設定はセキュリティよりも使いやすさに最適化されているため、別途ハードニングオプションの適用が必要
systemd-analyze security コマンドで、サービス全体または特定のサービスのセキュリティ露出指標を分析し、優先順位を決められる
- サービス単位で適用できるさまざまなセキュリティオプションがあり、これは
/etc/systemd/system/ServiceName.service.d/override.conf などを通じて個別に修正できる
- 主なオプションには
ProtectSystem, PrivateTmp, NoNewPrivileges, SystemCallFilter, MemoryDenyWriteExecute など、プロセス権限やリソースアクセスを制限する項目が含まれる
- 完全なセキュリティを目指すのではなく、外部公開サービスを優先的にハードニングしてリスクを減らし、self-hosting 環境でも大きな効果が期待できる
systemd 概要
- systemd はサービス管理において非常に完成度が高く堅牢な方式を提供する
- ただし、セキュリティよりも即時の使いやすさを優先しているため、デフォルト設定は緩めになっている
- 本文書は、systemd サービスユニットと podman quadlet に適用できる複数のセキュリティ強化オプションを紹介し、侵害の可能性を減らし、侵害発生時の被害範囲を最小化することを目的とする
- すべてのサービスへ一括適用するためのガイドではなく、それぞれのサービスの特性や必要機能に合わせた個別の実験、ログ確認、調整が必要
- インフラのセキュリティ責任は全面的に運用者にあり、本書は参考ツールである
systemd セキュリティ分析
systemd-analyze security コマンドでサービス全体のセキュリティ状態を確認したり、特定サービス(例: sshd.service)の詳細設定を分析したりできる
- 出力にはチェック有無、機能名、説明、Exposure スコアが含まれ、Exposure が高いほど危険度が高い
- セキュリティオプションは
[Service] セクション(systemd)または [Container] セクション(podman quadlet)に追加設定できる
systemctl edit ServiceName.service によって override ファイルを作る方法が推奨され、失敗した場合は必要な権限を確認して調整する必要がある
サービスのセキュリティオプション
- systemd は多様なセキュリティオプションのキーワードを提供しており、
man systemd.exec 5, man capabilities 7 などで確認できる
- 代表的なセキュリティ関連オプション
ProtectSystem → ファイルシステムを読み取り専用に制限するオプション
ProtectHome → /home, /root, /run/user へのアクセスを遮断するオプション
PrivateDevices → 物理デバイスへのアクセスを遮断し、/dev/null などの仮想デバイスのみ許可するオプション
ProtectKernelTunables, ProtectKernelModules, ProtectKernelLogs → カーネルリソースへのアクセスを遮断するオプション
NoNewPrivileges → setuid/setgid などによる新規権限取得を防ぐオプション
MemoryDenyWriteExecute → 書き込み可能かつ実行可能なメモリの同時使用を防ぎ、一部の JIT 言語では問題が起きる可能性がある
SystemCallFilter → 許可するシステムコールを制限するオプションで、違反時にプロセス終了または EPERM を返せる
各オプションの説明
- ProtectSystem:
strict 設定時はファイルシステム全体を読み取り専用でマウントし、/dev, /proc, /sys には別途保護オプションが必要
- ReadWritePaths: 一部のパスだけを書き込み可能に戻す設定
- ProtectHome:
/home, /root, /run/user へのアクセスを遮断
- PrivateDevices: 物理デバイスへのアクセスを無効化し、
/dev/null などの Pseudo デバイスのみ許可
- ProtectKernelTunables:
/proc, /sys を読み取り専用にする
- ProtectControlGroups: cgroup への読み取り専用アクセスのみ許可
- ProtectKernelModules: カーネルモジュールの明示的なロードを禁止
- ProtectKernelLogs: カーネルログバッファへのアクセスを制限
- ProtectProc:
invisible 設定時、他ユーザー所有のプロセスを /proc/ から隠す
- ProcSubset: 特定の PID 関連項目以外の内容を
/proc から遮断
- NoNewPrivileges: setuid、setgid、ファイルシステム capability による新たな権限昇格を防ぐ
- ProtectClock: システム/ハードウェアクロックへの書き込みを遮断
- SystemCallArchitectures:
native 設定時は x86-64 などネイティブ syscall のみ許可
- RestrictNamespaces: コンテナ向けの名前空間を制限
- RestrictSUIDSGID: ファイルの setuid, setgid ビット設定を遮断
- LockPersonality: 実行ドメインの変更を防ぐ(古いアプリケーションなどでのみ必要)
- RestrictRealtime: リアルタイムスケジューリングを制限(一部の特殊用途サービスのみ必要)
- RestrictAddressFamilies: 許可するソケットアドレスファミリを制限(例: AF_INET, AF_INET6, AF_UNIX などを指定)
- MemoryDenyWriteExecute: 書き込み+実行可能なメモリ領域の追加生成を防ぐ(JIT を使うサービスは注意)
- ProtectHostname:
sethostname, setdomainname syscall の使用を禁止
- SystemCallFilter: サービスごとに syscall の許可/遮断を設定でき、細かくフィルタリング可能
- グループ、個別 syscall、許可/遮断方式などを調整できる
- 違反時に終了の代わりとして EPERM などのエラーコードを返す設定もサポート
- 一覧は
systemd-analyze syscall-filter または man systemd.exec(5) で確認できる
~ 接頭辞でリスト全体を否定できる(例: CapabilityBoundingSet=~CAP_SETUID など)
SystemCallFilter 制限の調整プロセス
auditd を使えば、サービス失敗時にどの syscall がブロックされたかをログで確認できる
sudo ausearch -i -m SECCOMP -ts recent を実行後、syscall 値を確認
- 該当 syscall または関連グループを
SystemCallFilter に追加し、順次問題を解決できる
セキュリティ強化の適用優先順位と運用のヒント
- すべてのサービスに全部適用する必要はない
- 脅威モデルとリスク管理が核心であり、特に外部公開サービス(httpd, nginx, ssh など)は必ず検討したい
- カスタムコマンド、timer ユニット(旧来の cron 代替)などにも先行適用が効果的
- 複雑でないサービスほど細かな調整を行いやすい
チェックリスト: 推奨セキュリティオプションの組み合わせ(初期適用の優先順位)
ProtectSystem=strict
PrivateTmp=yes
ProtectHome=yes または ProtectHome=tmpfs
ProtectClock=yes, ProtectKernelLogs=yes, ProtectKernelModules=yes
RestrictSUIDGUID=yes
UMask=0077
LockPersonality=yes
RestrictRealtime=yes
MemoryDenyWriteExecute=yes
DynamicUser=yes または User を root 以外の特定ユーザーに指定
- 上記項目は一般にサービスへの影響がほとんどなく使える組み合わせ
- さらに syscall フィルタリング(
SystemCallFilter)まで適用するには詳細なテストが必要
Traefik の設定例
- コンテナベースの Traefik サービスを systemd quadlet で実行し、多数のセキュリティオプションを適用した事例
ProtectSystem=full, ProtectHome=yes, SystemCallFilter=@system-service @mount @privileged などを適用
CapabilityBoundingSet=~CAP_SETUID CAP_SETPCAP で特定権限を削除
RestrictAddressFamilies=AF_INET AF_INET6 AF_UNIX AF_NETLINK など、ネットワークアクセス制限を適用
結論
- systemd のセキュリティ強化オプションは、Unix 系システム管理者ならツールボックスに一つ入れておく価値のある実用的な手段
- 完璧なセキュリティ対策ではなく、リスクを減らすためのツールとして活用すべきであり、すべてのサービスに無差別にセキュリティ設定を適用する必要はない
- 特に self-hosting 環境の管理者が活用する場合、セキュリティ水準の向上に大きく役立つ
- 「完璧さより実用性」を優先し、業務や環境に合う範囲で部分的にでも適用することを推奨
まだコメントはありません。