サプライチェーンの崩壊を防げ:CosignとAdmission Controllerによる「信頼の起点」の強制
エンジニア諸君、日々CVEのスコアに一喜一憂し、パッチ適用の自動化に心血を注いでいることだろう。だが、一度立ち止まって考えてみてほしい。あなたが今日デプロイしたそのコンテナ、本当に「あなたがビルドしたそのコード」が中に入っていると言い切れるか?
昨今のサプライチェーン攻撃は、もはや古典的な脆弱性スキャンをすり抜ける。CI/CDパイプラインの途中で悪意あるレイヤーが注入されれば、どんなに厳格なOSハーデニングも無意味だ。OSのメモリ保護機能(ASLR/DEP)も、実行されるバイナリそのものが改竄されていれば、それは単なる「強固な檻の中で暴れる侵入者」を飼っているに過ぎない。
今日語るのは、Kubernetesにおける「信頼の強制」だ。Cosignによる署名と、それをAdmission Controllerで物理的に遮断するアーキテクチャについて、現場の泥臭い視点から紐解く。
1. なぜ「署名」が最後の砦なのか
コンテナイメージのSHA256ハッシュは、あくまで「その時点での状態」を示す指紋に過ぎない。しかし、その指紋が誰によって生成されたか、正当なビルドプロセスを通ったかを保証する術がなければ、攻撃者は中央レジストリ(Docker HubやECR等)の権限を奪取するだけで、世界中のクラスタを汚染できる。
ここでCosignが登場する。これは単なるツールではない。鍵ペアを用いた非対称暗号をコンテナワークフローに持ち込み、コンテナイメージを「改竄不可能な証跡」へと変貌させるためのプロトコルだ。
2. 署名の実装:Cosignによるアーティファクトの保護
まずは、ビルドプロセスに署名を組み込む。ここでは公開鍵暗号基盤(PKI)を用いた最も堅牢なアプローチを示す。
# 1. 鍵ペアの生成(秘密鍵はKMSやHashiCorp Vaultで管理すること)
cosign generate-key-pair
# 2. イメージに署名し、レジストリへプッシュ
# 署名データはイメージとは別のタグとしてレジストリに保存される
cosign sign --key cosign.key my-registry.com/my-app:v1.0.0
ここで重要なのは、秘密鍵の管理だ。ローカルの.keyファイルに保存するのは論外だ。AWS KMSやGCP KMS、あるいはVaultのTransit Secret Engineに鍵をオフロードし、署名のタイミングでのみメモリ上に展開する設計が必須となる。
3. Admission Controllerによる「論理的拒絶」
署名が存在しても、それを検証するプロセスがなければ意味がない。Kubernetesの ValidatingAdmissionWebhook を利用して、署名なきイメージの実行を根本から拒絶する。
ここでは、Kyvernoを用いたポリシー設定例を挙げる。Kyvernoは複雑なGoコードを書くことなく、宣言的に署名検証を強制できるため、運用負荷の観点から非常に優秀だ。
# Kyverno ClusterPolicy: 署名検証の強制
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: verify-image-signature
spec:
validationFailureAction: Enforce # ここをEnforceにすることで、署名なきPodの作成を拒否する
rules:
- name: check-signature
match:
resources:
kinds:
- Pod
verifyImages:
- imageReferences:
- "my-registry.com/my-app:*"
attestors:
- entries:
- keys:
publicKeys: |-
-----BEGIN PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE... # 公開鍵
-----END PUBLIC KEY-----
4. チーフホワイトハッカーの視点:盲点と対策
このアーキテクチャを導入しても、なお突破を試みる攻撃者は存在する。
- 署名鍵の奪取: もしCI/CD環境の権限が奪われれば、攻撃者は「正当な署名」を付与して悪意あるイメージをデプロイできる。これを防ぐには、「短命な鍵(Ephemeral Keys)」の利用を検討すべきだ。CosignのKeyless署名機能(Fulcio/Rekor)を利用すれば、公開鍵を管理することなく、OIDCアイデンティティに基づいた検証が可能になる。
- Admission Controllerのバイパス: 多くのエンジニアが陥る罠だが、Webhookの通信経路(TLS/SSL)が脆弱であれば、MITM攻撃によって検証をスルーされる。Webhook通信には厳格なCA証明書による相互認証(mTLS)を強制すること。
- メモリ挙動への介入: 署名検証はあくまで「配送」の信頼性を担保する。実行時に
ptraceを悪用したメモリダンプや、生成AIを利用したポリモーフィックなシェルコード注入に対しては、eBPFを用いたランタイムセキュリティ(Falco等)との多層防御が必須だ。
結論
署名検証は「魔法の杖」ではない。しかし、サプライチェーンの脆弱性を突く攻撃に対する、最もコストパフォーマンスの高い防壁であることは間違いない。
脆弱性スキャナに頼り切り、CVEが出るたびに右往左往する時代は終わらせろ。信頼の起点を自ら制御し、署名のないコードを「異物」としてクラスタから排除する。この冷徹なまでのエンジニアリングこそが、我々が守るべきインフラの最後の砦となるはずだ。
準備はいいか。次はクラスタのランタイム・インテグリティを、eBPFの深淵から解き明かしていくとしよう。
コメント