Percona Server for MySQL Data Masking Enhanced with Dictionary Term Cache

 

Percona Server for MySQL 8.0.41/8.4.4 에서는 Data Masking 구성 요소를 대폭 재설계했습니다. 특히 다음과 같은 변경 사항이 있습니다:

  • Dictionary 작업을 위한 internal query 를 실행할 때 사용하는 사용자를 변경했습니다.
  • Dictionary 작업의 속도를 크게 높이는 in-memory dictionary term cache 를 도입했습니다.
  • masking_dictionaries_flush() 사용자 정의 함수를 도입했습니다.
  • component_masking_functions.dictionaries_flush_interval_seconds 시스템 변수를 도입했습니다.
  • component_masking_functions.masking_database 시스템 변수를 도입했습니다.

percona

Internal SQL user

이번 버전부터는 dictionary 관련 함수(masking_dictionary_term_add(), masking_dictionary_term_remove(), masking_dictionary_remove(), gen_dictionary(), gen_blocklist(), masking_dictionaries_flush()) 이 생성하는 모든 internal query 에 더 이상 비밀번호 없는 “root” 사용자 계정으로 실행되지 않습니다.
MySQL 모범 사례에서는 이 계정을 비활성화할 것을 권장하며, 많은 MySQL 관리자가 이 권장 사항을 따르고 있습니다.
이러한 이유로 이전 버전에서는 “root” 계정을 비활성화할 경우, dictionary 관련 함수들이 정상적으로 작동하지 않는 문제가 있었습니다.
이 문제를 해결하기 위해, 이제는 시스템에 내장된 “mysql.session” 계정으로 dictionary 쿼리를 실행하도록 변경했습니다.
이 변경사항은 ‘ principle of least privilege (최소 권한 원칙)’에도 부합합니다. 슈퍼유저(root) 대신 제한된 권한을 가진 계정을 사용함으로써, 보안 위협 발생했을대 피해 범위를 크게 줄일 수 있게 되었습니다.
하지만 이 기능을 정상적으로 작동하게 하려면 “mysql.session” 계정에 반드시 “masking_dictionaries” 테이블에 대한 SELECT, INSERT, UPDATE, DELETE 권한을 명시적으로 부여해야 합니다.

GRANT SELECT, INSERT, UPDATE, DELETE ON mysql.masking_dictionaries TO 'mysql.session'@'localhost';

자세한 내용은 다음 지침을 참고하십시오.

In-memory dictionary term cache

이번 릴리스의 주요 하이라이트 중 하나는 dictionary 작업의 속도를 높이기 위해 in-memory dictionary term cache 도입입니다.

  • gen_dictionary()–dictionary 에서 무작위로 선택된 용어를 반환하는 함수
  • gen_blocklist() –dictionary 용어를 다른 dictionary 에서 무작위로 선택된 용어로 대체하는 함수

예를 들어, 미리 정의된 값 집합(dictionary)에서 임의의 단어를 얻고 싶다면 먼저 해당 dictionary 를 생성해야 합니다.
간단한 예로, “numbers” 라는 이름의 dictionary 을 만들고 여기에 숫자 one, two, three, four 영문 표현을 추가해보겠습니다.

아래의 모든 예제는 Data Masking 컴포넌트를 설치했을 뿐만 아니라, mysql.masking_dictionaries 테이블을 생성하고, MySQL 사용자에게 MASKING_DICTIONARIES_ADMIN 권한을 부여했으며, “mysql.session@localhost” 사용자에게도 필요한 권한을 위 지침에 따라 부여한 상태를 전제로 합니다.

다음은 숫자 1부터 4까지를 나타내는 단어 중에서 임의의 단어 3개를 생성하는 예제입니다.

SELECT masking_dictionary_term_add('numbers', 'one');
SELECT masking_dictionary_term_add('numbers', 'two');
SELECT masking_dictionary_term_add('numbers', 'three');
SELECT masking_dictionary_term_add('numbers', 'four');
SELECT gen_dictionary('numbers') AS random_number FROM PERCONA_SEQUENCE_TABLE(3) AS tt;

가능한 결과 중 하나는 다음과 같을 수 있습니다:

+---------------+
| random_number |
+---------------+
| two           |
| two           |
| three         |
+---------------+

3 rows in set (0.01 sec)

 


Manual dictionary cache reloading

이번 재설계의 부작용으로 인해 internal dictionary term cache 와 기본 dictionary 테이블(default: mysql.masking_dictionaries)의 동기화가 깨질수 있게 되었습니다.
이는 masking_dictionary_term_add(), masking_dictionary_term_remove(), masking_dictionary_remove() 와 같은 dictionary 조작 함수를 사용하는 대신 사용자가 해당 테이블을 직접 수정했을 때 발생할 수 있습니다.

이 internal dictionary term cache 를 동기화하기 위해, 인자값을 받지 않으며 성공했때에는 1을 반환하는    새로운 사용자 정의 함수 masking_dictionaries_flush() 를 추가했습니다.

이제 존재하지 않는 사전 “empty”에서 용어를 생성해보겠습니다.

SELECT gen_dictionary('empty');

예상대로 결과로는 NULL 값이 반환됩니다.

+-------------------------+
| gen_dictionary('empty') |
+-------------------------+
| NULL                    |
+-------------------------+
1 row in set (0.00 sec)

이제 “empty” 사전에 “first” 라는 새 용어를 추가하기 위해 “mysql.masking_dictionaries” 테이블에 직접 레코드를 삽입해보겠습니다.

INSERT INTO mysql.masking_dictionaries VALUES('empty', 'first');

이렇게 직접 insert 해도 이후 “gen_dictionary()” 호출 결과에는 영향을 주지 않습니다. in-memory term cache 가 아직 이 변경 사항을 반영하지 못했기 때문입니다.

SELECT gen_dictionary('empty');
+-------------------------+
| gen_dictionary('empty') |
+-------------------------+
| NULL                    |
+-------------------------+
1 row in set (0.00 sec)

in-memory term cache 를 다시 로드하려면 다음을 실행해야 합니다.

SELECT masking_dictionaries_flush();

이 명령을 실행하면 캐시가 반드시 다시 로드되며, 이 경우 “empty” dictionary 에는 “first” 라는 용어 하나만 포함되게 됩니다.

SELECT gen_dictionary('empty');
+-------------------------+
| gen_dictionary('empty') |
+-------------------------+
| first                   |
+-------------------------+
1 row in set (0.00 sec)

Periodic dictionary term cache reloading

이번 재설계의 또 다른 부작용은 row-based replication 과 관련이 있습니다.
사용자가 Source 에서 dictionary 테이블을 변경하면(전용 함수 또는 직접 수정), 변경 사항은 binlog 를 통해 Replica 로 전달됩니다.
Replica 측에서는 applier thread 가 이러한 binlog 이벤트를 받아 성공적으로 적용합니다.
그러나 안타깝게도, Replica 의 dictionary term cache 는 이 후 자동으로 업데이트되지 않습니다.

이 문제를 해결하기 위해, 새로운 시스템 변수 component_masking_functions.dictionaries_flush_interval_seconds (read-only, integer, unsigned, default 0)를 도입했습니다.
이 값을 0 이 아닌 값으로 설정하면, 컴포넌트가 시작될 때 background thread 가 생성되어 주기적으로 dictionary 테이블과 in-memory term cache 간의 동기화를 수행합니다.
이 변수의 값은 reloads 간격(초 단위)을 지정합니다.
따라서, Replica 에서 이 변수를 0 이 아닌 값으로 설정해 두면, binlog 이벤트를 수신한 후 설정된 시간 간격이 지나면 dictionary term cache 가 최종적으로 dictionary 테이블과 동기화됩니다.

Custom location for dictionary table

또한 컴포넌트의 유연성을 높였습니다.
기존에는 미리 정의되어 있는 “MySQL” 데이터베이스에서 “masking_dictionaries” 테이블을 찾도록 고정되어 있었던 것에서 벗어나, 이제는 이 컴포넌트가 해당 테이블을 찾아야 하는 데이터베이스 이름을 직접 지정할 수 있게 되었습니다.

component_masking_functions.masking_database - read-only, string, “default mysql”.

이 시스템 변수 값을 “mysql” 이 아닌 다른 값으로 변경할 경우, 지정한 데이터베이스에 새로운 “masking_dictionaries” 테이블을 생성해야 할 뿐만 아니라, “mysql.session” 사용자에게 새로운 사용자 정의 데이터베이스의 테이블에 대한 필수 권한을 GRANT 로 부여해야 합니다.

GRANT SELECT, INSERT, UPDATE, DELETE ON <component_masking_functions.masking_database>.masking_dictionaries TO 'mysql.session'@'localhost';

Conclusion

데이터 마스킹은 민감한 정보를 보호하기 위한 핵심 기술로, 개인 정보, 재무 기록, 기밀 데이터를 무단 접근으로부터 안전하게 보호하는 데 사용됩니다. 실제 데이터를 그럴듯한 대체 데이터로 치환함으로써, 조직은 개발, 테스트, 분석 등의 용도로 데이터를 활용하면서도 보안 취약점을 노출하지 않을 수 있습니다.

이러한 목적이 필요할 경우, Percona Server for MySQL 커뮤니티 에디션에서 사용할 수 있는 기업용 수준의 완전한 오픈소스 솔루션인 Data Masking Component 를 고려해보시기 바랍니다.

Data Masking 에 대한 더 많은 정보는 다음 블로그 글들을 참고해 주세요. 이 글들은 현재는 구버전으로 간주되는 data Masking plugin 에 대해 작성되었지만, 여전히 유용한 예제들을 다수 포함하고 있습니다.

  1. Data Masking in Percona Server for MySQL to Protect Sensitive Data (https://www.percona.com/blog/data-masking-in-percona-server-for-mysql-to-protect-sensitive-data/)
  2. Data Masking With Percona Server for MySQL – An Enterprise Feature at a Community Price (https://www.percona.com/blog/data-masking-with-percona-server-for-mysql-an-enterprise-feature-at-a-community-price/)
  3. Percona Server for MySQL 8.0 – New Data Masking Feature (https://percona.community/blog/2019/12/13/percona-server-for-mysql-8-0-new-data-masking-feature/)

블로그 원문 : https://www.percona.com/blog/percona-server-for-mysql-data-masking-enhanced-with-dictionary-term-cache/  

자유롭게 댓글을 달아주세요! 언제나 환영합니다.
기타 문의:  info@neoclova.co.kr
네오클로바 기술블로그 홈 바로가기: https://neoclova.net
네오클로바 홈페이지: http://neoclova.co.kr

 

Similar Posts

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다