systemd-analyze security で Linux サービスのセキュリティを「強化」する:5分でスコアを 9.6 から 2.0 へ改善

Security tutorial - IT technology blog
Security tutorial - IT technology blog

なぜ個々のサービスのセキュリティを気にする必要があるのか?

多くの開発者は Nginx、データベース、あるいは Node.js アプリをインストールして、動けばそれで良しとしがちです。しかし実際には、多くのサービスがデフォルトで「過剰な」権限を持っています。もしアプリに RCE(リモートコード実行)の脆弱性があった場合、ハッカーは即座にそれらの権限を継承します。もしサービスが root 権限で動作していれば、サーバー全体が悪意のある者の手に落ちたも同然です。

本番環境の監査に 6 ヶ月間 systemd-analyze security を使用した結果、これが非常に強力なツールであると確信しました。単に脆弱性を指摘するだけでなく、具体的なスコアを算出してくれるのです。特権昇格のリスクを最小限に抑えるために、具体的にどこを「ロック」すべきかが明確にわかります。

クイックスタート:5分でシステムのセキュリティをスコアリング

サードパーティ製のツールを追加でインストールする必要はありません。このツールは Ubuntu、CentOS、Debian などの systemd を採用しているディストリビューションに標準で備わっています。実行中の全サービスの安全性を素早くチェックするには、以下のコマンドを入力します:

systemd-analyze security

結果は、UNIT(サービス名)、EXPOSURE(リスクレベル)、STATUS(ステータス)を含む統計テーブルとして返されます。スコアは 0.0 から 10.0 の範囲で、0.0 はサービスが非常に厳密にサンドボックス化されていることを意味し、10.0 は「レッドアラート」レベルです。

nginx.service のような特定のサービスを詳しく調べたい場合は、以下のコマンドを使用します:

systemd-analyze security nginx.service

すると、systemd は数十の基準を含む詳細なチェックリストを表示します。合格したものには (✓) が、不合格のものには (✗) が表示されます。これがシステム強化を始めるためのロードマップとなります。

最も「価値の高い」セキュリティパラメータの解説

分析結果の項目が多くて圧倒されるかもしれませんが、スコアを素早く下げるために以下の 5 つの重要な項目に集中しましょう:

  • PrivateTmp: 有効(yes)にすると、サービス専用の /tmp ディレクトリが作成されます。アプリ A がアプリ B の一時ファイルを参照したり干渉したりできなくなります。
  • ProtectSystem: このモードは、サービスが /usr/boot/etc などの機密ディレクトリを上書きすることを防ぎます。
  • NoNewPrivileges: 子プロセスが親プロセスよりも高い権限を持てないようにし、sudo を利用した攻撃などを阻止します。
  • CapabilityBoundingSet: 完全な root 権限を許可する代わりに、サービスが必要とする最小限のカーネル権限のみを付与します。
  • ProtectHome: サービスが /home/root ディレクトリ内の個人データに「手を出す」のを防ぎます。

実践:Python サービスの権限を制限する

自作の Python アプリが 9.6 点(UNSAFE)と評価されたと仮定しましょう。強化するには、/lib/systemd/system/ 内のファイルを直接編集するのではなく、systemctl edit コマンドを使用します。これにより、パッケージのアップデート時に設定が失われるのを防げます。

sudo systemctl edit my-python-app.service

[Service] セクションに以下の設定を追加します:

[Service]
# root で実行しない
User=myuser
Group=mygroup

# サンドボックスを有効化
PrivateTmp=yes
ProtectSystem=full
ProtectHome=yes
NoNewPrivileges=yes
ProtectControlGroups=yes
ProtectKernelModules=yes
ProtectKernelTunables=yes
RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6
MemoryDenyWriteExecute=yes

# 必要に応じてポートのバインドのみを許可(例:ポート 80/443)
# CapabilityBoundingSet=CAP_NET_BIND_SERVICE

保存して、以下のコマンドで新しい設定を適用します:

sudo systemctl daemon-reload
sudo systemctl restart my-python-app.service

再度 systemd-analyze security で確認すると、スコアが 3.0 以下(SAFE レベル)まで大幅に低下しているのがわかります。わずか数行の設定で、非常に印象的な結果が得られます。

本番環境への導入における実戦経験

セキュリティを厳しくしすぎると、アプリが「Permission Denied(権限拒否)」エラーで動かなくなることがよくあります。焦らずに、「エラーが出たら修正する」という戦略をとりましょう。

まず、機能を一つずつ有効にします。変更を加えるたびに journalctl -u my-service -f コマンドを使ってリアルタイムでログを監視してください。もしアプリがファイルに書き込めなかったり、データベースに接続できなかったりすれば、どのオプションが原因かすぐにわかります。

次に、絶対的な 0.0 という数字に固執しすぎないでください。特定のサービスは、正常に動作するために高い権限を維持する必要があります。最終的な目標は、自分たちを苦しめることではなく、攻撃対象領域(Attack Surface)を最小化することです。

最後に、サービス実行用の専用ユーザーを作成する際は、パスワード生成ツールなどのツールを使用して、複雑なパスワードを設定してください。これにより、サービスアカウントに対するブルートフォース攻撃を防ぐことができます。

結論

systemd-analyze security は、サーバーの「健康状態」を把握するための強力な助っ人です。これらの指標を微調整するために 15 分費やすだけで、システムへの侵入難易度は何倍も高くなります。安全な設定を行い、ぐっすり眠れる夜を過ごしましょう!

Share: