mysql 사용자 계정 권한부여

호밀빵 굽는 쿼카·2022년 5월 12일
0

NHN Cloud 인턴

목록 보기
41/48

웹서버가 2대, ip가 각각 0.0.0.0, 1.1.1.1 이라고 가정
여기서 db서버에 접속하려면 db에서 접속을 허용할 ip를 등록해주는 과정이 있어야합니다.
그 과정이 유저를 추가하고 권한을 주는 것입니다.
그리고 그 과정을 커맨드로 나타내는 과정입니다.

1. 1차

저는 처음에

grant all privileges ON *.* TO [userid]@’%’ IDENTIFIED BY ‘[password]’;

라고 생각했습니다.
하지만 실제 운영할때에는 딱 필요한 권한만을 부여해야한다는 것을 알았습니다.
select, insert 등의 일부 권한만 부여하는 방식이었습니다. 또한 ip 지정도!

2. 2차

ip에 따른 접속 여부

  • 'user'@'127.0.0.1' //로컬에서만 사용 가능
  • 'user'@'%' //외부에서 접속 가능
  • 'user'@'192.103.24.1' //192.103.24.1 이라는 IP에서만 접속 가능
  • 'user'@'192.103.%' // 192.103.x.x 로 시작되는 모든 IP에서 접속 허용
create user '[userid]'@'0.0.0.0' identified by '[password]';
grant select,insert,update,delete on [dbname].* to '[userid]'@'0.0.0.0';
create user '[userid]'@'1.1.1.1' identified by '[password]';
grant select,insert,update,delete on [dbname].* to '[userid]'@'1.1.1.1';

3. 추가

다른 인턴분이 제출한 커맨드

create user '[userid]'@'0.0.0.0' identified by '[password]'; 
CREATE ROLE 'role';
GRANT SELECT, UPDATE, DELETE, INSERT ON [dbname].* TO 'role';
SET DEFAULT ROLE 'role' to '[userid]';

상황에 따라서 role로 관리하는게 편할 때에는 role로 묶어서 관리하기도 한다고 합니다.

mysql documnet 를 찾아보니 role에 대한 내용이 있었습니다.

예제 1>

CREATE ROLE 'r1', 'r2';
GRANT SELECT ON db1.* TO 'r1';
GRANT INSERT, UPDATE, DELETE ON db1.* TO 'r2';
CREATE USER 'u1'@'localhost' IDENTIFIED BY 'u1pass';
GRANT 'r1', 'r2' TO 'u1'@'localhost';

role을 생성해 각각의 권한(select/insert,update,delete)을 부여하고 user(u1)에 role을 할당

예제2>

# 역할 생성
mysql > CREATE ROLE
    role_emp_read,
    role_emp_write;
# 권한 부여
mysql > GRANT select on employees.* TO role_emp_read;
mysql > GRANT insert, update, delete on employees.* TO role_emp_write;
# 계정 생성
mysql > CREATE USER reader@'127.0.0.1' IDENTIFIED BY '123456';
mysql > CREATE USER writer@'127.0.0.1' IDENTIFIED BY '123456';
# 계정에 역할 설정
mysql > GRANT role_emp_read TO reader@'127.0.0.1';
mysql > GRANT role_emp_write TO writer@'127.0.0.1';
# reader로 접속
$ mysql -ureader -p123456 -h127.0.0.1
# 역할 active
# role_emp_read(select) role 권한 부여
mysql > SET ROLE 'role_emp_read';
mysql > SELECT current_role();

역할이 활성화되면 그 역할이 가진 권한은 사용할 수 있는 상태가 됩니다. 하지만 계정이 로그아웃됐다가 다시 로그인하면 역할이 초기화됩니다.
이를 자동화하기 위해 activate_all_roles_on_login 시스템 변수로 설정할 수 있습니다.

mysql > SET GLOBAL activate_all_roles_on_login=ON;

참고))
show grants를 사용하면 부여된 권한을 확인할 수 있습니다.

4. 비밀번호를 암호화해서 생성

보통은 native password로 저장하지만, 개발자 유저를 생성할 때 등은 비밀번호를 암호화해서 생성!!
mysql document

// 사용자 생성 
create user 'root'@'localhost' identified by 'pass'; 

// 권한 부여 
GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost'; 
GRANT GRANT OPTION ON *.* TO 'root'@'localhost'; 

// 비밀번호 plugin 변경 
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'pass';

여기서는 mysql_native_password를 사용합니다. 하지만, 이 경우 저장돼 있는 HASH code를 탈취하면 취약점을 이용해 비밀번호를 알아낼 수 있는 문제가 있었습니다.
MySQL 8.0부터는 좀 더 고도화된 SHA2암호화 기법을 기반으로 RSA key를 이용한 salt 추가 방법으로 더욱 보안을 강화시켰습니다. 이로써, 비밀번호가 같더라도 각기 다른 HASH code를 저장하게 되어 해당 HASH code가 탈취된다 하더라도 비밀번호를 알아내는것은 불가능에 가까워졌습니다. 단점으로는 여러번의 연산이 필요한데 이를 보완한것이 chaching_sha2_password
따라서, MySql 8.0의 기본 인증 플러그인은 예전의mysql_native_password가 아니라 caching_sha2_password 입니다.

8.0 버전 이상에서 password를 생성하는 법은 여러개

mysql> CREATE USER 'min_native_password1'@'localhost' IDENTIFIED WITH mysql_native_password BY 'min';
Query OK, 0 rows affected (0.05 sec)

mysql> CREATE USER 'min_native_password2'@'localhost' IDENTIFIED WITH mysql_native_password BY 'min';
Query OK, 0 rows affected (0.00 sec)


mysql> CREATE USER 'min_sha256_password1'@'localhost' IDENTIFIED WITH sha256_password BY 'min';
Query OK, 0 rows affected (0.04 sec)

mysql> CREATE USER 'min_sha256_password2'@'localhost' IDENTIFIED WITH sha256_password BY 'min';
Query OK, 0 rows affected (0.11 sec)


mysql> CREATE USER 'min_caching_sha2_password1'@'localhost' IDENTIFIED WITH caching_sha2_password BY 'min';
Query OK, 0 rows affected (0.04 sec)

mysql> CREATE USER 'min_caching_sha2_password2'@'localhost' IDENTIFIED WITH caching_sha2_password BY 'min';
Query OK, 0 rows affected (0.00 sec)

mysql> select user,host, plugin, authentication_string from mysql.user where user like 'min%' order by password_last_changed;
+----------------------------+-----------+-----------------------+------------------------------------------------------------------------+
| user                       | host      | plugin                | authentication_string                                                  |
+----------------------------+-----------+-----------------------+------------------------------------------------------------------------+
| min_native_password1       | localhost | mysql_native_password | *9E21D7C9BFE2F869A7DB7488D13C47E395408C1B                              |
| min_native_password2       | localhost | mysql_native_password | *9E21D7C9BFE2F869A7DB7488D13C47E395408C1B                              |
| min_sha256_password1       | localhost | sha256_password       | $5$Ye~8 %    2O*}F9B$BIwDvMezr1GCqbAs7BTinaYhXt2xvWP.mrr5FkbvWV9    |
| min_sha256_password2       | localhost | sha256_password       | $5$-H[6\zs1)zH]PF
                                                                                    :*$ch/PKE0rKRDmzolsMtr9gZJsRJxKRm9goWNTXvn.y91    |
1j8*D8n;r3RUUWK5keDdwWFjHqsOH3eNJ/RU/wCqzSzeNC6YfpI6 |2_password | $A$005$F}cJK{
| min_caching_sha2_password2 | localhost | caching_sha2_password | $A$005$tD=atb4k2p    NmI
                                                                                           S8Id.qr.iHc/P6q9abb6RLKRyy7lMl3sy0o5M4N2tXM/ |
+----------------------------+-----------+-----------------------+------------------------------------------------------------------------+

6 rows in set (0.00 sec)

caching_sha2_password plugin을 적용하는 경우 보안상 안정하지만, 낮은 버전의 mysql client 혹은 library를 사용하는 경우 지원하지 못해 에러가 발생 => 이럴땐 구버전의 mysql_native_password 사용

<순서>
1. 사용자의 암호를 ddl을 통해 구식방식으로 변경

ALTER USER 'username'@'ip_address' IDENTIFIED WITH mysql_native_password BY 'password';
  1. my.cnf 파일 설정
    새롭게 만들어진 계정이 caching_sha2_password plugin을 사용하지 못하도록 하는 것
[mysqld]

default_authentication_plugin=mysql_native_password

5. 운영서버 정보 변경

운영 웹서버에서 운영 db를 바라보도록 설정 변경 완료

여기서 잠깐!!🖐

서버를 바라본다, ip를 바라본다 이렇게 의미가 다양한 것 같아서 "바라보다"의 의미를 찾아보았습니다.

질문 : 1,2,3 서버가 있고 1,2 서버가 3 서버를 참조한다고 가정했을때, "1,2서버가 3서버를 바라보고있다"라고 할 수 있을까요?

답변 : 참조라는 의미가 만약 3서버에 db가 있고, 1,2 서버에서 그 db 정보를 가져와서 사용하는 의미라면 YES
하지만, 서버끼리 바라본다라는 것보다는 웹이 db를 바라본다가 정확한 의미!




참고링크

profile
열심히 굽고 있어요🍞

0개의 댓글