水深1024m

技術的なメモとか日記的なもの

AWS で作るシステムのセキュリティ考

AWS アカウントを複数人で使ってシステムを作っていく時に、 セキュリティの面からやるべきことについて。 主に Web アプリケーションを想定した内容ですが、特に書いてあることは特殊ではないと思います。 各所の Blog にも記事書かれてますが思っていることをつらつらと書いてみます。 なんか変なこと言ってたらご指摘ください。

参考: AWSのセキュリティが気になるなら読んでおくべきAWSセキュリティのベストプラクティス - yoshidashingo

はじめに (AWS アカウントと IAM ユーザ)

前提というか用語の話。

  • AWS アカウント
    • アカウント作成時のメールアドレス、パスワードでログインして使うユーザ
  • IAM ユーザ
    • AWS アカウントから発行できる、ユーザ名とパスワードでログインして使うユーザ

AWS アカウント周り

AWS アカウント (ルートユーザ) で作業できないようにする

AWS アカウントは Linux で言う root ユーザみたいなものなので、アカウント内全てのリソースにアクセス可能です。 構築運用面で最初に IAM ユーザを作成する時以外、アカウントで作業する必要があることはほとんどないです。

  • 操作用の IAM ユーザを作る
  • AWS アカウントに紐付いてる Access Key とか証明書を消す
  • AWS アカウントに MFA を設定する

あとは、重要なシステムのあるアカウントであれば MFA のハードウェアキー買って設定して 金庫にでも突っ込んでおくと良いです。

IAM ユーザを使う人ごとに分割する

IAM を使うと、作業者個人単位で専用のユーザを持てるので、これを使いまわす必要はどこにもないです。 使う人それぞれに IAM ユーザを作成して、必要に応じて権限設定して使いましょう。 CloudTrail 使えば大体の操作は後からトラックできるようになります。 例えばいわゆる Admin な人たちにはほぼ全権を渡しておいて、そうでない人には Describe 系の API だけ渡すとかの切り分けをしておきます。 IAM にも MFA が設定できるので、好みに応じてハードウェア買うかスマートフォンにアプリ入れて MFA を有効化しておきましょう。 アクセスキーとシークレットキーはいずれにせよそれなりに死守する必要があることに気をつけてください。 Mac な人なら envchain 使うとなお良いと思います。

OS X キーチェーンから環境変数をセットするツールを作りました - クックパッド開発者ブログ

難点はユーザ数が増加していくと管理するのが難しくなるところでしょうか。ここはまだうまい解が分からないところです。。。

アプリにキーを埋めない

例えば EC2 で特定の S3 バケットにファイルアップロードするアプリとかバッチを動かす時など。 一昔前まではそのアプリ用の IAM ユーザ発行してキー埋めたりすることもあったと思いますが、 キー埋めないで IAM Role for EC2 Instance 使いましょう。

Amazon EC2 の IAM ロール - Amazon Elastic Compute Cloud

AWS SDK 使える環境であれば大体の実装ではキーの取得とローテーションへの追随もやってくれます。 サーバ設定もデプロイも自動化したけどキーの配布どうしよう、みたいな問題はこれで大体解決するのでは。 難点は今のところインスタンス"起動"時にしかロール指定できないこと。Stop/Start じゃダメです。 イミュータボーでディスポーザボーなインフラをお持ちの各位であればそんな難しいことではないのでは。

Unix アカウント周り

IAM アカウントは分離していても EC2 インスタンスのユーザは ec2-user や ubuntu ユーザを共有して使っている方も多いと思います。 が、インスタンスを扱うユーザが多くなるのであれば、OS レイヤでの権限分離もちゃんとやる必要があります。 Chef とか Puppet で管理する手もあるんですが、ユーザ情報を変更するたびに全台への apply が必要なのも厳しい感じがします。 ここを分離したいのであれば今のところはおとなしく LDAP を使うのが良いでしょう。 OpenSSH を使っていると、ちょっと前まではパッチ当てない限り公開鍵認証にするために LDAP ユーザであっても 対象のインスタンスに事前に公開鍵を配布しておく必要があったのですが、 OpenSSH 6.2 から LDAP 側に保持している公開鍵を読む、みたいなことができるようになったので、ここも心配する必要がなくなりました。

ref. OpenSSH 6.2を使って公開鍵認証もLDAPで行いたい。 - Qiita

ただし LDAP サーバが壊れると全てが崩壊するので、cloud-init で作成されるユーザと EC2 のキーペアは無効化せずに あくまでキーペアを共有しない (これも金庫とかに放り込んでおく) だけに留めておいたほうが良いかもしれません。

暗号化

AWS の例えば S3 や EBS にはサーバサイド暗号化 (SSE) という機能がついてます。 暗号化鍵の管理を AWS 側がやってくれて、使う側としては透過的にデータを暗号化できる機能です。 透過的にというのは要は、API 越しにデータ送信する時は平文で、送信後格納されるタイミングで暗号化されて、 読み出しの際は復号されたデータが降ってくるというやつです。 これを有効化するだけで全てのデータが暗号化されて最高便利という機能に見えるのですが、 API の認証が通れば復号化されたデータが降ってくるので、実際に権限外のアクセスから保護できるケースはそんなに多くないです。 例えば AWS 側の管理者が悪意を持ってアクセスしてきたり、AWSAPI のバグで他人のオブジェクトにアクセスできたり、 AWS がセキュリティペーパーに書いてある通りじゃなく使い終わった HDD を適当に捨てていた場合なんかには保護できるかもしれませんが、 それよりも開発者の誰かがアクセスキーを Github に visible な状態で突っ込んでいたり、メールアドレスとパスワードを使いまわしていて AWS アカウントにログインされたりして死ぬ可能性のほうが遥かに高いんじゃないでしょうか。 というわけで暗号化については"それで守れる範囲"をちゃんと考えた上で、必要な場合はちゃんと実装したほうが良いでしょう。 例えば S3 を例に挙げると、 AWS SDK for Java, .NET, Ruby には S3 にアップロードする際クライアントサイドで任意のキーを渡して暗号化してからアップロードできるようになっています。 これは API がどうこうという話ではなく完全にクライアントサイドで暗号化しています。

Protecting Data Using Client-Side Encryption - Amazon Simple Storage Service

あるいは鍵を AWS に渡して暗号化してもらう SSE-C というのもあります。

Protecting Data Using Server-Side Encryption with Customer-Provided Encryption Keys (SSE-C) - Amazon Simple Storage Service

完全な SSE より、R/W に実際の鍵が必要な分保護できるケースはもちろん増えますが、端的には "暗号鍵を渡すことと引き換えに暗号化処理をオフロードする"というものなので、 暗号化を考えた時にこれがしっくりくるケースってあるのかなーと感じています。

EBS でも、AWS サイドで暗号化の手段が用意されています。

Amazon EBS Encryption - Amazon Elastic Compute Cloud

副次的な効果として、スナップショットを public にしたりアカウントをまたぐことが仕組み上できなくなりますので、 この効果だけ欲しいという方には良いのかも。そもそもの懸念については S3 のものと大差ないと考えています。 自前で暗号化やるのであれば、パートナーが提供してるソフトウェア使う手もありますし、 Linux であれば dm-crypt 使っても良いと思います。

ここだけ長くなっちゃいましたが、要は何を何から守るのかちゃんと考えて実装しようよというだけの話です。

ロギング/監視

オンプレ環境との大きな違いを挙げるとすれば、AWS 上ではコアスイッチでミラーポートを使ってネットワーク監視するみたいなことが難しいので、 基本的に各インスタンス上で監視を行う必要がある点でしょうか。 トレンドマイクロの DeepSecurity とかはそういったアプローチだと思います。

AWS API 周りであれば前述の CloudTrail を使うのが一番良いんじゃないでしょうか。 全サービスをカバーしているわけではないということに留意する必要がありますが。 ファイルは S3 に json で吐かれるので、MongoDB なり ElasticSearch に突っ込んで検索可能にしておくと トラブルシューティングの時などにも捗るとおもいます。 ログを S3 に置いておくのであれば、そのバケットのアクセス権をちゃんと設定するのは必須として、MFA Delete も有効化しておきましょう。

MFA Delete - Amazon Simple Storage Service

おわり

正直粒度もバラバラでまとまらないですが、ざっと書いてみました。 AWS 固有のことが(アカウントとか)それなりにはありますが、その他はこれまで普通にやられてきたことと大差ないと思います。 ここでカバーしていない内容も多々ありますが、そういうのも徐々に書いていきたいです。

完全にオフトピックですが、イミュータブルインフラとかテスト駆動インフラみたいな話って セキュリティ運用とも相性が良いよなあと最近考えています。 例えば Heartbleed なんかが記憶に新しいですが、ミドルウェア脆弱性があってバージョンアップしないとなんて時も パッチしたミドルウェアの検証は(もちろんカバレッジによりますが) Serverspecinfrataster で可能ですし、 実際の入れ替え作業も、既存のサーバを止めてバージョンアップするのではなく新しい構成のサーバを起動して入れ替えるだけで良ければ、かかる労力はかなり小さくなるでしょう。

最近の Web インフラ界隈の流れにうまいこと乗りつつ、より便利でセキュアな環境を作りたいですね。 以上です。