MySQL5.7がGAになって5ヶ月がたちますね。
この記事を書いている時点(2016/3/27)のMySQL最新版は5.7.11なのですが、
このMySQL 5.7.11で、なんと新機能が搭載されました。
5.7.9でGAだったのに、GAリリース後にも新機能が入るとは、、、
と言う話はおいといて、早速試してみましょう。
新機能は、
「InnoDB Tablespace Encryption」
です。
MySQLに格納されているデータは、
ibdataファイル、もしくは、
初期化パラメータ「innodb_file_per_table」がONの場合は、
(テーブル名).ibdファイルという形で
実ファイルで保持されています。
しかし、このファイルは暗号化されていないため、
OS上から直接中身を見ることができます。
(完全な平文ではないですが、要所要所のキーワードは読み取れる、
というような状態です。後で確認します)
これを暗号化しよう、というのが、
このInnoDB Tablespace Encryptionという機能です。
(ちなみに、MySQLでいうTablespaceというのは、
Oracle DatabaseでいうTablespaceとは全く別物ですので注意が必要です)
実際に見たほうが早いと思いますので、早速見ていきましょう。
ここではworldデータベース(MySQL公式サイトで公開されています)を例にとりましょう。
mysql> show create table Country\G
*************************** 1. row ***************************
Table: Country
Create Table: CREATE TABLE `Country` (
`Code` char(3) NOT NULL DEFAULT '',
`Name` char(52) NOT NULL DEFAULT '',
`Continent` enum('Asia','Europe','North America','Africa','Oceania','Antarctica','South America') NOT NULL DEFAULT 'Asia',
`Region` char(26) NOT NULL DEFAULT '',
`SurfaceArea` float(10,2) NOT NULL DEFAULT '0.00',
`IndepYear` smallint(6) DEFAULT NULL,
`Population` int(11) NOT NULL DEFAULT '0',
`LifeExpectancy` float(3,1) DEFAULT NULL,
`GNP` float(10,2) DEFAULT NULL,
`GNPOld` float(10,2) DEFAULT NULL,
`LocalName` char(45) NOT NULL DEFAULT '',
`GovernmentForm` char(45) NOT NULL DEFAULT '',
`HeadOfState` char(60) DEFAULT NULL,
`Capital` int(11) DEFAULT NULL,
`Code2` char(2) NOT NULL DEFAULT '',
PRIMARY KEY (`Code`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
1 row in set (0.00 sec)
mysql> exit
[root@mysql57 ~]#
[root@mysql57 ~]# head /var/lib/mysql/world/Country.ibd
(一部のみ抜粋)
Coprincipality 7AD @ANT
,ッ#RNetherlands Antilles Caribbean HDOィffBNederlandse Antillen Nonmetropolitan Territory of The Netherlands Beatrix !ANHARE
,ッ#]United Arab Emirates Middle East H」Gウ%?(33BNG珣Al-Imarat al-エArabiya al-Muttahida Emirate Federation Zayid bin Sultan al-Nahayan AAEPARG
,ッ#hArgentina
こんな具合に、ただの平文ではないにせよ、
中身をみると、NetherlandsとかUnited Arab Emiratesとか、
ところどころ平文が見えてしまいます。
ちなみに、MySQLに習熟している人であれば、
ここで見える平文以上に読み取れる情報はあるそうです。
これを暗号化しましょう。
今回はalter table文を使います。
alter table文は、MySQLでは内部的にテーブルの再作成を行っていますので、
新しいテーブルを作った、
と思って頂ければ良いと思います。
alter table文で、ENCRYPTION=’Y’と足すだけです。
(create table文でも同じです)
mysql> alter table world.Country ENCRYPTION='Y';
Query OK, 239 rows affected (0.06 sec)
Records: 239 Duplicates: 0 Warnings: 0
mysql> show create table world.Country\G
*************************** 1. row ***************************
Table: Country
Create Table: CREATE TABLE `Country` (
`Code` char(3) NOT NULL DEFAULT '',
`Name` char(52) NOT NULL DEFAULT '',
`Continent` enum('Asia','Europe','North America','Africa','Oceania','Antarctica','South America') NOT NULL DEFAULT 'Asia',
`Region` char(26) NOT NULL DEFAULT '',
`SurfaceArea` float(10,2) NOT NULL DEFAULT '0.00',
`IndepYear` smallint(6) DEFAULT NULL,
`Population` int(11) NOT NULL DEFAULT '0',
`LifeExpectancy` float(3,1) DEFAULT NULL,
`GNP` float(10,2) DEFAULT NULL,
`GNPOld` float(10,2) DEFAULT NULL,
`LocalName` char(45) NOT NULL DEFAULT '',
`GovernmentForm` char(45) NOT NULL DEFAULT '',
`HeadOfState` char(60) DEFAULT NULL,
`Capital` int(11) DEFAULT NULL,
`Code2` char(2) NOT NULL DEFAULT '',
PRIMARY KEY (`Code`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 ENCRYPTION='Y'
1 row in set (0.00 sec)
mysql>
出力の一番最後に、「ENCRYPTION=’Y’」と出力されている点が、
暗号化なしのshow create table結果と違っていますね。
さあ、.ibdファイルを見てみましょう。
[root@mysql57 ~]# head /var/lib/mysql/world/Country.ibd
(一部のみ抜粋)
偂ヨ鉉&8ゥwC・ンモコテJ?]ミ~+ v
ュヲコ>"b?o3ス^Z鑼ムh渧イNヒ]Usu・_・]m|ゥ。@、ヤ籠3Iュャ「m3Rョナ゚・7・ャs{。P{アンo聽OC
<<ャ朎1iG・メ蠑IZ・・゙\キnアモ==ツ#
[ミ・・'ゥ+K$ヤq
イ AO・sdc?7・
)/サア}S|?c;+@・
]コセ}?
ciV Vvd-}、
?サ粫6kエKpク>z|
_ネ。鬮50?L菽~?ッETS・;~Tセj?l・'・セリqP8臘
ユ~・nP>,「3ヲュセ雋ァ|エソユ・
莅WヌPtNォ。JiN・・隆Ob
yッ・?m! ウレR 箜鑈_P鵁t?cマV
CEF=Vヨ)sAlィ"F?ャe。﨑オシキ・7Oン
>$
ス?荿メtツク
gヤモdt」Hォ2ヲ・K67!エルワ・跋lII?xO?゙x(<-`8$xE。裲ノ_イhチc"EZスqィ7Lチナ・=N_\khノ゚ゥ・ワgェu」ーVJ?#sレナ・NGz@・釚yヲ}"シAGラ5h韭iホjエャィ~?「~ソnslR%Q濬
全く読めないですね。
これで暗号化できていることが確認できました。
この暗号化ですが、
MySQL全体で1つのキーリングファイルを持っていて、
このキーリングファイルを使うことによって
復号できるようになっているようです。
キーリングファイルの場所は、
初期化パラメータ「keyring_file_data」で保持されています。
mysql> show global variables like 'keyring_file_data'; +-------------------+--------------------------------+ | Variable_name | Value | +-------------------+--------------------------------+ | keyring_file_data | /var/lib/mysql-keyring/keyring | +-------------------+--------------------------------+ 1 row in set (0.00 sec) mysql>
昨今、セキュリティというのはIT業界全体で重要性を増してきています。
MySQLは元々さほどセキュリティ等は厳しくない(=シンプルで使いやすい、ということにしておいてください笑)
製品でしたが、昨今の流れを汲んで、セキュリティ対策にも力を入れ始めているのでしょうか、、、
MySQL商用版では、
MySQL Enterprise Encryption, MySQL Enterprise Audit, MySQL Enterprise Firewallなど、
セキュリティ系の製品が次々とリリースされています。
これらの流れからみても、MySQLもセキュリティに力を入れ始めている(もしくは入れざるを得ない)
という事情があるのかな、と言えるのではないでしょうか。
今回はこんなところです。
では。