IAM認証によるRDS接続を試してみた

まいどおおきに、大阪の市田です。
先日、IAM認証でRDSに接続できるリリースがありました。利用できるデータベースは「RDS for MySQL」と「Aurora」の2種類になります。

AWS IAM で RDS for MySQL と Amazon Aurora データベースへのアクセスを管理

やってみた

それでは早速試してみます。今回はRDS for MySQLで試してみました。

RDSインスタンスの作成

まずはRDSインスタンスの作成時についてです。

RDSインスタンスの作成時に「Enable IAM DB Authentication(IAMのDB認証を有効にする)」の項目で「Yes」 を選択するだけです。

02-enableiam

尚、利用できるエンジンバージョンとインスタンスタイプは下記に記載しています。今回は「MySQL 5.6.34」を指定しています。

01-mysqlversion

対象のインスタンスタイプとエンジンバージョン

対象となるインスタンスタイプとエンジンバージョンは、RDS for MySQLとAuroraのそれぞれで以下の様になっています。

対象RDS 対応バージョン 対応インスタンスタイプ
MySQL 5.6 5.6.34以上 db.t1.micro、db.m1.smallを除く全て
MySQL 5.7 5.7.16以上 db.t1.micro、db.m1.smallを除く全て
Aurora 1.10以上 db.t2.smallを除く全て

IAM認証用ユーザの作成

RDSインスタンスが作成出来たら、次の作業を行います。

  • マスターユーザでRDSに接続
  • IAM認証用のユーザ作成

まず、RDSに接続できるEC2にアクセスします。対象のEC2のAWS CLIをアップデートしておきます。

$ sudo pip install -U awscli
$ aws --version
aws-cli/1.11.81 Python/2.7.12 Linux/4.4.41-36.55.amzn1.x86_64 botocore/1.5.44

RDS for MySQLに接続します。

$ mysql -h iamtest.xxxxxxxxxxxx.ap-northeast-1.rds.amazonaws.com -u mymaster -p

Enter password:
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 26
Server version: 5.6.34-log MySQL Community Server (GPL)

Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql>

DBに接続できたら、IAM認証用ユーザを作成します。今回は「iam_user」 というユーザを作成します。

またインスタンス作成時に作成したデータベース「mytestdb」 に対する権限を追加します。 権限の種類は要件に応じたものにして下さい。今回は「SELECT」のみにしています。

アクセス元は「%」(ワイルドカード)を設定して制限を行っていません。 アクセス制御はセキュリティグループで行うことを想定した為です。

CREATE USER iam_user@'%' IDENTIFIED WITH AWSAuthenticationPlugin as 'RDS';

GRANT文の発行時に 「REQUIRE SSL」 でSSL接続を指定します。

mysql> GRANT SELECT ON `mytestdb`.* TO 'iam_user'@'%' REQUIRE SSL;

IAM Roleの設定

次に、EC2に設定しているIAM Roleに対して、IAM接続用のポリシーを設定します。「Resouce」に設定する書式は次の通りです。
region、account-id、dbi-resource-id、database-user-nameについては利用環境のものを指定します。

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

Tokyoリージョンで、「iam_user」というユーザの場合は、下記のようになります。(アカウントは12345678)

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "rds-db:connect"
      ],
      "Resource": [
        "arn:aws:rds-db:ap-northeast-1:12345678:dbuser:cluster-XXXXXXXXXXXXXXXXXXXXXXXXXX/iam_user"
      ]
    }
  ]
}

「dbi-resource-id」 の部分はマネージメントコンソールでは「Resource ID」 の箇所に表示されています。

03-resource-id

AWS CLIの場合は、aws rds describe-db-instancesコマンドで確認出来ます。
特定のRDSインスタンスを指定する場合は--filtersオプションを使いますが、フィルターに使う「db-instance-id」はARNを指定します。Auroraの場合は「db-cluster-id」をフィルタに使用します。

$ aws rds  describe-db-instances \
--filters "Name=db-instance-id,Values=arn:aws:rds:ap-northeast-1:xxxxxxxxxxxx:db:xxxxxxx" \
--query "DBInstances[*].DbiResourceId"
[
    "db-XXXXXXXXXXXXXXXXXXXXXXXXXX"
]

証明書の取得

IAM認証を利用する場合、SSL接続が必要になるため、証明書をダウンロードして適当なパスに保存します。
証明書は下記からダウンロードします。

https://s3.amazonaws.com/rds-downloads/rds-combined-ca-bundle.pem

参考URL:

Amazon Aurora の概要 - Amazon Relational Database Service

確認

これで準備が整いました。 IAM認証による接続では、認証トークンを使用してDBインスタンスに接続します。認証トークンは下記のコマンドで取得できます。

$ aws rds generate-db-auth-token \
--hostname iamtest.xxxxxxxxxxxx.ap-northeast-1.rds.amazonaws.com \
--port 3306 \
--username iam_user \
--region ap-northeast-1

このトークンをパスワードに指定してRDSに接続する形になります。 実際にコマンドラインで、IAM認証用のユーザ「iam_user」でRDSに接続する場合は次のようなコマンドになります。

$ mysql -u iam_user -h iamtest.xxxxxxxxxxxx.ap-northeast-1.rds.amazonaws.com \
-p`aws rds generate-db-auth-token --hostname iamtest.xxxxxxxxxxxx.ap-northeast-1.rds.amazonaws.com \
--port 3306 \
--username iam_user \
--region ap-northeast-1` \
--ssl-ca=/home/ec2-user/rds-combined-ca-bundle.pem \
--enable-cleartext-plugin

仮にIAMのARNの記載を間違えていると、下記のようになりログインできませんでした。

ERROR 1045 (28000): Access denied for user 'iam_user'@'192.168.2.47' (using password: YES)

--enable-cleartext-pluginオプションについて

トークンをパスワードとして使う場合、クリアテキストで送信する必要があります。その際「mysql_clear_password」 というプラグインを使う必要があるのですが、mysqlやmysqladminクライアントなどでは、「 --enable-cleartext-plugin 」 オプションを使うことで、接続の度にこのプラグインを有効にすることが出来ます。

その為、mysqlコマンドで接続する際は「--enable-cleartext-plugin」オプションが必要になります。もしこのオプションを省略すると、下記のように「mysql_clear_password」プラグインをロードする必要がある旨のエラーが表示されます。

ERROR 2059 (HY000): Authentication plugin 'mysql_clear_password' cannot be loaded: plugin not enabled

下記のページに詳細が記載されています。

6.3.8.7 クライアント側のクリアテキスト認証プラグイン

ローカルPCからRDSに直接接続してみる

次に、ローカルにあるMacから直接接続してみたいと思います。

これまではRDSに接続する場合は、VPN経由でアクセスしていたと思われますが、IAM認証で接続することで、SSL接続になり固定のパスワード認証もなくなりました。その為、VPNを張らずに直接RDSに接続するという方法も接続の選択肢になってくるのでは無いかと思います。

ただし、直接接続するには、RDSの「Publicly Accessible」 を有効にする必要がある点にご注意下さい。

必要な作業

ローカルPCから直接接続する為には次の作業が必要になります。

  • ルートテーブルにローカルPCへの戻りのルーティングの追加
  • RDSのセキュリティグループにローカルPCからのアクセス許可の追加
  • RDSの「Publicly Accessible」の有効化
  • ローカルPCにSSL証明書の設置
  • AWS CLIのアップデート

それぞれの作業を実行します。

ローカルPCへの戻りのルーティングの追加

対象のVPCに対して、ローカルPCへの戻りのルーティングを追加します。IPはローカルPCのある拠点のIPを指定しています。

05-route

セキュリティグループにアクセス許可を追加

ローカルPCのある拠点IPからのアクセスだけ追加します。

06-mysql

「Publicly Accessible」の有効化

インターネット経由でアクセスすることになるので、RDSの「Publicly Accessible」を有効化します。

04-pubaccess

ローカルPCにSSL証明書の設置

先程と同じように、証明書を適当なパスにダウンロードします。

MacのAWS CLIをバージョンアップ

接続する前に、MacのAWS CLIを最新のものにバージョンアップしておきます。

$ sudo pip install -U awscli
$ aws --version
aws-cli/1.11.81 Python/2.7.11 Darwin/16.5.0 botocore/1.5.44

Macから接続

これで準備ができましたので接続してみます。コマンドの内容は、証明書のパス以外は先程と同じです。

$ mysql -u iam_user -h iamtest.xxxxxxxxxxxx.ap-northeast-1.rds.amazonaws.com \
-p`aws rds generate-db-auth-token --hostname iamtest.xxxxxxxxxxxx.ap-northeast-1.rds.amazonaws.com \
--port 3306 \
--username iam_user \
--region ap-northeast-1` \
--ssl-ca=/Users/hoge/rds-combined-ca-bundle.pem \
--enable-cleartext-plugin

RDSの マスターユーザはパスワード認証になるので、VPCからのみアクセス可能にすればいい かと思います。

mysql> RENAME USER 'master_user'@'%' TO 'master_user'@'192.168.0.0/255.255.0.0';

mysql> select Host, User, Password from mysql.user;
+-------------------------+-------------+-------------------------------------------+
| Host                    | User        | Password                                  |
+-------------------------+-------------+-------------------------------------------+
| localhost               | rdsadmin    | *xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx |
| 192.168.0.0/255.255.0.0 | master_user | *xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx |
| %                       | iam_user    |                                           |
+-------------------------+-------------+-------------------------------------------+
3 rows in set (0.00 sec)

最後に

IAM認証による接続でRDSの利用方法が広がったと思います。セキュリティ要件に応じてうまく使い分けるようにしていきたいですね。

以上です。