개요
-
MySQL 8.0부터는 ANSI 에서 제공하는 “특정권한에 대한 집합” 을 나타내는 ROLE기능을 추가하였다.
- https://en.wikipedia.org/wiki/SQL:1999#Role-based_access_control
-
MySQL에서 ROLE은 마치 로그인을 할 수 없는 새로운 계정 (ROLE_NAME@%) 처럼 생성 되어지며, 해당 계정의 권한을 다른 계정에게 승계하는것처럼 ROLE의 부여 및 삭제가 이루어진다.
mysql> CREATE ROLE 'foolish'; Query OK, 0 rows affected (0.07 sec) --^^ 'foolish'라는 ROLE을 만든다. mysql> CREATE USER 'foolish'@'localhost'; Query OK, 0 rows affected (0.03 sec) --^^ 'foolish'@'localhost' 계정은 잘 만들어진다. mysql> CREATE USER 'foolish'@'%'; ERROR 1396 (HY000): Operation CREATE USER failed for 'foolish'@'%' --^^ 'foolish'@'%' 계정의 경우, 생성실패 에러가 발생한다. 해당이유는 이미 해당 계정 (foolish@%)이 ROLE의 이름으로 존재하기 때문이다. mysql> SELECT USER, HOST, ACCOUNT_LOCKED from mysql.user where user='foolish'; +---------+------+----------------+ | USER | HOST | ACCOUNT_LOCKED | +---------+------+----------------+ | foolish | % | Y | +---------+------+----------------+ 1 row in set (0.00 sec)
ROLE을 만들게 되면, 기본적으로 ‘ROLE_NAME’@’%’ 이라는 계정이 생성되는것에 유의해야 한다.
‘ROLE_NAME’@’%’ 의 account를 생성할 수 없음으로, ROLE 이름을 규칙성 있게 짖는것이 중요한다. (e.g. role_xyz)
사용예제
- ROLE은 부여 후 활성화가 되어야 정상적으로 사용이 가능하다. ROLE에 대한 활성화는 해당 ROLE을 부여받은 자기자신 혹은 SUPER 권한을 가진 계정에서 가능하다.
ROLE 생성과 부여
-- ROLE을 생성한다.
mysql> CREATE ROLE 'DEVSEL';
Query OK, 0 rows affected (0.06 sec)
-- ROLE에 대해 권한을 부여한다.
mysql> GRANT SELECT, SHOW VIEW ON `%\_%`.* TO 'DEVSEL';
Query OK, 0 rows affected (0.07 sec)
-- ROLE을 특정계정에 부여한다.
mysql> CREATE USER 'some.developer'@'localhost' IDENTIFIED BY 'somePassword';
Query OK, 0 rows affected (0.04 sec)
mysql> GRANT 'DEVSEL' TO 'some.developer'@'localhost';
Query OK, 0 rows affected (0.02 sec)
-- 특정계정의 권한을 확인한다.
mysql> show grants for 'some.developer'@'localhost';
+----------------------------------------------------+
| Grants for some.developer@localhost |
+----------------------------------------------------+
| GRANT USAGE ON *.* TO `some.developer`@`localhost` |
| GRANT `DEVSEL`@`%` TO `some.developer`@`localhost` |
+----------------------------------------------------+
2 rows in set (0.01 sec)
-- ROLE에 대한 권한을 정확히 확인하려면, using 구문을 사용하여 확인할 수 있다.
mysql> show grants for 'some.developer'@'localhost' using 'DEVSEL';
+---------------------------------------------------------------------+
| Grants for some.developer@localhost |
+---------------------------------------------------------------------+
| GRANT USAGE ON *.* TO `some.developer`@`localhost` |
| GRANT SELECT, SHOW VIEW ON `%\_%`.* TO `some.developer`@`localhost` |
| GRANT `DEVSEL`@`%` TO `some.developer`@`localhost` |
+---------------------------------------------------------------------+
3 rows in set (0.00 sec)
활성화
/MySQL/binaries/8.0.13/bin/mysql -usome.developer -psomePassword --socket=/var/folders/7v/j50shy2154jcrmtvg71x262r0000gn/T/mysql_sandbox8013.sock
-- 특정계정으로 접속하여, 나에게 부여된 권한을 확인한다.
/MySQL/binaries/8.0.13/bin/mysql --user some.developer -psomePassword --socket=/tmp/mysql_sandbox21621.sock;
mysql> show grants;
+----------------------------------------------------+
| Grants for some.developer@localhost |
+----------------------------------------------------+
| GRANT USAGE ON *.* TO `some.developer`@`localhost` |
| GRANT `DEVSEL`@`%` TO `some.developer`@`localhost` |
+----------------------------------------------------+
2 rows in set (0.00 sec)
-- DEVSEL 권한(계정)은 부여되었지만, 아직 권한이 없는것이 확인된다.
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
+--------------------+
1 row in set (0.00 sec)
-- 부여받은 계정에 대해 아래의 명령어로 활성화시킨다. 활성화 시키는 방법은 두가지 방법이 존재한다.
---- SET DEFAULT ROLE 명령어를 이용해 super권한을 가진 계정이 다른 계정의 ROLE을 활성화 시키기거나 자신이 가지고 있는 ROLE을 활성화 시킬 수 있다.
---- 두번째 방법으로는 SET ROLE 명령어를 통해, 현재 세션에 대해 자신이 가지고 있는 ROLE을 활성화 시킬 수 있다. 이는 mandatory_roles 과 activate_all_roles_on_login 의 옵션에 따라 자동으로 부여될 수 있다.
mysql> SET DEFAULT ROLE DEVSEL to 'some.developer'@'localhost';
Query OK, 0 rows affected (0.05 sec)
mysql> show grants;
+----------------------------------------------------+
| Grants for some.developer@localhost |
+----------------------------------------------------+
| GRANT USAGE ON *.* TO `some.developer`@`localhost` |
| GRANT `DEVSEL`@`%` TO `some.developer`@`localhost` |
+----------------------------------------------------+
2 rows in set (0.00 sec)
-- 다시 접속하여 권한을 확인한다.
mysql> connect;
Connection id: 15
Current database: *** NONE ***
mysql> show grants;
+---------------------------------------------------------------------+
| Grants for some.developer@localhost |
+---------------------------------------------------------------------+
| GRANT USAGE ON *.* TO `some.developer`@`localhost` |
| GRANT SELECT, SHOW VIEW ON `%\_%`.* TO `some.developer`@`localhost` |
| GRANT `DEVSEL`@`%` TO `some.developer`@`localhost` |
+---------------------------------------------------------------------+
3 rows in set (0.00 sec)
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| performance_schema |
| test_xyz |
+--------------------+
3 rows in set (0.00 sec)
-- ^^ 새로운 "test_xyz" 와 "performance_schema" database에 대한 권한이 생긴것이 확인된다.
Default Role 명령어에 의해 Activation된 ROLE의 확인
mysql> select * from mysql.default_roles;
Empty set (0.00 sec)
mysql> SET DEFAULT ROLE DEVDBA to 'min.cho'@'localhost';
Query OK, 0 rows affected (0.10 sec)
mysql> select * from mysql.default_roles;
+-----------+---------+-------------------+-------------------+
| HOST | USER | DEFAULT_ROLE_HOST | DEFAULT_ROLE_USER |
+-----------+---------+-------------------+-------------------+
| localhost | min.cho | % | DEVDBA |
+-----------+---------+-------------------+-------------------+
1 row in set (0.00 sec)
...
mysql> select * from mysql.default_roles;
+-----------+----------------+-------------------+-------------------+
| HOST | USER | DEFAULT_ROLE_HOST | DEFAULT_ROLE_USER |
+-----------+----------------+-------------------+-------------------+
| localhost | some.developer | % | DEVSEL |
+-----------+----------------+-------------------+-------------------+
1 row in set (0.00 sec)
mysql> set default role NONE to `some.developer`@`localhost`;
Query OK, 0 rows affected (0.01 sec)
mysql> select * from mysql.default_roles;
Empty set (0.00 sec)
ROLE 의 상속과 제거
-- DML가능한 ROLE 을 DEVDML 이라는 이름으로 만든다.
mysql> CREATE ROLE 'DEVDML';
Query OK, 0 rows affected (0.03 sec)
mysql> GRANT INSERT, UPDATE, DELETE ON `%\_%`.* TO 'DEVDML';
Query OK, 0 rows affected (0.05 sec)
mysql> show grants for DEVDML;
+----------------------------------------------------------+
| Grants for DEVDML@% |
+----------------------------------------------------------+
| GRANT USAGE ON *.* TO `DEVDML`@`%` |
| GRANT INSERT, UPDATE, DELETE ON `%\_%`.* TO `DEVDML`@`%` |
+----------------------------------------------------------+
2 rows in set (0.00 sec)
-- DEVDML 권한에 DEVSEL 권한을 상속한다.
mysql> GRANT 'DEVSEL' to 'DEVDML';
Query OK, 0 rows affected (0.04 sec)
mysql> show grants for DEVDML;
+----------------------------------------------------------+
| Grants for DEVDML@% |
+----------------------------------------------------------+
| GRANT USAGE ON *.* TO `DEVDML`@`%` |
| GRANT INSERT, UPDATE, DELETE ON `%\_%`.* TO `DEVDML`@`%` |
| GRANT `DEVSEL`@`%` TO `DEVDML`@`%` |
+----------------------------------------------------------+
3 rows in set (0.00 sec)
mysql> show grants for DEVDML using 'DEVSEL';
+-----------------------------------------------------------------------------+
| Grants for DEVDML@% |
+-----------------------------------------------------------------------------+
| GRANT USAGE ON *.* TO `DEVDML`@`%` |
| GRANT SELECT, INSERT, UPDATE, DELETE, SHOW VIEW ON `%\_%`.* TO `DEVDML`@`%` |
| GRANT `DEVSEL`@`%` TO `DEVDML`@`%` |
+-----------------------------------------------------------------------------+
3 rows in set (0.00 sec)
-- REVOKE를 통해 DEVSEL 권한을 제거한다.
mysql> REVOKE 'DEVSEL' from 'DEVDML';
Query OK, 0 rows affected (0.09 sec)
mysql> show grants for 'DEVDML';
+----------------------------------------------------------+
| Grants for DEVDML@% |
+----------------------------------------------------------+
| GRANT USAGE ON *.* TO `DEVDML`@`%` |
| GRANT INSERT, UPDATE, DELETE ON `%\_%`.* TO `DEVDML`@`%` |
+----------------------------------------------------------+
2 rows in set (0.00 sec)
주의사항
-
ROLE에 대한 요구사항이 발생하는 경우, 명확하게 ROLE에 대한 이름들을 지정하여 사용하여야 한다. 사용자의 계정과 절대 비슷해서는 안되며, grant 구문으로 ROLE 이 부여되었는지를 한눈에 알기 쉽도록 구성하기 위함이다. 예를들면 아래와 같다. “
ROLE_
” prefix를 붙여 가독성을 높인다.
- ROLE_SELECT
- ROLE_CRUD
- ROLE_ADMIN
- ROLE_DBA