Amazon Web Services ブログ

Active Directory 認証と承認を使って Amazon Elasticsearch Service ドメインをセキュリティ保護する

この記事では、Amazon Elasticsearch Service (Amazon ES) ドメインを Microsoft Active Directory (AD) に基づく認証および承認を使ってセキュリティ保護する方法を示します。これには、カスタム認証コードを実行している Nginx リバースプロキシを使用します。Amazon ES には、アクセス制御のための AD / LDAP との統合サポートは組み込まれていません。この記事では、この問題に対する単純で強力な解決策を提供します。

Amazon Elasticsearch Service (Amazon ES) は、Elasticsearch の使いやすい API とリアルタイム機能、ならびに本稼働ワークロードに必要な可用性、スケーラビリティ、セキュリティを提供する完全マネージド型のサービスです。このサービスには、KibanaLogstash、および Amazon Kinesis FirehoseAWS LambdaAmazon CloudWatch などの AWS サービスとの統合が組み込まれているため、ソリューションの迅速な構築が可能です。

Amazon ES では、AWS Identity and Access Management (IAM) を使用してクラスタ内のデータへのアクセス制御をきめ細かく行うことができます。前の記事では、クライアント アプリケーションでリソースベースのアクセス権、アイデンティティベースのアクセス権、および Signature Version 4 署名を適用して Amazon ES ドメインへのアクセスを制御する方法を学びました。この記事を読んだ後は、社内 AD (オンプレミスまたは AWS 内で稼動) と統合された Amazon Elasticsearch ドメインをデプロイできるはずです。また、AD ユーザーとグループを使用して、クラスタと組み込みの Kibana ダッシュボードへのアクセスをきめ細かく制御できることでしょう。このアプローチを使用すると、企業ユーザはシングルサインオン (SSO) を使用して Amazon ES インデックスと Kibana ダッシュボードにアクセスできます。このアプローチを使用して、どのユーザー、グループ、またはサービス アカウントが何にアクセスするかを制御することもできます。また、組織内の単一の BI またはアナリティクス ユーザーすべてに対して IAM ユーザー資格情報を作成せずにこれを行うこともできます。

ソリューションの概要

次の図にソリューションを示します。ここでは、このソリューションが上位レベルでどのように機能するかがわかります。

クライアント アプリケーション、ブラウザベースのアプリケーション (Kibana App など) は、Nginx リバース プロキシの IP アドレスまたはDNS 名を使用して Amazon ES にアクセスします。プロキシ エンドポイントにアクセスするクライアントは、HTTP または HTTPS 要求の基本認証ヘッダー内で AD ユーザー名とパスワード (個人アカウントまたはサービス アカウント) を提供する必要があります。無効なユーザー名またはパスワードを指定すると、401 not authorized エラーが返されます。有効なユーザー名またはパスワードを提供しても、Amazon ES ドメインへのアクセスが不十分な場合、403 forbidden エラーが返されます。

Nginx プロキシが使用するAmazon EC2 インスタンスは、パブリック サブネット内に存在します。この EC2 インスタンスが、負荷のかかる作業をすべて行います。この作業には、クライアントからの HTTP および HTTPS 要求の受信、AD による認証、IAM ロールベース認証のチェック、およびAmazon ESへの要求の転送が含まれます。この記事のソリューションは、高可用性設計ではありません。リファレンスおよび学習の例としてのみ使用してください。これを出発点と考え、その上に構築していってください。より多くのアイデアについては、この記事の最後にある機能強化のセクションを参照してください。

Active Directory は、データ センター内または AWS 内に存在します。Nginx プロキシ EC2 インスタンスは、LDAPS を使って AD と通信を行います。AWS の管理下にある Active Directory サービスで、LDAPS がサポートされるようになりました。したがって、AWS の管理下にある AD を使用している場合や、AWS 内で AD をホストする場合は、LDAPS のサポートを有効にすることを検討してください。詳細は、AWS セキュリティ ブログの記事「AWS Microsoft Active Directory 向けに LDAPS を有効にする方法」を参照してください。

お使いの Amazon ES ドメインは、お使いの AWS アカウント内に存在します。  エンドポイント アクセスには、2 つの選択肢、パブリックエンド ポイントまたは VPC エンドポイントのいずれかを選択するがあります。この記事では、パブリック エンドポイントを使用します。ただし、このソリューションは、設計上の変更をいくらか加えるなら、Amazon ES 用の VPC エンドポイントでも有効です。

これが内部でどのように機能しているかを見てみましょう。Nginx リバース プロキシのカスタム認証および承認コードは、ローカル デーモンとして実行されます。プロキシにヒットするすべての HTTP および HTTPS 要求は、まずプロキシ インスタンス (ポート 8888) でローカルに実行されている認証デーモンにルーティングされます。このルーティングには、Nginx プロキシのサブリクエスト機能が使用されます。認証デーモンは、AD に対して LDAP バインド呼び出しを行い、次に LDAP 検索呼び出しを行うことにより、リクエスト ヘッダーで指定されたユーザー名とパスワードを検証します。

要求ヘッダーに指定された資格情報が無効な場合、サブリクエストは失敗し、プロキシは HTTP 401 not authorized エラーを返します。AD 資格情報が有効な場合、認証デーモンはそのユーザーのすべての AD グループのリストを取得します。これは、指定された接頭辞で始まる AD グループ (「AWS」など) のみを検索します。検出された各 AD グループについて、認証デーモンは一致する IAM ロール (AD グループと正確に同じ名前の IAM ロール) を検索します。次に、認証デーモンは、IAM ロールのポリシーを評価して、その IAM ロールに指定されたアクションの実行が許可されているかどうかを判断します。アクションは、要求ヘッダーからの HTTP メソッド呼び出し (GET、POST、PUT、DELETE、HEAD など) です。アクションは、指定されたリソース、要求ヘッダーからの URL に対して実行されます。この評価では、IAM ポリシー シミュレータ API を使用します。

認証デーモンは、成功した結果 (つまり、許可された結果) が見つかるまで、ユーザーの AD グループの一致する IAM ロールすべてを反復処理します。認証デーモンが、指定されたリソースに対して指定されたアクションを実行する権限を持つ IAM ロールを検出すると、認証デーモンはそのサブリクエストに対して HTTP 200 を返します。また、元の要求を Amazon ES ドメインに転送します。それ以外の場合、認証デーモンは HTTP 403 forbidden を返します。Amazon ES ドメインは、Nginx プロキシによって転送された要求に応答します。Amazon ES ドメインのアクセス制御ポリシーは、IP ベースのアクセスポリシーを使用して、Nginx プロキシのパブリック IP からのすべての要求を許可するように構成されています。このため、Amazon ES ドメインはプロキシを信頼し、プロキシは着信した要求を認証および承認します。

これを理解するための例を見てみましょう。

あなたの組織には、Bob と Alice という 2人の AD ユーザーがおり、それぞれが異なる許可レベルで Amazon ES にアクセスする必要があります。Bob は、Amazon ES ドメイン内の全リソースに対してすべてのアクションを実行するための管理者権限が必要です。Alice に必要なのは、orders インデックスの読み取り専用アクセス権だけです。

2 つの AD グループを作成し、各ユーザーを適切な AD グループに追加します。Bob は AWSESAdmin という名前の ADグループに、Alice は AWSESUser という名前の AD グループにそれぞれ追加されます。また、AWS アカウントには、AD グループと同じ名前の IAM ロールを 2 つ作成します。各 IAM ロールに付属するポリシーは異なるため、Amazon ESドメインに対して与えられるアクセス権が異なります。

AWSESAdmin IAM ロールの IAM ポリシーの例を以下に示します。

{
    "Version": "2012-10-17",
    "Statement": [
      {
      "Action": ["es:*"],
      "Resource": 
		"arn:aws:es:ap-southeast-2:111122223333:domain/mydomain/*",
      "Effect": "Allow"
      }
    ]
}

AWSESUser IAM ロールの IAM ポリシーの例を以下に示します。

{
    "Version": "2012-10-17",
    "Statement": [
      {
      "Action": ["es:ESHttpGet"],
      "Resource": 
		"arn:aws:es:ap-southeast-2:111122223333:domain/mydomain/orders/*",
      "Effect": "Allow"
      }
    ]
}

Bob と Alice が Amazon ES にアクセスすると、プロキシを介して資格情報が検証されます。AD グループのメンバーシップによって、どのようなアクセスが許可されるかが決まります。Bob には AWSESAdmin ロールがあるため、AWSESAdmin IAM ロールはフルアクセスとして評価されます。Alice には AWSESUser ロールがあるため、AWSESUser IAM ロールは、orders インデックスへの読み取り専用 (HTTP GET) アクセスとして評価されます。

このモデルでは、AD と IAM を併用して Amazon ES ドメインへのアクセスを制御します。このソリューションの主なセキュリティ機能は、次のとおりです。

  • 企業 AD が認証のソースです。Amazon ES にアクセスする必要がある組織内のすべてのユーザーとサービスに対して、IAM ユーザーを作成する必要はありません。AD グループのセット (AWSESAdmin、AWSESDataLoader、AWSESReadOnly など) を作成して、適切なグループにユーザーを配置するだけで済みます。
  • IAM が承認のソースです。この機能は、Amazon ES のリソースに対してきめ細かなアクセス ポリシーを作成できることを意味します。限定された IAM ロールのセットを作成します。これらのロールのそれぞれは、AD グループの 1 つの並列アイテムと 1 対 1 でマッピングされています。このため、Amazon ES ドメインを完全に制御することができます。同時に、ユーザーとサービスに簡単なアクセスを提供できます。

ソリューションをデプロイする

それでは、このソリューションを配備する手順について説明しましょう。ソリューションを展開する前に、一定の前提条件を満たす必要があります。

  • パブリック サブネットを持つ既存の VPC が必要です。Nginx プロキシは、このパブリック サブネットに伸縮自在な IPアドレスで配備されます。
  • パブリック サブネットからアクセスできる AD サーバーが必要です。このサーバーは、データセンター内の AD、Amazon EC2 インスタンス上で動作する AD、または AWS 管理対象の AD のいずれかにできます。
  • プロキシが AD とのバインドおよび LDAP クエリの作成に使用できる一連のサービス アカウントの資格情報が必要です。このサービス アカウントの完全修飾ドメイン名とパスワードが必要です。

これらをすべて準備できたら、以下の手順に従ってソリューションを展開および実行できます。

手順 1: ソリューションの作成に必要な入力を収集する

AWS CloudFormation テンプレートを起動するために必要な入力パラメータ値を入力して、このテーブルを完成させます。

入力パラメータ 説明 Value
ESDomainName 作成する Elasticsearch ドメインの名前。
ESDomainDataInstanceCount
ESDomainDataInstanceType
ESDomainDataInstanceVolume
ESDomainMasterInstanceCount
ESDomainMasterInstanceType
Elasticsearch ドメイン内のインスタンスのタイプ、番号、およびインスタンス タイプ。
ESDomainAllowExplicitIndex 詳細オプション: Elasticsearch が要求本体で指定された明示的なインデックスを持つ要求を受け入れおよび拒否できるかどうかを制御する rest.action.multi.allow_explicit_index。
VpcId ソリューションを開始する既存の VPC。
VpcCIDR
OnPremisesCIDR
VPC および企業ネットワーク用の IP CIDR ブロック。これらの値は、Nginx プロキシ上でセキュリティ グループを構成するために使用されます。
SSHCIDR SSH を使用して Nginx プロキシへのアクセスを許可する IP CIDR ブロック。このタイプのアクセスは、管理 IP アドレスだけに制限してください。
KeyPairName Nginx プロキシへの SSH アクセス用の既存の EC2 キーペア。プロキシへの SSH アクセスを望まない場合は、このフィールドを空白のままにできます。
NginxServerPortHTTP
NginxServerPortHTTPS
Nginx プロキシ用の HTTP および HTTPS ポート。このソリューションは、両方のプロトコルをサポートしています。テスト用としてはデフォルトのままでかまいません。
InstanceType Nginx プロキシ用の EC2 インスタンス タイプ。
PublicSubnet Nginx プロキシを起動する既存のパブリック サブネット ID。
LDAPServer プロトコルとポートを備えた既存の LDAP / AD サーバー URL。このソリューションは、LDAP と LDAPS の両方をサポートしています。
BindDN
BindPassword
Nginx プロキシが LDAP / AD サーバーと通信するためのサービス アカウント資格情報。BindDN は、完全修飾ドメイン名にしてください。
重要: BindPassword 内のすべての「&」文字は、「\」でエスケープしてください。
BaseDN ユーザーとグループの検索が実行される LDAP / AD 内のベース ドメインの完全修飾ドメイン名。
GroupPrefix LDAP/AD グループの検索に使用する接頭辞。Nginx プロキシは、この接頭辞で始まるユーザー グループのみを検索します。デフォルト値は AWSES です。

手順 2: ユーザーとグループ管理用の AD を準備する

次の 3 つのユーザーグループを AD 内に作成し、必要に応じてこれらのグループにユーザーを追加します。

重要: 必要に応じて接頭辞を変更することを忘れないでください。この接頭辞は、GroupPrefix 入力パラメーターと一致している必要があります。

  • AWSESAdmin: このグループには、Amazon ES ドメインへのフル アクセスが必要なすべての管理者ユーザーを含めてください。
  • AWSESDataLoader: このグループには、Amazon ES ドメインへの読み書きアクセスが必要なユーザーとサービスを含めてください。
  • AWSESUser: このグループには、Amazon ES ドメインへの読み取り専用アクセスが必要なユーザーとサービスを含めてください。

手順 3: CloudFormation テンプレートをダウンロードして開始する

このソリューション用の CloudFormation テンプレートを入手します。収集したパラメータを使って AWS アカウント内でテンプレートを開始します。このテンプレートで次のリソースが作成されます。

  • IP ベースのアクセス ポリシーを含む Amazon ES ドメイン
  • 伸縮自在な IP アドレスを含む単一の Nginx プロキシ
  • Amazon ES ドメインにアクセスするための、ポリシーの異なる 3 つの IAM ロール

テンプレートの出力は次のようになります:

  1. Amazon ES ドメインの Amazon リソース ネーム (ARN)。
  2. プロキシ経由での Amazon ES ドメインのプライベート IP URL。Amazon ES ドメインへのアクセスには、これらを使用します。
  3. プロキシを経由する、組み込み Kibana ダッシュボードのプライベート IP URL。Kibana ダッシュボードへのアクセスには、これらを使用します。

手順 4: ソリューションをテストする

CloudFormation テンプレートを起動し、リソースが作成されたら、ソリューションをテストできます。これを行うには、Web ブラウザからプロキシのプライベート IP URL に移動するか、REST API 呼び出し (たとえば、Postman または SOAPUI ツールを使用して) を実行します。HTTPS ポートで SSL 証明書警告エラーが発生するため、最初のテストで HTTP ポートを使用することをお勧めします。この結果になるのは、このソリューションの Nginx プロキシ サーバーが自己署名証明書を使用するためです。

Web ブラウザを使用している場合、AD 資格情報を入力するよう求められます。上記の手順 2 で作成した AD ユーザー グループの 1 つに AD ユーザーが属していることを確認します。ツールまたはクライアント アプリケーションを使用して REST API 呼び出しを行う場合は、HTTP 要求ヘッダーのベーシック認証として AD ユーザーの資格情報を提供してください。

実行可能な機能拡張

必要に応じて、このソリューションにいくつかの機能拡張を追加できます。既に説明したように、このブログ記事は、あなたが使用して構築できるアイデアだけを示しています。本稼動目的でこのアプローチを使用する場合は、少なくとも次の点を考慮する必要があります。

  1. プロキシは、単一障害点になる可能性があります。高可用性と性能向上を実現するため、AWS サービスの Auto ScalingElastic Load Balancing を使用してください。
  2. Nginx プロキシは、自己署名入りの SSL 証明書を使用します。セキュリティ体制を向上させるため、信頼できる CA 証明書を使用してください。これにより、Web ブラウザおよびクライアント アプリケーションでの SSL 警告も防止できます。
  3. AWS ドキュメントで言及されているように、rest.action.multi.allow_explicit_index 詳細オプションには、知っておくべきアクセス制御上の意味があります。  この値を false (指定されたテンプレートの ESDomainAllowExplicitIndex パラメータ) に設定すると、ユーザーは制限をバイパスできなくなります。ただし、これにより Kibana が破壊されます。IAM ポリシーを定義する際には、このことを考慮することをお勧めします。最も安全な手法は、広範な許可と限定的な拒否を混合させるのではなく、最小特権の原則に従うことです。この手法では、タスクの実行に必要なアクセス権のみを付与します。
  4. このブログ記事の完全なコードと構成ファイルは、GitHub のここにあります。特定の使用事例のコードをダウンロードして拡張できます。

結論

このブログ記事のソリューションを使用して、Amazon ES ドメインにきめ細かな認証および承認を追加できます。LDAP / AD と IAM を組み合わせることで、シンプルで比較的安全な方法で要件を満たすことができます。このブログ記事に関する質問やコメントがある場合は、以下のコメント欄にメッセージを残してください。


著者について

Ali Asgar Juzer は、アマゾン ウェブ サービスのコンサルタントです。 AWS を使用する際にソリューションの価値を向上させる手助けとなるために、当社の顧客と協力してデータベースプロジェクト上の指導や技術支援を行っています。