暗号化EBSを使うEC2が起動しない ── KMSキーの状態と権限を切り分ける

目次

概要

暗号化したEBSボリュームでEC2インスタンスを動かしていると、ある日「起動できない」という事象に出会うことがあります。インスタンスの状態は stopped に戻り、「状態遷移の理由」には Server.InternalError とだけ出ます。アプリケーションのログにも、EC2のシステムログにも手がかりはありません。手がかりは同じ画面の「状態遷移メッセージ」にあり、ここに Client.InvalidKMSKey: Invalid KMS key provided と表示されます。

このとき疑うのはEC2側ではなくKMSキーです。暗号化ボリュームをインスタンスにアタッチするには、EBSがそのキーでデータキーを復号できる必要があります。キーが無効化されている、削除待ちになっている、あるいは必要な権限が外れていると、復号に失敗して起動そのものが止まります。

この記事では、EBSが裏でKMSをどう呼んでいるのかを整理したうえで、キーを無効化して実際に起動が失敗する状態を作り、そこから切り分けて復旧させます。

暗号化EBSを持つEC2の起動 ── 起動のたびに Decrypt が呼ばれる
暗号化EBSを持つEC2の起動 ── 起動のたびに Decrypt が呼ばれる
クラウドおさる

キーを無効化してEC2の起動をわざと失敗させ、どこに手がかりが出るかを確かめてから復旧させるでござる。疑う先はEC2ではなくKMSキー、その切り分けの順番を手で覚えるのでござるな。

この記事のメリット

  • 暗号化EBSでEC2が起動しないときに、どこを見ればよいか判断できるようになる
  • EBSがKMSに対して呼ぶAPIと、必要な5つのアクションを説明できるようになる
  • グラントと kms:GrantIsForAWSResource 条件キーの役割を理解できる
  • キーの状態(有効・無効・削除保留中)が起動に与える影響を把握できる
  • SCS試験で暗号化ボリュームのトラブルシューティングを問う設問に答えられるようになる

執筆者とキャラクター紹介

執筆者:土肥(とひ)

株式会社ジェニュインの代表であり元エンジニア。これまでオンプレミスと AWS 環境のインフラ業務を担当。AWS 認定資格の学習で得た知識を、ハンズオンとともに解説するのが得意。直近では新人の教育も行っており、これから技術を学ぶ方が納得できる解説を心がけています。基礎編・Cloud Practitioner の記事では、解説役としても登場します。

土肥

クラウドおさる

クラウドおさる

はじめましてでござる。弊猿はクラウドおさる。IT インフラが異常に発達した猿山から、雲に乗って地上の AWS を学びに降りてきたのでござる。

クラウドおさる

基礎編や Cloud Practitioner の記事では、とひさんに素朴な疑問をぶつける役でござるな。Security - Specialty などの記事では、要所でワンポイントや注意点をひとこと添えるでござる。

クラウドおさる

猿山にもデータセンターや監視当番があって、地上で起きることはだいたい猿山にも同じ仕組みがあるのでござる。例え話がつい猿山に寄るのは、弊猿の癖でござる。

技術解説

EBSはKMSをどう使っているか

暗号化EBSボリュームは、KMSキーで直接暗号化されているわけではありません。ボリュームごとに一意のデータキーがあり、それをKMSキーで暗号化した状態でボリュームと一緒に保管しています。エンベロープ暗号化です。

タイミングEBSが呼ぶAPI何が起きるか
ボリュームの作成時GenerateDataKeyWithoutPlaintext指定したKMSキーで暗号化されたデータキーを発行してもらい、ボリュームと一緒に保存する
インスタンスへのアタッチ時(=起動時)Decrypt保存してある暗号化データキーを復号し、ボリュームの読み書きに使う

つまり起動のたびに Decrypt が呼ばれます。作成できたボリュームが、あとになって使えなくなるのはこのためです。

リクエストには暗号化コンテキストが付き、どのボリューム・スナップショットに対する操作かが示されます。

"encryptionContext": {
  "aws:ebs:id": "vol-0cfb133e847d28be9"
}

CloudTrailでKMSのイベントを見るときは、この aws:ebs:id を手がかりに「どのボリュームの復号が失敗したか」を特定できます。

なお、Amazon EBSは対称KMSキーのみをサポートします。非対称キーでEBSボリュームを暗号化することはできません。

クラウドおさる

暗号化EBSは、作成のときだけでなく起動のたびに Decrypt を呼ぶのでござる。猿山のバナナ倉庫も、建てた日に鍵が回っても毎朝その鍵で開けるので、長老会が鍵を取り上げれば翌朝はもう開かぬでござるな。

起動が失敗する3つのポイント

原因症状確認するところ
KMSキーが有効でない(無効化・削除保留中)起動が失敗し、状態遷移メッセージが Client.InvalidKMSKey になるKMSコンソールのキーのステータス
キーポリシー・IAMポリシーで必要なアクションが許可されていない同上キーポリシーの Statement、呼び出し元のIAMポリシー
グラントが失効している・作成できない同上kms:CreateGrant の許可、キーのグラント一覧

公式ドキュメントは「KMSキーを使用できない場合(キーステータスが Enabled ではない場合など)、ボリュームの作成またはボリュームのアタッチメントは失敗します」と明記しています。まずキーのステータスを見るのが切り分けの第一歩です。

必要なKMSのアクセス許可

暗号化EBSボリュームを使うには、次の権限が必要です。

アクション用途
kms:CreateGrantKMSキーに対するグラント(権限の委譲)を作成する
kms:Decrypt暗号化されたデータキーを復号する
kms:DescribeKeyKMSキーの詳細を確認する
kms:GenerateDataKeyWithoutPlaintextボリューム用のデータキーを生成する
kms:ReEncrypt別のKMSキーで再暗号化する(スナップショットのコピーなど)

kms:GenerateDataKeyWithoutPlaintext という名前になっているのは、EBSが平文のデータキーを受け取る必要がないためです。平文のデータキーはEBSのインフラ側で扱われ、呼び出し元には返りません。

グラントは絞って許可する

グラントは、AWSサービスがユーザーに代わってKMSキーを使えるようにする仕組みです。EC2はインスタンスの起動時にグラントを作り、そのインスタンスが動いている間ボリュームを復号できるようにします。

kms:CreateGrant を無条件に許可すると、任意のプリンシパルにキーの使用権を配れてしまいます。最小権限の原則に従い、AWSサービスが代理で作る場合だけに絞ります。

{
  "Effect": "Allow",
  "Action": "kms:CreateGrant",
  "Resource": "arn:aws:kms:ap-northeast-1:111122223333:key/<キーID>",
  "Condition": {
    "Bool": { "kms:GrantIsForAWSResource": true }
  }
}
グラント ── EC2 がユーザーに代わってキーの使用権を受け取る
グラント ── EC2 がユーザーに代わってキーの使用権を受け取る

押さえておく制約

制約内容
暗号化の解除暗号化されたボリューム・スナップショットから暗号化を外すことはできない
KMSキーの変更既存のボリューム・スナップショットに関連付けられたKMSキーは変更できない
キーの種類対称KMSキーのみ。非対称キーは使えない

キーを変えたい場合は、スナップショットを別のキーで再暗号化してコピーし、そこからボリュームを作り直します。運用としては「キーを消す前に、そのキーで暗号化されたボリュームが無いか確認する」が鉄則です。

フリーランス案件
クラウドおさる
クラウドキャリアフリーランス

AWS の実務経験があるなら、単価を上げにいく

AWS に特化したフリーランスエージェントです。以下は取り扱い案件の一例です。設計・SRE・セキュリティ・生成 AI の領域で、専門を掛け合わせるほど単価が上がります。

横にスクロールできます。掲載時点の情報のため、募集が終了している場合があります。条件の近い案件をご紹介しますので、お気軽にご相談ください。

実践

ハンズオンガイド8 ステップ画面 8 枚

コンソールの横に開いて、チェックしながら進めましょう。

ガイドを開く

別タブで開きます。チェックはこのブラウザに保存されます。

カスタマー管理キーで暗号化したルートボリュームを持つEC2インスタンスを作り、キーを無効化すると起動が失敗すること、キーを戻すと復旧することを確認します。

前提条件

  • リージョン: ap-northeast-1(東京)
  • EC2・KMSの操作権限を持つIAMユーザーまたはロールでコンソールにログイン済みであること
  • VPCとサブネットが1つ以上あること。インスタンスは通信しないので、インターネットゲートウェイもパブリックIPも不要です(既定のVPCが削除されているアカウントでは、検証用のVPCとサブネットを1つ作ってから始めます)

このハンズオンで作成するリソースは以下のとおりです。

リソース種別リソース名用途
KMSカスタマー管理キーebs-lab-keyルートボリュームの暗号化用
EC2インスタンスebs-kms-lab-instance起動失敗と復旧の確認用(t3.micro)

KMSのカスタマー管理キーは1本あたり月 1 USD の課金対象です。インスタンスは検証中だけ起動し、確認後に終了します。

手順1: カスタマー管理キーを作成する

AWSマネジメントコンソールにログインし、リージョンが ap-northeast-1(東京)であることを確認します。

上部の検索バーに KMS と入力し、「Key Management Service」を選択します。

左側ナビゲーションの「カスタマー管理型のキー」から「キーの作成」をクリックします。キーの作成は6つのステップに分かれています。

  • ステップ1「キーを設定」: キーのタイプ 対称、キーの使用法 暗号化および復号化 が既定で選ばれていることを確認して「次へ」
  • ステップ2「ラベルを追加」: エイリアスに ebs-lab-key を入力して「次へ」
  • ステップ3「キーの管理アクセス許可を定義」/ ステップ4「キーの使用法アクセス許可を定義」: 自分がログインしているIAMユーザーまたはロールにチェックを入れて「次へ」
  • ステップ5「キーポリシーを編集」: 生成されたポリシーをそのまま使うので変更しません
  • ステップ6「確認」: 内容を確認して「完了」
作成された ebs-lab-key の詳細画面(ステータスが有効になっている状態)
作成された ebs-lab-key の詳細画面(ステータスが有効になっている状態)

手順2: 暗号化ルートボリュームでインスタンスを起動する

EC2コンソールの「インスタンス」から「インスタンスを起動」をクリックします。

以下を設定します。

  • 名前: ebs-kms-lab-instance
  • AMI: Amazon Linux 2023
  • インスタンスタイプ: t3.micro
  • キーペア: 「キーペアなしで続行」
  • ネットワーク設定: 既定のVPC・サブネットのまま

「ストレージ (ボリューム)」のセクションで表示を「シンプル」から「アドバンスト」に切り替え、「ボリューム 1 (AMI ルート)」を展開して以下を設定します。

  • 暗号化済み: 暗号化済み
  • KMS キー: ebs-lab-key
ストレージ設定でルートボリュームの暗号化にカスタマー管理キーを指定した画面
ストレージ設定でルートボリュームの暗号化にカスタマー管理キーを指定した画面

「インスタンスを起動」をクリックし、インスタンスの状態が 実行中、ステータスチェックが通ることを確認します。

インスタンスが実行中になり、ステータスチェックが成功した状態
インスタンスが実行中になり、ステータスチェックが成功した状態

手順3: ボリュームがキーで暗号化されていることを確認する

左側ナビゲーションの「Elastic Block Store」→「ボリューム」を開き、作成されたルートボリュームを選択します。

「暗号化」が 暗号化済み、「KMSキーID」が手順1のキーになっていることを確認します。

ボリュームの詳細(暗号化済みでKMSキーIDが ebs-lab-key を指している状態)
ボリュームの詳細(暗号化済みでKMSキーIDが ebs-lab-key を指している状態)

手順4: インスタンスを停止してキーを無効化する

EC2コンソールでインスタンスを選択し、「インスタンスの状態」→「インスタンスを停止」で停止します。状態が 停止済み になるまで待ちます。

KMSコンソールに戻り、ebs-lab-key を選択して「キーのアクション」→「無効化」をクリックします。確認のチェックを入れて無効化します。

キーのステータスが 無効 になったことを確認します。

ebs-lab-key のステータスが無効になった状態
ebs-lab-key のステータスが無効になった状態

手順5: 起動が失敗することを確認する

EC2コンソールに戻り、インスタンスを選択して「インスタンスの状態」→「インスタンスを開始」をクリックします。

しばらくすると状態が 停止済み に戻ります。インスタンスを選択して「詳細」タブを開き、「インスタンスの詳細」にある次の2つを確認します。

項目表示される値
状態遷移の理由Server.InternalError
状態遷移メッセージClient.InvalidKMSKey: Invalid KMS key provided
起動に失敗し、状態遷移メッセージに Client.InvalidKMSKey が表示されている状態
起動に失敗し、状態遷移メッセージに Client.InvalidKMSKey が表示されている状態

「状態遷移の理由」は Server.InternalError としか言いません。KMSが原因だと分かるのは「状態遷移メッセージ」のほうで、ここに Client.InvalidKMSKey と出ます。どちらの欄にもキーIDまでは出ないので、どのキーかはボリュームの「KMS キー ID」から辿ります。

「状態遷移の理由」だけを見て Server.InternalError = AWS側の一時的な障害と判断すると、原因にたどり着けません。暗号化ボリュームを使うインスタンスが起動できないときは、必ず「状態遷移メッセージ」まで見るのが切り分けの近道です。

クラウドおさる

「状態遷移の理由」は Server.InternalError としか言わぬでござる。KMSが原因だと分かるのは「状態遷移メッセージ」の Client.InvalidKMSKey のほうで、ここまで見ないと遠回りになるでござるぞ。

手順6: キーを有効化して復旧させる

KMSコンソールで ebs-lab-key を選択し、「キーのアクション」→「有効化」をクリックします。ステータスが 有効 に戻ったことを確認します。

EC2コンソールでインスタンスを再度開始します。今度は状態が 実行中 になり、ステータスチェックが通ることを確認します。

キーを有効化したあとインスタンスが実行中に戻った状態
キーを有効化したあとインスタンスが実行中に戻った状態

キーを削除スケジュールに入れた場合(削除保留中)も同じ症状になります。こちらは削除がキャンセルできる猶予期間(7〜30日)のうちに「キー削除のキャンセル」を行えば復旧できますが、削除が完了してしまうと、そのキーで暗号化されたボリュームは二度と復号できません。

手順7: キーポリシーで必要なアクションを確認する

ebs-lab-key の「キーポリシー」タブを開き、「ポリシービューに切り替える」をクリックします。

コンソールが生成したポリシーでは、Allow use of the key のステートメントでキーの使用者に kms:Encrypt kms:Decrypt kms:ReEncrypt* kms:GenerateDataKey* kms:DescribeKey が許可されています(EBSが使う GenerateDataKeyWithoutPlaintext は kms:GenerateDataKey* に含まれます)。

その下の Allow attachment of persistent resources のステートメントでは kms:CreateGrant kms:ListGrants kms:RevokeGrant が許可され、Condition に kms:GrantIsForAWSResource: true が付いていることを確認します。

キーポリシーの内容(CreateGrant と kms:GrantIsForAWSResource の条件が確認できる状態)
キーポリシーの内容(CreateGrant と kms:GrantIsForAWSResource の条件が確認できる状態)

このうち1つでも欠けると、ボリュームの作成やアタッチが失敗します。キーの状態を確認して問題が無ければ、次はこのポリシーを見る、という順番で切り分けます。

クラウドおさる

暗号化ボリュームのインスタンスが起動しないとき、EC2側ではなくKMSキーのステータス、キーポリシー、グラントを順に疑えるかが試験の観点でござるな。kms:CreateGrant を kms:GrantIsForAWSResource で絞る話も、同じ切り分けの中で問われるのでござる。

まとめ

確認する順番見るもの症状の切り分け
1インスタンスの「状態遷移メッセージ」Client.InvalidKMSKey ならKMSが原因
2KMSキーのステータス無効 / 削除保留中 なら起動できない
3キーポリシー・IAMポリシーDecrypt GenerateDataKeyWithoutPlaintext DescribeKey CreateGrant ReEncrypt が揃っているか
4グラントkms:CreateGrant が許可されているか、グラントが失効していないか
5CloudTrailKMSのイベントを aws:ebs:id の暗号化コンテキストで追う
  • 暗号化EBSは起動のたびに Decrypt を呼ぶ。作成できたボリュームがあとで使えなくなるのはこのため
  • 「状態遷移の理由」は Server.InternalError としか出ない。KMS由来だと分かるのは「状態遷移メッセージ」の Client.InvalidKMSKey
  • EBSが使うのは GenerateDataKeyWithoutPlaintext と Decrypt。平文のデータキーは呼び出し元に返らない
  • kms:CreateGrant は kms:GrantIsForAWSResource 条件で、AWSサービスの代理作成だけに絞る
  • キーを削除すると、そのキーで暗号化されたボリュームは復号できなくなる。削除前に利用状況を確認する

参照先

フリーランス案件
クラウドおさる
クラウドキャリアフリーランス

AWS の実務経験があるなら、単価を上げにいく

AWS に特化したフリーランスエージェントです。以下は取り扱い案件の一例です。設計・SRE・セキュリティ・生成 AI の領域で、専門を掛け合わせるほど単価が上がります。

横にスクロールできます。掲載時点の情報のため、募集が終了している場合があります。条件の近い案件をご紹介しますので、お気軽にご相談ください。

この記事が気に入ったら
フォローしてね!

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

この記事を書いた人

株式会社ジェニュイン(https://genuine-pt.jp)の代表取締役.

2018年〜インフラエンジニアとしてキャリアをスタートし、オンプレミスのネットワーク・サーバ環境で3年半、クラウド環境で4年半の8年間エンジニアとして従事。
2021年に佐藤氏の創業した株式会社Luxyを引き継ぎ、代表に就任。
その後アガルートグループ内の株式会社ジェニュインと合併。
合併後同社代表に就任。

目次