Amazon Web Services ブログ

Amazon ECS 上の Linux コンテナでの Windows 認証の使用

この記事は、Using Windows Authentication with Linux Containers on Amazon ECS を翻訳したものです。

本投稿は、Sr Solutions Architect の Matt Cline により寄稿されました。

統合 Windows 認証 (または統合認証) は、クライアントおよびアプリケーションが SQL Server データベースに接続するための推奨メカニズムですが、コンテナ化されたワークロードを実行する場合、統合 Windows 認証の使用は複雑な場合があります。一般的に統合 Windows 認証クライアントは SQL Server データベースと同じドメインに参加しますが、個々のコンテナは恒久的な実行ではないためにドメインに参加することは適切ではありません。

この記事は、Amazon Elastic Container Service (Amazon ECS) で実行されている Linux コンテナを設定して、コンテナをドメインに参加させることなく、統合 Windows 認証を使用して SQL Server データベースに接続する方法を示します。この例では AWS Fargate を使用してコンテナを実行しますが、このソリューションを少し変更して別のコンテナランタイムまたはコントロールプレーンにデプロイすることもできます。

概要

この例は Microsoft Active Directory 用のAWS Directory Service で実行されている、管理された Active Directory に基づいています。Active Directory にユーザーを作成し、そのユーザーに、Amazon Relational Database Service (Amazon RDS) で実行されているディレクトリに結合された SQL Server データベースへのアクセス権を付与します。なお、ディレクトリユーザーの認証情報は AWS Secrets Manager に保存されているとします。

次に、2 つのコンテナを持つ Fargate タスクを含む ECS サービスをデプロイします。1 つのコンテナには、Secrets Manager からディレクトリユーザーの資格情報を取得し、Active Directory に対する認証によってKerberos 認証チケットを生成するスクリプトが含まれています。このチケット更新のサイドカー (Sidecar) コンテナは、Fargate タスク内のすべてのコンテナが共有する一時ストレージボリュームである Fargate タスクストレージに、Kerberos チケットを格納します。タスク内の他のコンテナは、Fargate タスクストレージから Kerberos チケットを読み取り、Windows 認証を使用してデータベースに接続する Web アプリケーションを提供します。

Architecture of the solution "Using Windows Authentication with Linux Containers on Amazon ECS"

ソリューション

サンプルコードでは、AWS クラウド開発キット (CDK) を使用して、TypeScript を使用したクラウドリソースをプロビジョニングします。なお CDK は、JavaScript、Python、Java、C# など、使い慣れたプログラミング言語もサポートしています。

このソリューションをデプロイする手順は、次のとおりです。

  • ネットワークインフラストラクチャ、Active Directory、および ECS クラスタを展開します。
  • データベースを Amazon RDS にデプロイし、Active Directory に対して認証するように構成します。
  • Web アプリケーションおよび Kerberos 認証更新サイドカー用の Docker コンテナイメージを構築し、Amazon Elastic Container Registry (Amazon ECR) でホストされているリポジトリに送信 (プッシュ) します。
  • 両方のコンテナを含んだ Fargate タイプのタスクとして ECS サービスを作成します。

このソリューションのコードは GitHub から利用可能です。

前提条件

このチュートリアルでは、以下の前提条件が必要です。

ソリューションの概要

ソリューションを格納するディレクトリを作成して、https://github.com/aws-samples/amazon-ecs-windows-authentication-blog の Git リポジトリをソリューションディレクトリにて複製 (クローン) します。

ソリューションは、共有リソースアプリと Web サイト用のアプリの 2 つの CDK アプリで構成されています。それらの CDK アプリ間の依存関係は最小限です。Web サイト CDK アプリは、共有リソース CDK アプリによって作成された仮想プライベートクラウド (VPC) と ECS クラスターに依存しています。これにより、各マイクロサービスが (ECS クラスターを共有しながら) 独立して定義されるマイクロサービスアーキテクチャが容易になります。

共有リソース CDK アプリは、/cdk の下のソリューションディレクトリにあります。 Web サイト CDK アプリは、/web-site/cdk の下のソリューションディレクトリにあります。

Kerberos チケット更新サイドカーコンテナは、/kerberos-renewal-sidecar の下のソリューションディレクトリにあります。このコンテナは、独自にデプロイされていないため、独自の CDK アプリを持っていません。代わりに、Web サイト CDK アプリに組み込まれています。

共有リソースのデプロイ

共有リソーススクリプトにより、新しい Active Directory が作成されます。ソリューションディレクトリでコマンドプロンプトを開き、次のコマンドを実行します。

export CDK_DEFAULT_ACCOUNT=AWS_ACCOUNT_ID
export CDK_DEFAULT_REGION=AWS_REGION
cd SOLUTION_DIRECTORY/cdk
npm install
cdk bootstrap
cdk deploy --parameters keyPairName=KEY_PAIR_NAME

(このチュートリアル全体を通して、赤字部分 を適切な値に置き換えます。) AWS_ACCOUNT_ID は数字の AWS アカウント ID であり、AWS_REGION はリソースをデプロイするリージョンの識別子です (us-east-1eu-west-2 など)。

新しいディレクトリのドメイン名は directory.ecs-kerberos-sample.com です。CDK スクリプトでドメイン名を変更する場合は、以降のすべてのコマンドと設定でそのドメイン名にて適切に変更してください。

CDK の出力に含まれているもの

  • 新しい Active Directory のディレクトリ ID
  • Active Directory の設定に使用する Amazon EC2 インスタンスへのアクセスを制御する、セキュリティグループのセキュリティグループ ID
  • Active Directory 管理者ユーザーパスワードを含む AWS シークレットマネージャーシークレットを一意に識別する Amazon リソースネーム (ARN)

今後の使用に備えて、これら出力された値をすべてコピーしておきます。

EC2 インスタンスへのアクセスを許可する

CDK スクリプトによって、Active Directory の設定に使用する EC2 インスタンスが作成されました。この時点では、アクセスを許可するセキュリティグループのルールがないため、この EC2 インスタンスは着信接続をブロックしています。

EC2 インスタンスのセキュリティグループにルールを追加するには、AWS マネジメントコンソールの EC2 ページを使用するか、AWS CLI を使用します。CLI を使用するには、自分の IP アドレスを知っている必要がありますが、AWS には、checkip.amazonaws.com でそれを返す機能が提供されています。次のコマンドを実行して自分の IP アドレスを取得し、セキュリティグループを更新します。

AWS_IP_ADDRESS=$(curl checkip.amazonaws.com)
aws ec2 authorize-security-group-ingress --protocol tcp --port 3389 --cidr "$AWS_IP_ADDRESS/32" --group-id DIRECTORY_MANAGEMENT_INSTANCE_SECURITY_GROUP_ID

Active Directory 管理者パスワードの取得

CDK スクリプトは、AWS Secrets Manager に Active Directory 管理者ユーザーのパスワードを保存しました。このパスワードは後の手順で必要になるため、次のコマンドを実行します。

aws secretsmanager get-secret-value --secret-id /ecs-kerberos-sample/active-directory-administrator-password

管理者パスワードは SecureString キーの値です。今後使用するために、このパスワードをコピーしておいてください。

VPC DHCP オプションセットの確認

CDK アプリは、VPC にデプロイされたすべてのリソースに対して Active Directory の DNS サーバーを使用する DHCP オプションセットをデプロイしました。これは、AWS マネジメントコンソールで確認するか、次のコマンドを実行して確認できます。

DHCP_OPTIONS_ID=$(aws ec2 describe-vpcs --filters Name="tag:Name",Values="ecs-kerberos-stack/vpc" --output text --query 'Vpcs[*].DhcpOptionsId')
aws ec2 describe-dhcp-options --dhcp-options-ids $DHCP_OPTIONS_ID --output yaml

domain-name-serversの値に注意してください。これは、コンソール内のディレクトリの DNS アドレスの値と一致している必要があります。

Example of the Directory Details in the AWS Management Console, with the Directory ID and DNS addresses fields highlighted

データベースのデプロイ

サンプルアプリケーションは、2 つのコンテナと 1 つのデータベースで構成されています。最初にデータベースをデプロイしてから、そのデータベースに接続するようにアプリケーションコードを設定します。

コマンドプロンプトで、次のコマンドを実行します。

cd SOLUTION_DIRECTORY/web-site/cdk
ecs-kerberos-sample--web-database-stack

CDK のデプロイメントは、データベースインスタンス識別子、インスタンスエンドポイントアドレス (rds.amazonaws.com で終わるホスト名)、およびデータベース管理者の資格情報を含むシークレットのAmazon リソース名 (ARN) を出力します。これらの値を後で使用するためにコピーしておきます。

サンプルデータベースのインストール

サンプルデータベースをデプロイするには、データベースの管理者ユーザーの資格情報が必要です。 RDS は、これらの認証情報を AWS Secrets Manager に保存します。コンソールからそれらを取得するか、次のコマンドを実行します。

aws secretsmanager get-secret-value --output yaml --secret-id DB_CREDENTIALS_SECRET_ARN

コンソールを使用する場合は、対象のシークレットをクリックしてから [シークレットの値を取得する] をクリックして、ユーザー名とパスワードを表示します。コマンドラインを使用すると、RDS 管理者のユーザー名とパスワードが出力の SecretString 部分に表示されます。

RDS インスタンスはプライベートサブネットにデプロイされているため、インターネットからデータベースにアクセスできません。最初の CDK デプロイには、RDS インスタンスに接続してサンプルデータベースをデプロイするために使用する EC2 インスタンスが含まれています。

コンソールで EC2 に戻り、ecs-kerberos-stack/active-directory-management-instance という名前の EC2 インスタンスを選択し、次の手順に従ってリモートデスクトップを使用してインスタンスに接続します。最初の CDK デプロイメントの keyPairName パラメーター値と一致する秘密鍵を使用します。

リモートデスクトップセッションでは、Microsoft のサイトから次のツールを順番にダウンロードしてインストールします。

ツールがインストールされたら、[スタート] メニューをクリックし、[Windows PowerShell] をクリックします。

Web アプリケーションは、Chinook サンプルデータベースを使用します。 PowerShell にて次のコマンドを実行して、サンプルデータベースをダウンロードします。

mkdir ChinookSetup
cd .\ChinookSetup
Invoke-WebRequest -Uri https://raw.githubusercontent.com/lerocha/chinook-database/master/ChinookDatabase/DataSources/Chinook_SqlServer_AutoIncrementPKs.sql -OutFile Chinook.sql

次の PowerShell コマンドを実行して、サンプルデータベースをインストールします。データベースのパスワードは引用符で囲む必要があることに注意してください。

sqlcmd -S RDS_INSTANCE_ENDPOINT_ADDRESS -U RDS_ADMINISTRATOR_USERNAME -P 'RDS_ADMINISTRATOR_PASSWORD' -i Chinook.sql

サンプルデータベースへの Active Directory 認証を構成

次の PowerShell コマンドを実行して、「AD DS および AD LDS ツール」をインストールします。

Install-WindowsFeature -Name "RSAT-AD-Tools" -IncludeAllSubFeature

ツールをインストールしたら、次のコマンドを実行します。

$credential=Get-Credential

ユーザー名とパスワードの入力を求められます。ユーザー名として admin@directory.ecs-kerberos-sample.com を入力します。パスワードは、最初の CDK スタックをデプロイした後に Secrets Manager から取得した ActiveDirectory 管理者パスワードです。

次に、以下の PowerShell コマンドを実行して、データベースに接続する Active Directory ユーザーを作成します。

New-ADUser -Name "db-user" -UserPrincipalName "db-user@directory.ecs-kerberos-sample.com" -Credential $credential -Server directory.ecs-kerberos-sample.com

db-user の安全なパスワードを作成してから、次の PowerShell コマンドを実行します。

Set-ADAccountPassword -Identity db-user -Reset -Credential $credential -Server directory.ecs-kerberos-sample.com

プロンプトが表示されたら、db-user ユーザーのパスワードを入力します。

次の PowerShell コマンドを実行して、ユーザーを有効にします。

Enable-ADAccount -Identity "db-user" -Credential $credential -Server directory.ecs-kerberos-sample.com

ここで、db-user に RDS データベースへのアクセスを許可します。次の PowerShell コマンドを実行して、RDS インスタンスで SQL プロンプトを開始します。

sqlcmd -S RDS_INSTANCE_ENDPOINT_ADDRESS -U RDS_ADMINISTRATOR_USERNAME -P 'RDS_ADMINISTRATOR_PASSWORD'

SQL プロンプトが表示されたら、次のコマンドを実行します。

CREATE LOGIN [directory\db-user] FROM WINDOWS WITH DEFAULT_DATABASE = [Chinook]
GO
USE Chinook
GO
CREATE USER [directory\db-user] FOR LOGIN [directory\db-user] WITH DEFAULT_SCHEMA=[dbo]
GO
EXEC sp_addrolemember N'db_owner', N'directory\db-user'
GO
EXIT

リモートデスクトップセッションからログアウトします。

コマンドプロンプトで次のコマンドを実行して、db-user 認証情報を AWS Secrets Manager に保存します。

aws secretsmanager create-secret --name /ecs-kerberos-sample/web-site/db-user-credentials --secret-string '{"username":"db-user","password":"DB-USER_PASSWORD"}'

このコマンドの出力の「ARN」キーの値をコピーし、今後のステップで使用するために保存しておきます。

Kerberos 設定の確認

SOLUTION_DIRECTORY/web-site/krb5.conf をテキストエディタで開きます。これは、標準の Kerberos 構成ファイルです。このファイルに変更を加えることはありませんが、認証がどのように構成されているかを理解することが重要です。

[logging]
default = STDERR

[libdefaults]
dns_lookup_realm = true
dns_lookup_kdc = true
forwardable = true
rdns = false
default_ccache_name = FILE:/var/scratch/krbcache
default_realm = DIRECTORY.ECS-KERBEROS-SAMPLE.COM

[realms]
DIRECTORY.ECS-KERBEROS-SAMPLE.COM = {
  kdc = directory.ecs-kerberos-sample.com
  admin_server = directory.ecs-kerberos-sample.com
}

[realms] エントリは、すべて大文字の Active Directory のドメイン名であり、kdcadmin_server の値は Active Directory のドメイン名であることに注意してください。 VPC オプションセットにより、このドメイン名は VPC 内でのみ解決されます。

default_ccache_name は、Kerberos チケットが保存される場所 (上記設定の場合は/var/scratch/krbcache) を指定します。 CDK スクリプトは、Fargate タスク用のボリュームを作成し、このボリュームを両方のコンテナの /var/scratch にマウントして、コンテナがこのストレージを共有できるようにします。

kerberos-renewal-sidecar ディレクトリには、Web サイトの構成と一致する設定を持つ krb5.conf 設定ファイルも含まれています。

Docker コンテナイメージのビルド

SOLUTION_DIRECTORY/web-site/appsettings.Development_AWS.json をテキストエディタで開きます。文字列 {{RDS_INSTANCE_IDENTIFIER}} を RDS インスタンスのインスタンス識別子に置き換えます。接続文字列内のサーバー名は、ディレクトリの名前で終わる必要があります。データベースインスタンス識別子が foo の場合、サーバーは foo.directory.ecs-kerberos-sample.com である必要があります。RDS インスタンスのエンドポイントアドレスではなく、このホスト名を使用することが重要です。

接続文字列には資格情報が含まれておらず、代わりに Integrated Security=true を指定していることに注意してください。

次のコマンドを実行して、Web サイトコンテナイメージの ECR リポジトリを作成します。

cd SOLUTION_DIRECTORY/web-site
aws ecr create-repository --repository-name ecs-kerberos-sample/web-site

リポジトリを作成したら、コンソールで ECR に移動し、ecs-kerberos-sample/web-site ポジトリをクリックします。[プッシュコマンドの表示] ボタンをクリックし、指示に従って Docker イメージにタグを付けて ECR リポジトリにプッシュします。

Example ECR push commands in the AWS Management Console

次に、Kerberos 更新サイドカーコンテナの Docker イメージを作成します。次のコマンドを実行します。

cd SOLUTION_DIRECTORY/kerberos-renewal-sidecar
aws ecr create-repository --repository-name ecs-kerberos-sample/kerberos-renewal-sidecar

リポジトリを作成したら、コンソールで ECR に移動し、ecs-kerberos-sample/kerberos-renewal-sidecar リポジトリをクリックします。[プッシュコマンドの表示] ボタンをクリックし、指示に従って Docker イメージにタグを付けて ECR リポジトリにプッシュします。

Web サイト ECS サービスをデプロイ

コマンドプロンプトで次のコマンドを実行します。

cd SOLUTION_DIRECTORY/web-site/cdk
cdk deploy --parameters databaseCredentialsSecretArn='DB-USER_CREDENTIALS_SECRET_ARN' ecs-kerberos-sample--web-application-stack

この CDK スクリプトは、Fargate サービスを ECS クラスターにデプロイします。このサービスは Web サイト用ともう 1 つは Kerberos 更新サイドカー用の、2 つのコンテナを含む 1 つのタスクで構成されています。Kerberos 更新サイドカーは、データベース資格情報シークレットを使用して Active Directory に対して認証し、Kerberos チケットを生成します。 Kerberos チケットは、両方のコンテナがアクセスできる共有ボリュームに格納されます。Web アプリケーションは、データベースに接続するときに、共有ボリュームから Kerberos チケットを読み取ります。

CDK スクリプトは、Fargate サービスの前にインターネット向けロードバランサーをデプロイし、ロードバランサーの URL を出力します。ロードバランサーの DNS 名は、コンソールのロードバランサーのページでも確認できます。Web ブラウザでロードバランサーの URL にアクセスして、アプリケーションをテストします。 「Hello World」メッセージと、データベースからランダムに選択された 5 枚のアルバムのリストが表示されます。

クリーンアップ

今後の課金が発生しないようにするには、リソースを削除します。cdk destroy コマンドを使用して、スタックをデプロイしたのと逆の順序でスタックを削除できます。

  • cdk destroy ecs-kerberos-sample—web-application-stack
  • cdk destroy ecs-kerberos-sample—web-database-stack
  • cdk destroy ecs-kerberos-stack

コンソールの CloudFormation ページに移動してスタックを削除します。

スタックを削除することに加えて、ECR リポジトリとシークレットを削除する必要があります。

まとめ

この記事では、個々のコンテナをドメインに結合せずに、推奨されるメカニズムである統合 Windows 認証を使用して SQL Server のデータベースに接続するコンテナ化されたワークロードを Amazon ECS にデプロイしました。このソリューションの認証は、認証ソースとして機能する AWS Managed Active Directory に基づいています。

翻訳はソリューションアーキテクト 杉本 晋吾 が担当しました。原文はこちらです。