セキュリティリスク回避のためのRDS(MySQL)へのIAM認証導入

はじめに

Amazon RDSではユーザー名とパスワード以外にIAM認証という機能があります。RDSなどの接続用パスワードをソースコードに書き込むのはよくあるセキュリティリスクの一つではあるんですが、環境変数やParameter Store、Secrets Managerに格納するのはそれはそれで面倒臭いです。そこで、IAM認証という機能を使ってパスワードを使わないようにします。

今回は、MySQLでEC2からCLI接続するときの認証をIAM認証を使ったケースを試してみます。

準備

EC2からMySQLに接続するためのCLIをインストールします。以下を参照しますが、MariaDBクライアントを利用します。

docs.aws.amazon.com

今後の作業用のために環境変数としてDB_ENDPOINTIAM_USERNAMEを指定します。

export DB_ENDPOINT=RDSのエンドポイント
export IAM_USERNAME=IAM認証するユーザ名

手順

具体的な手順は以下のre:Postにて公開されていますので、この手順に従って作業を進めます。

repost.aws

IAM認証の有効化

まず、RDSのインスタンス作成時や変更でIAM認証を有効化しておきます。

IAM認証を有効化してない場合、以下のSQL文の実行時にエラーメッセージERROR 1524 (HY000): Plugin 'AWSAuthenticationPlugin' is not loadedが出力されます。

CREATE USER IAM認証するユーザ名 IDENTIFIED WITH AWSAuthenticationPlugin as 'RDS';

SSLを使用して接続するように設定します。

ALTER USER IAM認証するユーザ名 REQUIRE SSL;

IAMポリシーの作成

接続の許可を設定するためにIAMポリシーを設定します。詳細は以下を確認します。

docs.aws.amazon.com

作成したIAMポリシーをもとにIAMロールを作成し、EC2にアタッチすると準備はOKです。

証明書を取得する

接続時に指定する証明書をダウンロードします。上記のre:Postの記事にある証明書を使って接続しようとするとself signed certificate in certificate chainというエラーメッセージがでて接続できませんでした。そのため、以下のリンク先からリンクが貼られている証明書から使用しているAWSリージョンにあった証明書をダウンロードします。

docs.aws.amazon.com

今回の場合、東京リージョンで実施したので、wget https://truststore.pki.rds.amazonaws.com/ap-northeast-1/ap-northeast-1-bundle.pemを実行しました。

認証トークンを生成する

AWS CLIを使って認証トークンを取得して環境変数TOKENに保存します。以下のコマンドを実行します。

TOKEN=`aws rds generate-db-auth-token --hostname $DB_ENDPOINT --port 3306 --username $IAM_USERNAME`

接続する

以下のコマンドを実行します。

mariadb -h $DB_ENDPOINT  -u $IAM_USERNAME --ssl-ca=ap-northeast-1-bundle.pem --password=$TOKEN

無事、接続できました。

[ec2-user@ip-xxx-xxx-xxx-xxx ~]$ mariadb -h $DB_ENDPOINT  -u $IAM_USERNAME --ssl-ca=ap-northeast-1-bundle.pem --password=$TOKEN
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MySQL connection id is 39
Server version: 8.0.35 Source distribution

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

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

MySQL [(none)]> 

考察

初期セットアップは思いのほか大変ですが、パスワードを取り回さなくてもよいのは非常に楽です。

今回はMySQLのクライアントで試してみましたが、元々はプログラム内でRDSのパスワードを保持したくないという思いがあります。これを実装してみたいです。

また、PostgreSQLもIAM認証に対応しているのでPostgreSQL版も試してみます。