MariaDB 클라언트-서버 TLS/SSL 암호화 연결(1)

MySQL / MaraiDB 서버에 TLS 를 활성화 해서 암호화 통신을 할 수 있다. MySQL (MariaDB도 동일함)에서는 서버-클라이언트 사이에 전송되는 데이터를 TLS (이전 SSL) 프로토콜을 이용하여 암호화하여 DB 정보가 노출되지 않게 방지할 수 있다. SSL을 통해서 Replication Master - Slave 도 가능하다.

글 타래:

  1. MariaDB 클라언트-서버 TLS/SSL 암호화 연결(1)
  2. MariaDB 클라언트-서버 TLS/SSL 암호화 연결(2)
  3. MariaDB 클라언트-서버 TLS/SSL 암호화 연결(3)

글 진행 순서:

  1. 사설 CA 인증서 생성
  2. 클라이언트 인증서 생성
  3. 사설 CA 인증서 설정

시스템 사양

  1. Armbian 23.8.1 Bullseye / mariadb-server-10.5

1. 사설 CA 인증서 생성

openssl을 사용해서 ssl_cert, ssl_key, ssl_ca 에 사용하는 서버용 사설 인증서를 생성한다.

openssl을 이용한 사설 인증서 생성에 대해서는 HTTPS 를 위한 Private SSL 기사도 참조할 수 있다.


이 글에서는 아래 참고1, 참고2 를 적용했다.

인증서는 사설 CA(Certificate Authority)용 인증서, 서버용, 클라이언트용 총 3가지를 만든다.

인증서 저장 위치 생성

1
2
(SERVER) $ sudo mkdir /etc/ssl/mysql
(SERVER) $ cd /etc/ssl/mysql

생성한 TLS 인증서는 MySQL/MariaDB 의 my.cnf 설정파일의 변수를 3가지 설정한다.

  • ssl_cert 시스템 변수: 서버 인증서(X509) 경로 지정
  • ssl_key 시스템 변수: 서버 개인키 경로 지정
  • ssl_ca 혹은 ssl_capath 시스템 변수: Self-signed CA certificate CA 키 경로

openssl 사설 CA 인증서 생성

저장 위치 /etc/ssl/mysql 에서 관리용 CA 인증서 생성한다.

먼저 openssl에서 rsa 알고리즘으로 4096 크기 비밀키를 생성한다.

1
2
3
(SERVER) $ sudo openssl genrsa -out ca-key.pem 4096
Generating RSA private key, 4096 bit long modulus (2 primes)
...

비밀키 파일 ca-key.pem 파일을 사용해서 CA인증서 ca.pem 파일로 생성한다. 비밀키로 CA를 위한 CSR(certificate signing request) 과정을 거쳐 ca.pem 을 생성해9서 필요한 인증서 정보를 묻는다.

1
2
3
4
5
6
7
8
9
(SERVER) $ sudo openssl req -new -x509 -nodes -days 365000 -key ca-key.pem -out ca.pem
...
Country Name (2 letter code) [AU]: KR
State or Province Name (full name) [Some-State]:Seoul
Locality Name (eg, city) []:
Organization Name (eg, company) [Internet Widgits Pty Ltd]:YOUR company
Organizational Unit Name (eg, section) []: Administration
Common Name (e.g. server FQDN or YOUR name) []::mysql-admin.DOMAIN.name
Email Address []:

현재까지

1
2
3
(SERVER) $ ls -l
-rw------- 1 root root 3243 Jul 16 15:04 ca-key.pem
-rw-r--r-- 1 root root 1972 Jul 16 15:11 ca.pem

서버 인증서 생성

서버용 인증서 생성한다. 단, openssl 명령 과정에서 Common Name 을 3가지 모두 다르게 해야 검증오류를 피할 수 있다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
(SERVER) $ sudo openssl req -newkey rsa:4096 -days 365000 -nodes -keyout server-key.pem -out server-req.pem

Country Name (2 letter code) [AU]:KR
State or Province Name (full name) [Some-State]:Seoul
Locality Name (eg, city) []:
Organization Name (eg, company) [Internet Widgits Pty Ltd]:YOUR company
Organizational Unit Name (eg, section) []:Administration
Common Name (e.g. server FQDN or YOUR name) []:server.DOMAIN.name
Email Address []:

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
...

현재 디렉토리

1
2
3
4
5
(SERVER) $ ls -l
-rw------- 1 root root 3243 Jul 16 15:04 ca-key.pem
-rw-r--r-- 1 root root 1972 Jul 16 15:11 ca.pem
-rw------- 1 root root 3272 Jul 16 15:15 server-key.pem
-rw-r--r-- 1 root root 1704 Jul 16 15:16 server-req.pem

RSA 알고리즘으로

1
2
(SERVER) $ sudo openssl rsa -in server-key.pem -out server-key.pem
writing RSA key

CA 비밀키 ca-key.pem 를 사용해 X509 인증서를 사이닝한다.

1
2
3
4
(SERVER) $ sudo openssl x509 -req -in server-req.pem -days 365000 -CA ca.pem -CAkey ca-key.pem -set_serial 01 -out server-cert.pem
Signature ok
subject=C = KR, ST = Seoul, O = Thinkbee company, OU = Administration, CN = admin.thinkbee.kr
Getting CA Private Key
1
2
(SERVER) $ sudo openssl verify -CAfile ca.pem server-cert.pem
server-cert.pem: OK

현재 디렉토리

1
2
3
4
5
6
(SERVER) $ ls -l
-rw------- 1 root root 3243 Jul 16 15:04 ca-key.pem
-rw-r--r-- 1 root root 1972 Jul 16 15:11 ca.pem
-rw-r--r-- 1 root root 1862 Jul 16 15:20 server-cert.pem
-rw------- 1 root root 3243 Jul 16 15:19 server-key.pem
-rw-r--r-- 1 root root 1704 Jul 16 15:16 server-req.pem

2. 클라이언트 인증서 생성

클라이언트 인증서는 다음과 같은 용도로 사용한다. 단, openssl 명령 과정에서 Common Name 을 3가지 모두 다르게 해야 검증오류를 피할 수 있다.

  • DB 서버와 별도로 존재하는 웹 서버에서 DB 서버로 SSL 통신을 할 때 웹 서버에 적용
  • 접속하고자 하는 DB 서버와 별도의 리눅스 환경에서 mysql 클라이언트 프로그램으로 DB 서버에 접속할 때 클라이언트에 적용
  • Replication 에서 Master와 Slave 간의 SSL 통신을 하고자 할 때 Slave 서버에 적용
1
2
3
4
5
6
7
8
9
(SERVER) $ sudo openssl req -newkey rsa:2048 -days 365000 -nodes -keyout client-key.pem -out client-req.pem
Country Name (2 letter code) [AU]:KR
State or Province Name (full name) [Some-State]:Seoul
Locality Name (eg, city) []:
Organization Name (eg, company) [Internet Widgits Pty Ltd]:
Organizational Unit Name (eg, section) []:
Common Name (e.g. server FQDN or YOUR name) []::mysql-client.thinkbee.kr

...
1
2
(SERVER) $ sudo openssl rsa -in client-key.pem -out client-key.pem
writing RSA key
1
2
3
4
(SERVER) $ sudo openssl x509 -req -in client-req.pem -days 365000 -CA ca.pem -CAkey ca-key.pem -set_serial 01 -out client-cert.pem
Signature ok
subject=C = KR, ST = Seoul, O = Internet Widgits Pty Ltd, CN = client-thinkbee.kr
Getting CA Private Key
1
2
(SERVER) $ sudo openssl verify -CAfile ca.pem client-cert.pem 
client-cert.pem: OK

현재 디렉토리를 접근 권한을 조정한다.

1
2
3
4
5
6
7
8
9
10
(SERVER) $ sudo chown mysql.mysql *.*
(SERVER) $ ls -l
-rw-r--r-- 1 mysql mysql 3243 7월 16 15:43 ca-key.pem
-rw-r--r-- 1 mysql mysql 1984 7월 16 15:46 ca.pem
-rw-r--r-- 1 mysql mysql 1497 7월 16 15:51 client-cert.pem
-rw-r--r-- 1 mysql mysql 1679 7월 16 15:51 client-key.pem
-rw-r--r-- 1 mysql mysql 989 7월 16 15:50 client-req.pem
-rw-r--r-- 1 mysql mysql 1838 7월 16 15:48 server-cert.pem
-rw------- 1 mysql mysql 3243 7월 16 15:48 server-key.pem
-rw-r--r-- 1 mysql mysql 1671 7월 16 15:47 server-req.pem

파일 모드를 644 으로 변경한다.

1
(SERVER) $ sudo chmod 644 *.*

인증서의 내용 확인방법

1
2
3
(SERVER) $ openssl x509 -text -in ca.pem
(SERVER) $ openssl x509 -text -in server-cert.pem
(SERVER) $ openssl x509 -text -in client-cert.pem

3. 사설 CA 인증서 설정

my.cnf 에 TLS 를 위한 구성을 해야 한다. 주로 ssl_cert, ssl_key, ssl_ca 에 대한 인증서 파일을 지정해 준다.

  • ssl_cert 시스템 변수: X509 인증서 경로 지정
  • ssl_key 시스템 변수: 서버 개인키 경로 지정
  • ssl_ca 혹은 ssl_capath 시스템 변수: Certificate Authority (CA) 경로

TLS 활성화

참고3 의 mysql 설정파일 my.cnf 에 따르면 아래 변수가 설정되야 한다.

1
2
3
4
5
[mariadb]
...
ssl_cert = /etc/ssl/mysql/server-cert.pem
ssl_key = /etc/ssl/mysql/server-key.pem
ssl_ca = /etc/ssl/mysql/ca.pem

서버를 재시작한다.

TLS 가 활성화 되었는지 환경변수로 확인할 수 있다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
MariaDB [(none)]> show variables like '%ssl%';
+---------------------+--------------------------------+
| Variable_name | Value |
+---------------------+--------------------------------+
| have_openssl | YES |
| have_ssl | YES |
| ssl_ca | /etc/ssl/mysql/ca.pem |
| ssl_capath | |
| ssl_cert | /etc/ssl/mysql/server-cert.pem |
| ssl_cipher | |
| ssl_crl | |
| ssl_crlpath | |
| ssl_key | /etc/ssl/mysql/server-key.pem |
| version_ssl_library | OpenSSL 1.1.1n 15 Mar 2022 |
+---------------------+--------------------------------+
10 rows in set (0.003 sec)

이렇게 구성한 TLS 인증서는 만료기간이 있다. 아래 같이 만료 기간을 확인 할 수 있다.

1
2
3
4
5
6
7
>  SHOW STATUS LIKE 'Ssl_server_not%';
+-----------------------+--------------------------+
| Variable_name | Value |
+-----------------------+--------------------------+
| Ssl_server_not_after | Nov 16 06:48:41 3022 GMT |
| Ssl_server_not_before | Jul 16 06:48:41 2023 GMT |
+-----------------------+--------------------------+

mysql client TLS 사용 접속

mysql 클라이언트로 TLS 인증서를 사용해서 접속해 보자.

1
(SERVER) $ mysql -u root -p -h localhost --ssl=TRUE --ssl-ca=/etc/ssl/mysql/ca.pem --ssl-cert=/etc/ssl/mysql/client-cert.pem --ssl-key=/etc/ssl/mysql/client-key.pem

접속한 클라인트에서 status 를 살펴보면 TLS 로 접속한 내역을 SSL: Cipher in use is TLS_AES_256_GCM_SHA384 항목으로 확인할 수 있다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
MariaDB [(none)]> status
--------------
mysql Ver 15.1 Distrib 10.11.2-MariaDB, for debian-linux-gnu (aarch64) using EditLine wrapper

Connection id: 315
Current database:
Current user: root@localhost
SSL: Cipher in use is TLS_AES_256_GCM_SHA384
Current pager: stdout
Using outfile: ''
Using delimiter: ;
Server: MariaDB
Server version: 10.11.2-MariaDB-1:10.11.2+maria~deb11 mariadb.org binary distribution
Protocol version: 10
Connection: Localhost via UNIX socket
Server characterset: utf8mb4
Db characterset: utf8mb4
Client characterset: utf8mb3
Conn. characterset: utf8mb3
UNIX socket: /run/mysqld/mysqld.sock
Uptime: 6 min 54 sec

Threads: 69 Questions: 2386 Slow queries: 0 Opens: 37 Open tables: 30 Queries per second avg: 5.763
--------------



참고

  1. OpenSSL을 이용한 사설 인증서 생성
  2. MariaDB 외부접속시 ssl 사용법, 그리고 ssl 로 replication(동기화) 하기
  3. Configuring MySQL to Use Encrypted Connections

mysqladmin CLI 주요 사용

mysqladmin, mysqldump 명령 사용

mysqladmin 명령 사용하기

  • MYSQL의 root 패스워드 변경하기
  • MYSQL의 일반계정 사용자 패스워드 변경하기
  • 새로운 데이터베이스 생성하기
  • 사용중인 데이터베이스 삭제하기
  • MYSQL의 현재상황 살펴보기
  • MYSQL에 접속한 클라이언트(threads)리스트 확인하기
  • MYSQL 캐쉬 데이터 동기화하기
  • MYSQL 종료하기
  • MYSQL 실행 환경변수 확인하기
  • MYSQL에 접속한 사용자 접속끊기
  • MYSQL의 버전 및 여러가지 실행 정보들 확인하기
  • MYSQL이 정상적으로 살아있는지 죽었는지 확인하기
  • 기타 MYSQL관리에 필요한 유용한 설정 및 정보확인

사용법

1
2
3
4
mysqladmin [-h서버] -u아이디 -p 데이터베이스명 <명령어>

<명령어>: reload, shutdown, create, status등

- MYSQL의 root 패스워드 변경하기

- MYSQL의 일반계정 사용자 패스워드 변경하기

- 새로운 데이터베이스 생성 / 사용중인 데이터베이스 삭제하기

새로운 스키마를 생성할 때 create 명령을 사용한다.

1
mysqladmin -u root -p create 새로운데이터베이스명

기존 스키마를 삭제 할 때 drop 명령을 사용한다.

1
mysqladmin -u root -p drop  데이터베이스명

- MYSQL의 현재상황 살펴보기

status 명령으로 MySQL의 상태를 확인할 수 있다.

  • MYSQL의 총 실행시간
  • 현재 처리중인 스레드(Threads)수
  • 오픈된 데이터베이스 및 테이블 수
  • 초당 평균 처리속도
  • Slow query, Flush tables등
1
mysqladmin -u root -p status

i 인자에 상태 확인 간격을 주어 계속 관찰이 가능하다.

1
2
# 5초 간격
mysqladmin -i5 status -u root -p

- MYSQL의 현재상황 자세히 살펴보기

extended-status라는 명령어는 SQL 명령의 SHOW STATUS 로 보는 시스템 상태와 거의 동일.

1
mysqladmin -u root -p extended-status

- MYSQL에 접속한 클라이언트(threads)리스트 확인하기

- MYSQL 캐쉬 데이터 동기화하기

reload, flush-privileges 를 사용해서 테이블 및 권한 테이블의 캐시를 갱신한다.

MYSQL의 모든 실제 데이터들은 각각의 데이터베이스 내에 존재하는 테이블(table)에 저장되므로 MYSQL의 테이블(table)을 reload 혹은 priviliges 테이블을 flush 해서 갱신한다.

1
2
mysqladmin -u root -p reload
mysqladmin -u root -p flush-privileges

- MYSQL 실행 환경변수 확인하기

mysql client 로 접속해 show variables; 명령을 mysqladmin 명령으로 사용이 가능하다.

1
mysqladmin -u root -p variables

- MYSQL 실행 프로세스 확인하기

mysql client 로 접속해 processlist; 로 mysqladmin 명령으로 사용이 가능하다.

1
mysqladmin -u root -p processlist

- MYSQL에 접속한 사용자 접속끊기

보통 processlist 로 실행중인 ID 를 끊을 수 있다.

1
2
3
4
+----+-----------+------------------+-----------+---------+------+----------+-----------------+----------+
| Id | User | Host | db | Command | Time | State | Info
+----+-----------+-----------------+-----------+---------+------+----------+------------------+----------+
| 31 | stockmart | 192.168.0.2:564 | fedb | Sleep | 18 |

processlist 의 Id컬럼에 있는 접속 Id를 끊는다.

1
mysqladmin -u root -p kill 사용자ID

- MYSQL의 버전 및 여러가지 실행 정보들 확인하기

  • MYSQL의 버전

사용형식 : mysqladmin -u root -p version

  1. MYSQL이 죽었는지 살았는지 확인하기

사용형식 : mysqladmin -u root -p ping

  • MYSQL 소켓파일 위치정보

  • MYSQL의 총 실행시간 정보

- 기타 MYSQL관리에 필요한 유용한 설정 및 정보확인

  • MYSQL의 총 스레드(threads)수

  • MYSQL의 오픈된 데이터베이스와 테이블 수

  • MYSQL의 초당 응답완료 시간

- MYSQL 종료하기



mysqldump 명령

예: 문자셋 latin1 데이터 덤프

문자셋을 mysql> show variables like 'c%' 등으로 확인해서 적절히 덤프를 한다.

1
mysql> mysqldump -u [username] –p[password] --default-character-set=utf8 -N --routines --skip-triggers --databases [database_name] > [dump_file.sql]

덤플 사례: https://itzone.tistory.com/711

MySqLI CLI 주요 명령

mysql CLI 에서 MySQL/MariaDB 관리자로서 사용할 수 있는 명령을 요약한다.

  • create user, grant, drop, delete, remove …

MySqLI CLI Client 로 접속하기

1
mysql [-h서버] -u아이디 -p 데이터베이스명

데이터베이스 스키마

1
mysql> SHOW DATABASES;

use 명령을 사용하여 사용할 데이터베이스/스키마를 선택

1
mysql> USE TESTDB;

선택된 데이터베이스 안의 테이블 확인

1
2
mysql> SHOW TABLES;
mysql> SHOW TABLES LIKE 't%'; # t로 시작하는 테이블

특정 스키마 혹은 테이블의 생성 쿼리를 출력

1
2
mysql> SHOW CREATE DATABSE SAKILA;
mysql> SHOW CREATE TABLE STUDENTS;

데이터베이스의 생성 및 삭제

1
mysql> CREATE DATABASE testdb CHARACTER SET utf8 COLLATE utf8_general_ci;
  • utf8_general_ci 는 대소문자를 구분하지 않는다.
  • 대소문자를 구분하려면 binary 타입으로 지정. 예) “utf8_bin”

캐릭터셋과 COLLATE 를 생략하면 서버 설치시 지정한 기본 값으로 설정

1
mysql> CREATE DATABASE testdb;

스키마 제거

1
mysql> DROP [SCHEMA]DATABASE testdb;

시스템 환경 확인

서버의 환경 변수

1
2
# 모든 변수
mysql> SHOW VARIABLES;

DBMS 버전

1
2
3
mysql> select @@version;       -- DBMS version

mysql> SHOW VARIABLES LIKE 'version';
1
mysql> SHOW VARIABLES LIKE 'innodb_%';

지원하는 문자세트 구성

1
2
3
mysql> SHOW CHARACTER SET;

mysql> SHOW CHARACTER SET LIKE 'utf%';

문자세트 확인

1
2
-- 환경변수에서 확인
mysql> SHOW VARIABLES LIKE 'c%';

지원하는 콜레이션

1
2
3
mysql> SHOW COLLATION;

mysql> SHOW COLLATION WHERE Charset = 'utf8mb4';

외부 파일 실행하기

첫 번째는 mysql cli 에 지정하여 실행하는 방법

1
2
3
$ mysql -u dbuser -p testdb < insert.sql

Enter password: ****

두 번째 방법을 mysql cli에서 source 명령을 사용

1
mysql> SOURCE C:\Users\USERID\insert.sql;


User & Privileges

사용자 db

mysql 스키마의 user 테이블을 사용한다.

SELECT Host,User,plugin,authentication_string FROM mysql.user;

사용자 추가

사용자를 생성시 호스트 주소에 ‘%’, ‘localhost’로 호스트 범위를 지정한다

1
2
3
mysql> CREATE USER 'USERID'@'localhost' IDENTIFIED BY 'password';
mysql> CREATE USER 'USERID'@'%' IDENTIFIED BY 'password';
mysql> FLUSH PRIVILEGES;

grant 명령: [권한 부여]

사용자가 특정 자원에 접근하기 위해서 grant 명령 사용.

1
2
3
4
5
6
GRANT ALL PRIVILEGES ON DB이름.테이블이름 TO 아이디@호스트 IDENTIFIED BY '비밀번호' with grant option;

- ALL PRIVILEGES : 모든 권한 추가
- SELECT, INSERT, UPDATE, DELETE, ... : 권한을 일부분을 추가
- with grant option : GRANT를 사용할 수 있는 권한 추가
- Grant 로 주어지는 권한은 여기 [grant: privilege-levels](https://mariadb.com/kb/en/grant/#privilege-levels) 명령에서 찾을 수 있다.

아래는 userid 사용자가 특정 sampledb 에만 모든 권한을 부여하고 있다.

1
2
mysql> GRANT ALL PRIVILEGES ON sampledb.* TO 'USERID'@'localhost';
mysql> FLUSH PRIVILEGES;

다음 GRANT 명령에서 ALL PRIVILEGES ON *.* 는 모든 권한(ALL PRIVILEGES)을 모든 스카마의 모든 테이블 *.* 에 준다는 의미.

1
2
mysql> GRANT ALL PRIVILEGES ON *.* TO 'USERID'@'localhost' WITH GRANT OPTION;
mysql> FLUSH PRIVILEGES;
  • WITH GRANT OPTION 의 의미는 다른 사용자에게 자신이 가진 권한을 주거나 회수할 수 있다는 의미.
  • ALL PRIVILEGES 부분에는 SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, INDEX, ALTER 등 권한 명칭을 콤마로 분리해서 나열하는 방식으로 특정 권한만을 줄 수도 있다.

[권한 제거]

권한을 없앨때는 REVOKE 명령을 사용한다. 두가지 형식을 사용한다.

1
2
3
REVOKE priv_type ON db.tables FROM user[,user]  ...

REVOKE ALL PRIVILEGES, GRANT OPTION FROM user [, user] ...

아래 명령으로 ‘localhost’ 에서 접속가능한 ‘testdbuser’ 에게서 모든 권한을 제외한다.

1
mysql> REVOKE ALL PRIVILEGES *.* FROM 'USERID'@'localhost';

GRANT 명령과는 달리 REVOKE 명령은 모든 권한을 제거해도 mysql.user 테이블 사용자 정보는 완전히 삭제되지 않는다.

사용자 정보의 완전한 제거를 원한다면 DROP USER 명령을 사용한다.

1
mysql> DROP USER 'USERID'@'localhost';

권한 조회

사용자별 권한 확인

1
mysql> SHOW GRANTS FOR 'USERID'@'HOST';

접속된 계정 권한 확인

1
mysql> SHOW GRANTS FOR CURRENT_USER;


실행 프로세스 확인

현재 접속자를 확인하고, lock 이 걸린 프로세스를 죽이거나 하는 작업

  • 프로세스 리스트보기
1
2
3
4
5
6
7
8
mysql> SHOW PROCESSLIST;
+------+-----------+----------------------+-----------+---------+------+---------------------------------+------------------------------------------------------------------------------------------------------+----------+
| Id | User | Host | db | Command | Time | State | Info
| Progress |
+------+-----------+----------------------+-----------+---------+------+---------------------------------+------------------------------------------------------------------------------------------------------+----------+
| 1371 | dbkmart | 205.22.168.143:29762 | yourdb | Sleep | 2673 | | NULL
| 0.000 |
|
  • 프로세스 죽이기(프로세스 아이디는 리스트에 나오는 Id.)
1
mysql> kill 프로세스아이디

ex: DB 생성해 사용자 추가

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
-- 1. mysql/mariadb 데이터베이스 생성
create database webdb;

-- 2. mysql/mariadb 계정 생성
create user 'webdb'@'192.168.1.%' identified by 'webdb';

-- 3. 권한주기
grant all privileges on webdb.* to 'webdb'@'192.168.1.%';

-- 4. flush privileges;

-- 5. 사용자 계정 삭제
drop user 'webdb'@'192.168.1.%';

-- 6. 데이터베이스 삭제
drop database webdb;

  1. grant: privilege-levels : https://mariadb.com/kb/en/grant/#privilege-levels

MariaDb 10/ MySQL 8 - data 디렉토리 변경 (Ubuntu)

data 폴더 위치를 변경해 이동한다.

  • 여기서는 MariaDB 를 사용하고 있다.
  • rsync 를 사용해서 복사한다.

위치 이동

my.cnf 에 있는 기본 디렉토리를 /data 폴더로 변경하고 적용한다.

  1. 기본 data 디레토리 확인

my.cnf 에서 datadir 로 지정된 항목을 찾아 보자.

1
2
~$ grep datadir /etc/mysql/mariadb.conf.d/*
/etc/mysql/mariadb.conf.d/50-server.cnf:#datadir = /var/lib/mysql

기본으로 Ubuntu 종류에서는 /var/lib/mysql 를 기본 데이터 디렉토리로 지정하고 있다.

  1. data 디렉토리를 /data 로 변경한다.

my.cnf 를 수정해서 /data로 변경하자

1
~$ sudo vi /etc/mysql/mariadb.conf.d/50-server.cnf
  1. data 폴더 권한

mysqld / mariadbd 데몬은 mysql 사용자, mysql 그룹으로 사용권이 실행되고 있다. 데이터베이스에서 접근하는 모든 자원(폴더, 파일, 로그 등등)은 mysql 사용자로 접근이 가는해야 한다. 그래서 /data 디렉토리 권한을 변경한다.

mysql 사용자와 그룹 확인한다.

1
2
3
4
5
$ grep mysql /etc/passwd
mysql:x:111:117:MySQL Server,,,:/nonexistent:/bin/false

$ grep mysql /etc/group
mysql:x:117:

소유권을 mysql 사용자로 변경한다.

1
2
3
4
5
$ sudo chown -R mysql:mysql /data
[sudo] 암호:
$ ls -al /data
drwxr-xr-x 3 mysql mysql 4096 5월 6 22:35 .
drwxr-xr-x 20 root root 4096 5월 6 17:15 ..
  1. data 이동

rsync 를 사용해서 /var/lib/mysql 데이터를 /data 아래로 복사한다.

1
$ sudo rsync -avzph /var/lib/mysql/ /data/
  1. mysqld 데몬을 재시작하고 확인한다.
1
2
3
4
$ sudo systemctl restart mysql
$ sudo systemctl status mysql

● mariadb.service - MariaDB 10.11.2 database server

데이터베이스에 접속해 데이터를 확인해 보자. @@datadir 환경변수를 출력해서 /data 가 출력되면 my.cnf 의 설정이 잘 구성된 상태를 확인할 수 있다.

1
2
3
4
5
6
7
8
$ mysql -u root -p

> select @@datadir;
+-----------+
| @@datadir |
+-----------+
| /data/ |
+-----------+

rsync 로 복사한 실제 데이터들은 각 스키마에서 확인해 보자.

Docker 기반 mongodb

Docker 기반 mongodb

Official : https://hub.docker.com/_/mongo/
참조: https://github.com/dockerfile/mongodb

로컬에 “mongo_data” 라는 데이터 저장소가 있고 29817 포트로 실행하기를 한다면 다음 같다:

1
$ docker run -d -p 29817:27017 -v /home/its/mongo_data:/data/db --name mongodb mongo

그리고 docker로 시작한 mongodb 컨테이너에 있는 mongo 를 사용해서 데이터베이스에 접속할 수 있다.

1
$ docker exec -it mongodb mongo

인증 이용

1
$ docker run -d -p 29817:27017 -v /home/its/mongo_data:/data/db --name mongodb mongo --auth

admin 데이터에이스에서 사용자 관리 계정 등록

1
2
$ docker exec -it mongodb mongo admin
> db.createUser({ user: 'jsmith', pwd: 'some-initial-password', roles: [ { role: "userAdminAnyDatabase", db: "admin" } ] });

MongoDB 구성 설정과 사용자 인증 사용

MongoDB에 관련 글

MongoDB Community Edition Installations 시리즈:ㅇ

  1. MongoDB Community Edition 4.2 설치 - ARM64 Ubuntu/Debian Armbian
  2. MongoDB 구성 설정 과 사용자 인증 사용

MongoDB Tutorials 시리즈:

  1. MongoDB Tutorials: collections
  2. MongoDB Tutorial

MongoDB와 Middleware Platform:

  1. NodeJS Mongoose
  2. Mongodb mongoose-middleware

이전 버전과 기타 자료:

  1. MongoDB User Authentication
  2. MongoDB Community Edition 3.6 on Ubuntu(ARM64)
  3. Mongodb 3.4 install on Armv8
  4. Raspberry Pi 3 64bit OS openSUSE: Build MongoDB 3.4


Mongo Database 설정과 사용자 인증 사용

이 문서는 MongoDB Community Edition 를 리눅스 플랫폼에서 시작과 운영에 필요한 구성 파일 mongod.conf 의 설정을 다루고 있다. 이를 통해 데이터베이스 서비스를 동작시키고, 인증한 사용자로서 클라이언트 프로그램으로 접속하기 위한 기본 인증방식을 구성하는 것을 정리하고 있다.

  1. Mongo Database 설정
  2. 기본인증 구성

이 글의 내용은 MongoDB Community Edition 3.6 이후 4.2 까지 사용이 가능하다.

자세히 보기

MongoDB Community Edition 4.2 설치 - ARM64 Ubuntu/Debian Armbian

MongoDB에 관련 글

MongoDB Community Edition Installations 시리즈:ㅇ

  1. MongoDB Community Edition 4.2 설치 - ARM64 Ubuntu/Debian Armbian
  2. MongoDB 구성 설정 과 사용자 인증 사용

MongoDB Tutorials 시리즈:

  1. MongoDB Tutorials: collections
  2. MongoDB Tutorial

MongoDB와 Middleware Platform:

  1. NodeJS Mongoose
  2. Mongodb mongoose-middleware

이전 버전과 기타 자료:

  1. MongoDB User Authentication
  2. MongoDB Community Edition 3.6 on Ubuntu(ARM64)
  3. Mongodb 3.4 install on Armv8
  4. Raspberry Pi 3 64bit OS openSUSE: Build MongoDB 3.4


Install MongoDB 4.2 Community edition 설치

이 문서는 Arm64 기반 CPU를 사용하는 Raspberry Pi, Odroid, PINE64, OrangePi 등 SBC 지원 보드 계열 위에서 Ubuntu/Debian 에서 설치 및 사용 가능한 MongoDB Community Edition 4.2 버전을 설치하고 구성하는 과정을 정리하고 있다.

MongoDB Community Edition 버전 Amd64, Arm64 의 설치는 Install MongoDB Community Edition on Debian 에서 제공하고 있다.

하지만 Arm64를 지원하는 Odroid C2, PINE64, OragePi 등 SBC 브드의 Armbian, Ubuntu 오에스에서 MongoDB Community Edition 을 저장소에서 apt 명령으로 직접 설치가 안되서 작은 트릭 이 필요하다.

  • MongoDB Community Edition 4.2 설치
  • systemd 사용이 가능한 mongod Unit 파일 구성
자세히 보기

Armbian 기반 MongoDB 4.2 설치

Armbian 을 사용하는 보드에서 mongodb 4.2 를 설치한다. 여기에 대한 자세한 내용은 아래 링크를 참조하고 있다.

https://docs.mongodb.com/manual/tutorial/install-mongodb-on-ubuntu/#install-mongodb-community-edition

GPG error

1
W: GPG error: https://repo.mongodb.org/apt/ubuntu bionic/mongodb-org/4.2 Release: The following signatures couldn't be verified because the public key is not available: NO_PUBKEY 4B7C549A058F8B6B
1
2
3
4
5
$ sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 3B4FE6ACC0B21F32
7C549A058F8B6B
gpg: key 4B7C549A058F8B6B: public key "MongoDB 4.2 Release Signing Key <packaging@mongodb.com>" imported
gpg: Total number processed: 1
gpg: imported: 1
1
$ sudo apt install -y mongodb-org

설정

mongod.conf 를 간단하게 다음

1
2
3
4
5
6
7
8
9
10
11
12
13
14
storage:
#dbPath: /var/lib/mongodb
dbPath: /home/qkboo/Db-data/mongodb4
journal:
enabled: true

systemLog:
destination: file
logAppend: true
path: /var/log/mongodb/mongod.log

net:
port: 27017
bindIp: 127.0.0.1

https://docs.mongodb.com/manual/core/security-mongodb-configuration/

인증

명령으로 mongod 로 실행이 가능한 MongoDB Server는 기본적으로 보안 모델이 없이 실행된다. 따라서 별도의 인증 절차를 가지고 있지 않습니다. 이 때문에 2017년 1월에는 이런 약점을 노린 랜섬웨어가 발생하기도 했습니다. MongoDB는 되도록이면 외부로부터의 신뢰되지 않은 접속을 허용하지 않는, 보안에 문제가 되지 않는 환경에서 보안 모델 없이 실행하는 것을 지향하고 있으나, 어쨌든 MongoDB도 ID와 비밀번호로 접근하는 기본적인 보안 모델을 가지고 있으니 이를 통해 MongoDB Server에 인증 과정을 추가해 보도록 합시다.

  1. 비인증 모드에서 관리자 계정 생성
  2. 인증 접속

1. 비인증 관리자 계정 생성하기

mongod로 별도의 보안 모델이 없는 MongoDB Server를 실행하고, MongoDB Shell에 접속합니다.

1
2
3
4
> mongo
MongoDB shell version v3.6.3
connecting to: mongodb://127.0.0.1:27017
MongoDB server version: 3.6.3

MongoDB에는 admin이라는 데이터베이스가 존재하며, 해당 데이터베이스에 사용자를 추가합니다.

1
2
3
4
5
6
> use admin
> db.createUser({
user: 'username',
pwd: 'password',
roles: ['userAdminAnyDatabase']
})

db.createUser()는 현재 사용하고 있는 데이터베이스(여기서는 admin)에 사용자를 추가합니다. 여기에는 사용자 이름, 비밀번호와 함께 권한(roles)을 array로 정의합니다. MongoDB에서 빌트인으로 제공하고 있는 권한은 MongoDB Built-In Roles에서 확인할 수 있습니다.

위에서 정의한 userAdminAnyDatabase는 어느 데이터베이스든 사용자를 생성하고 제거할 수 있다는 것을 의미합니다. 모든 권한을 가지게 하려면 root를 사용하면 되고, MongoDB 2.4 이하의 경우 db.addUser()를 통해 사용자를 추가합니다.

mongod 인증하기

만약 mongod 명령으로 실행하면 MongoDB Server를 실행하도록 한다.

1
> mongod --auth

MongoDB Server 재시작하기

Ubuntu와 같은 리눅스 시스템에서 service mongod start처럼 service를 이용할 경우, config 파일을 통해 실행됩니다. 이 경우 /etc/mongod.conf를 다음처럼 수정하고 재시작(service mongod restart)하면 됩니다.

mongodb 4.x

인증을 활성화 하려면

1
2
security:
authorization: enabled
mongodb 3.x

mongod.conf 를 사용하면 다음 옵션을 true 로 구성한다.

1
auth = true

그리고 서비스를 재시작한다.

1
2

$ sudo systemctl restart mongod.service

2. 인증 접속

mongo 쉘에 접속하여 db.auth()를 사용하는 것입니다.

1
2
3
4
5
$ mongo
MongoDB shell version v4.2.1
connecting to: mongodb://127.0.0.1:27017/?compressors=disabled&gssapiServiceName=mongodb
Implicit session: session { "id" : UUID("177716fe-5b3c-41f6-bdae-d2584819abff") }
MongoDB server version: 4.2.1

쉘에서 db.auth() 를 사용해 인증에 성공하면 1이 나오면 성공이다.

1
2
3
4
5
> use admin
switched to db admin
> db.auth('admin', '!23456789');
1
>

인증 접속이 되면 로그에 아래 같은 로그를 확인할 수 있다.

1
2019-12-02T09:49:24.392+0000 I  ACCESS   [conn3] Successfully authenticated as principal admin on admin from client 127.0.0.1:52370
명령행에서 접근

인증과 함께 admin 데이터베이스로 접근하려면 아래 같이 명령어에 아이디와 비밀번호를 명시만 해 주면 된다.

1
> mongo admin -u username -p password --authenticationDatabase admin

아래 같이 mongo 명령행에서 인증을 통해 접속하면 test 라는 데이터베이스로 접속합니다.

1
2
3
4
5
6
$ mongo -u admin -p
MongoDB shell version v4.2.1
Enter password:
...
>
> use admin

사용자 계정 만들기

관리자 계정을 만들고 인증까지 수행 했으면, 일반 사용자를 만들어 데이터베이스를 사용하도록 해보자. 관리자 계정을 만들었던 것처럼 계정을 만들고자 하는 데이터베이스를 use 한 다음 db.createUser()를 실행하면 된다.

1
2
3
4
5
6
7
8
9
> use bookdiary
switched to db bookdiary
> db.createUser({
... user:'student',
... pwd:'0123456789',
... roles:['dbOwner']
... });
Successfully added user: { "user" : "student", "roles" : [ "dbOwner" ] }
>

dbOwner라는 권한은 해당 데이터베이스에 대한 모든 수정/삭제 권한을 가진다는 것을 의미합니다.

사용자 인증

db.auth()를 통해 인증을 진행해 봅시다.

1
2
3
> db.auth('username', 'password')
1
>

참고

MongoDB Community Edition 3.6 on Ubuntu

2018-06-22 내용 정리, User auth 링크
{:.right-history}

이 문서는 Ubuntu/Debian 계열 정규 배포본에 3.x 버전을 지원하지 않는 플랫폼에 MongoDB Community Edition 3.6 버전을 설치하는 과정을 정리하고 있다. 내용의 기초는 MongoDB Community Edition 3.6 버전을 Amd64, Arm64 지원하는 64bit OS에 설치해 사용하기 위해서 Install MongoDB Community Edition, on-ubuntu를 따라서 진행하고 경험상 필요한 부분을 추가로 정리했다.

  • MongoDB Community Edition 3.6 설치
  • Mongo Database 구성
자세히 보기

mongodb - Collection

Collection

mongoDB는
mongoDB는 Collection 이 데이터베이스 테이블과 같은 개념이다. 아래 테이블은 관계형 데이터베이스 MySQL과 MongoDB의 개념을 비교해 주고 있다. [^1]

MySQL MongoDB
Table Collection
Row Document
Column Field
Joins Embedded documents, linking
자세히 보기