MENU

seccompプロファイルでコンテナのsyscallを制限する|auditログからのプロファイル生成と本番段階適用の検証

目次

seccompとコンテナのsyscall制限――なぜ今この仕組みが重要なのか

コンテナはホストカーネルを共有するため、プロセスが呼び出せるsystem call(syscall)を絞り込まない限り、カーネルへの攻撃面が広いまま残ります。seccomp(Secure Computing Mode)はLinuxカーネルが提供するsyscallフィルタリング機能であり、許可・拒否・ログ記録のアクションをsyscallごとに細かく指定できます。

コンテナランタイムがseccompを無効にして起動すると、コンテナ内のプロセスはホストカーネルが実装するほぼすべてのsyscallを呼び出せます。過去のCVEの多くはこの前提を悪用しており、プロファイルが適切に設定されていれば影響を局所化できたケースが現場では繰り返し報告されています。

2026年現在、DockerやcontainerdのデフォルトはRuntimeDefaultプロファイルの自動適用へと移行が進んでいます。しかしワークロード固有の最小権限プロファイルを自前で用意することが、ゼロトラスト運用の観点から強く求められています。本記事では「auditログからsyscallを洗い出してプロファイルを生成し、段階的に本番へ適用する」という一連の流れを解説します。

auditログを使ってコンテナのsyscallを洗い出す

プロファイルを手書きするアプローチは現実的ではありません。Webサーバー1つ取っても、起動・TLS handshake・ログローテーション・シグナル処理など、意図せず呼ばれるsyscallが数十種類に及ぶためです。そこで活用するのがLinux Audit subsystemと、それをseccomp用に可視化するツール群です。

auditdの準備とsyscallトレースの有効化

まずホスト側でauditdを起動し、対象コンテナのsyscallを記録する監査ルールを追加します。

sudo systemctl enable --now auditd

# 対象PIDのsyscall全件を記録(起動後にコンテナPIDを確認して差し替える)
sudo auditctl -a always,exit -F arch=b64 -S all -F pid=<コンテナPID> -k seccomp_trace

本番相当のトラフィックをかけながら全syscallを記録するとaudit.logが急増するため、開発環境または専用のステージング環境で実施することが原則です。

oci-seccomp-bpf-hookによる自動収集

より実用的な手法として、oci-seccomp-bpf-hook(containers/oci-seccomp-bpf-hook)が広く使われています。これはOCIフックとして動作し、eBPFを利用してコンテナが発行したsyscallを自動記録し、JSON形式のseccompプロファイルを直接出力します。

# フックを登録してコンテナを起動(Podman例)
podman run --annotation \
  io.containers.trace-syscall="of:/tmp/myapp-profile.json" \
  --rm myapp:latest /entrypoint.sh

コンテナ終了後、/tmp/myapp-profile.jsonに実際に使われたsyscallだけを列挙したプロファイルが生成されます。Dockerの場合はstracesyscalls2seccompスクリプトを組み合わせる方法で代替できます。

生成されたプロファイルをそのまま本番に投入するのは危険です。テスト時に通らなかったコードパスで必要なsyscallが漏れている可能性があるため、次節のLOGモードによる検証が不可欠です。

seccompプロファイルのJSON構造と最小権限設計

seccompプロファイルはJSON形式で記述します。基本構造はdefaultActionsyscallsの2要素です。

{
  "defaultAction": "SCMP_ACT_ERRNO",
  "architectures": ["SCMP_ARCH_X86_64", "SCMP_ARCH_AARCH64"],
  "syscalls": [
    {
      "names": [
        "read", "write", "close", "mmap", "mprotect", "brk",
        "rt_sigaction", "rt_sigprocmask", "exit_group",
        "futex", "nanosleep", "clock_gettime", "epoll_wait",
        "accept4", "recvfrom", "sendto", "openat", "fstat",
        "getpid", "gettid", "socket", "connect", "bind",
        "listen", "setsockopt", "getsockopt"
      ],
      "action": "SCMP_ACT_ALLOW"
    }
  ]
}

defaultActionSCMP_ACT_ERRNOにすると、リストにないsyscallはEPERMで即拒否されます。設計時には以下の点に注意が必要です。

  • allowlistはツール生成後に手動でレビューし、ptraceprocess_vm_readvperf_event_openなど攻撃に悪用されやすいsyscallが含まれていないかを確認する。
  • architecturesフィールドはコンテナが動くノードのアーキテクチャに合わせて列挙する。ARM64ノードへのデプロイを忘れると起動失敗になるため注意が必要です。
  • マルチスレッドアプリはcloneset_robust_listfutexが必要なことが多く、トレース段階でこれらが確実に収集できているかを確認します。

段階的な本番適用――LOGモードからENFORCEへ

プロファイルを初日からENFORCEモードで本番投入するのはリスクが高い判断です。現場では「LOG→検証→ENFORCE」の3段階を踏むアプローチが定着しています。

ステップ1:SCMP_ACT_LOGで違反syscallを洗い出す

defaultActionSCMP_ACT_LOGに設定して本番相当のトラフィックを数日間流します。この状態ではsyscallは拒否されず、auditログに記録されるだけなのでサービスへの影響はありません。

{
  "defaultAction": "SCMP_ACT_LOG",
  "syscalls": [
    {
      "names": ["read", "write", "openat"],
      "action": "SCMP_ACT_ALLOW"
    }
  ]
}

KubernetesではSecurityContextseccompProfileフィールドでプロファイルを参照します。

securityContext:
  seccompProfile:
    type: Localhost
    localhostProfile: profiles/myapp-log.json

auditログに記録されたsyscallを集計するには次のコマンドが便利です。

sudo ausearch -k seccomp_trace --raw \
  | aureport --syscall -i \
  | sort -k 4 -rn \
  | head -30

ここで新たに検出されたsyscallをallowlistに追加し、プロファイルを更新します。LOGモードで1〜2週間、本番相当の負荷下で違反が出なくなったことを確認してから次のステップへ進みます。

ステップ2:SCMP_ACT_ERRNOで本番ENFORCE、切り戻し設計も準備する

LOGモードの検証が完了したらdefaultActionSCMP_ACT_ERRNOに切り替え、ローリングアップデートで段階的に展開します。このとき、エラーレートとkubelet/containerdのイベントログを監視します。

# 違反が出た場合はcontainerdのログで確認
journalctl -u containerd -f | grep -i seccomp

# Kubernetes Eventsでも確認できる
kubectl get events --field-selector reason=Failed -n <namespace>

切り戻しはプロファイルをLOGモード版に戻してローリングアップデートするだけです。ConfigMapや外部ファイルでプロファイルを管理し、Helm値またはKustomizeの変数でモードを切り替えられる構成にしておくと、切り戻しのリードタイムを数分以内に抑えられます。

Kubernetes 1.30以降および2026年の現行環境差分

Pod Security AdmissionとseccompProfileの必須化

Kubernetes 1.27以降、Pod Security AdmissionのRestrictedポリシーではseccompProfile.typeRuntimeDefaultまたはLocalhostの指定が必須です。UnconfinedのままではRestrictedネームスペースへのデプロイが拒否されます。既存のHelmチャートや社内マニフェストにseccompProfileが記載されていない場合は、移行時の修正対象として早期に洗い出しておく必要があります。

security-profiles-operator(SPO)による運用自動化

Kubernetes SIGのsecurity-profiles-operator(SPO)は、seccompプロファイルをCRD(SeccompProfileリソース)として管理し、ノードへの配布・バージョン管理・監査を自動化するOperatorです。2024年のv0.8リリース以降、本番導入事例が増えており、手動でのノードへのファイル配置という運用負荷を大幅に削減できます。

apiVersion: security-profiles-operator.x-k8s.io/v1beta1
kind: SeccompProfile
metadata:
  name: myapp-profile
  namespace: default
spec:
  defaultAction: SCMP_ACT_ERRNO
  syscalls:
    - action: SCMP_ACT_ALLOW
      names:
        - read
        - write
        - openat
        - futex
        - exit_group

SPOはrecording機能も備えており、ProfileRecordingリソースをデプロイするだけでBPF経由のsyscall収集が自動化されます。auditdを手動でセットアップする手順は、SPOを導入した環境では不要になりつつあります。

containerd 2.x系とマルチアーキテクチャ対応

containerd 2.0(2024年リリース)ではRuntimeDefaultプロファイルの実装がmoby/mobyからcontainerd本体に移管され、内容も更新されています。以前のDockerデーモン付属のデフォルトプロファイルと内容が異なるため、「旧デフォルトで動いていたのに新環境で失敗する」というケースが報告されています。移行時はdiffによる内容確認が必要です。

また、ARM64(AWS Graviton・Azure Ampere)ノードへの展開が一般化したことで、architecturesフィールドの漏れによるトラブルも増えています。x86_64専用のプロファイルをそのままARM64ノードに適用すると、syscall番号の差異で意図しない拒否が発生します。プロファイルを設計する段階からマルチアーキテクチャ対応を前提にすることが、2026年の現行環境では標準的な判断になっています。

継続的なプロファイルメンテナンスと運用上の注意点

seccompプロファイルの適用で最も多いトラブルは「ライブラリやミドルウェアのアップデート後に新しいsyscallが追加されて拒否される」というケースです。アプリケーションのバージョンアップは静かにsyscallの呼び出しパターンを変えることがあり、テストが通っても本番でのコードパスで初めて問題が発覚することがあります。

  • コンテナイメージのビルドパイプラインにseccompプロファイルのリグレッションテストを組み込む。新しいsyscallが発生したらCIが警告を出すように設定することで、本番到達前に検出できます。
  • プロファイルをGitで管理し、変更はPRレビューを経て適用する。誰がいつどのsyscallを追加・削除したかのトレーサビリティを確保することが、インシデント時の調査速度に直結します。
  • 本番でENFORCEモードを有効にした後も、定期的にauditログを確認してプロファイルの陳腐化を検出する体制を維持する。SPOのrecording機能を定期実行する仕組みも有効です。

seccompプロファイルは一度適用して終わりではなく、アプリケーションのライフサイクルとともに継続的にメンテナンスが必要なセキュリティ設定です。初期の投資コストは高く見えますが、security-profiles-operatorのような自動化ツールが成熟した現在では、運用コストは着実に下がっています。LOGモードからの段階適用という確実なアプローチを基本に、コンテナ基盤のセキュリティ成熟度を高めていくことが現実的な選択肢です。

「コマンドは打てる。次は”現場で通用する型”を最短で身につけたい」——そんなあなたへ。

ネットの断片的なTipsをコピペするだけでは、体系的な運用スキルはなかなか積み上がりません。リナックスマスター.JPの無料メルマガ「リナマガ」では、現場で実際に使うLinuxサーバー運用の考え方を、順を追って実務目線でお届けしています。いま登録された方には、安全なサーバー構築の「型」をまとめた『Linuxサーバー構築入門マニュアル(図解60P)』を完全無料でプレゼント中です。

>> 図解60P『Linux入門マニュアル』を無料で受け取る
(メルマガ登録は10秒・いつでも解除OK)

※ 「独学の時間がもったいない」「プロから現場の技術を最短で学びたい」という本気の方には、2日で実務レベルが身につく初心者向けハンズオンセミナーもご用意しています。

PR・広告

[試して理解]Linuxのしくみ 増補改訂版(Amazon)

プロセス・権限・ファイルシステムなどLinux内部を図解で理解できる一冊。運用判断の勘所に。

Amazonで見る

※ Amazonのアソシエイトとして、当サイトは適格販売により収入を得ています。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

目次