エンジニアの金田です。
Zen Cartとセキュリティ対策について、いくつかに記事を分けて考えていきたいと思います。今回はデータベースの透過的データ暗号化(TDE - Transparent Data Encryption。Zen Cartなどプロダクトに大きな変更を加えることなく、データベース側で暗号化処理を行うもの)についてです。
※以下、「透過的データ暗号化」は「透過的暗号化」と略します。
Zen Cartは標準でMySQLを使っていますが、MySQLは透過的暗号化の実装がありません。しかし、MySQLとの互換性があり、透過的暗号化をサポートしているAWS(アマゾンウェブサービス)が提供するリレーショナルデータベース「Amazon RDS」で代用できることが分かりました。ただし、複数のクエリを投げることでレイテンシ上の問題が発生し、レスポンスの悪化に繋がることが分かったので、これを解消するためにはZen Cart自体もAWS上で構築する必要があることも判明しました。
近年になって、個人情報の流出が相次ぐなどしてセキュリティの意識が高まっていますが、Zen CartやEC-CUBE、MagentoなどMySQLを利用しているECソフトウェアのデータベースに保存された個人情報は基本的にパスワードを除き暗号化されていません。しかしデータの暗号化の潜在的な需要はゼロではないでしょう。
データベースを平文で保存することには一定のリスクがあります。データベースそのものに接続不能でも、データベースのファイルシステムに侵入することでファイルを窃取され、解析されることで個人情報が漏れてしまいます。
商用データベースのOracleなどでは透過的暗号化をサポートしていますが、Zen Cartなど多くのソフトウェアが使用するMySQLは今のところこの暗号化はサポートされていません。
ただ、方法がないわけではありません。Amazonが提供しているクラウド上のデータベースAmazon RDSはMySQLをサポートし、インスタンスの暗号化もサポートしています。そしてMySQLの5倍のパフォーマンスを持つと言われるAuroraもMySQLとの互換性と透過的暗号化のサポートを謳っています。
そこで今回は、AWS Auroraを使用してZen Cartを動かしてみることにしました。
AWS Auroraのセットアップは普段AWSに使い慣れている人には簡単だと思います。VPCは自動生成を選択し、暗号を有効化にチェックを入れます。鍵は「Enter a key ARN」をチェックしてKMSで別途作成して値を入れる必要があります。
さて、Auroraのセットアップが完了したらデータベースのエンドポイント(FQDNなドメイン名です)とポート番号が渡されます(ポート番号はデフォルトでMySQLの標準ポートと同じなので意識する必要はありません)。
DB名もユーザー名・パスワードもAuroraのセットアップ時に設定したはずなので、以下のようにして接続してみます。
$ mysql -uroot -p -h arkweb-testdb.cd38****7cuy.ap-northeast-1.rds.amazonaws.com my_database
arkweb-testdb.cd38で始まる長い文字列がエンドポイント(サーバー名)です。
パスワードを聞かれるので入力してやると、「MySQL> 」のプロンプトが出ます。当初の予想とは違い、ほぼ完全にMySQLのクローンですね。
ではZen Cartのデータベースをインポートしてみます。例示ではmysqldumpを使って無理やり流し込んでいますが、初回は一旦ファイルに落として確認してからの方が良いと思います。
$ mysqldump -uroot -p -h 127.0.0.1 | mysql -uroot -p -h arkweb-testdb.cd38****7cuy.ap-northeast-1.rds.amazonaws.com my_database
ローカルとリモートのパスワードを1回ずつ聞かれるので気をつけてください。
AuroraはInnoDBしかサポートしていませんが、mysqldumpに記述されているMyISAMの部分は読み飛ばすらしく、MyISAMを使っていたとしてもエラーもなくインポートが完了します(InnoDBとして作成されます)。今回は10万件の商品が登録されているデータベースをインポートしました。
ではさっそくつなぎ変えてみましょう。includes/configure.php を編集します。
define('DB_SERVER', '1270.0.1'); // eg, localhost - should not be empty
define('DB_SERVER_USERNAME', 'root');
define('DB_SERVER_PASSWORD', '*********');
ここを書き換えるだけです。簡単ですね。
define('DB_SERVER', 'arkweb-testdb.cd38****7cuy.ap-northeast-1.rds.amazonaws.com'); // eg, localhost - should not be empty
define('DB_SERVER_USERNAME', 'root');
define('DB_SERVER_PASSWORD', '*********');
早速ページを表示させてみると……。表示されるのに5秒以上待たされました。これはおそらく、Zen Cart側がクエリを大量に送信していて、Zen CartサーバーとAWSの間の遅延が積もり積もったものと思われます。DB部分だけを切り離して使うには厳しいようです。
※その後、同一VPC(AWSにおけるLAN空間のようなもの)内で追試したところ、時間単価あたり約1.5倍のパフォーマンスが出ることが確認できました。それについては追ってまとめます。
Auroraは暗号化だけでなく、高速化、高い可用性とデータ堅牢性が期待できるので、個人情報を扱うためのサーバーとしては訴求力があると感じました。他方で、月の使用料が最も安いインスタンスdb.r3.largeで月額138.70ドル(120円換算で16,644円)、これに加えストレージとI/Oにかかる従量課金がかかるなど、提案しにくい部分もあります。