【入門編】 ノードレベルのカーネルセキュリティ:Seccompプロファイルの適用 – インフラ・ネットワーク & クラウドセキュリティ防御ガイド

こんにちは!国内外のさまざまなシステムでセキュリティの診断やインシデント対応を行っている、ホワイトハッカーの「セキュアおじさん」こと、チーフ・セキュリティ・オフィサーです。

日々、サイバー攻撃者たちがどうやってシステムに侵入し、どこを狙ってくるのかを監視・分析している私ですが、最近特に現場で重要視しているのが「コンテナのセキュリティ」、その中でも「カーネル(OSの心臓部)の守り方」です。

「DockerやKubernetesを使っているから、コンテナの中は安全ですよね?」
「コンテナ同士は隔離されているから大丈夫!」

新人IT担当者の方や、セキュリティを学び始めたばかりの開発者の方から、よくこのような質問をいただきます。ですが、実はここに攻撃者が狙う最大の「盲点」があるのです。

今回は、コンテナの壁を突き破ってOS全体を乗っ取ろうとする泥棒(ハッカー)からシステムを守るための最強の盾、「Seccomp(セックコンプ)プロファイル」について、おうちの防犯に例えながら、一歩ずつ優しく、そして現場のリアルな視点を交えて解説していきますね!

—

1. コンテナという「シェアハウスの個室」と、ハッカーの狙い

まず、コンテナとOS(カーネル)の関係を、身近な「シェアハウス」に例えて考えてみましょう。

  • ホストOSのカーネル = シェアハウスの「大家さん(兼、建物の基礎)」
  • コンテナ = 入居者が暮らす「個室」
  • システムコール = 入居者が大家さんに頼む「お願い事(お風呂を沸かして、鍵を増やして、など)」

コンテナは、一見すると独立した部屋(仮想マシン)のように見えますが、実はすべて同じ大家さん(カーネル)を共有して暮らしている「シェアハウスの個室」にすぎません。個室の壁はとても薄いのです。

もし、ある一つの個室(Webアプリが入ったコンテナ)に泥棒(ハッカー)が忍び込んだとします。泥棒の本当の狙いは、その個室の中のテレビ(データ)だけではありません。大家さんを騙して、「シェアハウス全体のマスターキーをよこせ!」「建物の土台を工事させろ!」と要求することです。

この「大家さんへのお願い事」の手段こそが、IT用語でいう「システムコール(System Call)」になります。

攻撃者が狙う「カーネルエクスプロイト」とは?

システムコールは、プログラムが「ファイルを読み書きしたい」「ネットワークに繋ぎたい」といった、OSの根本的な機能を使うために大家さん(カーネル)に送るリクエストです。

Linuxカーネルには、なんと 300種類以上 のシステムコール(お願い事のメニュー)が存在します。
しかし、一般的なWebアプリケーションが動くために必要なメニューは、そのうちのせいぜい 数十種類 程度。使わない残りの200種類以上のメニューの中には、過去に脆弱性(バグ)が見つかった「危険なメニュー」や、管理者しか使わないはずの「強力すぎるメニュー」がたくさん眠っています。

泥棒(ハッカー)は、侵入した個室から大家さんに向けて、普段使わないような怪しい裏メニュー(脆弱性のあるシステムコール)を送りつけ、大家さんをパニックに陥らせてシェアハウス全体(ホストOS)を乗っ取ろうとします。これが「カーネルエクスプロイト(カーネルの脆弱性攻撃)」の正体です。

—

2. Seccomp(セックコンプ)は「大家さんの厳格な受付ルール」

この恐ろしい乗っ取りを防ぐために登場するのが、今回の主役「Seccomp(Secure Computing Mode)」です。

Seccompをわかりやすく言うと、「この個室の入居者は、あらかじめ決めた『安全なお願い事リスト』以外のメニューを大家さんに頼んではいけない」という防犯ルールブックです。

もし泥棒が個室を乗っ取り、大家さんに「建物の土台を改造して(危険なシステムコール)」とお願いしても、大家さんはルールブック(Seccompプロファイル)を見て、
「ん? あなたの部屋からは、そのお願い事は受け付けられない決まりになっています!」
と、即座にそのリクエストを拒否(ブロック)してくれます。

これこそが、カーネルセキュリティの極意なのです。

—

3. 【実践】Seccompプロファイル(ルールブック)を覗いてみよう!

それでは、実際にSeccompのルールブックがどのようなものか、具体的なコードを見ていきましょう。
Seccompのプロファイルは、通常 JSON(ジェイソン) という形式のテキストファイルで記述します。

一見難しそうに見えますが、意味がわかればとてもシンプルですよ!

優しいSeccompプロファイルのサンプル例

以下は、安全なシステムコールだけを許可し、それ以外をエラーにする「カスタムSeccompプロファイル」の基本形です。

{
  "defaultAction": "SCMP_ACT_ERRNO",
  "archMap": [
    {
      "architecture": "AUDIT_ARCH_X86_64",
      "subArchitectures": [
        "AUDIT_ARCH_X86_64"
      ]
    }
  ],
  "syscalls": [
    {
      "names": [
        "accept4",
        "epoll_wait",
        "pwrite64",
        "read",
        "write",
        "close",
        "exit_group"
      ],
      "action": "SCMP_ACT_ALLOW"
    }
  ]
}

パラメーターの意味を噛み砕いて解説!

上の設定ファイルで何を指定しているのか、泥棒対策の視点で解説しますね。

  • "defaultAction": "SCMP_ACT_ERRNO"
  • 意味:リストに載っていない「想定外のお願い事」が来たら、すべて「エラー(お断り)」にして追い返す、という基本方針です。
  • 防犯の例え:「基本、知らない人の頼み事はすべてお断り!」という徹底した防犯の姿勢ですね。
  • "archMap"
  • 意味:対象とするCPUの構造(アーキテクチャ)を指定しています。一般的な64ビットのサーバー(x86_64)を指定しています。
  • "syscalls" -> "names"
  • 意味:このコンテナが動くために「どうしても必要な最低限のシステムコール(お願い事)」の名前を並べたホワイトリストです。
  • read や write(ファイルの読み書き)、accept4(ネットワークの接続受け入れ)など、アプリの動作に必須の基本メニューだけが並んでいます。
  • "action": "SCMP_ACT_ALLOW"
  • 意味:上に書いた名前のシステムコールだけは「許可(実行してよし!)」とします。

このように、「基本は全部ダメ!でも、このリストに載っている基本の仕事だけはやっていいよ」というルールを作ることで、万が一Webアプリがハッキングされても、ハッカーはOSの深い部分に攻撃を仕掛けることができなくなります。

—

4. 【実践】作成したプロファイルをコンテナに適用してみよう

ルールブック(JSONファイル)を作ったら、次はそれを実際にコンテナへ適用させてみましょう。
ここでは、よく使われる「Docker」と、本番環境で大活躍する「Kubernetes」の2つの方法をご紹介します。

パターンA:Dockerで実行する場合

Dockerでコンテナを起動する際に、作成した my-seccomp-profile.json を指定して適用します。

# 作成したSeccompプロファイルを指定して、コンテナを起動するコマンドです
docker run --rm \
  -it \
  --security-opt seccomp=./my-seccomp-profile.json \
  nginx

このコマンドを実行すると、Nginx(Webサーバー)のコンテナは、あなたが作った厳しいルールブック(Seccomp)の監視下で動くようになります。

パターンB:Kubernetes(マニフェスト)で適用する場合

Kubernetes(クバネティス)を使って本番環境で動かす場合は、以下のようにPod(ポッド)の設定ファイル(YAML)の securityContext という場所に指定します。

apiVersion: v1
kind: Pod
metadata:
  name: secure-web-pod
  labels:
    app: secure-web
spec:
  securityContext:
    # 1. Pod全体にSeccompプロファイルを適用します
    seccompProfile:
      type: Localhost
      # ノード上の指定されたパスにあるルールブック(JSON)を読み込みます
      localhostProfile: profiles/my-seccomp-profile.json
  containers:
  - name: web-container
    image: nginx:alpine
    ports:
    - containerPort: 80

*※注意:Kubernetesで Localhost を指定する場合、設定ファイル(JSON)は各ノード(サーバーの実体)の /var/lib/kubelet/seccomp/profiles/my-seccomp-profile.json にあらかじめ配置しておく必要があります。*

—

5. 現場のリアル:Seccomp導入でよくある「落とし穴」と対策

ここまで読むと、「よし、じゃあ今すぐすべてのコンテナにガチガチのSeccompを適用しよう!」と思うかもしれません。

しかし、ここにインシデントハンドリングの現場で数々のトラブルを見てきた私からの、とても重要なアドバイスがあります。

🚨 よくある落とし穴:「動かなくなっちゃった!」

ルールを厳しくしすぎると、アプリケーションが必要としているシステムコールまで止めてしまい、「コンテナが起動すらしない」「特定の処理の途中でエラーになって落ちる」という大惨事が発生します。

「何が必要なシステムコールなのか、開発者でも全部把握するのは難しい…」というのが本音ですよね。

💡 プロが実践する解決策:「監査(Audit)モード」から始めよう!

いきなり処理を「拒否(Error)」にするのではなく、まずは「怪しいお願い事が来たら、拒否はしないけどログ(履歴)に記録する」というお試し期間を設けます。

プロファイル内の defaultAction を以下のように書き換えてみましょう。

"defaultAction": "SCMP_ACT_LOG"
  • SCMP_ACT_LOG に設定すると、許可リストにないシステムコールが呼ばれたとき、拒否はせずに「システムログに記録」だけしてくれます。
  • この状態でテスト環境をしばらく動かし、ログ(/var/log/audit/audit.log や /var/log/syslog など)を確認します。
  • ログに記録された「使われたシステムコール」を許可リストに少しずつ追加していき、過不足のない完璧なリストが完成したところで、最後に SCMP_ACT_ERRNO(拒否)へ切り替えるのです。

この「一歩ずつ確認しながら進める泥臭いステップ」こそが、本番環境のサービスを止めずにセキュリティを極限まで高めるプロのノウハウです。

—

6. まとめ:一歩ずつセキュアな環境を作っていきましょう!

お疲れ様でした!今回は「Seccompプロファイル」について、家の鍵やシェアハウスの防犯に例えて解説してきました。

おさらいをすると、
1. コンテナは同じOSカーネル(大家さん)を共有しているため、カーネルへの攻撃が最大の脅威になる。
2. Seccomp は、コンテナからカーネルへの「お願い事(システムコール)」を制限する防犯ルールブック。
3. まずは監査モード(LOG)で必要なお願い事を洗い出し、安全を確認してから拒否モード(ERRNO)にするのがプロの鉄則。

セキュリティ対策は、一朝一夕で完璧にできるものではありません。ですが、こうして仕組みを一つずつ紐解いていけば、決して恐れるものではないことが分かっていただけたかと思います。

あなたが作るこれからのシステムが、より安全で、攻撃者に隙を与えない強固なものになるよう、一歩ずつ一緒にセキュリティ対策を学んでいきましょう!応援しています!

コメント

タイトルとURLをコピーしました