LoginSignup
8
3

More than 5 years have passed since last update.

Elasticsearchのデータ暗号化

Last updated at Posted at 2019-02-10

はじめに

Elasticsearchのデータ暗号化について、検討する機会があったので、記事にまとめてみました^^:

利用した環境

product version
cryptsetup 1.7.4
Elasticsearch 6.6.0
OS Amazon Linux2 (4.14.88)
Instance Type m5.2xlarge
EBS ルート(8GB)、追加(30GB)
AMI ami-04677bdaa3c2b6e24

【ディスクの状態】
nvme0n1が8GBのルートボリューム、nvme1n1が追加の30GBボリュームです。
※m5はNitro世代のEC2インスタンスでEBS NVMeボリュームのため、/dev/nvmeXnXという名称

[root@ip-172-31-34-49 ~]# lsblk
NAME          MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
nvme1n1       259:0    0  30G  0 disk 
nvme0n1       259:1    0   8G  0 disk 
├─nvme0n1p1   259:2    0   8G  0 part /
└─nvme0n1p128 259:3    0   1M  0 part 

[root@ip-172-31-34-49 ~]# df -h
Filesystem      Size  Used Avail Use% Mounted on
devtmpfs         16G     0   16G   0% /dev
tmpfs            16G     0   16G   0% /dev/shm
tmpfs            16G  388K   16G   1% /run
tmpfs            16G     0   16G   0% /sys/fs/cgroup
/dev/nvme0n1p1  8.0G  1.2G  6.9G  15% /
tmpfs           3.1G     0  3.1G   0% /run/user/1000

基本的な考え方

Elasticsearchのデータ(=Index)暗号化では、日立ソリューションズ社のCredeon Secure Full-text Searchがありますが、あくまで全文検索のためのIndex暗号化であって、Kibanaが利用するaggregation機能には対応していません。

Elastic Stackでは5.3.0から保存データの暗号化に対応しています。
サブスクリプションのPlatinum Editionで対応していますが、あくまでdm-cryptを用いたボリュームの暗号化を利用した場合でもElasticsearchとしてサポートするというものです。暗号化機能が付いている訳ではありません。

dm-cryptとは

Device-Mapperの機能の1つでLinuxにおけるブロックデバイス暗号の仕組みです。
Kernel 2.6以降のdevice-mapperモジュールに標準で組み込まれていて、cyptsetupという暗号化管理ツールを使ってストレージデバイスの暗号化を行います。
dmcrypt.PNG

【参考】
LUKSとは?

設定手順

  1. Java 1.8.0 インストール
  2. Elasticsearch 6.6.0 インストール
  3. JVMヒープサイズ設定
  4. Elasticsearch設定
  5. 暗号化ボリュームの設定
  6. Index保存領域の作成
  7. 設定確認

1. Java 1.8.0 インストール

Javaがインストールされていないことを確認した上でJava 1.8.0をインストールします。

[root@ip-172-31-34-49 ~]# java -version
-bash: java: command not found

[root@ip-172-31-34-49 ~]# yum install -y java-1.8.0-openjdk
<インストールの経過は省略>

[root@ip-172-31-34-49 ~]# java -version
openjdk version "1.8.0_191"
OpenJDK Runtime Environment (build 1.8.0_191-b12)
OpenJDK 64-Bit Server VM (build 25.191-b12, mixed mode)

2. Elasticsearch 6.6.0 インストール

Elastic社公式のリポジトリを登録し、Elasticsearch 6.6.0をインストールします。

[root@ip-172-31-34-49 ~]# vi /etc/yum.repos.d/elastic.repo
[root@ip-172-31-34-49 ~]# cat /etc/yum.repos.d/elastic.repo
[elasticsearch-6.x]
name=Elasticsearch repository for 6.x packages
baseurl=https://artifacts.elastic.co/packages/6.x/yum
gpgcheck=1
gpgkey=https://artifacts.elastic.co/GPG-KEY-elasticsearch
enabled=1
autorefresh=1
type=rpm-md

[root@ip-172-31-34-49 ~]# yum install -y elasticsearch
<インストールの経過は省略>

[root@ip-172-31-34-49 ~]# systemctl status elasticsearch
● elasticsearch.service - Elasticsearch
   Loaded: loaded (/usr/lib/systemd/system/elasticsearch.service; disabled; vendor preset: disabled)
   Active: inactive (dead)
     Docs: http://www.elastic.co

3. JVMヒープサイズ設定

Elasticsearchには物理メモリの半分を上限にJVMヒープを割り当てます。
m5.2xlargeのメモリは32GBなので、今回は15GBのメモリを割り当てます。

[root@ip-172-31-34-49 ~]# vi /etc/elasticsearch/jvm.options
-Xms15g
-Xmx15g
# 以下、設定の確認です。
[root@ip-172-31-34-49 ~]# cat /etc/elasticsearch/jvm.options | grep 15

4. Elasticsearch設定

ElasticsearchのIndex保存領域をpath.dataで指定します。今回は/mnt/es/elasticsearchとします。

[root@ip-172-31-34-49 ~]# vi /etc/elasticsearch/elasticsearch.yml
path.data: /mnt/es/elasticsearch
# 以下、設定の確認です。
[root@ip-172-31-34-49 ~]# cat /etc/elasticsearch/elasticsearch.yml | grep path.data

5. 暗号化ボリュームの設定

cryptsetupコマンドで/dev/nvme1n1にAES256/SHA1暗号化ボリューム(esvol)を作成し、/mnt/esにマウントします。

[root@ip-172-31-34-49 ~]# cryptsetup --key-size 512 --hash sha512 luksFormat /dev/nvme1n1

WARNING!
========
This will overwrite data on /dev/nvme1n1 irrevocably.

Are you sure? (Type uppercase yes): YES
Enter passphrase: #パスワードを設定
Verify passphrase: #パスワードの確認

[root@ip-172-31-34-49 ~]# cryptsetup luksOpen /dev/nvme1n1 esvol
Enter passphrase for /dev/nvme1n1: #上記で設定したパスワードを入力

[root@ip-172-31-34-49 ~]# ls /dev/mapper
control  esvol

[root@ip-172-31-34-49 ~]# mkfs.ext4 /dev/mapper/esvol
mke2fs 1.42.9 (28-Dec-2013)
Filesystem label=
OS type: Linux
Block size=4096 (log=2)
Fragment size=4096 (log=2)
Stride=0 blocks, Stripe width=0 blocks
1966080 inodes, 7863808 blocks
393190 blocks (5.00%) reserved for the super user
First data block=0
Maximum filesystem blocks=2155872256
240 block groups
32768 blocks per group, 32768 fragments per group
8192 inodes per group
Superblock backups stored on blocks: 
        32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208, 
        4096000

Allocating group tables: done                            
Writing inode tables: done                            
Creating journal (32768 blocks): done
Writing superblocks and filesystem accounting information: done

[root@ip-172-31-34-49 ~]# mount /dev/mapper/esvol /mnt/es
[root@ip-172-31-34-49 ~]# ll /mnt
total 4
drwxr-xr-x 3 root root 4096 Feb 10 18:29 es

暗号化ボリュームが作成されていることを確認します。

[root@ip-172-31-34-49 ~]# lsblk
NAME          MAJ:MIN RM SIZE RO TYPE  MOUNTPOINT
nvme1n1       259:0    0  30G  0 disk  
└─esvol       253:0    0  30G  0 crypt /mnt/es
nvme0n1       259:1    0   8G  0 disk  
├─nvme0n1p1   259:2    0   8G  0 part  /
└─nvme0n1p128 259:3    0   1M  0 part

[root@ip-172-31-34-49 ~]# df -h
Filesystem         Size  Used Avail Use% Mounted on
devtmpfs            16G     0   16G   0% /dev
tmpfs               16G     0   16G   0% /dev/shm
tmpfs               16G  392K   16G   1% /run
tmpfs               16G     0   16G   0% /sys/fs/cgroup
/dev/nvme0n1p1     8.0G  1.5G  6.6G  19% /
/dev/mapper/esvol   30G   45M   28G   1% /mnt/es
tmpfs              3.1G     0  3.1G   0% /run/user/1000

6. Index保存領域の作成

/mnt/es配下にelasticsearchディレクトリを作成し、適切な権限を付与します。

[root@ip-172-31-34-49 elasticsearch]# cd /mnt/es
[root@ip-172-31-34-49 es]# mkdir elasticsearch
[root@ip-172-31-34-49 es]# chown elasticsearch:elasticsearch elasticsearch/
[root@ip-172-31-34-49 es]# chmod 750 elasticsearch/
[root@ip-172-31-34-49 es]# ll
total 20
drwxr-x--- 2 elasticsearch elasticsearch  4096 Feb 10 21:47 elasticsearch
drwx------ 2 root          root          16384 Feb 10 18:29 lost+found

Elasticsearchをサービス起動し、path.data配下にNodeIDファイル(node-0.st)が生成されていることを確認します。

[root@ip-172-31-34-49 es]# systemctl start elasticsearch
[root@ip-172-31-34-49 es]# cat elasticsearch/nodes/0/_state/node-0.st
?lstate:)
node_idUWTgg6zqmS2Cq72YdCOdCpA(

7. 設定確認

  • 暗号化した30GBの追加EBSボリュームのSnapshotを作成します。
  • 作成したSnapshotから別途EBSボリュームを作成し、別EC2にアタッチします。

EBSをアタッチしたEC2にログインし、追加EBSとしてnvme1n1が存在していることを確認します。

[root@ip-172-31-6-22 ~]# lsblk
NAME          MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
nvme0n1       259:0    0  100G  0 disk 
├─nvme0n1p1   259:1    0  100G  0 part /
└─nvme0n1p128 259:2    0    1M  0 part 
nvme1n1       259:3    0   30G  0 disk 

[root@ip-172-31-6-22 ~]# df -h
Filesystem      Size  Used Avail Use% Mounted on
devtmpfs        3.8G     0  3.8G   0% /dev
tmpfs           3.8G     0  3.8G   0% /dev/shm
tmpfs           3.8G  380K  3.8G   1% /run
tmpfs           3.8G     0  3.8G   0% /sys/fs/cgroup
/dev/nvme0n1p1  100G  2.2G   98G   3% /
tmpfs           763M     0  763M   0% /run/user/1000

/mnt/esにマウントし、内容を確認してみます。

[root@ip-172-31-6-22 ~]# mkdir /mnt/es
[root@ip-172-31-6-22 ~]# mount -o discard /dev/nvme1n1 /mnt/es
mount: /mnt/es: unknown filesystem type 'crypto_LUKS'.

まとめ

LUKSで暗号化したボリュームを他マシンにマウントしても認識しませんでした。
これでElasticsearchノードにログインされない限り、OSレベルでのIndexデータの機密性は確保できました。

ElasticsearchのData Nodeをi3系インスタンスで構築し、NVMe SSDにIndexを配置することで暗号化することも可能です。

NVMe インスタンスストレージのデータは、インスタンスのハードウェアモジュールに実装されている XTS-AES-256 ブロック暗号を使用して暗号化されます。暗号化キーは、ハードウェアモジュールで作成され、NVMe インスタンスストレージデバイスごとに固有です。すべての暗号化キーは、インスタンスが停止または終了して復元できないときに破棄されます。この暗号化を無効にしたり、独自の暗号キーを指定したりすることはできません。

以上、いかがでしたでしょうか。
不明な点、誤植などありましたら、コメントをお願いします!!

8
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
3