MySQL 서버의 데이터 암호화, keyring_file 플러그인, 테이블, 언두 로그 및 리두 로그, 바이너리 로그 암호화에 대해 알아보자

데이터베이스 서버와 디스크 사이의 데이터 읽고 쓰기 지점에서 암호화 또는 복호화
=> InnoDB 스토리지 엔진의 I/O 레이어에서만 데이터 암호화 및 복호화 과정 실행
TDE(Transparent Data Encryption)이라고도 함
=> MySQL 서버에서 암호화 여부를 식별할 필요가 없으며, 동일한 처리 과정 거침
TDE에서 암호화 키는 키링(KeyRing) 플러그인에 의해 관리

MySQL 서버의 데이터 암호화는 마스터 키와 테이블스페이스 키의 두 종류 키를 가짐
=> 테이블스페이스 키는 프라이빗 키
MySQL 서버는 HashiCorp Vault 같은 외부 키 관리 솔루션(KMS) 또는 디스크 파일(keyring_file)에서 마스터 키를 가져오고, 암호화된 테이블이 생성될 때 마다 해당 테이블을 위한 임의의 테이블스페이스 키 발급
마스터 키를 이용해 테이블스페이스 키를 암호화해서 각 테이블의 데이터 파일 헤더에 저장
=> 테이블스페이스 키는 MySQL 서버 외부로 노출되지 않아 보안상 취약점 X
=> 마스터 키는 외부의 파일을 이용해 주기적으로 변경해줘야 함
alter instance rotate innodb master key;
데이터 페이지는 암호화 키보다 훨씬 크기 때문에 암호화 결과가 평문의 결과와 동일한 크기의 암호문 반환
=> 암호화한다고 해서 InnoDB 버퍼 풀의 효율이 달라지거나 메모리 사용 효율이 떨어지는 현상 발생X
쿼리가 InnoDB 버퍼풀에 존재하지 않는 데이터 페이지를 읽을 경우, 복호화 과정을 거치므로 쿼리 처리 지연될 것
소스 서버와 레플리카 서버는 서로 다른 마스터키를 갖도록 설정해야 하며, 마스터 키 자체가 레플리카로 복제되지 않기 때문에 테이블스페이스 키 또한 레플리카로 복제되지 않음
테이블스페이스 키를 암호화하기 위한 마스터 키를 디스크 파일로 관리하는데, 마스터 키는 평문으로 디스크에 저장
=> 외부 노출 시 데이터 암호화 무용지물
my.cnf에 keyring_file 플러그인을 위한 라이브러리 명시하고, 마스터 키 저장할 경로를 명시하면 됨
# /etc/my.cnf
early-plugin-load=keyring_file.so
keyring_file_data=/very/secure/directory/tde_master.key
# 재시작
systemctl restart mysqld
#키링 파일의 마스터 키 초기화
alter instance rotate innodb master key;
https://dev.mysql.com/doc/refman/8.0/en/keyring-plugin-installation.html
8.0.34부터 더이상 지원X
create table tab_encrypted(
id int,
data varchar(100),
primary key(id)
) encryption='Y';
응용 프로그램 암호화는 암호화되기 전 값으로 정렬 불가능
=> MySQL 서버의 암호화 기능 선택 권장
-- 테이블스페이스 export
flush tables source_table for export;
암호화 X시
디스크로 기록잠금source_table.cfg 파일로 기록목적지 서버로 복사unlock tables 명령을 실행해 source_table을 사용할 수 있게 함TDE 암호화시
마스터 키 발급해 source.table.cfp로 기록테이블스페이스 키를 기존 마스터 키로 복호화 한 후, 임시로 발급한 마스터 키를 이용해 다시 암호화MySQL 서버의 메모리에 존재하는 데이터는 복호화된 평문으로 관리되며, 평문 데이터가 테이블의 데이터 파일 이외에 디스크 파일로 기록되는 경우에는 여전히 평문으로 저장
=> 8.0.16 이후 리두 로그와 언두 로그를 암호환 상태로 저장 가능하게 개선
리두 로그나 언두 로그를 평문으로 저장하다가 암호화 활성화시 그 이후 생성되는 리두 로그나 언두 로그만 암호화해서 저장
=> 반대로 비활성화시 그 이후 저장되는 로그만 평문
리두 로그와 언두 로그는 암호화를 활성화했다가 비활성화한다고 해도 즉시 암호화에 사용된 키가 불필요해지는 것 X
리두 로그와 언두 로그 모두 각각의 테이블스페이스 키로 암호화
=> 테이블 암호화에 사용되는 키 아님
=> 리두 로그와 언두 로그를 위한 각각의 프라이빗 키가 발급되고, 해당 프라이빗 키는 마스터 키로 암호화되어 리두 로그 파일과 언두 로그 파일 헤더에 저장
--리두 로그 암호화 여부
show global variables like 'innodb_redo_log_encrypt';


바이너리 로그와 릴레이 로그 파일의 데이터는 파일 키로 암호화, 파일 키는 바이너리 로그 암호화 키로 암호화해서 각 바이너리 로그와 릴레이 로그 파일의 헤더에 저장
alter instance rotate binlog master key;
바이너리 로그 암호화 키 변경시
바이너리 로그 암호화 키 발급 후 키링 파일에 저장스위치(새로운 로그 파일로 로테이션)파일 키를 생성하고, 파일 키는 바이너리 로그 파일 키(마스터 키)로 암호화해서 로그 파일에 저장기존 바이너리 로그와 릴레이 로그 파일의 파일 키를 읽어서 새로운 바이너리 로그 파일 키로 암호화해 다시 저장바이너리 로그 암호화 키로 암호화됐다면 기존 바이너리 로그 암호화 키 제거--암호화 여부
show binary logs;

바이너리 로그 암호화 키는 바이너리 로그나 릴레이 로그 파일을 생성한 MySQL 서버만 가지고 있으므로 mysqlbinlog 도구만으로는 복호화 불가
#MySQL 서버에 접속해서 바이너리 로그를 가져오는 것
mysqlbinlog --read-from-remote-server -uroot -p -vvv 바이너리파일