Amazon Web Services ブログ

Amazon Aurora MySQLやAmazon RDS for MySQLへIAM authenticationを利用してSQL Workbench/Jから接続する

はじめに

Amazon Relational Database Service(Amazon RDS)を使用すると、Amazon RDS for MySQL DBインスタンスとAmazon Aurora MySQL DBクラスタをAWS Identity and Access Management(IAM)を使用してデータベースアクセスを管理できます。データベース管理者は、データベースユーザーをIAMユーザーおよびロールに関連付けることができます。 IAMを使用すると、1箇所でAWSリソース全てへのユーザーアクセスを管理し、異なるAWSリソース間で同期がとれていないアクセス権によって引き起こされる問題を回避できます。使い慣れたクライアントツールでパスワードの代わりにIAM認証を使用できます。

この記事では、Aurora MySQLクラスタに接続するために既に使用しているツールでIAM認証を使用する方法を説明します。この手順は、Amazon RDS for MySQLインスタンスでも同様にご利用頂けます。提供されたスクリプトを使用して、リソースをプロビジョニングしたり、IAM認証用に環境を構成したりすることができます。

スクリプトを使用してIAM認証情報を使用して、mysqlコマンドラインツールまたはSQL Workbench / Jを使用してクラスタに接続します。GitHubリポジトリでは、この投稿で使用されているコードサンプルをご覧いただけます。

 

事前準備

mysqlコマンドラインツールを使用する場合は、Amazon RDSドキュメントに記載されているAmazon S3バケットから証明書をダウンロードしてください。mysqlコマンドラインツールでは、SSL(Secure Sockets Layer)接続をするためにこの証明書が必要です。

初めてSQL Workbench / Jを使用してMySQLデータベースに接続するには、JDBCドライバを設定する必要があります。 初めてSQL Workbench / Jを使用する場合は、SQL Workbench / Jのドキュメントの手順に従ってドライバを設定してください。

 

セットアップ

既存のAurora MySQLクラスタまたはAmazon RDS for MySQLデータベースを使用してIAM認証を有効にするか、新規に作成することができます。私のテストでは、AWS CloudFormationテンプレートを使用して新しいAurora MySQLクラスタを作成しました。新しいIAMユーザーとデータベースユーザーを作成し、データベースユーザーのIAM認証を設定しました。スクリプトを使用したい場合は、「すべてをbashスクリプトで実行」というタイトルのセクションをご覧ください。

データベースの作成

Aurora MySQLクラスタまたはAmazon RDS MySQLインスタンスをまだお持ちでない場合は、作成する必要があります。データベースは、クライアントマシンからの接続を許可するセキュリティグループを設定する必要があります。すでにAurora MySQLデータベースをお持ちの場合は、この手順をスキップして下さい。

お持ちでない場合は、AWS Management Console、AWS CLI、AWS SDK、またはAWS CloudFormationテンプレートを使用して、Aurora MySQLクラスタをプロビジョニングできます。この記事のコードセットには、Aurora MySQLクラスタを作成するAWS CloudFormationテンプレートが含まれています(2つのインスタンス、1つのアベイラビリティゾーンと2つのアベイラビリティゾーンに配置したリードレプリカがで構成されています)。コードサンプルをダウンロードする場合は、AWS CloudFormationテンプレートのcreate-databases.yamlを使用してクラスタをプロビジョニングすることができます。または、Amazon RDS User GuideCreating an Amazon Aurora DB Clusterの手順に従ってください。

Create-Stack

IAM authenticationの有効化

デフォルトでは、DBインスタンスとDBクラスタでIAMデータベース認証は無効になっています。コンソール、AWS CLI、またはAmazon RDS APIを使用して、IAMデータベース認証を有効にする(または無効にする)ことができます。コンソールでの手順を含め、データベースでIAM認証を有効にする手順は、Enabling and Disabling IAM Database Authenticationを参照してください。

コマンドラインからIAM認証を有効にするには、クラスタ名を知る必要があります。 Amazon RDSコンソールまたはAWS CloudFormationテンプレートの出力を参照することで確認できます。

CF-Template

次のコマンドは、クラスタiamauth-databasecluster-abcdefg222hqでIAM認証を有効する例です:

aws rds modify-db-cluster \
    --db-cluster-identifier "iamauth-databasecluster-abcdefg222hq" \
    --apply-immediately \
    --enable-iam-database-authentication

IAMリソース

この記事では、次の図に示すように、1つのIAMユーザーにrds-db:connectというアクションのポリシーを追加しました。

iam-policy

Amazon Resource Names(ARN)を利用して、さまざまなアクセスパターンをサポートするために、複数のユーザーまたはロールにポリシーを追加することができます。その他のアクセスパターンの詳細については、Creating and Using an IAM Policy for IAM Database Accessを参照してください。

Policy

IAMユーザーまたはロールがDBインスタンスまたはDBクラスタに接続できるようにするに、IAMポリシーを作成する必要があります。 そして、ポリシーをIAMユーザーまたはロールに追加します。 4つの重要なデータからポリシーを作成します:

  • クラスタのAWSリージョン
  • アカウント番号
  • DBリソースID
  • データベースユーザー名
{
  "Version" : "2012-10-17",
  "Statement" :
  [
    {
      "Effect" : "Allow",
      "Action" : ["rds-db:connect"],
      "Resource" : ["arn:aws:rds-db:us-east-1:123456789012:dbuser:cluster-11AABB87JJCCTZUFR551111111/mydbuser"]
    }
  ]
}

次の形式で指定で、アカウント内に存在する特定のDBインスタンスを示すARNを記述します:

arn:aws:rds-db:region:account-id:dbuser:resource-id/database-user-name

前述のポリシー例では、以下の要素を私の環境に合わせて記述しています:

  • AWSリージョン: us-east-1
  • アカウントID: 123456789012
  • リソースID: cluster-11AABB87JJCCTZUFR551111111
  • データベースユーザー名: mydbuser

最後の2つの値を詳しく見てみましょう。

リソースIDは、DBインスタンスの識別子です。 この識別子はAWSリージョンに固有のものであり、決して変更されません。このポリシー例では、識別子はcluster-11AABB87JJCCTZUFR551111111です。 Amazon RDSコンソールでリソースIDを検索するには、目的のDBクラスタを選択し、 DetailsセクションにリソースIDが表示されます。

または、AWS CLIコマンドを使用して、次のように、現在のAWS Region内のすべてのDBインスタンス識別子とリソースIDを表示することができます:

aws rds describe-db-instances \
    --query "DBInstances[*].[DBInstanceIdentifier,DbiResourceId]"

DBユーザー名は、IAM認証に関連付けるMySQLデータベースアカウントの名前です。 このポリシー例では、ユーザー名はmydbuserです。

ポリシーの作成

ポリシーを作成するために、私はbashスクリプトcreate-stack-and-user.sh内でAWS CLI create policyコマンドを使用しました。 次の図は、引用符をエスケープしたポリシードキュメントの文字列表現を使用して、database-login-mydbuserという名前のポリシーを作成するcreate policyコマンドを示しています。

IAM-Policy

ポリシーの付与

データベース認証を許可するIAMポリシーを作成したら、IAMユーザーまたはロールにポリシーを追加する必要があります。このトピックに関するチュートリアルについては、IAMユーザーガイドCreate and Attach Your First Customer Managed Policyを参照してください。

新しいIAMユーザーを作成し、次のAWS CLIコマンドを使用して新しいIAMユーザーにポリシーを追加しました。 この機能では、コンソールのパスワードまたはアクセスキーは必要ありません。私の例で作成したユーザーはどちらも持っていません。

aws iam create-user --user-name mydbuser

aws iam attach-user-policy \
  --policy-arn arn:aws:iam123456789012:policy/database-login-mydbuser \
  --user-name mydbuser

データベースユーザの作成

IAMユーザーを作成し、ユーザーにIAMポリシーを添付したら、ポリシーで指定したものと同じ名前のデータベースユーザーを作成する必要があります。mysqlコマンドラインツールを使用して、マスターユーザーとしてデータベースに接続し、ユーザーを作成しました。次のコマンドは、Aurora MySQLクラスタに接続し、create-user.sqlファイルでSQLを実行します。

mysql -h ${AURORAEP%%:*} -P 3306 --user=$MASTERUSER -p < create-user.sql

CREATE USER権限を持つユーザーとして接続し、次のステートメントを実行します。

CREATE USER mydbuser IDENTIFIED WITH AWSAuthenticationPlugin AS 'RDS';
GRANT ALL ON `%`.* TO mydbuser@`%`;

最初のステートメントでは、IDENTIFIED WITH句を指定することで、MySQLはAWSAuthenticationPluginを使用してデータベースアカウント(mydbuser)を認証できます。 AS 'RDS'句は、mydbuserデータベース・アカウントを、ポリシーによって指定された対応するIAMユーザーまたは役割にマップします。2番目のステートメントは、すべてのデータベースに対するユーザー権限を付与します。

通常、MySQLデータベースにユーザーを追加するときに、特定のユーザーアカウントに対してSSL接続を要求するかどうかを指定できます。IAM認証を使用する場合、ユーザーの設定はSSLを要求するように上書きされます。ユーザー作成時のREQUIRE SSLオプションの詳細については、Security with Amazon Aurora MySQLを参照してください。

すべてをbashスクリプトで実行

前のプロセスをcreate-stack-and-user.shスクリプトを使用して実行するには、次の手順を実行します。

  1. リポジトリファイルをローカルにダウンロードします
  2. ご使用の環境に合わせてcreate-stack-and-user.shの、accountidstacknameregion、およびiamuserを編集します
  3. ご使用の環境に合わせてAWS CloudFormationパラメータ値config / cf-parameters.jsonを編集します
  4. 所望ののIAMユーザ名をconfig / create-user.sql内で編集します。名前は、手順2のスクリプトのiamuserと一致する必要があります
  5. コマンドラインからcreate-stack-and-user.shスクリプトを実行します。

このスクリプトは、AWS CLImysqlコマンドラインツール、およびjqプログラミング言語に依存しています。スクリプトはAWS CloudFormationスタックを起動し、IAMを使用するように実行中のインスタンスを変更します。インスタンスの設定が変更されると、スクリプトは新しいIAMユーザーと新しいIAMポリシーを作成し、新しいポリシーをユーザーに割り当てます。最後に、スクリプトはIAMユーザーをデータベースユーザーとして新しいデータベースに追加し、セットアッププロセスを完了します。

 

接続

IAMデータベース認証では、DBインスタンスまたはDBクラスタに接続するときにIAM認証トークンを使用します。 IAM認証トークンは、パスワードの代わりに使用する文字列です。 IAM認証トークンを生成した後は、有効期限が切れるまで15分間有効です。期限切れのトークンを使用して接続しようとすると、接続要求は拒否されます。 MySQLは既存の接続を再チェックしないので、トークンの有効期限が切れたときに確立された接続は破棄されません。

AWS Signature Version 4を使用して、すべてのIAM認証トークンに有効な署名が付いている必要があります(詳細は、AWS General Referenceの Signature Version 4 Signing Process を参照してください)。AWS CLIおよびAWS SDK for Javaは自動で署名を作成出来ますし、AWS CLIを使用して接続トークンの生成も可能です。

署名されたIAM認証トークンを取得したら、Amazon RDS DBインスタンスまたはAurora DBクラスタに接続できます。

トークンの作成

以下の例では、AWS CLIを使用して、署名付きIAM認証トークンを生成します。AWS CLIコマンドはgenerate-db-auth-tokenで、次の4つのパラメータを入力として受け取ります:

  • hostname: Aurora MySQLクラスタのエンドポイント
  • port: 接続時に使用される接続ポート。この例では3306
  • username: アクセスするデータベースのアカウント
  • region: DBクラスタが動作しているAWSリージョン
aws rds generate-db-auth-token --hostname $AURORAEP --port 3306 \
--username $IAMUSER --region=$REGION

このコマンドから生成されるトークンは、長さが数百文字であり、コマンドラインに直接入力することが難しい場合があります。

aws rds generate-db-auth-token \
--hostname iamauth-databasecluster.cluster-abcdefg222hq.us-east-1.rds.amazonaws.com \
--port 3306 --username mydbuser --region us-east-1

接続を行うときに使用する変数にトークンをセットすることがベストプラクティスです。

TOKEN="$(aws rds generate-db-auth-token --hostname $AURORAEP --port 3306 --username $IAMUSER --region=$REGION)"

mysqlコマンドを使用してクラスタに接続する

トークンを生成したら、mysqlコマンドラインツールを使用してAurora MySQLクラスタに接続するのは簡単です。この方法を使用するためには、クライアントマシンにSSL証明書ファイルが必要です。

mysql -h ${AURORAEP%%:*} -P 3306 --ssl-ca=~ /Downloads/rds-ca-2015-root.pem \
--enable-cleartext-plugin --user=$IAMUSER --password=$TOKEN

既にmysqlコマンドラインツールを使用している場合は、上記のコマンドのほとんどをご存知かと思います。2つのオプションをご説明します。

  • enable-cleartext-plugin: この接続にAWSAuthenticationPluginを使用する必要があることを設定します
  • ssl-ca: 信頼できるSSL証明機関のリストを含むファイル。上記の証明書は、すべてのリージョンで利用頂けます。しかし、失敗した場合は、リージョン固有の証明書をダウンロードする必要があります

すべてを接続スクリプトに設定したら、MySQLクラスタへの接続を開始するには、コマンドラインから次のようなbashスクリプトを実行するだけです:

#!/usr/bin/env bash

STACKNAME="iamauth"
REGION="us-east-1"
IAMUSER="mydbuser"
AURORAEP="$(aws cloudformation describe-stacks --stack-name "$STACKNAME" --region $REGION | jq '.Stacks[].Outputs[] | select(.OutputKey=="AuroraClusterEndpoint")' | jq -r .OutputValue)"
DBNAME="$(aws cloudformation describe-stacks --stack-name "$STACKNAME" --region $REGION | jq '.Stacks[].Outputs[] | select(.OutputKey=="AuroraDatabaseName")' | jq -r .OutputValue)"

# Make sure you have the right region for the token!!
TOKEN="$(aws rds generate-db-auth-token --hostname $AURORAEP --port 3306 --username $IAMUSER --region=$REGION)"

#set -x
mysql -h ${AURORAEP%%:*} -P 3306 --ssl-ca=~/Downloads/rds-ca-2015-root.pem \
--enable-cleartext-plugin --user=$IAMUSER --password=$TOKEN
#set +x

./conn-aurora-iam-auth.sh

スクリプトが実行されると、トークンを生成し、mysqlコマンドラインツールで接続します。

conn

SQL Workbench/Jで接続する

SQL Workbench / Jを使用してAurora MySQLクラスタに接続する方法は、以前にアプリケーションを起動した方法とは少し異なります。 SQLWorkbenchJ.appを使用してSQL Workbench / Jを起動する代わりに、トークンを利用して起動するため.jarファイルを使用して直接起動します。

java -jar ~/workbench/sqlworkbench.jar \
-url=jdbc:mysql://$AURORAEP:3306/$DBNAME?verifyServerCertificate=false\&useSSL=true\&requireSSL=true \
    -driver=com.mysql.jdbc.Driver \
    -username=$IAMUSER \
    -password=$TOKEN \
    -libdir= /Users/wendyneu/workbench \
    -driverjar=/Users/wendyneu/workbench/mysql-connector-java-5.1.45-bin.jar
  • url: クラスタ名、データベース名、およびSSLオプションで構成されるJDBC接続URL
  • driver: ドライバのフルクラス名。正しいスペルが必要で、大文字と小文字が区別されます
  • username: データベースのユーザー名
  • password: 生成されたトークン
  • libdir: JDBCドライバの.jarファイルを含むディレクトリの絶対パス名。相対パスにすることはできません
  • driverjar: JDBCドライバーを含む.jarファイルへの絶対パス名。相対パスにすることはできません

すべてを接続スクリプトに入れたら、MySQLクラスタへの接続を開始するには、コマンドラインから次のようなbashスクリプトを実行するだけです:

#!/usr/bin/env bash
#
#   Script to launch SQL Workbench from a command line and connect to
#   an Aurora MySQL database cluster using IAM authentication
#
STACKNAME="iamauth"
REGION="us-east-1"
IAMUSER="mydbuser"
AURORAEP="$(aws cloudformation describe-stacks --stack-name "$STACKNAME" --region $REGION | jq '.Stacks[].Outputs[] | select(.OutputKey=="AuroraClusterEndpoint")' | jq -r .OutputValue)"
DBNAME="$(aws cloudformation describe-stacks --stack-name "$STACKNAME" --region $REGION | jq '.Stacks[].Outputs[] | select(.OutputKey=="AuroraDatabaseName")' | jq -r .OutputValue)"

# Make sure you have the right region for the token!!
TOKEN="$(aws rds generate-db-auth-token --hostname $AURORAEP --port 3306 --username $IAMUSER --region=$REGION)"

#set -x
java -jar ~/workbench/sqlworkbench.jar \
    -url=jdbc:mysql://$AURORAEP:3306/$DBNAME?verifyServerCertificate=false\&useSSL=true\&requireSSL=true \
    -driver=com.mysql.jdbc.Driver \
    -username=$IAMUSER \
    -password=$TOKEN \
    -libdir= /Users/wendyneu/workbench \
    -driverjar=/Users/wendyneu/workbench/mysql-connector-java-5.1.45-bin.jar
#set +x
./wbconn-aurora-iam-auth.sh

スクリプトは自動的に実行され、トークンを生成してSQL Workbench / J GUIを起動し、データベースに接続します。

Command-Line

SQL Workbench / Jのその他のコマンドラインオプションについては、SQL Workbench / Jのドキュメントを参照してください。

 

Limitations

IAMデータベース認証を使用する場合、いくつかの制限があります。以下は、IAM認証のドキュメントに記載されています。記事全体を読むには、IAM Database Authentication for MySQL and Amazon Auroraを参照してください。

IAMデータベース認証では、毎秒最大20新規接続に制限されています。db.t2.microインスタンスクラスを使用している場合、制限は1秒あたり10接続です。

IAMデータベース認証を使用する場合は、アプリケーションでIAM認証トークンを生成する必要があります。アプリケーションは、そのトークンを使用してDBインスタンスまたはクラスタに接続します。1秒あたりの最大新規接続数の上限を超えると、IAMデータベース認証のオーバーヘッドによって接続が制限される可能性があります。

以下を推奨します:

  • データベースへの一時的で個人的なアクセスのための機能としてIAMデータベース認証を使用します
  • アプリケーションで毎秒20を超える新規接続が必要な場合は、IAMデータベース認証を使用しないでください
  • 簡単に再試行できるワークロードに対してのみIAMデータベース認証を使用します

 

最後に

Amazon RDS for MySQLおよびAmazon Aurora MySQLデータベースでIAM認証を使用することには多くの利点があります。データベースとの間のネットワークトラフィックは、SSLを使用して暗号化されます。新しいユーザーと既存のデータベースユーザーをIAMユーザーとロールに関連付け、IAMを使用して資格情報を管理し、データベース内でユーザーを管理する必要はありません。Amazon EC2上で動作するアプリケーションの場合、セキュリティを強化するために、EC2インスタンスプロファイル認証情報を使用してパスワードの代わりにデータベースにアクセスできます。この記事では、mysqlコマンドラインツールやSQL Workbench / Jなどのツールで、パスワードの代わりにIAM認証を使用する方法を紹介しました。これらの方法とプロセスを他のツールに適用することができます。

 


About the Author

Wendy Neu 2015年1月よりData Architect としてAmazonで働いています。 Amazonに入社する前は、オハイオ州シンシナティでコンサルタントとして働いていました。お客様がさまざまなデータソースからデータを統合して管理できるよう支援しています。

 

 

翻訳は星野が担当しました。原文はこちら