보안 설정을 잘 하는 것도 중요 하지만 보안에 문제가 없는지 상시 모니터링을 하고 확인을 하는 것도 매우 중요한 부분입니다.

하지만 규모가 작은 조직에서는 개발자가 모든 것을 다 하는 경우가 많기 때문에 항상 들여다 보고 있기가 쉽지 않으며 사실상 무었을 봐야 하는지 쉽지 않은 경우가 많습니다.

우선은 대량의 평문화된 개인정보를 조회 하는 경우를 모니터링 확인할 수 있게 하고 특이 사항이 있는 경우 담당자에게 소명을 하도록 하는 프로세스를 만들어 보았습니다.

 

준비

고객정보 테이블 생성

 

고객정보 암호화 함수 생성

 

[MySQL/MariaDB] 보안점검 - 개인정보 암호화 저장

사전 배경고객 정보 저장시 개인정보 컬럼(이름, 생년월일, 전화번호, 계좌번호... 등등) 암호화 저장이 필요함암/복호화가 가능한 방식으로 최소 권고 사항을 봤을 때 AES128 이상 적용해야 함어

opensrc.tistory.com

주의 : 위 글의 내용에도 있지만 function을 생성 하고 수정 할 수 있는 DBA권한을 가진 계정에서 생성하고 일반 사용자와는 권한을 분리해야 하는 점입니다. 일반 사용자에게도 모든 권한을 부여한다면 암호화 키가 노출 되는 문제가 발생합니다.

 

모든 권한이 있는 dba@192.168.45.102 계정의 function 소스 보기

 

DBA 권한이 없이 조회,입력,수정,삭제,보기 권한만 있는 developer1@192.168.45.102 계정의 function 소스보기

 

샘플데이터 입력

INSERT INTO CUSTOMER_INFO (NAME, PHONE_NO, BIRTH_DT, GENDER, EMAIL, REG_DATE, REG_SEQ) VALUES (AES256_ENCRYPT('홍길동'), AES256_ENCRYPT('010123456789'), AES256_ENCRYPT('20090101'), AES256_ENCRYPT('M'), AES256_ENCRYPT('gildong@xxxx.co.kr'), CURRENT_TIMESTAMP(), 0);
INSERT INTO CUSTOMER_INFO (NAME, PHONE_NO, BIRTH_DT, GENDER, EMAIL, REG_DATE, REG_SEQ) VALUES (AES256_ENCRYPT('이순신'), AES256_ENCRYPT('010234567891'), AES256_ENCRYPT('19600101'), AES256_ENCRYPT('M'), AES256_ENCRYPT('sunsin@xxxx.co.kr'), CURRENT_TIMESTAMP(), 0);
INSERT INTO CUSTOMER_INFO (NAME, PHONE_NO, BIRTH_DT, GENDER, EMAIL, REG_DATE, REG_SEQ) VALUES (AES256_ENCRYPT('강감찬'), AES256_ENCRYPT('010345678912'), AES256_ENCRYPT('18010101'), AES256_ENCRYPT('M'), AES256_ENCRYPT('kang@xxxx.co.kr'), CURRENT_TIMESTAMP(), 0);
INSERT INTO CUSTOMER_INFO (NAME, PHONE_NO, BIRTH_DT, GENDER, EMAIL, REG_DATE, REG_SEQ) VALUES (AES256_ENCRYPT('을지문덕'), AES256_ENCRYPT('010456789123'), AES256_ENCRYPT('19950101'), AES256_ENCRYPT('M'), AES256_ENCRYPT('moonduck@xxxx.co.kr'), CURRENT_TIMESTAMP(), 0);

COMMIT;

 

암호화 되어서 저장된 모습

 

함수를 이용해 복호화 해서 조회한 결과

 

Audit Plugin 설정

이전 스텝에서 MariaDB Server Audit Plugin 을 설치 했습니다.

Audit Plugin 은 설치후 기본은 logging = OFF 입니다. 로그를 남기도록 설정 하겠습니다.

MariaDB [webservice]> set global server_audit_logging = on;
Query OK, 0 rows affected (0.001 sec)

MariaDB [webservice]> show global variables like 'server_audit%';
+-------------------------------+-----------------------+
| Variable_name                 | Value                 |
+-------------------------------+-----------------------+
| server_audit_events           |                       |
| server_audit_excl_users       |                       |
| server_audit_file_path        | server_audit.log      |
| server_audit_file_rotate_now  | OFF                   |
| server_audit_file_rotate_size | 1000000               |
| server_audit_file_rotations   | 9                     |
| server_audit_incl_users       |                       |
| server_audit_logging          | ON                    |
| server_audit_mode             | 0                     |
| server_audit_output_type      | file                  |
| server_audit_query_log_limit  | 1024                  |
| server_audit_syslog_facility  | LOG_USER              |
| server_audit_syslog_ident     | mysql-server_auditing |
| server_audit_syslog_info      |                       |
| server_audit_syslog_priority  | LOG_INFO              |
+-------------------------------+-----------------------+
15 rows in set (0.007 sec)

MariaDB [webservice]>

 

이 설정은 DB가 재가동 되면 초기화 됩니다. 자동으로 남기기 위해서는 설정 파일에 추가 해야 합니다.

나의 설정에서는 /etc/mysql/mariadb.conf.d/50-server.cnf 이 파일에 추가 했습니다.

[server]

[mariadbd]
... 생략 ... 
server_audit_logging=ON
server_audit_file_path=/var/log/mysql/server_audit.log
... 생략 ...

 

log 파일의 경로는 mysql 기본 디렉토리 안에 logs 디렉토리를 만들어서 그곳에 모두 담을 생각입니다.

이렇게 하는게 나중에 로그 관리, logrotation 같은 것 설정하기가 편한 것 같습니다.

general_log_file, log_eror, log_slow_query_file 등 기타 로그도 한곳으로 모은 것이 관리에 편합니다.

 

$ sudo mkdir /var/log/mysql
$ sudo chown -R mysql:mysql /var/log/mysql
$ sudo chmod 660 /var/log/mysql
$ ls -al /var/log | grep mysql
drw-rw----   2 mysql     mysql              4096 Mar  2 00:09 mysql
$

 

/var/log/mysql/server_audit.log 파일을 보면 로그가 잘 남고 있습니다.

logrotation 설정 (선택)

MariaDB에서 기본 적으로 지원하는 server_audit 로그의 rotation 설정은 용량 기준 밖에 없는 것 같습니다.

매일 새벽 전 일자 server_audit 로그를 읽어서 의심이 가는 작업은 별도의 감사 로그 테이블에 추가하는 프로세스를 만들고자 합니다. 그렇게 하기 위해서는 로그를 일단위 rotation 해주는 것이 좋습니다.

일단위 rotation 된 로그는 향후 로그를 소산 보관하는 데도 편리합니다.

$ sudo apt install logrotate
logrotate is already the newest version (3.22.0-1).
logrotate set to manually installed.
Summary:
  Upgrading: 0, Installing: 0, Removing: 0, Not Upgrading: 10
$

ubuntu 에는 기본 설치가 되어 있습니다. RED Hat, CentOS 계열은 yum 을 이용하여 설치 합니다.

기본으로 제공하는 /etc/logrotate.d/mariadb 설정 파일을 잘 수정 하면 쉽게 해결 할 수 있을 것 같습니다.

혹시 모르니 수정을 위해서 원본 파일 백업

$ cd /etc/logrotate.d/
$ sudo tar zcvf mariadb.original.tar.gz mariadb
mariadb
$ ls -al | grep mariadb
-rw-r--r--   1 root root 1859 Aug 19  2024 mariadb
-rw-r--r--   1 root root 1034 Mar  2 00:02 mariadb.original.tar.gz
$

 

매일 12시에 log 파일을 분할 하도록 합니다.

/etc/logrotate.d/mariadb 파일 수정

/var/log/mysql/*.log {

  # 오류가 있어도 자동으로 넘어감
  missingok
  
  # 파일의 내용이 없는 경우 제외
  notifempty

  # 일단위 실행
  daily

  # 90일 보관
  rotate 90

  # 파일명에 yyyyMMdd 확장자 추가
  dateext

  # 압축
  compress

  # 압축 하는 동안 파일의 크기가 변경되어 오류가 발생하는 것을 대비 지연 압축
  delaycompress

  # postrotate 한번 만 실행
  sharedscripts

  # 파일 롤링 후 실행 MariaDB 10.4.0 이후 mysql 계정이 unix_socket 인증으로 되어 있어야 함
  postrotate
    if test -r /etc/mysql/debian.cnf
    then
      EXTRAPARAM='--defaults-file=/etc/mysql/debian.cnf'
    fi

    if test -x /usr/bin/mariadb-admin
    then
      /usr/bin/mariadb-admin $EXTRAPARAM --local flush-log
    fi
  endscript
}

 

파일이 일단위 분할 되는 것을 확인하기 위해서 1일 이상 기다려햐 합니다.

 

다음번에는 server audit log  파일을 분석하여 DB에 적재 하는 프로그램을 작성해서 데이터를 적재해 보겠습니다.

 

끝.

+ Recent posts