はじめに
データマスキング機能とは、権限のないユーザーによるアクセスを防止することで機密データを保護します。テストなどの実際のデータを使用すべきではない状況で、個人情報などのデータを特定の文字に置き換えることでデータの機密性を保護し、データのセキュリティを向上させるための手法です。
このブログでは Percona Server for MySQL の Data masking component について紹介します。
この機能は現在、こちらのマニュアルページ に記載がある通り、tech preview 段階です。
Data masking component と Data masking plugin の比較
Percona Server for MySQL では、元々 Data masking plugin が実装されていましたが、8.0.34-26 から新しく Data masking component が実装されました。
Data masking component では、以下の機能が新しく追加されました。
- ランダム生成 / マスキング関数のマルチバイト文字セットのサポート
- IBAN、UUID、カナダ SIN、および英国 NIN の新しいマスキング関数
- BAN、UUID、カナダ SIN、英国 NIN 用の新しいランダム生成機能
- データベースに置換辞書を保存する機能
- MASKING_DICTIONARIES_ADMIN 辞書操作操作に必要な動的権限
- コンポーネントのインストール/アンインストール時のロード可能関数の自動登録 / 登録解除
引用元 : Release highlights (8.0.34-26 リリースノート) (原文を機械翻訳)
plugin と比較して component は、マルチバイト文字セットが許可されていたり、より多くのマスキングをサポートしているため、component をおすすめします。
component | plugin |
---|---|
マスキング関数にマルチバイト文字セットを許可する | マルチバイト文字セットは許可されない |
PAN、SSN、IBAN、UUID、カナダ SIN、英国 NIN の マスキングをサポート |
PAN と SSN のマスキングをサポート |
ランダムな電子メール、米国の電話番号、PAN、SSN、IBAN、UUID、カナダの SIN、英国の NIN データを生成する | ランダムなメール、米国の電話番号、PAN、SSN を生成する |
データベース内の置換辞書の永続化をサポート | ファイル内の置換辞書の永続化をサポート |
辞書を管理するための専用権限 (MASKING_DICTIONARIES_ADMIN) をサポート |
FILE 権限が必要 |
コンポーネントのインストールまたはアンインストール中に、ロード可能な関数の登録または登録解除を自動化する | プラグインのインストールまたはアンインストール中に、ロード可能な関数の登録または登録解除を自動化しない |
引用元 : Compare the data masking component to the data masking plugin (原文を機械翻訳)
Percona と Oracle MySQL の比較
Percona の Component と Plugin 比較表 と、Oracle MySQL の Component と Plugin 比較表 を参考に以下の表を作成しました。
表から Percona の Data masking component は Oracle MySQL の Data masking component とほとんど同じ機能を有していることがわかります。
Percona Server for MySQL | MySQL Enterprise Edition | |
---|---|---|
名前 | Data masking component | Data masking component |
提供元 | Percona | Oracle |
マルチバイト文字セット | マスキング関数にマルチバイト文字セットを許可する | マスキング関数にマルチバイト文字セットを許可する |
サポートしているマスキング | PAN、SSN、IBAN、UUID、カナダ SIN、英国 NIN | PAN、SSN、IBAN、UUID、カナダ SIN、英国 NIN |
データ生成 | 電子メール、米国の電話番号、PAN、SSN、IBAN、UUID、カナダの SIN、英国の NIN | 電子メール、米国の電話番号、PAN、SSN、IBAN、UUID、カナダの SIN、英国の NIN |
置換辞書の保存 | データベース内に保存 | データベース内に保存 |
辞書を管理する権限 | MASKING_DICTIONARIES_ADMIN 権限 | MASKING_DICTIONARIES_ADMIN 権限 または SUPER 権限 |
インストール / アンインストール時のロード可能関数 の登録/解除 |
自動 | 自動 |
インストール
環境情報
- Oracle Linux 8
- Percona Server for MySQL 8.0.36-28
Percona Server for MySQL のインストール
Data masking component をインストールするために、まずは Percona のリファレンスから Percona Server for MySQL をインストールしておきます。
インストールが完了したら Data masking component のインストールに進みます。
Data masking component のインストール
以下のインストール手順を参考にインストールを行っていきます。
すでに Data masking plugin をインストールしている場合、アンインストールしないと競合が発生します。
1. masking_dictionaries
テーブルを作成します。
1 2 3 4 5 6 |
mysql> CREATE TABLE IF NOT EXISTS mysql.masking_dictionaries( Dictionary VARCHAR(256) NOT NULL, Term VARCHAR(256) NOT NULL, UNIQUE INDEX dictionary_term_idx (Dictionary, Term) ) ENGINE = InnoDB DEFAULT CHARSET=utf8mb4; |
2. Data masking component とロード可能な関数をインストールします。
1 |
mysql> INSTALL COMPONENT 'file://component_masking_functions'; |
インストールされたか確認します。
1 2 3 4 5 6 7 |
mysql> select * from mysql.component; +--------------+--------------------+------------------------------------+ | component_id | component_group_id | component_urn | +--------------+--------------------+------------------------------------+ | 1 | 1 | file://component_validate_password | | 2 | 2 | file://component_masking_functions | ← OK +--------------+--------------------+------------------------------------+ |
3. MASKING_DICTIONARIES_ADMIN 権限を付与します。
1 |
mysql> GRANT MASKING_DICTIONARIES_ADMIN ON *.* TO <ユーザー名>; |
以下の関数を使用する時に、MASKING_DICTIONARIES_ADMIN 権限が必要です。
masking_dictionary_term_add()
masking_dictionary_term_remove()
masking_dictionary_remove()
Data masking component を使ってみる
関数を 3 つほどピックアップして使ってみます。
各関数のパラメータや使用方法の詳細は 機能一覧 をご確認ください。
gen_dictionary()
: 辞書からランダムな用語を返します。masking_dictionary_term_add()
: 辞書に用語を追加します。masking_dictionary_term_remove
: 辞書の用語を削除します。masking_dictionary_remove()
: 辞書自体を削除します。
gen_rnd_email()
: 電子メールアドレスを生成します。mask_inner()
: 文字列の内部をマスクします。
gen_dictionary(dictionary_name)
gen_dictionary()
関数は、辞書からランダムに選択された用語を返します。
引数に辞書名 (dictionary_name
) を指定することで、指定した辞書にあらかじめ登録されていた用語がランダムに返されます。
gen_dictionary()
を使用するために、まずは masking_dictionary_term_add()
を使用して辞書を作成していきます。
辞書を作成するには、先ほど付与した MASKING_DICTIONARIES_ADMIN 権限が必要です。
- masking_dictionary_term_add(dictionary_name, term_name)
masking_dictionary_term_add()
関数は、term_name
で指定された用語を辞書 (dictionary_name
) に追加します。
まずは辞書のテーブル情報を確認します。
1 2 3 4 5 6 7 |
mysql> DESCRIBE mysql.masking_dictionaries; +------------+--------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +------------+--------------+------+-----+---------+-------+ | Dictionary | varchar(256) | NO | PRI | NULL | | | Term | varchar(256) | NO | PRI | NULL | | +------------+--------------+------+-----+---------+-------+ |
テーブル情報に基づいて vegetables
辞書と fruits
辞書を作成していきます。
成功の場合、戻り値 1
を返します。
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 26 27 28 29 |
mysql> SELECT masking_dictionary_term_add('vegetables','potato'); +----------------------------------------------------+ | masking_dictionary_term_add('vegetables','potato') | +----------------------------------------------------+ | 1 | +----------------------------------------------------+ mysql> SELECT masking_dictionary_term_add('vegetables','onion'); +---------------------------------------------------+ | masking_dictionary_term_add('vegetables','onion') | +---------------------------------------------------+ | 1 | +---------------------------------------------------+ mysql> SELECT masking_dictionary_term_add('vegetables','asparagus'); +-------------------------------------------------------+ | masking_dictionary_term_add('vegetables','asparagus') | +-------------------------------------------------------+ | 1 | +-------------------------------------------------------+ mysql> select * from masking_dictionaries; +------------+-----------+ | Dictionary | Term | +------------+-----------+ | vegetables | asparagus | | vegetables | onion | | vegetables | potato | +------------+-----------+ |
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 26 27 28 29 30 31 32 |
mysql> SELECT masking_dictionary_term_add('fruits','apple'); +-----------------------------------------------+ | masking_dictionary_term_add('fruits','apple') | +-----------------------------------------------+ | 1 | +-----------------------------------------------+ mysql> SELECT masking_dictionary_term_add('fruits','pear'); +----------------------------------------------+ | masking_dictionary_term_add('fruits','pear') | +----------------------------------------------+ | 1 | +----------------------------------------------+ mysql> SELECT masking_dictionary_term_add('fruits','orange'); +------------------------------------------------+ | masking_dictionary_term_add('fruits','orange') | +------------------------------------------------+ | 1 | +------------------------------------------------+ mysql> select * from masking_dictionaries; +------------+-----------+ | Dictionary | Term | +------------+-----------+ | fruits | apple | | fruits | orange | | fruits | pear | | vegetables | asparagus | | vegetables | onion | | vegetables | potato | +------------+-----------+ |
間違って登録した場合は masking_dictionary_term_remove()
を使います。
- masking_dictionary_term_remove(dictionary_name, term_name)
masking_dictionary_term_remove()
関数は、term_name
で指定された用語を辞書 (dictionary_name
) から削除します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
mysql> SELECT masking_dictionary_term_remove('vegetables','asparagus'); +----------------------------------------------------------+ | masking_dictionary_term_remove('vegetables','asparagus') | +----------------------------------------------------------+ | 1 | +----------------------------------------------------------+ mysql> select * from masking_dictionaries; +------------+--------+ | Dictionary | Term | +------------+--------+ | fruits | apple | | fruits | orange | | fruits | pear | | vegetables | onion | | vegetables | potato | +------------+--------+ |
辞書自体を削除する場合は masking_dictionary_remove()
を使います。
- masking_dictionary_remove(dictionary_name)
masking_dictionary_remove()
関数は、dictionary_name
で指定した辞書自体を削除します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
mysql> SELECT masking_dictionary_remove('vegetables'); +-----------------------------------------+ | masking_dictionary_remove('vegetables') | +-----------------------------------------+ | 1 | +-----------------------------------------+ mysql> select * from masking_dictionaries; +------------+--------+ | Dictionary | Term | +------------+--------+ | fruits | apple | | fruits | orange | | fruits | pear | +------------+--------+ |
fruits
辞書を作成したので gen_dictionary()
を使って、辞書からランダムに選択された用語を返します。
選択された辞書が存在しない、または用語が空の場合は NULL
を返します。
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 26 27 28 29 |
mysql> SELECT gen_dictionary('fruits'); +--------------------------+ | gen_dictionary('fruits') | +--------------------------+ | orange | +--------------------------+ 1 row in set (0.00 sec) mysql> SELECT gen_dictionary('fruits'); +--------------------------+ | gen_dictionary('fruits') | +--------------------------+ | apple | +--------------------------+ 1 row in set (0.00 sec) mysql> SELECT gen_dictionary('fruits'); +--------------------------+ | gen_dictionary('fruits') | +--------------------------+ | pear | +--------------------------+ mysql> SELECT gen_dictionary('vegetables'); +------------------------------+ | gen_dictionary('vegetables') | +------------------------------+ | NULL | +------------------------------+ |
gen_rnd_email([name_size, surname_size, domain])
gen_rnd_email()
関数は、name.surname@domain
形式でランダムな電子メールアドレスを生成します。
name_size
: 先頭の文字数を指定します。デフォルトの文字数は5
で1
–1024
が指定可能です。surname_size
: 「.
」 で区切られた後半部分の文字数を指定します。デフォルトの文字数は7
で、1
–1024
が指定可能です。domain
: 使用するドメイン名を指定します。デフォルト値はexample.com
です。
実際に gen_rnd_email()
を実行して、デフォルトサイズの電子メールアドレスを生成します。
1 2 3 4 5 6 |
mysql> SELECT gen_rnd_email(); +---------------------------+ | gen_rnd_email() | +---------------------------+ | tyfsi.pwxyncj@example.com | +---------------------------+ |
1 2 3 4 5 6 |
mysql> SELECT gen_rnd_email(); +---------------------------+ | gen_rnd_email() | +---------------------------+ | xyuvk.kntjbsz@example.com | +---------------------------+ |
デフォルトサイズの電子メールアドレスが生成されたことが確認できます。
次に、name_size
, surname_size
, domain
を指定して電子メールアドレスを生成します。
1 2 3 4 5 6 |
mysql> SELECT gen_rnd_email(1, 1, 'test.email'); +-----------------------------------+ | gen_rnd_email(1, 1, 'test.email') | +-----------------------------------+ | o.w@test.email | +-----------------------------------+ |
1 2 3 4 5 6 |
mysql> SELECT gen_rnd_email(10, 10, 'test.email'); +-------------------------------------+ | gen_rnd_email(10, 10, 'test.email') | +-------------------------------------+ | dcxvevalow.ujjcdqwxdt@test.email | +-------------------------------------+ |
mask_inner(str, margin1, margin2 [,mask_char])
mask_inner()
関数は、選択した内部部分が置換文字でマスクされた文字列を返します。
string
: マスクする文字列を指定します。margin1
: 文字列の左端でマスクされない文字の数を0
以上で指定可能です。margin2
: 文字列の右端でマスクされない文字の数を0
以上で指定可能です。mask_char
: マスキングする文字を指定できます。デフォルトはX
です。
SELECT mask_inner('123456789', 3, 3)
を実行して、123456789
の左右 3
文字ずつマスクされない文字列を返します。
margin1
とmargin2
の合計がstring
の長さ以上の場合、マスキングは発生しません。
1 2 3 4 5 6 |
mysql> SELECT mask_inner('123456789', 3, 3); +-------------------------------+ | mask_inner('123456789', 3, 3) | +-------------------------------+ | 123XXX789 | +-------------------------------+ |
次に、mask_char
を指定して、マスクされている X
の部分を a
に変更します。
1 2 3 4 5 6 |
mysql> SELECT mask_inner('123456789', 3, 3, 'a'); +------------------------------------+ | mask_inner('123456789', 3, 3, 'a') | +------------------------------------+ | 123aaa789 | +------------------------------------+ |
まとめ
Data masking component でデータをマスキングすることで、重要なデータを保護して、情報漏洩を防ぐことができます。
データマスキングの身近な例としては、クレジットカード番号の下 4
桁以外をマスキングする (XXXX-XXXX-XXXX-1234
)、電話番号やメールのアドレスの一部をマスキングするといったマスキング方法をよく目にします。
Percona Server for MySQL の Data masking component はセットアップが非常に簡単で公式リファレンスも充実しているので、気軽に使用することができます。
Percona Server for MySQL を使っていない場合でも、Percona Server for MySQL のインストール自体簡単なので一度ダウンロードして Data masking component を使用してみてください。
また、今回のブログでは、Percona Server for MySQL の Data masking component の活用方法についてご紹介しましたが、過去ブログで Oracle MySQL のデータマスキングについても紹介しています。
- SmartStyle TECH BLOG : MySQL Enterprise Masking and De-identification を使ってみた
- SmartStyle TECH BLOG :MySQL Database Service での Data Masking and De-Identification Functions の紹介
他に、Percona Server for MySQL のセキュリティ関連の機能として監査イベントを記録するための Audit Log Filter Plugin についても過去ブログで紹介していますので併せてご覧ください。
- SmartStyle TECH BLOG : Percona Server for MySQL の Audit Log Filter Plugin をインストールしてみる