使用Elasticsearch进行数据加密
首先
由于有机会研究Elasticsearch的数据加密,所以我将其总结在文章中^^。
利用环境
【磁盘状态】
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全文搜索,但它仅仅是为全文搜索而提供的Index加密,并不支持Kibana使用的聚合功能。
在Elastic Stack中,自5.3.0版本开始,支持对存储数据进行加密。
这个功能是在Platinum Edition的订阅中提供的,但仅仅支持使用dm-crypt对卷进行加密,并支持作为Elasticsearch进行支持。这并不意味着它具备加密功能。
dm-crypt是一种加密方法。

【参考】
・LUKS 是什么?
设置步骤
-
- 安装Java 1.8.0
-
- 安装Elasticsearch 6.6.0
-
- 设置JVM堆大小
-
- 配置Elasticsearch
-
- 设置加密卷
-
- 创建索引保存区域
- 确认配置
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. Java虚拟机堆大小设置
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中,通过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. 创建索引保护领域
在 /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节点,就可以在操作系统级别上确保索引数据的机密性。
使用i3系列实例在Elasticsearch的数据节点上建立索引,并将索引存储在NVMe SSD上,这样可以实现加密。
使用XTS-AES-256块密码对NVMe实例存储的数据进行加密,该数据存储在实例的硬件模块中。加密密钥由硬件模块生成,并且对每个NVMe实例存储设备都是唯一的。所有加密密钥在实例停止或终止时无法恢复时被销毁。无法禁用此加密或指定自定义加密密钥。
以上、你觉得如何呢?如果有任何不清楚的地方、错别字等,请留下评论!