Amazon Web Services ブログ

暗号化を用いたセキュアな Amazon EMR

ここ数年で、エンタープライズ企業において Apache hadoop エコシステムを用いて、センシティブであったり、きわめて秘匿性が高かったりするデータを扱う、重要なワークロードを走らせるケースが非常に増えてきています。そうしたワークロードの特性により、エンタープライズ企業ではしっかりした組織/業界全体のポリシーや、規制、コンプライアンスのルールを定めています。それに基づいて、機密データの保護や、権限のない人がアクセスできないようにすることが求められています。

こうしたポリシーにおいては一般的に、データストアに保存されているとき、そしてデータを転送しているときの両方で暗号化が要求されます。Amazon EMR では “セキュリティ設定” を使うことで、AWSキーマネジメントサービス (KMS) からお客様自身が用意した暗号化要素まで、さまざまな暗号化キーや証明書を指定することができます。

暗号化設定についてのセキュリティ設定を作り、クラスター作成の際に、その設定を当てることができます。セキィリティ設定を一度作っておくことで、いくつものクラスターにその設定を簡単に適用可能です。

o_Amazon_EMR_Encryption_1_

この投稿ではEMRのセキュリティ設定による、複数段階のデータ暗号化のセットアッププロセスを概観します。暗号化について深く見ていく前に、データ暗号化が必要な状況を整理しましょう。

保存時のデータ

  • Amazon S3にあるデータ – EMRのS3クライアントサイド暗号化
  • ディスク上のデータ – Linux Unified Key System (LUKS) による、Amazon EC2 のインスタンスストアボリューム(ブートボリュームを除く)、クラスターインスタンスにアタッチされた Amazon EBS
    ボリューム

転送中のデータ

  • EMRからS3に転送中のデータ、またはその逆 – EMR の S3 クライアントサイド暗号化
  • クラスター内のノード間で転送中のデータ – Secure Socket Layer (SSL) による MapReduce の in-transit 暗号化と、Simple Authentication と Security Layer (SASL) による Spark の shuffle 暗号化
  • ディスクに溢れたデータ、またはシャッフルフェーズの最中にキャッシュされたデータ – Spark の shuffle 暗号化、またはLUKS 暗号化

暗号化の手順

この投稿のために、転送中、保存時の暗号化に使うためのセキュリティ設定を作りましょう。

  • EMRやS3にあるデータに対して、LUKS 暗号化やS3 クライアントサイド暗号化のための KMS キー
  • MapReduce のshuffle 暗号化で使用する SSL 証明書
  • EMR クラスタが立ち上げられる環境。プライベートサブベットで EMR を立ち上げて、S3 からデータを取得するための VPC エンドポイントを設定します
  • EMR セキュリティ設定

この手順で説明するすべてのスクリプトとコードスニペットは、aws-blog-emrencryption Github レポジトリから取得できます。

KMS キーの生成

この手順では鍵管理について、データやディスクを暗号化するために使用する暗号化キーを、簡単に生成、管理できるマネージドサービスの、AWS KMS を使用します。

2つの KMS マスターキーを生成します。ひとつは EMR外のデータを暗号化する S3 クライアントサイド暗号化キーとして、もうひとつはローカルディスクを暗号化するための LUKS 暗号化のキーとして使用します。 Hadoop MapReduce フレームワークは HDFS を使用します。Spark は、ワークロードの中でメモリから溢れた中間データを一時的に保存する先として、各スレーブインスタンスのローカルファイルシステムを使用します。

鍵を生成するために、kms.json という AWS CloudFormation スクリプトを使用します。スクリプトの中で、キーの エイリアス名またはディスプレイ名を指定します。エイリアスは “alias/エイリアス名” 形式で、エイリアス名はアルファベット、アンダースコア、ダッシュのみで構成される必要があります。

o_Amazon_EMR_Encryption_2

キーの作成が終わったら、Outputs として ARN が表示されます。

o_Amazon_EMR_Encryption_3

SSL 証明書の作成

SSL 証明書によって、Mapreduce のシャッフル中にデータがノード間を転送されるときに、データの暗号化が行われます。

o_Amazon_EMR_Encryption_4

この手順では、OpenSSL で 2048-bit RSA 秘密鍵による X.509 自己署名証明書を作成します。これを使って EMR クラスタのインスタンスにアクセスします。画面に従って、証明書発行に必要な情報を入力します。

cert-create.sh を使って、zip ファイルに圧縮した SSL 証明書を生成します。zip 圧縮済みの証明書を S3 にアップロードし、S3 のプレフィックスをメモしておきます。セキュリティ設定を構成するときには、この S3 プレフィックスを使用します。

重要
この例は、あくまで proof-of-concept のデモにすぎません。自己署名証明書を使うことは推奨されませんし、潜在的なセキュリティリスクを孕みます。実運用システムでは、信頼できる認証局が発行した証明書を使ってください。

カスタムプロバイダの証明書には、TLSArtifacts プロバイダインタフェースを使用してください。

環境の構築

EMR クラスタをプライベートサブネットに構築します。もしすでに VPC があり、パブリックサブネットにクラスターを立てたい場合には、このセクションを飛ばして、セキュリティ設定の作成のセクションに進んでください。

クラスターをプライベートサブネット内に立てるためには、以下のリソースが必要です。

  • VPC
  • プライベートサブネット
  • パブリックサブネット
  • 踏み台サーバ
  • マネージド NAT ゲートウェイ
  • S3 VPC エンドポイント

EMR クラスターをプライベートサブネットに立てる際には、クラスターに SSH で入るための踏み台サーバかジャンプサーバが必要になります。クラスターの起動が終わったら、KMS からデータキーを取得するためにインターネットに接続する必要があります。プライベートサブネットからは直接インターネットに接続できないので、マネージド NAT ゲートウェイ経由でトラフィックの経路を制御します。S3 に対して、高信頼性を確保して安全に接続するために、S3 VPC エンドポイントを使用します。

o_Amazon_EMR_Encryption_5

CloudFormation コンソールで、environment.json テンプレートを使って、環境構築用の新しいスタックを作成します。

パラメタとして、踏み台サーバのインスタンスタイプと、そのサーバに SSH アクセスするための EC2 キーペアを入力します。適切なスタック名とタグを指定します。例えば、私の作成したスタックのレビューステップのスクリーンショットは、以下の通りになります。

o_Amazon_EMR_Encryption_6

スタックの作成が終わったら、Outputs タブを開いて VPC、踏み台サーバ、プライベートサブネットのIDをメモしておきます。これらはあとで EMR クラスタを立ち上げる際に使用します。

o_Amazon_EMR_Encryption_7

セキュリティ設定の作成

セキュアな EMR クラスタを立ち上げる前の最終ステップは、セキュリティ設定の構成です。EMR の S3 クライアントサイド暗号化と、先ほど作成した KMS キーを用いたローカルファイルの LUKS 暗号化について、セキュリティ設定を作成します。さらに MapReduce のシャッフルで暗号化を行うために、先ほど作成して S3 にアップロードしておいた SSL 証明書も使用します。

o_Amazon_EMR_Encryption_8

EMR クラスターの立ち上げ

さて、これでプライベートサブネットに EMR クラスタを立ち上げることができるようになりました。まずサービスロールとして、サービスポリシー内の AmazonElasticMapReduceRole が EMR に割り当てられていることを確認します。デフォルトのサービスロールは EMR_DefaultRole です。詳しくはIAMロールを使用したユーザーアクセス権限の設定を参照してください。

環境の設定セクションでメモしておいた VPC ID とサブネット ID の中で、EMR クラスタを立ち上げます。Network EC2 Subnet フィールドで、それらの値を選択してください。続いてクラスタの名前とタグを入力します。

o_Amazon_EMR_Encryption_9

最後のステップはプライベートキーの選択です。ここでは、セキュリティ設定の作成セクションで作っておいたセキュリティ設定を適用します。そして Create Cluster をクリックします。

o_Amazon_EMR_Encryption_10

これで作成した環境の上で、クラスタが立ち上がりました。続いてマスターノードに入ってスクリプトを実行します。EMR コンソールページからクラスタの IP アドレスを取得します。HardwareMaster Instance Group と選択して、マスターノードのプライベート IP アドレスをメモします。

o_Amazon_EMR_Encryption_11

マスターノードはプライベートサブネット内にあるので、まず踏み台サーバに SSH で入り、そこからさらにマスターノードに接続します。踏み台サーバと Hadoop マスタへの SSH については、ssh-commands.txt ファイルをみてください。踏み台サーバへのアクセスについてのさらなる詳細は、Securely Connect to Linux Instances Running in a Private Amazon VPC のエントリーを参照してください。

マスターノードに入った後は、Hive や Spark のスクリプトを実行します。動作確認用として、GitHub /code ディレクトリには PySpark の test.py と Hiveの test.q スクリプトが含まれています。

まとめ

この投稿の中で、データの暗号化が必要な複数のパターンについて述べ、各パターンでどうやって暗号化するかについての手順を説明しました。そして暗号化の前提要件である KMS キーの作成、SSL 証明書の発行、強力なセキュリティ設定による EMR クラスタの立ち上げについて、順を追って解説しました。そして VPC 内のプライベートサブネットでのクラスター起動によって、データをセキュアに
保つとともに、EMR クラスターにアクセスするために踏み台サーバを活用することができました。

もし疑問や助言があれば、ぜひおしらせください。

(翻訳はSA志村が担当しました。原文はこちら