背景
サービスを利用するとき、提供者に悪意があることを前提にもの事を考えるべきである。 何かがあってからでは遅いからである。 クラウドサービスのストレージが暗号化されていないのが気に食わない。 万が一ストレージのデータが流出することに備え、ストレージを暗号化したい。 アプリケーションレイヤーではなく、fsレイヤーで暗号化したい。 さて、どうやるのかね。
透過的暗号 & 復号
gocryptfsという、透過的暗号化をディレクトリ単位でしてくれるツールがあります。 これが素晴らしい。ユーザランドで動く。すぐ動かせる。
インストール方法
sudo apt install gocryptfs # または公式のバイナリをダウンロード
暗号化されるディレクトリの作成方法
mkdir ~/secure_data.encrypted
gocryptfs -init ~/secure_data.encrypted
復号されるディレクトリを暗号化されたディレクトリにマウント
mkdir ~/decrypted_data
gocryptfs ~/secure_data.encrypted ~/decrypted_data
gocryptfs はシンプルで信頼性が高く、後付けでも運用しやすいです。
実際に、mongodbのデータを移植した方法がこちら
# install
sudo apt update
sudo apt install gocryptfs
# make directories
mkdir -p /secure/mongodb.encrypted
gocryptfs -init /secure/mongodb.encrypted # パスワードを設定
mkdir /secure/mongodb
# mongodbのデータ領域の確認
docker volume inspect rocketchat_mongodb_data
# コピーを/secure/mongodbに移動 (allow_otherでしないとmongodb(非rootユーザが読めなくなる))
gocryptfs -o allow_other /secure/mongodb.encrypted /secure/mongodb
cp -a /var/lib/docker/volumes/rocketchat_mongodb_data/_data/* /secure/mongodb/
# バインドマウントからボリュームマウントに切り替える
vim compose.yml
volumes:
- /secure/mongodb:/bitnami/mongodb
# docker composeで再起動
docker compose up -d
つまりポイント
権限回り。mongodbが実行するのですが、所有者と権限にはくれぐれもご注意。 1001をownerにしないとうまくいかないです。
gocryptfsのすごいところ
encrypted data -> decrepted dataがon the flyで実行されるってこと。これがすごい。 つまり、decrypted_dataというディレクトリ(インターフェース)を介して、 encrepted_dateのディレクトリにリアルタイムで読み書きが実行されている。
パスワードを忘れたら詰むっていうのがきついところだね。
hoge:/secure# gocryptfs -passwd /secure/mongodb.encrypted
Password:
Decrypting master key
Please enter your new password.
Password:
これで、パスワードの確認と更新もできます。
あと、再起動したらマウントし直す必要があります。 これも大事だね。
on the flyで暗号復号をしてくれるプロセス
root@x162-43-53-234:/secure# ^C
root@x162-43-53-234:/secure# ps aux | grep gocryptfs
root 273211 0.8 1.8 2540788 36256 ? Ssl 19:11 1:09 /usr/bin/gocryptfs -fg -notifypid=273205 -o allow_other /secure/mongodb.encrypted /secure/mongodb
root 273220 0.0 0.1 9612 2560 ? S 19:11 0:00 logger -t gocryptfs-273211-logger
root 292223 0.0 0.1 7080 2048 pts/0 S+ 21:34 0:00 grep --color=auto gocryptfs
最後に気になったこと
root@x162-43-53-234:/secure# ls -la
total 136
drwxrwxrwx 4 root root 4096 May 3 18:57 .
drwxr-xr-x 23 root root 4096 May 3 18:57 ..
drwx------ 3 1001 1001 65536 May 3 20:50 mongodb
drwx------ 3 1001 1001 65536 May 3 20:50 mongodb.encrypted
これ、rootがmongodb.encryptedに書き込むと思うんだけど。 所有者はrootでない & パーミッション的にもrootは書き込めない。なのに問題なく動いている。 なんで??
✅ 結論:大丈夫な理由
gocryptfs は root 権限で起動している /secure/mongodb.encrypted に直接アクセスするのは mongod ではなく、gocryptfs プロセス。 gocryptfs が root 権限で動作していれば、実体である /secure/mongodb.encrypted の読み書きは root によって問題なく実行可能。
FUSE の allow_other オプションを使っている allow_other により、他ユーザー(この場合は MongoDB ユーザー=UID 1001)にも /secure/mongodb(復号ディレクトリ)へのアクセスが許可される。これがなければ、MongoDB は復号ディレクトリにアクセスできない。
/secure/mongodb は FUSE 経由の仮想ディレクトリ MongoDB が実際に触っているのは 暗号化されたデータではなく、復号後のデータ(FUSEマウント)。
その裏で、gocryptfs が /secure/mongodb.encrypted に対して「暗号化・復号化」を自動で行っている。
🧠 まとめ(シンプル版)
/secure/mongodb.encrypted の所有者が 1001:1001 でも問題ない。
理由は: gocryptfs が rootで起動しているので、root がその中を操作できる。 allow_other を指定しているので、MongoDB(UID 1001)も /secure/mongodb にアクセスできる。 結果として、MongoDB は 復号された仮想ディレクトリを通して通常通り動作する。
あー研究室の環境が特殊だった
自分は、rootでも権限がないと見られないということがあるのでは??と思っていたが、rootは基本的には全てのファイルとディレクトリにアクセス 可能な権限を持っている
「root 他人のディレクトリ」は、一般的にLinuxなどのオペレーティングシステムにおけるセキュリティ上の問題や権限の取り扱いに関連するキーワードです。rootユーザーは、システム管理者の権限を持つユーザーで、すべてのファイルやディレクトリにアクセス可能です。したがって、他人のディレクトリにアクセスすることは、そのユーザーのプライバシーを侵害する可能性があり、場合によっては不正アクセスとみなされることもあります。
自分が所属していた研究室では、rootになっても他人のディレクトリを見られないことがあった。 しかしそれはADだったからで、単一のマシン内ではルートは全てのファイルを見られる。OK。理解しました。
ちなみにファイルシステムを見ると、ちゃんとマウントされているし動いている
root@x162-43-53-234:~# df -h
Filesystem Size Used Avail Use% Mounted on
tmpfs 197M 1.4M 195M 1% /run
efivarfs 256K 25K 227K 10% /sys/firmware/efi/efivars
/dev/vda1 48G 28G 20G 59% /
tmpfs 982M 0 982M 0% /dev/shm
tmpfs 5.0M 0 5.0M 0% /run/lock
/dev/vda16 881M 112M 707M 14% /boot
/dev/vda15 105M 6.1M 99M 6% /boot/efi
tmpfs 197M 28K 197M 1% /run/user/0
/secure/mongodb.encrypted 48G 28G 20G 59% /secure/mongodb
これすげーわ。