プログラマでありたい

おっさんになっても、プログラマでありつづけたい

S3のマイナー機能の四天王候補の一つであるS3 オブジェクトロックの機能について

 Amazon S3の正式名称は、Amazon Simple Storage Serviceです。Simpleを辞書で紐解くと、次のような言葉が出てきます。

1. 易しい、難しくない
2. 簡素な、簡略した、シンプルな
3. 質素な、地味な、豪華でない
4. 単一の、一つだけで構成される
5. 単純な、複雑でない
6. 〔人が〕気取らない、控えめな、見えを張らない
7. 〈軽蔑的〉〔知的レベルが〕単純な、ばかな
8. 〈軽蔑的〉教養がない、無知な
9. 〔人が〕素朴な、洗練されていない
10. 〔人が〕真面目な、誠実な、うそをつかない
11. 普通の、いつもの、ありふれた
12. 基本の、初歩の
13. ささいな、重要でない、つまらない
14. 《植物》単一の◆【対】compound
15. 《化学》〔化合物が〕単純な
16. 《言語学》〔文構造が〕単純な

引用元 英辞郎 on the Web

 AWSの認定試験を受けていると、普段あまり使わないような機能がどんどん出てきて、Simpleってなんだろうと哲学的な気分になります。昔、大阪でインド人がやっているカレー屋で辛そうに食べていたら、インド人に「辛くない〜、辛くな〜い」と励まされた事も思い出されます。シンプルなのかシンプルじゃないのか、辛いのか辛くないかは、人それぞれということですね。

 前置きが長くなりましたが、今回のテーマは、数あるS3の機能の中で一般的な機能要件ではまず使うことがないオブジェクトロックの機能についてです。

S3のオブジェクトロックの概要とそのニーズ

 S3のオブジェクトロックは、雑な言い方をすると指定されていると何があっても変更したり消せなくする機能です。モードによりますが、管理者であっても消せなくなります。何故、そのような機能が求められるのかというと、コンプライアンス対応です。業種・業界によっては、一定期間データを保持し続けないといけないとルールで定められているものがあります。ルールの多くは、データの完全性を求めていて、期間中のデータ変更や削除を防がないといけません。そんな時に、どうしたらいいでしょうか?
 ぱっと思いつくのは、データにアクセスできる場所と人を限定することです。しかし、その場合は期間中のそのデータへのアクセス履歴とともに、データにアクセスできる人の行動履歴を残し続けないといけません。また、履歴データ自体も改ざんされていないことを証明することが必要です。結構、大変ですよね。そこで登場するのがS3のオブジェクトロックの機能です。これはAWSによって、期間中は一切変更・削除できないということを保証する機能です。利用者は、対象データが確かにその設定がされていることだけ確認するだけで良くなります。格段に楽になりますよね。

S3のオブジェクトロックの機能

 S3 オブジェクトロックは、リテンションモードリーガルホールドの2つを利用できます。どちらか一方を利用することも、両方を利用することも可能です。まずここからして、オブジェクトロックが解らなくなります。順を追って説明します。

リテンションモードの2つのモード

 リテンションとは、保持とか維持するという意味です。オブジェクトを保護しますよという機能ですね。リテンションモードは2つのモードを提供しています。

  • ガバナンスモード
  • コンプライアンスモード

 ガバナンスモードは、特別なアクセス許可を持つユーザー以外は、オブジェクトのバージョンの上書きや削除、ロック設定を変更することはできません。つまり、限定したユーザーだけは変更・削除できるということです。続いて、コンプライアンスモードは、AWSアカウントのルートユーザーを含めて、指定期間中は対象のオブジェクトのバージョンを上書きまたは削除、ロック設定の変更をすることはできません。結構強烈な機能ですね。

保持期間

 リテンションモードには、保持期間が設定されます。これはバケット単位で○○日までというような設定ではなく、オブジェクト単位に何日保持するかというような指定です。例えば、ルールで1年間保持しないといけないのであれば、365日と指定します。

リーガルホールド

 オブジェクトロックは、リテンションモードとは別にリーガルホールドというオブジェクトを保護する仕組みがあります。リテンションモードとの違いは、保持期間がないという点です。削除するためには、リーガルホールドの適用を解除する必要があり、s3:PutObjectLegalHold を持つユーザーがその設定をできます。つまりS3のFullAccessをもっていると、リーガルホールド対象のオブジェクトは直接は消せないけど、ひと手間掛けると消せるということになります。リテンションモードよりは少し弱い保護となります。

リテンションモードとリーガルホールドの組み合わせ

 さて、ここからが地獄です。リテンションモードとリーガルホールドは何故か排他の設定ではなく組み合わせることができます。設定のパターンとしては、以下のパターンが可能です。

  • オブジェクトロックなし(デフォルトの状態)
  • リテンションモードのガバナンスモード
  • リテンションモードのコンプライアンスモード
  • リーガルホールド
  • リーガルホールドかつリテンションモードのガバナンスモード
  • リーガルホールドかつリテンションモードのコンプライアンスモード

 AWSの認定試験でここまで問われることは無いと信じています。ただ、オブジェクトロック機能がリテンションモードとリーガルホールドの2つの機能があることと、それの違いを理解していないと混乱するでしょう。事実、試験のたびにどうだったかなぁと頭を悩まします。

オブジェクトロックを利用する方法

 オブジェクトロックの概要はだいたい理解できたかと思います。それでは、実際にどう設定すればいいのでしょうか?たぶんこの記事を読んでいる人の9割8分3厘は実際に設定することがないと思いますので、詳細は省きます。下記の2点が必要という事を覚えておいてください。

  • バケット設定でオブジェクトロックの有効化
  • オブジェクト単位で保持期間やリーガルホールドの設定

 バケット設定でオブジェクトロックを有効化して、その後にオブジェクト単位で設定していくという流れです。注意点としては、バケット設定で有効化するには新規作成のバケットのみで指定できるという点です。既存のバケットに対しては、サポートにお願いすると有効化してくれそうな雰囲気ですが、試したことはないです。またオブジェクトロックを利用する場合は、バージョニング設定が必須となります。

f:id:dkfj:20201019015129p:plain

デフォルトの保持設定

 先程、バケットでオブジェクトロックを有効化されても、オブジェクト単位で指定する必要があると説明しました。いやいや、それは面倒くさいという人のために、デフォルトの保持期間が設定可能です。なお、画面コンソールから指定できるのは、リテンションモードのみです。

f:id:dkfj:20201019022006p:plain

オブジェクトロックされたファイルの消し方

 最後にオブジェクトロックされたファイルの消し方をまとめておきましょう

  • リテンションモードのガバナンスモード

  保持期間明けまで待ってから削除
  特別なアクセス許可を持つユーザーでガバナンスモードを解除してからオブジェクトを削除

  • リテンションモードのコンプライアンスモード

  保持期間明けまで待ってから削除

  • リーガルホールド

  IAMで権限を持つユーザーでリーガルホールドを解除してからオブジェクトを削除

 リテンションモードとリーガルホールドは併用できるので、その場合はそれぞれの条件を満たす必要があります。こうやってみると、リテンションモードのコンプライアンスモードの制約の大きさが解りますね。退職前にコンプライアンスモードの設定で保持期間をこっそり10年とか指定するのは、テロに等しいのでやめましょうね。

まとめ

 S3のマイナー機能の四天王候補の一つであるオブジェクトロック機能です。機能を知ると、よく考えられているなぁと感心します。ただ、ここまで求められる要件がでてくるのは、ごく一部の業界のみで大半の人は使わずに終わるのではないかなぁと思います。そんな業界に飛び込んだあなたは、ラッキーと思ってドヤ顔で使いましょう。私は、残りの四天王の3つを探す旅にでることとします


AWSのロードバランサ、CLB, ALB, NLBの機能差まとめ

いい加減に12冠にならないとなぁということで、スキマ時間にちょっとづつ勉強しています。隙間時間だと、前回勉強したところの続きに戻るまでに隙間時間が過ぎてしまう辛みがありますが、皆さんいかがお過ごしでしょうか?

 私にとっての最鬼門のAWS認定アドバンスドネットワーク専門知識の試験範囲の確認のために公式トレーニングの試験対策を見ています。AWSの試験で一番わからないのが、どのサービスが対象範囲なのかという点だと思います。これを受けることにより、ここを勉強すればよいのだというのがはっきりするのでお勧めです。
Exam Readiness: AWS Certified Advanced Networking - Specialty (Digital)

 その中で、AWSのロードバランサであるELB(CLB, ALB, NLB)のまとめ表があったので紹介しておきます。

3種類のELBの違いを1枚の図でまとめる

 みなさん、3種類のELB(CLB, ALB, NLB)の違いを説明できますでしょうか?CLBはTCPとHTTP,HTTPSが使えて、ALBはHTTP,HTTPSだけでNLBはとか頭の中を駆け巡ると思います。その辺を一枚の表にしておけばもう悩みません。常々作ろうと思いつつ、既にまとめてあったので紹介させて貰います。どん!!

f:id:dkfj:20201013115235p:plain

※2020年10月13日 11:55追記 
優しいマサカリが飛んできたので、図を修正しています。NLBも2019年1月よりTLS Terminationが出来るようになっています。Container Supportについてはもう少し補足が必要なので、Container Native Supportに変更の上で、下に補足を書いています。

 図の項目名で、一部分かりづらいものがあるので補足しておきます。

Protcol

 どのプロトコルを受け付けるかですね。NLBはレイヤー4のサービスなのでTCPのみです。ALBはレイヤー7でHTTP,HTTPSの他にHTTP/2も受け付けます。CLBはそういえばSSLも受け付けましたね。UDPについては言及なしの世界線です。

SSL offloading

 SSLオフロードは、TLSまたはSSLの通信を紐解いて後ろに平文の通信で流すという機能です。現実的にはSSLはもう使わないのでTLS offloadingというのが正しいのでしょうね。CLBとALBがもともと対応していましたが、NLBも対応しました。つまりこの観点では、どれを使っても大丈夫。これがないと、個々のWebサーバーに直接SSLの証明書をそれぞれ入れないといけないので不便です。試験問題だと逆に、Webサーバからアプリケーションサーバ間の通信も暗号化したままにしたいというのがあるので、頭のひねりどころですよ

IP as target

 これは言葉にすると解りづらいのですが、ターゲットグループにIPを指定できるかという事です。一般的にはインスタンスを指定すると思いますが、ALBとNLBはローカルIPアドレスを指定できます。これ使うと、VPNやダイレクトコネクト先の(嬉しいかどうかしりませんが)オンプレサーバを指定するといったことも可能です。オンプレに対して使うかどうかは別として、設計の幅が広がるのは確かです。リバースプロキシ立ててたけどっていうのを、NLBやALBで代替できるケースも多数あるでしょうね。

Path-based routhing, host-base routing

パスベースのルーティングというのは、example.com/imageやexample.com/contentsなどドメインの後の/以下の部分を判断して振り分けるという機能です。ホストベースのルーティングは、app.example.comやimage.example.comといったようにサブドメイン部分を判断して振り分けるということです。これが出来るのは、ALBだけです。そもそもCLBはELBとターゲットは1対1の紐付けしかできません。ALBは、1対多の紐付けができます。便利ですねぇ~。その気になれば、複数のシステムでALBを共有してコスト削減できますが、システム同士が密結合になるので止めた方がよいですね。

Static IP

 パスベース・ホストベースのルーティングができるのがALBの売りですが、このStatic IPの機能がNLBの売りの一つです。このStatic IPはロードバランサーに固定のIPアドレスを設定できます。ALBやCLBはURLベースでしたが、NLBは固定のIPを指定できます。これが利点になることが多いです。IPを固定したいという用途がある時に、前にNLBを置くことにより解決することができます。

WebSockets

 WebSocketsはシンプルに対応しているかどうかですね。ALBとNLBが対応しています。

Container Support

 Container Support。これは、ECS等に対応している「仮想マシンでのホップなしにコンテナネイティブなルーティングができる」かという点です。細かくケース別にわけると長くなるので、別途まとめようと思いますが、ALBとNLBが対応しています。単純なルーティングだけであればCLBでも一応使えます。

まとめ

 AWSはCLB, ALB ,NLBと3種類もロードバランサがあって解らんよという方もいると思います。まずは、この表で頭の中を整理してみるのも良いのではないでしょうか。ただ実質CLBはリタイアしていく運命のサービスですから、ALBとNLBだけ覚えれば充分です。WebサイトのロードバランスにALB、それ以外の用途はNLBとなることが多いです。原則のALB覚えて、それに対応できないケースを解決しているNLBになります。NLBの構成図を見ると、なるほどなぁとなることが多いです。一度、目を通してみると良いですよ

AWSのS3のバージョニングとライフサイクルの組み合わせについて

 S3を使っていて、初見でイマイチ腑に落ちないのが、バージョニングです。このバージョニング機能は、その名の通りオブジェクトの履歴管理を行いオブジェクトが更新されるたびに新たな履歴として追加していきます。これが腑に落ちないとなるのは、何ででしょうか?順番に説明していきます。

f:id:dkfj:20201005080025p:plain

バージョニングとライフサイクルの機能解説

 まずはS3のバージョニングとライフサイクルの機能の概要を見ていきましょう。どちらも考え方としては、非常にシンプルです。

S3のバージョニングの機能

 S3のバージョニングを有効にすると、オブジェクトの更新履歴を保持します。保存期間・世代数はバージョニング機能で指定できないので、永遠に保持し続けます。まず、ここが最初の?となるポイントです。保存期間・世代数の指定方法を無しに、どうやって制限するのと思うのではないでしょうか?AWSは、そこをライフサイクルという別の機能でカバーしています。

S3のライフサイクル機能

 S3のライフサイクルを使うと、ルールに従ってストレージクラスの変更とオブジェクトの削除ができます。また、対象は「現行バージョン」と「以前のバージョン」をそれぞれ指定可能です。ここで、「以前のバージョン」を指定することによりバージョニングを有効にした場合のオブジェクトの管理ができます。バージョニング設定はオン・オフしかできなくて、過去バージョンを管理するのがライフサイクルという別の機能というのがAWSらしい設計思想です。
 では、実際にライフサイクルの画面をみて確認してみましょう。ファイルの削除は「有効期限」の設定画面で失効の設定を行うことによりできます。バージョニングによる過去の履歴ファイルを消したい場合は、「以前のバージョン」をチェックの上で、○○日以前のオブジェクトを消すか設定します。

f:id:dkfj:20201005090950p:plain

 この時点で、また疑問が出てくると思います。バージョニングとライフサイクルの組み合わせで、例えば何世代残すという設定はできないのでしょうか?答えとしては、S3の機能だけではできません。S3のバージョニング機能とライフサイクルのファイル削除機能でできるのは、過去の更新履歴を残し続けること、一定期間が過ぎたオブジェクトを消すことの、シンプルな2点のみです。

f:id:dkfj:20201007132938p:plain

ユースケース別にS3のバージョニング機能の適合性を考える

 S3のバージョニング機能とライフサイクル機能を抑えたうえで、じゃぁどういったパターンで使うのかという話になります。よく聞かれるケースを3つほど紹介してみます。

ケース1 Gitのようなタグやブランチで管理したい

 無理!!

素直にGit系のサービスを使ってください。AWSだったらCodeCommit

ケース2 バケット内の全てのファイルを、1世代前のオブジェクトに戻したい

 出来るけど、たぶんやりたい事と違う動きになる

スクリプトを組んで、全部のオブジェクトを1世代前に戻すことは可能です。でも、S3の世代の概念は、オブジェクトごとです。そのため1世代前のファイルが3日前に更新されたものもあれば、1年前ということもありえます。そんな状態で1世代前に戻しても意味がないです。

ケース3 バケット内の全てのファイルを、特定日付のオブジェクトに戻したい

 出来なくはないけど、自分で実装が必要

オブジェクトごとに履歴があって日付の情報もあるので、一つづつのオブジェクトに対して調べてバージョン指定で戻すということで実現ができます。ただし、対象ファイルが多いと手作業で出来るものではないので、何らかのプログラムが必要になります。何が事があってからでは厳しいので、そういったことが必要であれば事前に作って検証しておきましょう。

まとめ

 S3のバージョニングとライフサイクルの話でした。AWSらしくそれぞれの機能はシンプルです。その特性を使ってどうするかというは、料理人の腕次第です。個人的には、バックアップと特定日での戻しに関して言うと、S3と連携する専用のバックアップソフトを使うことをお勧めです。また、静的Webサイトに多いリリース前に戻したいという要件は、複数のバケットを使ったBlue/Greenデプロイを使うのがいいんじゃないかなと思っています。現場からは以上です。

AdministratorAccess権限を持ったIAMユーザーでも閲覧できないS3バケットの消し方

 AWSのS3のマネジメントコンソールを見ていると、アクセスタイプで絞り込むことができることに気が付きます。絞り込みの条件として、「公開」や「オブジェクトは公開可能」など5種類あり、その中の一つに「エラー」というものがあります。今日は、このエラーというバケットが何者なのかというのと、それを無理やり消すための豆知識をお伝えします。

エラーが表示されるS3バケットは何者なのか?

 まずこのエラーと表示されるS3バケットが何者なのかという話からです。これは、S3のバケット一覧・詳細を表示しようとしているIAMユーザーもしくはIAMロールの権限とバケットポリシーの組み合わせで表示する権限がない場合に発生します。バケットポリシーも考慮するので、たとえ制限のないAdministratorAccessの権限を持っている利用者でも発生する場合があります。

 ちょっとイメージが付きにくいと思うので、具体的な例で紹介します。
手元にあった表示できないS3のバケットです。
f:id:dkfj:20201001001236p:plain


 バケットを選択の上で、概要を見ようにもAccessDenyになっています。
f:id:dkfj:20201001001345p:plain

 このバケットのバケットポリシーがどうなっているかを見てみましょう。
特定のVPCエンドポイント経由からのアクセス以外はすべて拒否するようにしています。

{
    "Version": "2012-10-17",
    "Id": "Policy1415115909152",
    "Statement": [
        {
            "Sid": "Access-to-specific-VPCE-only",
            "Effect": "Deny",
            "Principal": "*",
            "Action": "s3:*",
            "Resource": [
                "arn:aws:s3:::tmp-test1234/*",
                "arn:aws:s3:::tmp-test1234"
            ],
            "Condition": {
                "StringNotEquals": {
                    "aws:sourceVpce": "vpce-xxxxxxxx"
                }
            }
        }
    ]
}

 極めて機密性が高いデータや個人情報を含むものについては、IAMのアクセス権のコントロールのみならずバケット側でも制御することは必須となります。その際の選択肢として、そのデータを活用するシステムが格納されている特定のVPCからのみ制御はよくあるんじゃないでしょうか。

 そして、ここからが本題です。こういった制御はVPCエンドポイントのID等を指定します。そのエンドポイントが消してしまったり、指定の仕方がを間違えた場合はどうなるのでしょうか?答えは、誰も見えない消せないバケットの誕生です。ということで、そうならないように気をつけましょう!!

AdministratorAccess権限を持ったユーザーでも消せないバケットの消し方

 気をつけましょうで終われれば、世の中システム障害や謝罪会見は発生しません。気をつけても現実には起こりうるので、その時の対処法です。AdministratorAccess権限を持ってしても消せないのは、バケットポリシーによって制限されているからです。解決策としては、そのバケットポリシーを消せばいいのです。ということで、AdministratorAccess権限を持ったIAMユーザーで、バケットポリシーを表示してみましょう。

f:id:dkfj:20201001002202p:plain

 はい。無慈悲にも何も表示されませんし、保存・削除ボタンも押せません。では、どうしたらいいのか?実は、ルートユーザーであれば、どんな状態でもバケットポリシーの編集だけは出来るのです。

f:id:dkfj:20201001002441p:plain

 ということで解決策としては、ルートユーザーでバケットポリシーを削除するです。なお、ルートユーザーでもバケットポリシー以外の部分はすべてAccess Denyのエラーがでて、表示することができません。

 その他の解決策としては、AWSのサポートに問い合わせてみるというのもあるかと思います。過去、どうやったのか忘れたのですが、どうやっても消せないバケットが出来たこともあったような気がします。その時にサポートに聞いた記憶があるので。(遠い昔の話で、全く覚えていないですが)

まとめ

 結論としては、シンプルです。AdministratorAccess権限を持ったIAMユーザーでも消せないS3バケットを作ってしまったら、ルートユーザーでバケットポリシーを消しましょう。ちゃんちゃん

AWSのEC2 インスタンスメタデータサービスのv1(IMDSv1) とv2 (IMDSv2) の違いと効果

 SecurityHubにIMDSv2にしろよと警告が出るようになった今日この頃です。そこで、そもそもIMDSv2って何という疑問があるので、簡単に解説してみます。IMDSv2は、インスタンスメタデータサービス Version 2です。iPhone 3Gの前は無印のiPhone(初代)ですが、version 2ということはversion 1があります。v2 (IMDSv2) が出てきた経緯と、その動作の違い等についての豆知識です。

インスタンスメタデータとは?

 インスタンスメタデータとはインスタンスに関する情報(データ)で、実行中のインスタンスからcURLなどのツールからリンクローカルアドレス(http://169.254.169.254)を呼び出すことで取得できます。取得できる情報とては、インスタンスIDや自身のIPアドレス、所属するセキュリティグループなどです。インスタンスの中で実行するプログラムあるいはAWSの各種サービスが、この情報を使って何らかの処理をする時に利用します。

 v1とv2の違いは、取得の仕方です。

v1は次のように単純にURLを叩くだけで取得できます。

curl http://169.254.169.254/latest/meta-data/

v2は、リクエストのヘッダーに有効期限などを元にしたトークンを埋め込む必要があります。

TOKEN=`curl -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600"` \
&& curl -H "X-aws-ec2-metadata-token: $TOKEN" -v http://169.254.169.254/latest/meta-data/

Capital Oneを襲ったSSRF攻撃とインスタンスメタデータ

 それでは何故v2は、わざわざトークンを埋め込んで取得しにくくしているのでしょう?その背景を知るために、Capital Oneを襲ったSSRF攻撃の事件を紹介します。事件の概要を簡単に説明すると、攻撃者はWAFの脆弱性を利用してIAM Roleが設定されているインスタンスにServer Side Request Forgery(SSRF)攻撃を仕掛け、インスタンスメタデータを利用してIAMのクレデンシャル情報を取得しました。そのクレデンシャルを利用して、S3にアクセスして大量のデータを盗んだという事件です。

f:id:dkfj:20190812151512p:plain

Capital Oneの個人情報流出事件に思うこと - プログラマでありたい

 この事件には幾つかポイントがあるのですが、そのうちの一つがインスタンスメタデータを通じてIAMロールの一時的なアクセスキー・シークレット(クレデンシャル)が取得され、それを悪用された事にあります。

f:id:dkfj:20200930094358p:plain

 インスタンスメタデータからクレデンシャルを取得できる事自体は、インスタンスメタデータサービスの仕様なのでそれ自体は問題ありません。問題は、そのデータが簡単に取得できるので、SSRF攻撃を受けた時に悪用されやすいという点です。その改善としてv2が出てました。v2がもともと計画していたのか、Capital Oneを受けて作ったのかは不明です。ただGCPのメタデータの取得はv2的な動きで、AWSもそうして欲しいという話は以前からありました。

インスタンスに対してv1・v2を指定して設定する

 インスタンスメタデータサービスのバージョンの指定は、インスタンス起動時に指定できます。v2が出た当初は、CLIでの起動のみ指定可能ですが、今だとマネジメントコンソールからでも指定できるようになっています。インスタンスの詳細設定の高度な詳細(どんな日本語だよ)のMetadata Versionで指定できます。デフォルトはv1とv2の両方を使えるもので、v2のみ使えるものも指定できます。また、Metadata accessibleで、メタデータ自体にアクセスできないようにすることもできます。

f:id:dkfj:20200930095414p:plain

v1とv2の挙動の確認

 それでは、実際にv1とv2の設定をしたインスタンスで、それぞれの挙動を確認してみましょう。まずは、v1設定のインスタンスです。

単純なcurlコマンドでの取得

$ curl http://169.254.169.254/latest/meta-data/ami-id/
ami-0ce107ae7af2e92b5

 成功しますね。
次にv2に対応したトークン埋め込みでの取得

$ TOKEN=`curl -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600"` && curl -H "X-aws-ec2-metadata-token: $TOKEN" -v http://169.254.169.254/latest/meta-data/ami-id/
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 56 100 56 0 0 11200 0 --:--:-- --:--:-- --:--:-- 11200

Trying 169.254.169.254...

TCP_NODELAY set

Connected to 169.254.169.254 (169.254.169.254) port 80 (#0)

> GET /latest/meta-data/ami-id/ HTTP/1.1
> Host: 169.254.169.254
> User-Agent: curl/7.61.1
> Accept: */*
> X-aws-ec2-metadata-token: AQAAAMVnM-DonAFD57_6PRycSd7L-6KgnwwOK2i352oj2ir7dYa85g==
>

HTTP 1.0, assume close after body

< HTTP/1.0 200 OK< Accept-Ranges: bytes< Content-Length: 21< Content-Type: text/plain< Date: Tue, 29 Sep 2020 15:32:45 GMT< Last-Modified: Tue, 29 Sep 2020 15:03:15 GMT< X-Aws-Ec2-Metadata-Token-Ttl-Seconds: 21600< Connection: close< Server: EC2ws<

Closing connection 0

 見え方が違うけど、成功しています。
v1,v2のどちらのコマンドでも取得できることが確認できました。

次にv2設定のインスタンスで、v1で取得する際に利用する単純なcurlコマンドでの取得してみます。

$ curl http://169.254.169.254/latest/meta-data/ami-id/
<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
	"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
 <head>
  <title>401 - Unauthorized</title>
 </head>
 <body>
  <h1>401 - Unauthorized</h1>
 </body>
</html>

 401 Unauthorizedで権限がないためにエラーがでています。
ということで、v2に設定しているとトークンを埋め込まないと取得できないことが解りました。

 v1からv2に変更する場合、AWSの機能・サービスで呼ぶ出しているところは影響ないですが、自前でメタデータを取得するプログラム・コマンドを作っている場合は変更が必要です。

v2 (IMDSv2) を設定した場合のセキュリティ的な効果は?

 それでは、v2 (IMDSv2) を設定するとセキュリティ的にどういった効果があるのでしょうか?AWSやクラスメソッド臼田さんのブログにある通り、幾つかの効果があります。

  • 誤って設定された Web アプリケーションファイアウォールからの保護
  • 誤って設定されたリバースプロキシからの保護
  • SSRF 脆弱性からの保護
  • 誤って設定されたレイヤ3ファイアウォール、NAT 機器からの保護

 v2を使うと何故防げるのかというと、ヘッダーを検証するようになっているのでX-Forwarded-Forが入っているとトークンを発行しないなどの幾つかの仕様がはいっているためです。詳しくはブログを確認してください。

aws.amazon.com

dev.classmethod.jp

実際、どれくらいの効果があるのか?

 それでは、v2 (IMDSv2) にした場合にどれくらいの効果があるのでしょうか?これはSSRF等の防止策ではなく緩和策と認識しています。つまり単純な攻撃からの被害を防げるけど、もっと本気を出した攻撃は防げません。このあたりは徳丸さんが詳細指摘しています。

blog.tokumaru.org

 対策として大事なのは、設計レベルでそれぞれのサービスに防御を盛り込むことだと思います。例えば、インスタンスに付与するIAMロールには最小権限に絞るとか、取得される先のS3バケットはバケットポリシーで接続元を絞り込むなどがあります。このあたりは、過去にまとめています。

blog.takuros.net

 今後作るインスタンスについては、v2 (IMDSv2) にすべきだと思います。またIAMポリシーで、IMDSv2を強制するということもできます。ただし、その設定をしていれば安心という代物ではないということはしっかり認識しておきましょう。それぞれのレイヤーで、出来うる限りの設計・防御をしていくという観点をもっていきましょう。でもIAMとかAWSのセキュリティサービスが解らんという方は、お勧めの本がありますよというステマで終わらせて頂きます。現場からは以上です!!

booth.pm

booth.pm

ファイルストレージ・ブロックストレージ・オブジェクトストレージの違いと、AWSのストレージサービスとのマッピング

 こんにちは。仕事でAWSの構築し、プライベートでAWSの研究と技術書の執筆をし、Amazonで本を売っているAmazon依存症疑惑のある佐々木(@dkfj)です。
 AWS使い始めてまず悩むことのベスト10の一つが、ストレージサービスの選び方です。AWSにはS3やEBSの他に、EFSやFSxなど多種多様なストレージサービスがあります。今回は、ストレージサービスの種類から、AWSのサービスの使い分けを説明したいと思います。

ストレージサービスの種別

 一口にストレージといっても、用途に応じて幾つか分類できます。代表的なのが、ファイルストレージ・ブロックストレージ・オブジェクトストレージです。まずは、この3つの違いをみてみましょう。

ブロックストレージ

 まず一番イメージしにくいのが、このブロックストレージ。ブロックストレージは、ものすごくザックリいうとハードディスクのようなもので、ブロックと呼ばれる論理単位でのアクセスします。ハードディスクは物理的な単位に制約されますが、クラウドのブロックストレージはバックエンドのストレージを論理的にまとめて好きな単位に切り売りしてくれます。人間が直接扱うというより、OSとかが使う低レイヤーなストレージになります。

ファイルストレージ

 次にファイルストレージとは何かです。こちらはいわゆるファイルサーバーのようなイメージです。ユーザーは、ストレージ上のデータを個々のファイル単位で扱います。OSを介して見えるのがファイルストレージですし、それをネットワーク越しに利用するのがNAS(ネットワーク・アタッチト・ストレージ )です。

オブジェクトストレージ

 最後にオブジェクトストレージです。字義的には、データをオブジェクト単位で扱うストレージです。これだと、ファイル単位で扱うファイルストレージと何が違うのだという気がしますが、その通りです。ディレクトリ構造で管理するファイルストレージと違い、オブジェクトストレージはオブジェクトを一意に識別するIDと、それを管理するメタデータで構成されています。さらにS3のようにアクセスするためのAPIが提供されているケースもあります。というか、オブジェクトストレージの概念と実装は、S3の存在が大きいんですね。知らなかった。

ストレージ種別のまとめ

 ブロックストレージ⇒ファイルストレージ⇒オブジェクトストレージとレイヤーが上がってくるイメージですかね。この辺りRedHatさんが上手くまとめています。流石、ストレージ会社の側面がありますね。

www.redhat.com

ストレージ種別とAWSのサービスのマッピング

 ストレージ種別の概要がザックリ解ったところで、AWSのサービスをマッピングしてみましょう。

ストレージ種別 サービス名 概要
オブジェクトストレージ S3 AWSが誇るオブジェクトストレージ
オブジェクトストレージ Glacier S3のストレージクラスの一部に取り込まれたアーカイブ用ストレージ
ブロックストレージ EBS 不揮発性のストレージ
ブロックストレージ EC2のインスタンスストア 揮発性のストレージ
ファイルストレージ EFS NASみたいに複数のインスタンスからマウントできる
ファイルストレージ FSx for Windowsとfor Lustreの2種類があるよ

ファイルストレージの使い分け

 オブジェクトストレージは2種類ありますが、Glacierはアーカイブ用と用途と機能がはっきりしているので使い分けに悩みません。またブロックストレージも永続化&使いまわししたければEBSで、インスタンスストアはローカルで高速なI/O処理に利用すると、これも使い分け方がはっきりしています。一番悩むのが、ファイルストレージだと思います。ファイルストレージには、EFSとFSx for WindowsとFSx for Lustreがあります。ここをどう使い分けたらよいのか難しいので、個人的な見解含みでザックリと分けたいと思います。

EFS

 まずEFSは、Linux向けのファイルシステムとして考えましょう。何故ならば、Windowsの素のドライバーでは、未だEFSをサポートしていないからです。EFSはNFSv4プロトコル経由でのアクセスを前提としていますが、Windowsは今のところNFSv4に対応していません。利用したい場合は、サードパーティ製のドライバを使うという手がありますが、それであれば次で紹介するFSx for Windowsを使ったほうが良いです。
 それ以外の特徴として、参照系のアクセスに強く書き込み性能は高くないという点があります。『何千もの Amazon EC2 インスタンスに対して大規模な並列共有アクセスを提供するように設計されている』と豪語されているのですが、一方でWrite Manyなシステムには向いていません。あと、EBSに比べるとRead・Writeとも性能はそこまで高くないです。更にスループットモードがバーストとがあり、バーストモードはサイズによって基本性能が変わります。使い所として悩みますが、CMSの共有ストレージとしてのコンテンツの置き場に使いやすいのも事実です。その際は、CloudFront等と併用してキャッシュを上手く使いましょう。

FSx for Windows

 EFSがWindowsに使えないとすると、じゃぁどうすんのという時に出てくるのがこのFSx for Windowsです。FSxは、FとSが大文字でxが小文字というこだわりのネーミングですが、そもそも何の略称か解りません。FSxにはfor Windowsとfor Lustreの2種類があり、アーキテクチャ・機能・用途も大きく違っています。for Windowsは名前の通りWindows用のサービスで、フルマネージドなWindowsのファイルサーバとして使えます。ということで、Windowsでファイルストレージが必要になった場合は、FSx for Windowsを使いましょう。

www.slideshare.net

FSx for Lustre

 最後のファイルストレージがFSx for Lustreです。Lustreは、フルマネージドな分散ファイルシステムで、S3とシームレスに統合できるファイルストレージです。個々の単語の意味を理解できても、つなげると解らなくなってしまいます。まずS3とのシームレスな統合というのは何かというと、ファイルシステム作成時にS3のバケットと関連付けできます。そして、S3上のファイルをインデックスし、あたかも自前のファイルのようにみせます。初回アクセス時はS3から取得するので遅いのですが、2回目以降はキャッシュしているので高速です。なんとなくStorage Gatewayのキャッシュ型ボリュームの挙動と似ていますね。主な用途は、高速なデータアクセスが必要なハイパフォーマンス・コンピューティングや機械学習とのことです。

www.slideshare.net

まとめ

 AWSのサービスはいろいろあって悩むと思います。悩んだ時は、一度基本に立ち返ってどのレイヤーに対応したサービスなのかを確認するといいのかもしれません。


See Also

blog.takuros.net

blog.takuros.net

夢の機能なのか?Amazon EBS マルチアタッチを使用した複数インスタンスからのEBS共有

 こんにちは。仕事でAWSの構築し、プライベートでAWSの研究と技術書の執筆をし、Amazonで本を売っているAmazon依存症の佐々木(@dkfj)です。

 今回の基本に立ち返ろうシリーズ(?)は、EBSです。EBSといっても、2020年2月に出てきたAmazon EBS マルチアタッチについです。この機能、ものすごくザクッというと、EBSを複数のインスタンスから共有する仕組みです。EC2とかEBSの設計をしていると誰しも一度は、EBSを複数のインスタンスで共有できないのかなぁと思ったことはあるんではないでしょうか?新機能として出たマルチアタッチの仕組みは、その救世主となるのでしょうか?簡単に解説してみます。

EBSのマルチアタッチ機能の概要

 まずEBSのマルチアタッチ機能はどういったものなのでしょうか?図で見たほうが早いので、それをもとに解説します。

f:id:dkfj:20200903175117p:plain
Amazon EBS マルチアタッチ

 EBSのマルチアタッチの動きとして、まずアベイラビリティー・ゾーン(AZ)をまたいでのアタッチはできません。そもそもEBS自体がAZまたぎでアタッチできないので、その仕様に引きずられるというのはある意味納得できます。同一のAZの場合のみ、複数のインスタンスにアタッチできます。これだけの制約であれば、まだ使えそうな気がしますね。ただ、それ以外の制約が結構ありますので、列挙してみます。

  • 同一のAZのみ(説明済み)
  • Nitro システムのインスタンスのみ利用可能
  • 最大 16 の Linux インスタンス(Windowsはアタッチできるが、インスタンス間で共有されているボリューム上のデータはOSから認識されない)
  • プロビジョンド IOPS SSD (io1) ボリュームのみ利用可能
  • 現状では、us-east-1、us-west-2、eu-west-1、および ap-northeast-2 リージョンのみ利用可能
  • I/O フェンスをサポートしていない
  • ブートボリュームとして作成できない
  • インスタンスあたり 1 つのブロックデバイスマッピングにアタッチできる
  • リュームの作成後に、マルチアタッチを有効または無効にできない
  • ボリュームのボリュームタイプ、サイズ、プロビジョンド IOPS を変更できない
  • Amazon EC2 コンソールまたは RunInstances API を使用してインスタンスの起動時に有効にすることはできない

参照元は、こちらです。
Amazon EBS マルチアタッチを使用した複数のインスタンスへのボリュームのアタッチ - Amazon Elastic Compute Cloud

 いろいろと無い無い尽くしですが、できたばかりのサービスなので致し方がないと思います。一方で、サラッと別のところでもっと大きな課題が提示されています。

EBS Multi-Attach では、標準ファイルシステムはサポートされていません。XFS、EXT3、EXT4、NTFS などのファイルシステムは、複数のサーバーまたは EC2 インスタンスが同時にアクセスするようには設計されていません。したがって、これらのファイルシステムには、書き込み、読み取り、ロック、キャッシュ、マウント、フェンシングなどの調整と制御を管理するための組み込みメカニズムがありません。

複数のサーバーが標準ファイルシステムに同時にアクセスできるようにすると、データの破損または損失が発生する可能性があります。EBS Multi-Attach ボリューム上の標準ファイルシステムを操作できるようにする設定は、サポートされていません。

aws.amazon.com

 OSが備えているファイル保護の仕組みは、マルチアタッチでは対応していないので、データの扱い方によってはファイルが壊れることがありますよということです。端的にいうと、排他制御ができないということです。じゃぁ、書き込み用のインスタンスを1台にして、後はリードオンリーのインスタンスにすれば良いのではという案も出てくると思いますが、リード側は書き込み完了を検知できないので難しそうです。じゃぁ何に使うのというところを、考察してみます。

EBSのマルチアタッチ機能のユースケース

 先述の制約を考えると、参照系のみの不変のデータを扱うのに良さそうだなと思いした。みなさん、AWSが提供するパブリックデータセットってご存知でしょうか?主に学術向けで、天文や科学、気象データなどをパブリックで公開して役立てようというプロジェクトです。

registry.opendata.aws

 今見てみると、データはS3で提供されているのですが、昔はEBSのスナップショットとして公開されていたような気がします。それを自分の環境でEBSとして実体化させて使うと。データ分析の分野であれば元となるデータセットがあって、それを元に複数のインスタンスで計算するというのがよくあると思います。その際、個々のインスタンスにEBSをアタッチすると高コストになりますが、マルチアタッチEBSであれば1つ分のコストで済みます。
 用途としてはかなり限定されますが、EBSのコスト高で困っているシステムというのは意外に多いです。そういった問題の解決に活用できないか検討するのも良さそうですね。

まとめ

 まとめとしては、EBSのマルチアタッチは夢はあるけど、現状では制約が大きい。特に大きな問題としては、ファイルの書き込みの排他制御ができないことです。ただ、参照系にしか使っていないEBSがあるのであれば、ワンチャンあるよという感じです。
 ちょっと発表を聞いた時に比べると夢がしぼんだような気がしますが、私達には夢のストレージであるS3があります。四の五の言わずに、S3を上手く活用する仕組みを考えましょう

booth.pm

booth.pm