裸机部署Elasticsearch集群并开启X-Pack安全认证
0x00 说明
本文记录在三台 Linux 服务器上裸机部署 Elasticsearch 7.17.29,并开启 X-Pack 安全认证。
这里默认采用的方式是:
- 三节点 Elasticsearch 集群
- 9200 HTTP 接口开启用户名密码认证,访问方式仍然是
http:// - 9300 transport 节点通信开启 TLS 证书
- 使用百年 CA 证书签发 Elasticsearch 节点通信证书
- Kibana 和 Logstash 使用账号密码连接 Elasticsearch
注意:本文只配置 transport 证书,也就是 Elasticsearch 节点之间的 9300 通信证书。客户端访问的 9200 端口默认还是 HTTP,只是需要账号密码认证。
如果需要让 9200 也走 HTTPS,需要额外开启:
xpack.security.http.ssl.enabled: true
0x01 环境规划
服务器规划如下:
172.26.231.201 node001
172.26.231.202 node002
172.26.231.203 node003
每台服务器都添加 hosts 解析:
cat >> /etc/hosts <<'EOF'
172.26.231.201 node001
172.26.231.202 node002
172.26.231.203 node003
EOF
Elasticsearch 安装目录:
/opt/elasticsearch-7.17.29
数据目录和日志目录使用默认目录:
/opt/elasticsearch-7.17.29/data
/opt/elasticsearch-7.17.29/logs
0x02 安装 Elasticsearch
三台服务器都需要下载并解压 Elasticsearch。
cd /opt
wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-7.17.29-linux-x86_64.tar.gz
tar -xf elasticsearch-7.17.29-linux-x86_64.tar.gz
创建运行用户:
useradd elasticsearch
chown -R elasticsearch:elasticsearch /opt/elasticsearch-7.17.29
系统参数也需要提前调整,否则 Elasticsearch 可能启动失败。
cat >> /etc/sysctl.conf <<'EOF'
vm.max_map_count=262144
EOF
sysctl -p
配置文件句柄限制:
cat >> /etc/security/limits.conf <<'EOF'
elasticsearch soft nofile 65536
elasticsearch hard nofile 65536
elasticsearch soft nproc 4096
elasticsearch hard nproc 4096
EOF
0x03 生成百年证书
证书只需要在一台服务器上生成,本文以 node001 为例。
cd /opt/elasticsearch-7.17.29
1、生成百年 CA 证书
./bin/elasticsearch-certutil ca \
--days 36500 \
--out elastic-stack-ca.p12 \
--pass ''
查看 CA 证书过期时间:
openssl pkcs12 -in elastic-stack-ca.p12 -nokeys -out elastic-stack-ca.crt
openssl x509 -enddate -noout -in elastic-stack-ca.crt
正常会看到类似下面的时间:
notAfter=Dec 11 13:09:48 2124 GMT
2、生成 Elasticsearch 节点通信证书
这里生成的是 9300 transport 节点通信证书。
./bin/elasticsearch-certutil cert \
--days 36500 \
--ca elastic-stack-ca.p12 \
--ca-pass '' \
--out elastic-certificates.p12 \
--pass ''
查看证书过期时间:
openssl pkcs12 -in elastic-certificates.p12 -nokeys -out elastic-certificates.crt
openssl x509 -enddate -noout -in elastic-certificates.crt
把证书复制到 Elasticsearch 配置目录:
cp elastic-certificates.p12 /opt/elasticsearch-7.17.29/config/
chown elasticsearch:elasticsearch /opt/elasticsearch-7.17.29/config/elastic-certificates.p12
同步证书到另外两个节点:
scp /opt/elasticsearch-7.17.29/config/elastic-certificates.p12 root@node002:/opt/elasticsearch-7.17.29/config/
scp /opt/elasticsearch-7.17.29/config/elastic-certificates.p12 root@node003:/opt/elasticsearch-7.17.29/config/
在 node002 和 node003 上调整证书权限:
chown elasticsearch:elasticsearch /opt/elasticsearch-7.17.29/config/elastic-certificates.p12
0x04 编写 Elasticsearch 配置
1、node001 配置
/opt/elasticsearch-7.17.29/config/elasticsearch.yml
cluster.name: es-cluster
node.name: node001
path.data: /opt/elasticsearch-7.17.29/data
path.logs: /opt/elasticsearch-7.17.29/logs
network.host: 0.0.0.0
http.port: 9200
transport.host: 172.26.231.201
discovery.seed_hosts:
- node001
- node002
- node003
cluster.initial_master_nodes:
- node001
- node002
- node003
bootstrap.memory_lock: false
transport.tcp.compress: true
# 开启 X-Pack 安全认证
xpack.security.enabled: true
# 开启 9300 transport 节点通信 TLS
xpack.security.transport.ssl.enabled: true
xpack.security.transport.ssl.verification_mode: certificate
xpack.security.transport.ssl.keystore.path: elastic-certificates.p12
xpack.security.transport.ssl.truststore.path: elastic-certificates.p12
# 默认不建议直接打开 CORS,确实需要浏览器跨域访问 ES 时再启用
# http.cors.enabled: true
# http.cors.allow-origin: "*"
2、node002 配置
node002 只需要改节点名和 transport 地址:
cluster.name: es-cluster
node.name: node002
path.data: /opt/elasticsearch-7.17.29/data
path.logs: /opt/elasticsearch-7.17.29/logs
network.host: 0.0.0.0
http.port: 9200
transport.host: 172.26.231.202
discovery.seed_hosts:
- node001
- node002
- node003
cluster.initial_master_nodes:
- node001
- node002
- node003
bootstrap.memory_lock: false
transport.tcp.compress: true
xpack.security.enabled: true
xpack.security.transport.ssl.enabled: true
xpack.security.transport.ssl.verification_mode: certificate
xpack.security.transport.ssl.keystore.path: elastic-certificates.p12
xpack.security.transport.ssl.truststore.path: elastic-certificates.p12
3、node003 配置
node003 也只需要改节点名和 transport 地址:
cluster.name: es-cluster
node.name: node003
path.data: /opt/elasticsearch-7.17.29/data
path.logs: /opt/elasticsearch-7.17.29/logs
network.host: 0.0.0.0
http.port: 9200
transport.host: 172.26.231.203
discovery.seed_hosts:
- node001
- node002
- node003
cluster.initial_master_nodes:
- node001
- node002
- node003
bootstrap.memory_lock: false
transport.tcp.compress: true
xpack.security.enabled: true
xpack.security.transport.ssl.enabled: true
xpack.security.transport.ssl.verification_mode: certificate
xpack.security.transport.ssl.keystore.path: elastic-certificates.p12
xpack.security.transport.ssl.truststore.path: elastic-certificates.p12
0x05 使用 supervisor 启动 Elasticsearch
三台服务器都安装 supervisor:
apt update
apt install -y supervisor
systemctl enable --now supervisor
编写启动配置:
cat > /etc/supervisor/conf.d/elasticsearch.conf <<'EOF'
[program:elasticsearch]
directory=/opt/elasticsearch-7.17.29/
user=elasticsearch
command=/opt/elasticsearch-7.17.29/bin/elasticsearch
autostart=false
autorestart=false
startsecs=3
startretries=3
exitcodes=0
stopsignal=QUIT
stopwaitsecs=10
redirect_stderr=true
stdout_logfile=/opt/elasticsearch-7.17.29/logs/stdout.log
stdout_logfile_maxbytes=500MB
stdout_logfile_backups=10
EOF
加载 supervisor 配置:
supervisorctl reread
supervisorctl update
启动 Elasticsearch:
supervisorctl start elasticsearch
查看日志:
tail -f /opt/elasticsearch-7.17.29/logs/es-cluster.log
0x06 初始化内置用户密码
等三个节点都启动正常后,任选一台节点执行密码初始化。
cd /opt/elasticsearch-7.17.29
./bin/elasticsearch-setup-passwords interactive
也可以自动生成密码:
./bin/elasticsearch-setup-passwords auto
示例输出:
Please confirm that you would like to continue [y/N]y
...
Changed password for user elastic
PASSWORD elastic = xxxxxxxxxxxxxxxx
注意:
elasticsearch-setup-passwords主要用于首次初始化内置用户密码- 密码初始化后要保存好,不要写到公开文章、脚本或 Git 仓库里
- 不建议所有内置用户都设置成同一个密码
测试访问:
curl -u elastic:你的密码 "http://127.0.0.1:9200/_cluster/health?pretty"
正常会返回类似:
{
"cluster_name" : "es-cluster",
"status" : "green",
"number_of_nodes" : 3
}
0x07 Kibana 连接 Elasticsearch
Kibana 版本建议和 Elasticsearch 保持一致。
cd /opt
wget https://artifacts.elastic.co/downloads/kibana/kibana-7.17.29-linux-x86_64.tar.gz
tar -xf kibana-7.17.29-linux-x86_64.tar.gz
编辑 Kibana 配置:
server.port: 5601
server.host: "0.0.0.0"
server.name: "node003"
elasticsearch.hosts:
- "http://node001:9200"
- "http://node002:9200"
- "http://node003:9200"
elasticsearch.username: "kibana_system"
elasticsearch.password: "你的 kibana_system 密码"
elasticsearch.pingTimeout: 1500
elasticsearch.requestTimeout: 30000
i18n.locale: "zh-CN"
浏览器访问 Kibana 后,登录时可以使用 elastic 用户,也可以使用自己创建的普通用户。
0x08 Kibana 多节点会话问题
如果 Kibana 启多个节点,并且前面挂了负载均衡,可能会出现登录成功后又跳回登录页的问题。
原因是多个 Kibana 节点的加密密钥不一致,导致会话无法共享。
在任意一个 Kibana 节点生成密钥:
cd /opt/kibana-7.17.29
./bin/kibana-encryption-keys generate
把生成的三行配置写到每个 Kibana 节点的 kibana.yml 中,并保持完全一致:
xpack.encryptedSavedObjects.encryptionKey: "这里填生成的密钥"
xpack.reporting.encryptionKey: "这里填生成的密钥"
xpack.security.encryptionKey: "这里填生成的密钥"
重启所有 Kibana 节点后,登录后反复跳转的问题就会消失。
0x09 Logstash 输出到 Elasticsearch
Logstash 输出到 Elasticsearch 时配置账号密码即可。
input {
beats {
port => 5044
}
}
output {
elasticsearch {
hosts => ["http://node001:9200", "http://node002:9200", "http://node003:9200"]
user => "logstash_internal"
password => "你的 logstash_internal 密码"
index => "logstash-%{+YYYY.MM.dd}"
}
}
不建议直接使用 elastic 超级用户给 Logstash 写数据。生产环境建议单独创建 Logstash 写入用户,并给对应索引授权。
0x10 如果需要开启 9200 HTTPS
上面的配置只加密 9300 transport 节点通信,9200 HTTP 接口只是开启了用户名密码认证。
如果要让 9200 也使用 HTTPS,需要在 elasticsearch.yml 中增加:
xpack.security.http.ssl.enabled: true
xpack.security.http.ssl.keystore.path: elastic-certificates.p12
xpack.security.http.ssl.truststore.path: elastic-certificates.p12
开启后,访问命令要改成:
curl -k -u elastic:你的密码 "https://127.0.0.1:9200/_cluster/health?pretty"
Kibana 的 elasticsearch.hosts 也要改成 https://,并配置 CA 或关闭校验。生产环境建议配置 CA,不建议长期关闭证书校验。
0x11 删除认证信息
删除认证信息会影响 Kibana 中的用户、角色和权限配置,生产环境谨慎操作。
如果只是想临时关闭认证,可以先停 Elasticsearch:
supervisorctl stop elasticsearch
修改配置:
xpack.security.enabled: false
然后重新启动:
supervisorctl start elasticsearch
如果确实要删除安全索引,可以调用接口删除 .security-7:
curl -X DELETE -u elastic:你的密码 "http://127.0.0.1:9200/.security-7"
删除后如果重新开启:
xpack.security.enabled: true
需要重新初始化内置用户密码。
0x12 常见问题
1、为什么配置了证书还用 http 访问 9200?
因为本文配置的是:
xpack.security.transport.ssl.enabled: true
它只加密 Elasticsearch 节点之间的 9300 transport 通信。
9200 是否使用 HTTPS,由下面这个配置决定:
xpack.security.http.ssl.enabled: true
2、为什么 verification_mode 使用 certificate?
因为这里三台节点共用一个 p12 证书,使用 certificate 只校验证书是否由可信 CA 签发,不校验主机名。
如果要更严格,可以给每个节点签发包含 IP/DNS SAN 的独立证书,并把校验模式改为 full。
3、为什么不直接用 elastic 用户给 Kibana 和 Logstash?
elastic 是超级用户,权限太大。
Kibana 建议使用 kibana_system,Logstash 建议创建单独写入用户,根据索引授权。
参考链接
- Elasticsearch 7.17 Security settings:https://www.elastic.co/guide/en/elasticsearch/reference/7.17/security-settings.html
- elasticsearch-certutil:https://www.elastic.co/guide/en/elasticsearch/reference/7.17/certutil.html
- Built-in users:https://www.elastic.co/guide/en/elasticsearch/reference/7.17/built-in-users.html
linux 集群 部署 kibana elasticsearch es