こんにちは!インフラやクラウドのセキュリティの世界へようこそ。
新人のIT担当者さんや、「セキュリティってなんだか難しそう……」と感じている一般開発者さんのために、今日から実践できるリアルなセキュリティの知見をお伝えしていきますね。
今回は、現代のクラウド開発で絶対に避けて通れない「コンテナイメージの署名検証とAdmission Controllerによる強制」について、身近な例えを交えながら一歩ずつ紐解いていきましょう!
—
1. 家の鍵と宅配便に例える「コンテナの安全」
まずは、私たちが普段暮らしている現実世界で考えてみましょう。
あなたはネット通販で欲しかった最新のガジェットを注文しました。数日後、ダンボール箱が自宅に届きますよね。この時、あなたはどうやってその荷物を受け取りますか?
きっと、見知らぬ怪しい人が道端で手渡してきたダンボールは受け取らないはずです。信頼できる大手宅配業者の制服を着た人が、きちんとした伝票を持ってきて、インターホンを鳴らしてくれたからこそ、安心して受け取りますよね。
実は、私たちがクラウド上で動かす「コンテナ(Dockerなど)」の世界もこれとまったく同じなんです。
開発者がインターネット上からダウンロードしてサーバーで動かす「コンテナイメージ」は、いわば「見知らぬ誰かが作ったダンボール箱」です。もし、そのダンボール箱の中に、悪意あるハッカーが仕込んだ「危険なウイルス(マルウェア)」が入っていたらどうなるでしょうか?
箱を開けた瞬間、サーバー全体が乗っ取られてしまう――これが、昨今猛威を振るう「サプライチェーン攻撃」の恐ろしい手口です。
「でも、公式の場所からダウンロードしているから大丈夫だよ」と思いましたよね?
残念ながら、公式の倉庫(レジストリ)であっても、巧妙になりすました偽物が置かれる事件が後を絶ちません。だからこそ、「本当に信頼できる人が作ったものか?」を証明する身分証(署名)と、「怪しい荷物は絶対に家に入れない番人(Admission Controller)」が必要になるのです。
—
2. 攻撃者はどこを狙う?コンテナサプライチェーンの盲点
攻撃者は、私たちが開発で使う便利でオープンな環境の「隙」を巧みに突いてきます。
例えば、開発チームの誰かが「便利なツールだから」と、ネットの海で見つけた名もなきコンテナイメージを引っ張ってきたとします。攻撃者はそのイメージの裏で、こっそりパスワードを盗み出すプログラムを忍ばせておくのです。
従来のセキュリティ対策では、「ウイルス対策ソフトでスキャンするから大丈夫」と考えがちでしたが、巧妙に作られた未知の脅威はスキャンをすり抜けてしまいます。
だからこそ、「中身を疑う」のではなく、「送り主が誰であるかを暗号技術でガチガチに証明する」アプローチが必要不可欠になります。それが、今回学ぶ「Cosign」を使ったイメージ署名です。
—
3. Cosignでコンテナに「封印(署名)」をしよう
「署名」といっても、紙にハンコを押すわけではありません。現代のセキュリティでは、秘密の鍵(プライベートキー)を使って、コンテナイメージに改ざん不可能なデジタルスタンプを押します。
まずは、手元の環境で実際にCosignを使ってイメージに署名する流れを見てみましょう。一歩ずつ進めれば難しくありませんよ!
ステップ1:鍵のペアを作る
まずは、あなた(またはあなたの組織)だけが持つ秘密の鍵と、みんなに公開する公開鍵のペアを作ります。
# 秘密の鍵 (cosign.key) と 公開鍵 (cosign.pub) を生成します
# パスワード(パスフレーズ)の入力を求められるので、安全なものを設定してくださいね
cosign generate-key-pair
ステップ2:コンテナイメージに署名する
次に、ビルドした自分たちのコンテナイメージに対して、先ほど作った秘密の鍵で署名を付与します。
# 例として、自分たちのレジストリにあるイメージに署名をつけるコマンドです
cosign sign --key cosign.key ghcr.io/your-org/your-app:v1.0.0
これで、このコンテナイメージには「私たちが責任を持って作りました!」という強固なデジタル署名が刻まれました。もし後から誰かがイメージのコードを1行でも書き換えると、この署名は一瞬で無効化されます。すごい仕組みですよね。
—
4. 番人を置こう:KubernetesのAdmission Controller
さて、いくら私たちがコンテナに立派な署名をつけても、サーバー(Kubernetesなど)が「あ、署名?そんなの見てなかった!」と、どんな荷物でもホイホイ受け入れてしまっては意味がありません。
ここで登場するのが、Kubernetesの門番である「Admission Controller(アドミッションコントローラー)」です。
これは、新しいコンテナをサーバーで動かそうとする「その瞬間」に、門番が割って入ってこう尋ねる仕組みです。
- 「ちょっと待った!その荷物(コンテナイメージ)、ちゃんとした署名はついているかい?」
- 「え? ついてない? じゃあ、このサーバーの中には一歩も入れさせないよ!」
この門番役として非常に強力なのが、オープンソースのポリシーエンジンである「Kyverno」や「OPA/Gatekeeper」です。
実際に、Kyvernoを使って「署名のないイメージのデプロイを問答無用で拒否する」設定ファイル(ポリシー)を見てみましょう。
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: check-image-signature
spec:
validationFailureAction: Enforce # 違反した場合はデプロイを強制的にブロックする設定です
rules:
- name: verify-cosign-signature
match:
any:
- resources:
kinds:
- Pod
verifyImages:
- imageReferences:
- "ghcr.io/your-org/*" # 対象とするコンテナイメージのパターン
attestors:
- entries:
- keys:
publicKeys: |
-----BEGIN PUBLIC KEY-----
# 先ほど生成した公開鍵(cosign.pub)の中身をここに貼り付けます
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA...
-----END PUBLIC KEY-----
この設定をKubernetesクラスターに適用しておくだけで、仮に開発者のうっかりミスや、万が一外部から侵入された攻撃者が「不正なコンテナ」をデプロイしようとしても、門番(Kyverno)がガッチリとガードしてデプロイを即座にハネ返してくれます。
—
5. 現場のエンジニアから最後にひとこと
「署名なんてめんどくさそう……」「設定ファイルが増えて大変だな」と感じたかもしれません。最初は誰しもそう思います。
けれど、セキュリティの本質は「完璧を目指すこと」ではなく、「攻撃者のコストを圧倒的に引き上げ、標的から外させること」です。コンテナの署名とAdmission Controllerによる強制は、サプライチェーン攻撃という現代の厄介な泥棒に対する「頑丈な二重ロック」のようなものです。
最初は小さな検証環境から、一歩ずつ。ぜひあなたのプロジェクトでも、この確かな安心感を導入してみてくださいね。
あなたの手掛けるシステムが、今日も安全で素晴らしいものでありますように!
コメント