NECの透過的暗号化モジュール「Transparent Data Encryption forPostgreSQL」(以降PGTDE)を組み込んだDocker環境を作成してみました。
ベースのOSにはalpineを使用しています。
先に出来上がったものは以下で公開しています↓
https://github.com/imo-tikuwa/docker-pgtde
構築メモ
- PGTDEのWikiでシステム要件やLinuxのインストール手順を読む
- Dockerhubからpostgresqlコンテナを起動するDockerfileを取得
- 検索窓に「postgresql」とか入れて検索
- イメージの提供元に「Docker Official Images」と表記されてるpostgresのページを開く
- 「Supported tags and respective Dockerfile links」からPGTDEが対応しているバージョンの(今回は9.6.19-alpine, 9.6-alpine, 9-alpine)を選択
- Dockerfileと docker-entrypoint.shの内容を自分の空のリポジトリにコピー、ソースについてざっと読み込む
postgres/9.6/alpine/ - docker-compose.ymlを作成。
- コンテナ名はpostgres、ポートフォワードは15432:5432
その他environmentに以下設定
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
- コンテナ名はpostgres、ポートフォワードは15432:5432
- とりあえず空のpostgresコンテナを起動、コンテナの中に入る
-
docker-compose build docker-compose up -d docker-compose exec postgres bash
-
- PGTDEの構築を行う
- うまく行ったコマンドをメモしておく
- コマンドはDockerfile、docker-entrypoint.sh、docker-entrypoint-initdb.d以下のシェルスクリプトなどに追記する
- PGTDEのビルドはpostgresqlが起動してる状態で行う必要があったみたい
- PGTDEのセットアップスクリプト(cipher_setup.sh)と暗号化キー発行スクリプト(cipher_key_regist.sh)はソースの初期状態だと、PGHOST=localhostという記述が邪魔をしてpostgresコンテナ内で起動中のpostgresにアクセスできなかった。
そのため、上記変数をコメントアウトしたスクリプトを別途作成(init_cipher_setup.sh,init_cipher_key_regist.sh)した。
作成したスクリプトはDockerfileのCOPYコマンドで/tmpにコピーしdocker-entrypoint-initdb.d内のシェルスクリプトでPGTDEのbinディレクトリに移動して実行した。
- コマンドを切りのいいとこまで追加したら既存のコンテナ、イメージを削除し作成しなおし、正常に起動することを確認する
-
docker-compose down --rmi all --volumes docker-compose up --build
- 起動に失敗したときは出力されてるログを調査したり、起動に失敗したコンテナ内に入って調べたり。
docker commit <container id> pgtde docker run --rm -it pgtde bash
- どこでエラーが起きてるのかわからないときはecho “@@@@@@”とかした^q^
-
技術メモ
- PGTDEのセットアップスクリプトは対話シェルになっているためexpectで自動化した
- expectコマンド自体は正直よくわかっておらずいくつかの参考サイト見てコピペした
- その後の問題で、セットアップスクリプトを別途作ってるので対話シェル自体消しても良いかもしれない?
- apk addで「.build-deps」という名前を付けてインストールしたモジュール群はPGTDEのビルドでも使うため、Dockerfile内でのapk delをひとまずコメントアウトした
- イメージのサイズが大きくなったような気がする。entrypoint.sh内で消した方が良い?
動作確認
動作確認用のサンプルデータベースとして以下のサイトに記載のDVDレンタルに関するデータベースを使用させていただきました
[PostgreSQL] サンプルのデータベースを用意する | Developers.IO
1.customerテーブルのemailカラムがencrypt_text型になっていることを確認。
2.暗号化セッションが開始されていない状態で暗号化カラムを含むSELECTを行い、TDE-E0017のエラーとなることを確認。
暗号化セッションを開始してなくても暗号化カラムを含まないSELECTはできることを確認。
3.暗号化セッションを開始した状態で正常にSELECTが行えることを確認。
一連の暗号化セッションに関する関数について正しい入力で「t」が返ってくることを確認。
参考サイト
Alpine Linux packages
dockerでコンテナが立ち上がらないときやってみること – Qiita
《滅びの呪文》Docker Composeで作ったコンテナ、イメージ、ボリューム、ネットワークを一括完全消去する便利コマンド – Qiita
Bashの便利な構文だがよく忘れてしまうものの備忘録 – Qiita
[docker] CMD とENTRYPOINT の違いを試してみた – Qiita
その他1
最近鍵かけてないTwitterアカウント作りました。作ってるプログラムのこととか趣味のゲームのことつぶやいてます。
https://twitter.com/2tRUbYkU1l0MR3s
今回作成したDocker環境についても「こうした方が良い」や「ここ違う」などアドバイスいただけると嬉しいです><
その他2
4,5年くらい前に求人サイトの個人情報をPGTDEを使って保護するというタスクがあり、その当時導入を担当したことをふと思い出した。当時はPostgreSQLのバージョンも9.3とかだったと思う。
Dockerはなかった(気がする)し、サイトが稼働してるサーバーがバックアップの取れないVPSサーバーみたいな環境で結構苦労した覚えがある。
正直docker-compose.ymlの設定についてはまだまだよくわかってないところが多い状態です。enviromentとかトップレベルのvolumesとかnetworksとか。一度時間作って読み込んだ方が良いんだろうけど、まだ必要に迫られてないし別にいいかなという感じ。dockerとdocker-composeの境界もよくわかってない。
postgresのデータベースのデータを永続化する辺り微妙に理解できませんでした(^^;
少し調べてみたところによるとビルドの前にdockerコマンドからボリュームを作る必要がある???( ・`ー・´)