すごくマニアックな要件過ぎて、需要があるかどうかは不明なのですが、
ネットを探してもほとんど情報が見つからなかったので、備忘録代わりに書いておきます。
##現在の状況
まず、既存の構築済みDockerコンテナはこんな感じ。
MySQLコンテナはCentOSです。
MySQLのデータを別のDockerコンテナに分けています。
しかし、データのみの持ち出しが容易な反面、
tar等のコマンドでデータを別の人に持ちだされてしまうと、
セキュリティが心配!という声が有りました。
というわけでなんとかデータ部分だけを暗号化してくれ、というオーダーを受け、
色々試行錯誤してみたわけです。
##そもそもMySQLの暗号化は
どうも色々調べると、MySQLの場合、レコードに挿入するデータ自体を暗号化することが多いらしく、そういった記述は多々見つかりました。
7.11.2. 暗号化関数と圧縮関数
http://mysql.stu.edu.tw/doc/refman/5.1-olh/ja/encryption-functions.html
ですが、今回はこれじゃないんです。
##色々調べた結果、こんな感じで暗号化すると良さそう
LinuxOSが持っている、「自分自身のとある一部のディレクトリのみ暗号化する」という手法を使おうと思いました。
###とある一部のディレクトリを暗号化する手順
理解してしまえば簡単ですが、下記のような感じ
- ディスクイメージファイル(IMGとかISOとか)を作る。
- 作成したディスクイメージファイルを暗号化する。
- ディスクイメージファイルを自分自身にマウントする(ループバックデバイスというらしい)
仮想的に暗号化された外付けUSBディスクのようなものを作り出し、それを自分にマウントしてその中にデータを書き込むような感じです。
で、そのディスクイメージを、別のDockerコンテナ内に作成するようにしてしまえば、今回の要件は達成できそうです。
##ではコマンド
####データ用コンテナ作成
まずはイメージファイルを入れるコンテナを作成
docker run -it -v /var/lib/img/ --name crypttest_db_data busybox /bin/sh
####MySQLコンテナを作成
#イメージのループバックマウントには--privilegedが必要
docker run -it --name crypttest_db2 -p 3306 --volumes-from crypttest_db_data --privileged centos /bin/bash
ここで注意が必要です。
ループバックデバイスというものを利用するためには、Dockerコンテナを作成する際に「--privileged」というオプションが必須になります。
####コンテナスタート
docker start crypttest_db2
####必要ソフトのインストール
MySQL関連のインストールはできてるものとして、それ以外の必要ソフトウェアを入れます。
#デバイスの暗号化ソフトウェア
yum install -y cryptsetup
#ファイルをフォーマットするソフトウェア
yum install -y e2fsprogs
####MySQLを格納しておくイメージファイルを作成
ひとまず5GBで。
dd if=/dev/zero of=/var/lib/img/mysql.img bs=1M count=5120
####空きループバックデバイスを確認
losetup -f
/dev/loop0
#loop0が空いているようです。
####作成したディスクをループバックデバイスに関連付け
losetup /dev/loop0 mysql.img
####ループバックデバイスに接続したディスクを暗号化のために初期化
cryptsetup luksFormat /dev/loop0
#パスフレーズを求められるので、適当に入力してください。
####暗号化して読み書きできるデバイスファイルを作成
cryptsetup luksOpen /dev/loop0 encrypted
これで、/dev/mapper/encryptedというデバイスファイルができます。このデバイスファイル経由で読み書きすれば暗号化されるので、今後はこのデバイスファイルに対して操作します。
####デバイスのフォーマット
mkfs -t ext4 /dev/mapper/encrypted
####mountし、読み書きできることを確認
mount -t ext4 /dev/mapper/encrypted /var/lib/mysql/
###以上で終了です。
これでmysql.imgファイルを/var/lib/mysqlにマウントすることができました。
仮に、mysql.imgだけ1人でどこかに行ってしまっても、解読されることがありません。