언두 로그 및 리두 로그 암호화

공부하는 감자·2024년 4월 21일
0

MySQL

목록 보기
58/74
post-thumbnail

평문으로 저장되는 로그

  • 테이블의 암호화를 적용해도 리두 로그나 언두 로그, 복제를 위한 바이너리 로그에는 평문으로 저장된다.
    • 디스크로 저장되는 데이터만 암호화되고 MySQL 서버의 메모리에 존재하는 데이터는 복호화된 평문으로 관리된다.
    • 평문 데이터가 데이터 파일 이외의 디스크 파일로 기록되는 경우에는 여전히 평문으로 저장된다.
  • MySQL 8.0.16 버전부터는 다음 시스템 변수를 이용해 InnoDB 스토리지 엔진의 리두 로그와 언두 로그를 암호화된 상태로 저장할 수 있게 개선됐다.
    • innodb_undo_log_encrypt 시스템 변수
    • innodb_redo_log_encrypt 시스템 변수

리두 로그와 언두 로그 암호화

암호화 적용 시

  • 테이블의 암호화는 일단 테이블 하나에 암호화가 적용되면 해당 테이블의 모든 데이터가 암호화돼야 한다.
    • 그러나 실행 중인 MySQL 서버에서 언두 로그나 리두 로그를 활성화한다고 하더라도 모든 리두 로그나 언두 로그의 데이터를 해당 시점에 한 번에 암호화해서 다시 저장할 수 없다.
  • MySQL 서버는 리두 로그나 언두 로그를 평문으로 저장하다가 암호화가 활성화되면 그때부터 생성되는 리두 로그나 언두 로그만 암호화해서 저장한다.
  • 반대로 리두 로그와 언두 로그가 암호화되는 상태에서 암호화를 비활성화하면, 그때부터 저장되는 로그만 평문으로 저장한다.
  • 리두 로그와 언두 로그는 암호화를 활성화했다가 비활성화한다고 해서 즉시 암호화에 사용된 키가 불필요해지는 것이 아니다.
    • 특히 언두 로그의 경우 암호화를 비활성화한다고 하더라도 기존의 언두 로그는 여전히 암호화된 상태로 남아있다.
    • 그래서 상황에 따라 며칠 또는 몇 달 동안 여전히 암호화키가 필요할 수도 있다.

암호화 적용 과정

-- 암호화 활성화
SET GLOBAL innodb_undo_log_encrypt=ON;
SET GLOBAL innodb_redo_log_encrypt=ON;

-- 암호화 활성여부 확인
SHOW GLOBAL VARIABLES LIKE 'innodb_undo_log_encrypt';
SHOW GLOBAL VARIABLES LIKE 'innodb_redo_log_encrypt';
  1. 리두 로그와 언두 로그 데이터 모두 각각의 테이블스페이스 키로 암호화된다.
    • 여기서 테이블스페이스 키는 실제 테이블 암호화에 사용된 테이블스페이스 키가 아니라, 리두 로그와 언두 로그 파일을 위한 프라이빗 키를 의미한다.
  2. 테이블스페이스 키는 다시 마스터 키로 암호화된다.

즉, 리두 로그와 언두 로그를 위한 각각의 프라이빗 키가 발급되고, 해당 프라이빗 키는 마스터 키로 암호화되어 리두 로그 파일과 언두 로그 파일의 헤더에 저장되는 것이다.

새로운 마스터 키 발급시

  • ALTER INSTANCE ROTATE INNODB MASTER KEY 명령이 실행되면 새로운 마스터 키가 발급되고, 테이블 암호화에 사용된 테이블 스페이스 키와 동일하게 그 새로운 마스터 키에 의해 다시 암호화된다.

암호화 확인

  • InnoDB 리두 로그가 암호화됐는지는 다음과 같이 확인할 수 있다.
    • 암호화 활성화 후 INSERT된 레코드의 문자열이 InnoDB의 리두 로그에 보이는지 확인한다.

    • grep 명령을 이용한 단순한 검색 결과에서 암호화되기 전에 INSERT한 문자열은 검색되지만, 암호화된 이후 INSERT된 문자열은 검색되지 않는다.

      ## grep 명령의 결과, 문자열이 존재하면 "matches"라는 메시지를 보여준다.
      grep '문자열' ib_logfile0 ib_logfile1
      ## 검색한 문자열이 존재한다면 grep 명령은 반환 값으로 "0"을 리턴한다.
      echo $?
      
      ## grep 명령의 결과, 문자열이 존재하지 않으면 아무런 메시지 출력이 없다.
      grep '문자열' ib_logfile0 ib_logfile1
      ## 검색한 문자열이 존재하지 않으면 grep 명령은 반환 값으로 "1"을 리턴한다.
      echo $?

Reference

참고 서적

📔 Real MySQL 8.0

profile
책을 읽거나 강의를 들으며 공부한 내용을 정리합니다. 가끔 개발하는데 있었던 이슈도 올립니다.

0개의 댓글