MySQL 5.7 の透過的暗号化をやってみたよ

  • このエントリーをはてなブックマークに追加
  • Pocket

こんにちは。SREチーム  インフラエンジニアの綿引です。

今回は MySQL の透過的暗号化 について記載したいと思います。
因みに透過的暗号化が使用できるのは MySQL 5.7.11 からですのでご認識のほど。

前回 は RDS の暗号化について軽く触れましたが、
その際はWebコンソールからボックスにチェックを入れるだけでした。

今回の MySQL の透過的暗号化を使用する場合には設定が必要です。
では早速やっていきたいと思います。

環境

・OS : CentOS 7.1
・データベース : MySQL 5.7.22

設定

まずは暗号化の前に検証用のテストテーブルを作成します。

・データベース : test
・テーブル : test

カラムは適当に id , name とし、2レコードほど、insert しております。

なお、エンジンは InnoDB です。

少し脱線致しますが MyIsam でも暗号化(alter table XX ENCRYPTION=’Y’)ができたのですが、
mysqldump を取得して、インポートする際に失敗したので、
暗号化する際はエンジンが InnoDB であることを確認した方が良いです。
こちらに関してはまた別途書きたいと思います。

では、次に OS 上でどのように見えるか確認します。
ibd ファイルはバイナリのため strings コマンドで確認します。

先ほど insert した name 列の文字が確認できる状態ですね。
次は暗号化用の設定を行なっていきたいと思います。

プラグインのインストール

まずはプラグインのインストールです。

なお、MySQL 5.7.11 ではデフォルトのプラグインでしたが、
MySQL 5.7.12 以降はデフォルトで入っていないので明示的にインストールする必要があります。

my.cnf修正

次に my.cnf に以下の2行を追加していきます。

パラメータの意味としては、
1行目の early-plugin-load がロードするプラグインを指定します。
先ほどインストールしたキーリングプラグイン(keyring_file.so)ですね。

2行目の keyring_file_data はキーリングファイルの置き場所です。
他のデータベースファイルと混在しない場所が推奨されているので、
次の項目で専用のディレクトリを作成していきます。

因みに以下もパラメータとして必要なのですが、
MySQL 5.6.6以降はデフォルトで有効なのでいじってなければ大丈夫です。

キーリングファイルの置き場所(ディレクトリ)作成

上記で指定したディレクトリを作成していきます。

MySQL 再起動

後は MySQL を再起動していきます。

暗号化するぞ!

ここまで出来れば暗号化できる環境の準備は整いました。
暗号化の方法としては、以下です。

・新規テーブル : Create オプションに「ENCRYPTION=’Y’」を付与する
・既存テーブル : 対象テーブルに対して、「alter table テーブル名 ENCRYPTION=”Y”」を実施する

今回は検証用にテーブルを作成しているので、 alter table 文で暗号化していきます。

まずは対象テーブルが暗号化されていないことを確認します。
確認には information_schema の tables を使用します。

暗号化されると、上記の CREATE_OPTIONSENCRYPTION=’Y’ が入ります。

では alter table 文を実行します。

再度、information_schema の tables を確認しましょう。

CREATE_OPTIONS が ENCRYPTION=”Y” となっているので暗号化されたようですね。
実際にどうなっているか確認していきましょう。

当然ながら、select 文は問題なく発行できます。

では、先ほどは確認できた OS から strings コマンドを発行したらどうでしょう。

先ほどは出力されていた、test などの文言が表示されず、
暗号化された文字列が出力されていますね。
想定通り暗号化できたようです。

最後にログを見て問題ないことを確認しましょう。

ERROR が出てる、、

以下のようなエラーが出ておりました。。

今回キーリングファイルの置き先として
/var/lib/mysql/mysql-keyring ディレクトリ配下を指定しましたが、
datadir にて /var/lib/mysql/ を指定しているので、
mysql-keyring ディレクトリをデータベースと捉えてしまったようです。
そこで、「これ何? DB? いる?」 というメッセージが ERROR として出力された模様。

確かに show databases で確認すると以下のような表記になります。

#mysql50#mysql-keyring というのがそれっぽいですね。

DML は問題なく発行できたので挙動的には問題なさそうですが、メッセージの量がハンパない、、
ざっと見た感じ MySQL の再起動時やテーブルアクセス時にも出力されているみたい。。

対応していきましょう。
方法としては2つあり、一つはキーリングファイルの置き場所を変更する。
もう一つは既存の設定はそのままにパラメータを一つ追加する方法です。
設定変更するのは面倒なので、後者を実施していきます。

my.cnf再修正

設定は簡単です。以下を追加します。

ですので最終的な my.cnf としては以下のようになりました。

MySQL 再起動

再度、再起動していきます。

この後ログを確認しましたが、
もう [ERROR] Invalid (old?) table or database name ・・・というエラーは出てなさそう。。

show databases の結果も問題なさそうです。

まとめ

想定外もありましたが、透過的暗号化ができて良かったです。
特にアプリケーション側を変更せずに、インフラ側だけで対応できる点は非常に良いと思います。
皆さまも是非ご興味があれば。

この度は、ご清覧頂きありがとうございました。
Wedding Parkでは一緒に技術のウエディングパークを創っていくエンジニアを募集しています。
興味のある方はぜひ一度気軽にオフィスに遊びにいらして頂ければと思います。

ブライダル業界のデジタルシフトを加速させるリードエンジニア候補募集!

  • このエントリーをはてなブックマークに追加
  • Pocket

SNSでもご購読できます。