本記事はAsiaQuest Advent Calendarの16日目です。
クラウドインテグレーション部の渡邊です。
今回は、Aurora Serverless v2(MySQL)のマスターユーザ同等の権限のユーザを作成する手順、作成時の注意点を説明します。
以下にも記載の通り、アプリケーションによるマスターユーザの使用は非推奨であるため、今回の手順を参考に、権限をカスタムするとよいと思います。
アプリケーションではマスターユーザーを直接使用しないことを強くお勧めします。代わりに、アプリケーションに必要な最小の特権で作成されたデータベースユーザーを使用するというベストプラクティスに従ってください。
引用元:Amazon Aurora MySQL でのセキュリティ
クライアント側で以下の環境変数を設定してください(<>には実際のエンドポイントを入れる)。
DB_ENDPOINT=<test-db-clusterのエンドポイント>
テスト用のユーザ(以降、テストユーザと呼ぶ)を作成します。
# DBへadminユーザでログイン
[ec2-user@ip-10-0-1-233 ~]$ mysql -h ${DB_ENDPOINT} -P 3306 -u admin -p
Enter password:
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MySQL connection id is 45
Server version: 8.0.23 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)]> SELECT user, host FROM mysql.user;
+-----------------------+-----------+
| user | host |
+-----------------------+-----------+
| AWS_COMPREHEND_ACCESS | % |
| AWS_LAMBDA_ACCESS | % |
| AWS_LOAD_S3_ACCESS | % |
| AWS_SAGEMAKER_ACCESS | % |
| AWS_SELECT_S3_ACCESS | % |
| admin | % |
| rds_superuser_role | % |
| mysql.infoschema | localhost |
| mysql.session | localhost |
| mysql.sys | localhost |
| rdsadmin | localhost |
+-----------------------+-----------+
11 rows in set (0.002 sec)
# テストユーザの作成
MySQL [(none)]> CREATE USER 'test'@'%' IDENTIFIED BY 'Passw0rd!';
Query OK, 0 rows affected (0.018 sec)
MySQL [(none)]> SELECT user, host FROM mysql.user;
+-----------------------+-----------+
| user | host |
+-----------------------+-----------+
| AWS_COMPREHEND_ACCESS | % |
| AWS_LAMBDA_ACCESS | % |
| AWS_LOAD_S3_ACCESS | % |
| AWS_SAGEMAKER_ACCESS | % |
| AWS_SELECT_S3_ACCESS | % |
| admin | % |
| rds_superuser_role | % |
| test | % |
| mysql.infoschema | localhost |
| mysql.session | localhost |
| mysql.sys | localhost |
| rdsadmin | localhost |
+-----------------------+-----------+
12 rows in set (0.022 sec)
接続元のホストを制限せずに、ユーザを作成します。
たとえば、接続元のホストをlocalhost
とすると、リモート接続によるログインに失敗するため注意してください。
# DBへtest-localユーザでログイン
[ec2-user@ip-10-0-1-233 ~]$ mysql -h ${DB_ENDPOINT} -P 3306 -u 'test-local' -p
Enter password:
ERROR 1045 (28000): Access denied for user 'test-local'@'10.0.1.233' (using password: YES)
接続元IPアドレスで絞る方法も可能ですが、今回はAWS環境を前提としており、基本的に接続元IPアドレス等はセキュリティグループで制限します。
なお、以下はクライアントのプライベートIPアドレスを指定して、接続元を制限している例です。
[ec2-user@ip-10-0-1-233 ~]$ mysql -h ${DB_ENDPOINT} -P 3306 -u 'admin' -p
Enter password:
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MySQL connection id is 2927
Server version: 8.0.23 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.
# test-remote1ユーザを作成
MySQL [(none)]> CREATE USER 'test-remote1'@'10.0.1.233' IDENTIFIED BY 'Passw0rd!';
Query OK, 0 rows affected (0.029 sec)
MySQL [(none)]> SELECT user, host FROM mysql.user;
+-----------------------+------------+
| user | host |
+-----------------------+------------+
| 1$%&#*tmp-1110 | % |
| AWS_COMPREHEND_ACCESS | % |
| AWS_LAMBDA_ACCESS | % |
| AWS_LOAD_S3_ACCESS | % |
| AWS_SAGEMAKER_ACCESS | % |
| AWS_SELECT_S3_ACCESS | % |
| admin | % |
| rds_superuser_role | % |
| test | % |
| tmp-1110 | % |
| test-remote1 | 10.0.1.233 |
| mysql.infoschema | localhost |
| mysql.session | localhost |
| mysql.sys | localhost |
| rdsadmin | localhost |
| test-local | localhost |
+-----------------------+------------+
16 rows in set (0.002 sec)
# ログアウト
MySQL [(none)]> exit
Bye
# DBへtest-remote1ユーザでログイン
[ec2-user@ip-10-0-1-233 ~]$ mysql -h ${DB_ENDPOINT} -P 3306 -u 'test-remote1' -p
Enter password:
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MySQL connection id is 2933
Server version: 8.0.23 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)]> SELECT user(), current_user();
+-------------------------+-------------------------+
| user() | current_user() |
+-------------------------+-------------------------+
| test-remote1@10.0.1.233 | test-remote1@10.0.1.233 |
+-------------------------+-------------------------+
1 row in set (0.004 sec)
以上を踏まえて、今回は接続元を制限せずにユーザを作成しました。
マスターユーザ作成時にあった命名の制約は、通常のユーザ作成時にはその制約がなかったです。
マスターユーザー名 は文字 (A~Z と a~z) で始まり、文字、数字 (0~9)、およびアンダースコア (_) のみを使用する必要があります。
# 1$%&#*tmp-1110ユーザを作成
MySQL [(none)]> CREATE USER '1$%&#*tmp-1110'@'%' IDENTIFIED BY 'Passw0rd!';
Query OK, 0 rows affected (0.046 sec)
MySQL [(none)]> GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, RELOAD, PROCESS, REFERENCES, INDEX, ALTER, SHOW DATABASES, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, REPLICATION SLAVE, REPLICATION CLIENT, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, CREATE USER, EVENT, TRIGGER, CREATE ROLE, DROP ROLE ON *.* TO `1$%&#*tmp-1110`@`%` WITH GRANT OPTION;
Query OK, 0 rows affected (0.018 sec)
MySQL [(none)]> exit
Bye
# DBへ1$%&#*tmp-1110ユーザでログイン
[ec2-user@ip-10-0-1-233 ~]$ mysql -h ${DB_ENDPOINT} -P 3306 -u '1$%&#*tmp-1110' -p
Enter password:
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MySQL connection id is 2646
Server version: 8.0.23 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)]> SELECT user, host FROM mysql.user;
+-----------------------+-----------+
| user | host |
+-----------------------+-----------+
| 1$%&#*tmp-1110 | % |
| AWS_COMPREHEND_ACCESS | % |
| AWS_LAMBDA_ACCESS | % |
| AWS_LOAD_S3_ACCESS | % |
| AWS_SAGEMAKER_ACCESS | % |
| AWS_SELECT_S3_ACCESS | % |
| admin | % |
| rds_superuser_role | % |
| test | % |
| mysql.infoschema | localhost |
| mysql.session | localhost |
| mysql.sys | localhost |
| rdsadmin | localhost |
+-----------------------+-----------+
ただし、MySQLでは「-」が特殊文字扱いになるので、基本的に利用は避けてください。
ユーザ作成時には、マスターユーザ作成時にあった制約を守るのが無難かと思います。
マスターユーザと同等の権限付与ができるかやってみます。
まず、テストユーザの権限の初期状態を確認します。USAGE
は権限がないことを示すため、なにも動作しないことを表します。
# testユーザの権限を確認
MySQL [(none)]> show grants for 'test'@`%`;
+--------------------------------------+
| Grants for test@% |
+--------------------------------------+
| GRANT USAGE ON *.* TO `test`@`%` |
+--------------------------------------+
1 row in set (0.004 sec)
次に、マスターユーザがどのような権限を持っているのか確認します。
マスターユーザはrds_superuser_role
がアタッチされているので、ロールの権限を確認します。
# adminユーザの権限を確認
MySQL [(none)]> show grants for 'admin'@`%`;
+-----------------------------------------------+
| Grants for admin@% |
+-----------------------------------------------+
| GRANT USAGE ON *.* TO `admin`@`%` |
| GRANT `rds_superuser_role`@`%` TO `admin`@`%` |
+-----------------------------------------------+
2 rows in set (0.003 sec)
# rds_superuser_roleロールの権限を確認
MySQL [(none)]> SHOW GRANTS FOR 'rds_superuser_role'@'%';
+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Grants for rds_superuser_role@% |
+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, RELOAD, PROCESS, REFERENCES, INDEX, ALTER, SHOW DATABASES, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, REPLICATION SLAVE, REPLICATION CLIENT, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, CREATE USER, EVENT, TRIGGER, CREATE ROLE, DROP ROLE ON *.* TO `rds_superuser_role`@`%` WITH GRANT OPTION |
| GRANT APPLICATION_PASSWORD_ADMIN,CONNECTION_ADMIN,REPLICATION_APPLIER,ROLE_ADMIN,SESSION_VARIABLES_ADMIN,SET_USER_ID,XA_RECOVER_ADMIN ON *.* TO `rds_superuser_role`@`%` WITH GRANT OPTION |
| GRANT `AWS_COMPREHEND_ACCESS`@`%`,`AWS_LAMBDA_ACCESS`@`%`,`AWS_LOAD_S3_ACCESS`@`%`,`AWS_SAGEMAKER_ACCESS`@`%`,`AWS_SELECT_S3_ACCESS`@`%` TO `rds_superuser_role`@`%` |
+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
3 rows in set (0.002 sec)
確認した結果、静的権限、動的権限、AWS用のロールが付与されています。
以下のように、マスタユーザのロールを付与することも可能です。
# rds_superuser_roleロールをtestユーザへ付与
MySQL [(none)]> GRANT `rds_superuser_role`@`%` TO `test`@`%`;
Query OK, 0 rows affected (0.076 sec)
今回は、そのロールに含まれる権限およびAWS用のロールを、テストユーザに付与します。
# adminに付与されていた静的権限をtestユーザへ付与
MySQL [(none)]> GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, RELOAD, PROCESS, REFERENCES, INDEX, ALTER, SHOW DATABASES, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, REPLICATION SLAVE, REPLICATION CLIENT, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, CREATE USER, EVENT, TRIGGER ON *.* TO `test`@`%` WITH GRANT OPTION;
Query OK, 0 rows affected (0.005 sec)
# adminに付与されていた動的権限をtestユーザへ付与
MySQL [(none)]> GRANT APPLICATION_PASSWORD_ADMIN,CONNECTION_ADMIN,REPLICATION_APPLIER,ROLE_ADMIN,SESSION_VARIABLES_ADMIN,SET_USER_ID,XA_RECOVER_ADMIN ON *.* TO `test`@`%` WITH GRANT OPTION;
Query OK, 0 rows affected (0.024 sec)
# adminに付与されていたAWS用のロールをtestユーザへ付与
MySQL [(none)]> GRANT `AWS_COMPREHEND_ACCESS`@`%`,`AWS_LAMBDA_ACCESS`@`%`,`AWS_LOAD_S3_ACCESS`@`%`,`AWS_SAGEMAKER_ACCESS`@`%`,`AWS_SELECT_S3_ACCESS`@`%` TO `test`@`%` ;
Query OK, 0 rows affected (0.028 sec)
MySQL [(none)]> show grants for 'test'@`%`;
+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Grants for test@% |
+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, RELOAD, PROCESS, REFERENCES, INDEX, ALTER, SHOW DATABASES, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, REPLICATION SLAVE, REPLICATION CLIENT, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, CREATE USER, EVENT, TRIGGER, CREATE ROLE, DROP ROLE ON *.* TO `test`@`%` WITH GRANT OPTION |
| GRANT APPLICATION_PASSWORD_ADMIN,CONNECTION_ADMIN,REPLICATION_APPLIER,ROLE_ADMIN,SESSION_VARIABLES_ADMIN,SET_USER_ID,XA_RECOVER_ADMIN ON *.* TO `test`@`%` WITH GRANT OPTION |
| GRANT `AWS_COMPREHEND_ACCESS`@`%`,`AWS_LAMBDA_ACCESS`@`%`,`AWS_LOAD_S3_ACCESS`@`%`,`AWS_SAGEMAKER_ACCESS`@`%`,`AWS_SELECT_S3_ACCESS`@`%` TO `test`@`%` |
+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
3 rows in set (0.004 sec)
マスターユーザと同等の権限の付与に成功しました。
アプリケーションのユーザの権限は最小限にするように、注意してください。
以下の権限は、とくに慎重に検討する必要があります。
DELETE
DROP
CREATE USER
CREATE ROLE
DROP ROLE
権限の付与に成功したので、一部の静的権限のみ動作確認を行います。
[ec2-user@ip-10-0-1-233 ~]$ mysql -h ${DB_ENDPOINT} -P 3306 -u test -p
Enter password:
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MySQL connection id is 245
Server version: 8.0.23 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)]> SELECT user(), current_user();
+-----------------+----------------+
| user() | current_user() |
+-----------------+----------------+
| test@10.0.1.233 | test@% |
+-----------------+----------------+
1 row in set (0.004 sec)
# tmpという名前のデータベースを作成
MySQL [(none)]> CREATE DATABASE tmp;
Query OK, 1 row affected (0.027 sec)
# データベースの一覧を確認
MySQL [(none)]> SHOW databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
| tmp |
+--------------------+
5 rows in set (0.021 sec)
# tmpという名前のデータベースを削除
MySQL [(none)]> DROP DATABASE tmp;
Query OK, 0 rows affected (0.081 sec)
MySQL [(none)]> SHOW databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
+--------------------+
4 rows in set (0.007 sec)
動作確認完了です。マスターユーザと同等の権限を得られました。
USAGE
は権限がないことを示すrds_superuser_role
がアタッチされており、そのロールには静的権限、動的権限、AWS用のロールが付与されている
【参考】
Master user account privileges
MySQL が実行されている Amazon RDS DB インスタンスの別のマスターユーザーを作成する方法を教えてください。
Aurora MySQL で Amazon Aurora 機械学習を使用する
Trying to add the File permission to MySQL RDS instance access denied
6.2.2 Privileges Provided by MySQL
今日は、MySQLでオブジェクト名にハイフンはエラーになるの日。