在我之前的文章 “Elasticsearch:设置 Elastic 账户安全” 我详细地介绍了如何为 Elasticsearch 配置安全。在那里我们使用了 elasticsearch-setup-passwords 命令来配置用户名及密码。这种方法,需要我们手动来创输入密码,或者由命令帮我们生成随机的密码。这种方法的坏处是不便于自动部署。假如我们有1万台服务器,那么我们需要操作1万遍才可以完成所有的工作。在今天的文章中,我们将介绍使用 elasticsearch-keystore 来设置密码,并使用 API 的方法来设置其它的内置用户密码。这种方法的好处是:你可以使用脚本或者其它自动部署工具,比如 ansible 来进行使用。

在今天的教程中,我将使用一个 Ubuntu OS 20.04 的机器来进行安装及部署。

在 Ubuntu 机器上安装 Elasticsearch

如果你还从来没有在你的机器上安装过 Elasticsearch 的话,那么你可以参阅我之前的文章 “如何在 AWS 上一步一步地安装 Elastic Stack”。我们可以按照如下的步骤来进行安装。

在 Ubuntu 上安装 Elasticsearch 非常简单。 我们将启用 Elasticsearch 存储库,导入仓库 GPG 密钥,然后安装 Elasticsearch 服务器。Elasticsearch 软件包随附 OpenJDK 的捆绑版本,因此你不必安装 Java。首先,更新程序包索引并安装添加新的 HTTPS 仓库所需的依赖项

sudo apt update
sudo apt install apt-transport-https ca-certificates wget

导入仓库的 GPG 密钥:

wget -qO - https://artifacts.elastic.co/GPG-KEY-elasticsearch | sudo apt-key add -

上面的命令应该输出 OK,这表示密钥已成功导入,并且来自此存储库的软件包将被视为受信任的软件包。

接下来,通过发出以下命令将 Elasticsearch 仓库添加到系统中:

sudo sh -c 'echo "deb https://artifacts.elastic.co/packages/7.x/apt stable main" > /etc/apt/sources.list.d/elastic-7.x.list'

启用仓库后,通过输入以下命令安装 Elasticsearch:

sudo apt update
sudo apt install elasticsearch

安装过程完成后,Elasticsearch 服务将不会自动启动。 要启动服务并启用服务运行,请执行以下操作:

sudo service elasticsearch start

我们可以通过如下的命令来检查 Elasticsearch 服务是否已经被成功启动:

service elasticsearch status

如果你看到如下的状态:

$ service elasticsearch status
● elasticsearch.service - Elasticsearch
     Loaded: loaded (/lib/systemd/system/elasticsearch.service; enabled; vendor>
     Active: active (running) since Tue 2021-01-26 08:17:24 CST; 3h 45min ago
       Docs: https://www.elastic.co
   Main PID: 1809 (java)
      Tasks: 90 (limit: 18985)
     Memory: 1.5G
     CGroup: /system.slice/elasticsearch.service
             ├─1809 /usr/share/elasticsearch/jdk/bin/java -Xshare:auto -Des.net>
             └─2448 /usr/share/elasticsearch/modules/x-pack-ml/platform/linux-x>

1月 26 08:17:12 liuxgu systemd[1]: Starting Elasticsearch...
1月 26 08:17:24 liuxgu systemd[1]: Started Elasticsearch.

则表明 Elasticsearch 的服务已经被正常启动。我们可以通过如下的命令来检查 Elasticsearch 是否正常运行:

curl -X GET "localhost:9200/"
$ curl -X GET "localhost:9200/"
{
  "name" : "elk-1",
  "cluster_name" : "demo-elk",
  "cluster_uuid" : "rvdA4ZxgTqOEp6O28CT05w",
  "version" : {
    "number" : "7.10.2",
    "build_flavor" : "default",
    "build_type" : "deb",
    "build_hash" : "747e1cc71def077253878a59143c1f785afa92b9",
    "build_date" : "2021-01-13T00:42:12.435326Z",
    "build_snapshot" : false,
    "lucene_version" : "8.7.0",
    "minimum_wire_compatibility_version" : "6.8.0",
    "minimum_index_compatibility_version" : "6.0.0-beta1"
  },
  "tagline" : "You Know, for Search"
}

如果你能看到上面的输出,则表明 Elasticsearch 运行正常。你可以通过如下的命令来检查 Elasticsearch 的运行日志:

sudo journalctl -u elasticsearch
$ sudo journalctl -u elasticsearch
-- Logs begin at Tue 2020-10-27 19:19:12 CST, end at Tue 2021-01-26 12:05:55 CS>
1月 25 18:40:24 liuxgu systemd[1]: Starting Elasticsearch...
1月 25 18:40:33 liuxgu systemd[1]: Started Elasticsearch.
-- Reboot --
1月 26 08:17:12 liuxgu systemd[1]: Starting Elasticsearch...
1月 26 08:17:24 liuxgu systemd[1]: Started Elasticsearch.

它表明一切运行正常。

Elasticsearch keystore 介绍

我们可以像之前文章 “Elasticsearch:设置 Elastic 账户安全” 介绍的那样来配置 Elasticsearch 的安全。配置完后,我们必须重新启动 elasticsearch 服务即可。在今天的文章中,我们将使用一种不同的方法。这个方法可以使得我们将来很方便地使用脚本或者 ansible 这样的工具来进行自动部署。首先我们先来看一下两个重要的目录:

es_home 目录

/usr/share/elasticsearch

如果你仔细查看一下 Elasticsearch 的安装目录,我们会发现 Elasticsearch 被安装于上面的目录中:

$ pwd
/usr/share/elasticsearch
liuxg@liuxgu:/usr/share/elasticsearch$ ls
NOTICE.txt  README.asciidoc  bin  jdk  lib  modules  plugins

es_conf_dir 目录

/etc/elasticsearch

这是一个 Elasticsearch 的配置目录。它具有 root 权限。我们必须使用如下的方法才可以进入:

$ su
Password: 
root@liuxgu:/home/liuxg# cd /etc/elasticsearch
root@liuxgu:/etc/elasticsearch# ls
elasticsearch.keystore  jvm.options.d      roles.yml
elasticsearch.yml       log4j2.properties  users
jvm.options             role_mapping.yml   users_roles

在上面,我们可以看到 Elasticsearch 的配资文件。我们在这里可以看到 elasticsearch.keystore 文件。这个是用来存放一些 key/value 的不想让别人知道的数据。

熟悉 elasticsearch-keystore

在这个章节里,我们先来熟悉一下 elasticsearch-keystore。在 /usr/share/elasticsearch 目录下,我们打入如下的命令:

sudo ./bin/elasticsearch-keystore -help

上面的命令显示:

$ sudo ./bin/elasticsearch-keystore -help
A tool for managing settings stored in the elasticsearch keystore

Commands
--------
create - Creates a new elasticsearch keystore
list - List entries in the keystore
add - Add a string settings to the keystore
add-file - Add a file setting to the keystore
remove - Remove settings from the keystore
upgrade - Upgrade the keystore format
passwd - Changes the password of a keystore
has-passwd - Succeeds if the keystore exists and is password-protected, fails with exit code 1 otherwise.

Non-option arguments:
command              

Option             Description        
------             -----------        
-E <KeyValuePair>  Configure a setting
-h, --help         Show help          
-s, --silent       Show minimal output
-v, --verbose      Show verbose output

比如我们使用如下的命令来检查一下 keystore 是否含有 password:

$ sudo ./bin/elasticsearch-keystore has-passwd
ERROR: Keystore is not password-protected

上面显示我们的 keystore 目前还没有被密码所保护。我们可以使用如下的命令来设置 password:

$ sudo ./bin/elasticsearch-keystore passwd
Enter new password for the elasticsearch keystore (empty for no password): 
Enter same password again: 
Elasticsearch keystore password changed successfully.

在上面,我们不输入任何东西,这样也就没设置任何的密码。我们将在接下来的练习中来设置这个密码。接下来,我们来看如何添加一个项到 keystore 中:

$ sudo ./bin/elasticsearch-keystore add user.name
Enter value for user.name: 

在上面,我们输入任何东西。然后我们可以通过如下的命令来进行查看:

$ sudo ./bin/elasticsearch-keystore list
keystore.seed
user.name

在上面,我们可以看到有一个 user.name 的项被列出来了。这个是我们刚才创建的。我们可以通过如下的命令来进行删除:

$ sudo ./bin/elasticsearch-keystore remove user.name
liuxg@liuxgu:/usr/share/elasticsearch$ sudo ./bin/elasticsearch-keystore list
keystore.seed

在删除过后,我们再进行 list 来展示。我们发现刚才被创建的 user.name 不见了。

Elastic bootstrap password

在安装 Elasticsearch 时,如果 elastic 用户还没有密码,它将使用默认的 bootstrap。 bootstrap 是一种临时密码,使你可以运行设置所有内置用户密码的工具。

默认情况下,bootstrap 密码来自于随机化的 keystore.seed 设置,该设置在安装过程中添加到了密钥库中。 你不需要知道或更改此 bootstrap 密码。 但是,如果您在密钥库中定义了 bootstrap.password 设置,则将使用该值。 有关与密钥库进行交互的更多信息,请参阅安全设置。

 注意:为内置用户(尤其是 elastic 用户)设置密码后,bootstrap 密码将不再使用。

为 Elasticsearch 配置安全

为了能够对 Elasticsearch 进行安全配置,我们必须修改 Elasticsearch 的配置文件。我们在 Elasticsearch 的配置目录中找到 elasticsearch.yml 文件。我们在该文件中,添加如下的一行:

/etc/elasticsearch/elasticsearch.yml

xpack.security.enabled: true

你需要使用 root 权限修改上面的文件。我们可以重新启动 elasticsearch 服务:

sudo service elasticsearch restart

如果我们这个时候在去访问 http://localhost:9200 的话,我们将不能访问 Elasticsearch。这是因为我们现在已经设置了安全。我们需要使用用户名及密码来访问才可以。

$ curl -X GET "localhost:9200/"

{"error":{"root_cause":[{"type":"security_exception","reason":"missing authentication credentials for REST request [/]","header":{"WWW-Authenticate":"Basic realm=\"security\" charset=\"UTF-8\""}}],"type":"security_exception","reason":"missing authentication credentials for REST request [/]","header":{"WWW-Authenticate":"Basic realm=\"security\" charset=\"UTF-8\""}},"status":401}

我们接下来安装如下的步骤来配置安全用户:

1)创建 elasticsearch keystore:

$ pwd
/usr/share/elasticsearch
liuxg@liuxgu:/usr/share/elasticsearch$ sudo ./bin/elasticsearch-keystore create
[sudo] password for liuxg: 
An elasticsearch keystore already exists. Overwrite? [y/N]y
Created elasticsearch keystore in /etc/elasticsearch/elasticsearch.keystore

2)设置 elasticsearch keystore permissions

sudo chown root:elasticsearch /etc/elasticsearch/elasticsearch.keystore
sudo chmod 0660 /etc/elasticsearch/elasticsearch.keystore

在默认的安装下,/etc/elasticsearch/elasticsearch.keystore 的属性已经是我们所需要的。我们这个步骤可以省去。

# ls -al elasticsearch.keystore
-rw-rw---- 1 root elasticsearch 199 1月  26 12:58 elasticsearch.keystore

3)通过如下的命令来检查 elasticsearck keystore 是否已经设置好

$ sudo ./bin/elasticsearch-keystore list
keystore.seed

4)配置 bootstrap 密码

我们可以参照官方文档 “Built-in users” 来进行配置。我们需要为 bootstrap 配置密码。我们可以使用如下的命令来得到一些帮助:

$ sudo ./bin/elasticsearch-keystore add -help
Add a string settings to the keystore

Non-option arguments:
setting names        

Option             Description                                           
------             -----------                                           
-E <KeyValuePair>  Configure a setting                                   
-f, --force        Overwrite existing setting without prompting, creating
                     keystore if necessary                               
-h, --help         Show help                                             
-s, --silent       Show minimal output                                   
-v, --verbose      Show verbose output                                   
-x, --stdin        Read setting values from stdin        

我们可以使用 -x 选项从 stdin 中读取密码并配置:

$ pwd
/usr/share/elasticsearch
liuxg@liuxgu:/usr/share/elasticsearch$ echo "demopassword" | sudo ./bin/elasticsearch-keystore add -x "bootstrap.password"

在上面,我们为 bootstrap 设置了 demopassword 这个密码。经过上面的设置后,我们可以使用如下的命令来检查 elasticsearch keystore:

$ sudo ./bin/elasticsearch-keystore list
bootstrap.password
keystore.seed

我们可以看到一个叫做 bootstrap.password 的项。

5)重新启动 elasticsearch 服务

我们使用如下的命令来重新启动 elasticsearch 服务:

sudo service elasticsearch restart

经过上面的重启后,我们可以使用如下的方法来检查一下:

curl -u elastic:demopassword localhost:9200

在上面,我们使用了超级账号 elastic 及之前设置的密码 demopassword。上面的命令显示的结果为:

$ curl -u elastic:demopassword localhost:9200
{
  "name" : "elk-1",
  "cluster_name" : "demo-elk",
  "cluster_uuid" : "rvdA4ZxgTqOEp6O28CT05w",
  "version" : {
    "number" : "7.10.2",
    "build_flavor" : "default",
    "build_type" : "deb",
    "build_hash" : "747e1cc71def077253878a59143c1f785afa92b9",
    "build_date" : "2021-01-13T00:42:12.435326Z",
    "build_snapshot" : false,
    "lucene_version" : "8.7.0",
    "minimum_wire_compatibility_version" : "6.8.0",
    "minimum_index_compatibility_version" : "6.0.0-beta1"
  },
  "tagline" : "You Know, for Search"
}

显然这个设置是对的。

6)为内置用户创建账号

为了说明问题的方便,我们将使用如下的一下账号及密码:

# A built-in superuser.
elastic_username: elastic
elastic_password: goodwitch
 
# The user Kibana uses to connect and communicate with Elasticsearch.
kibana_username: kibana
kibana_password: badsanta

# The user Logstash uses when storing monitoring information in Elasticsearch.
logstash_system_username: logstash_system
logstash_system_password: dragonprince

# The user the Beats use when storing monitoring information in Elasticsearch.
beats_system_username: beats_system
beats_system_password: avatar

# The user the APM server uses when storing monitoring information in Elasticsearch.
apm_system_username: apm_system
apm_system_password: mashaandthebear

# The user Metricbeat uses when collecting and storing monitoring information in Elasticsearch. It has the remote_monitoring_agent and remote_monitoring_collector built-in roles.
remote_monitoring_user_username: remote_monitoring_user
remote_monitoring_user_password: gossipgir

我们可以直接使用 REST API  来创建用户名及密码,比如:

curl -u elastic:demopassword -XPOST "http://localhost:9200/_security/user/elastic/_password" -H 'Content-Type: application/json' -d'{  "password": "password"}'

比如在上面,我们使用了 API 来直接修改 elastic 用户的密码。经过上面的修改后,我们的超级用户 elastic 的密码就变成了 password 而不是之前的 demopassword:

$ curl -u elastic:demopassword localhost:9200

{"error":{"root_cause":[{"type":"security_exception","reason":"unable to authenticate user [elastic] for REST request [/]","header":{"WWW-Authenticate":"Basic realm=\"security\" charset=\"UTF-8\""}}],"type":"security_exception","reason":"unable to authenticate user [elastic] for REST request [/]","header":{"WWW-Authenticate":"Basic realm=\"security\" charset=\"UTF-8\""}},"status":401}

取而代之的是如下的方式:

$ curl -u elastic:password localhost:9200
{
  "name" : "elk-1",
  "cluster_name" : "demo-elk",
  "cluster_uuid" : "rvdA4ZxgTqOEp6O28CT05w",
  "version" : {
    "number" : "7.10.2",
    "build_flavor" : "default",
    "build_type" : "deb",
    "build_hash" : "747e1cc71def077253878a59143c1f785afa92b9",
    "build_date" : "2021-01-13T00:42:12.435326Z",
    "build_snapshot" : false,
    "lucene_version" : "8.7.0",
    "minimum_wire_compatibility_version" : "6.8.0",
    "minimum_index_compatibility_version" : "6.0.0-beta1"
  },
  "tagline" : "You Know, for Search"
}

我们可以安装上面的方法如法炮制,为其它的内置账号来建立账号:

  • Kibaba

curl -u elastic:password -XPOST "http://localhost:9200/_security/user/kibana/_password" -H 'Content-Type: application/json' -d'{  "password": "badsanta"}'

  • Logstash

curl -u elastic:password -XPOST "http://localhost:9200/_security/user/logstash_system/_password" -H 'Content-Type: application/json' -d'{  "password": "dragonprince"}'

  • Beats

curl -u elastic:password -XPOST "http://localhost:9200/_security/user/beats_system/_password" -H 'Content-Type: application/json' -d'{  "password": "avatar"}'

  • APM

curl -u elastic:password -XPOST "http://localhost:9200/_security/user/apm_system/_password" -H 'Content-Type: application/json' -d'{  "password": "mashaandthebear"}'

  • Remote monitoring

curl -u elastic:password -XPOST "http://localhost:9200/_security/user/remote_monitoring_user/_password" -H 'Content-Type: application/json' -d'{  "password": "gossipgirl"}'

这样我们就为所有的内置用户创建了账号。

经过上面的设置后,我们在其它的机器上访问 Ubuntu 系统上的机器,我们需要使用 elastic/password 来进行访问:

输入 elastic 及密码 password:

总结

在今天的练习中,我们为 Elasticsearch 配置了安全。我们通过 elasticsearch keystore 设置 bootstrap 密码,从而创建了超级用户 elastic 的访问。之后我们使用这个超级用户,并使用 REST API 来创建其它的内置用户。这个方法有别于我们之前的文章  “Elasticsearch:设置 Elastic 账户安全” 里所介绍的方法。但是这个方法可以让我们轻松地使用脚本或者 ansible 这样的工具进行大规模地部署,而不用交互。在接下来的文章中,我将展示如何使用 ansible 来为 Elasticsearch 进行进行自动化部署。敬请期待!

参考:

【1】https://linuxize.com/post/how-to-install-elasticsearch-on-ubuntu-20-04/

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐