如题,这两天接到一个新的业务需求,需要给自建集群的elasticsearch增加安全认证。如果你不了解elasticsearch的话,建议可以自行Google一下,或者看这里->elasticsearch
接到新需求后,先将需求拆分。现有的情况是自建集群中的elasticsearch不支持TLS加密通信,且现有的访问方式是可以匿名访问。那我们增加安全认证的话,主要就是要实现以下两个目标:
- 支持TLS加密通信,禁止http的方式访问集群
- 提供自定义内置用户的功能,支持自定义用户名与密码,禁止匿名访问
然后我就一顿 Google,发现网上关于elasticsearch的文章都是一个样,而且普遍是抄袭官方文档的,Google一下就发现,内容都是一样的,真的是无了大语。于是我就下苦功,狠啃官方文档,终于搞明白了如何通过eck- operator的方式来给es集群增加安全认证。
支持TLS加密通信
elasticsearch从6.8.0和7.1.0之后的版本,都是默认支持安全功能,如下所示:
- TLS 功能,可对通信进行加密
- 文件和原生 Realm,可用于创建和管理用户
- 基于角色的访问控制,可用于控制用户对集群 API 和索引的访问权限;通过针对 Kibana Spaces 的安全功能,还可允许在 Kibana 中实现多租户
如果你发现的你自建的es集群不支持,那很有可能是配置eck-operator的时候将其禁用掉了,这个很好解决,通过配置项即可解决。
xpack.security.enabled: true
xpack.security.transport.ssl.enabled: true
xpack.security.http.ssl.enabled: true
需要注意的是,xpack.security.enabled默认是true,如果设置为false,则关闭了安全功能,此时es集群则可以通过http直接访问,在生产模式中不推荐这么使用。
按照如上配置之后,重启es集群,你就会发现无法再通过http的方式访问了,但巧的是,你用https的方式也访问不了,咋回事呢,继续往下看。
关于xpack的更多可选配置项,可参考文档 -> anonymous-access-settings
自定义用户
书接上文,开启TLS加密通信之后,则无法通过http的方式访问,只能通过https+用户名密码的方式访问。
市面上能过查到的文章大多数是通过docker run的方式来配置生成自定义用户的,但是这种方法在实际的生产生产中是不太适用的,因为实际在集群中配置elasticsearch我们是通过eck-operator的方式来配置拉起的,而我们也旨在通过配置来创建我们的自定义用户,而非再多此一举通过docker run的方式来。
市面上常见的方式(十篇博客有十一篇是这种方式:
# create a folder with the 2 files
mkdir filerealm
touch filerealm/users filerealm/users_roles
# create user 'myuser' with role 'monitoring_user'
docker run \
-v $(pwd)/filerealm:/usr/share/elasticsearch/config \
docker.elastic.co/elasticsearch/elasticsearch:8.3.3 \
bin/elasticsearch-users useradd myuser -p mypassword -r monitoring_user
# create a Kubernetes secret with the file realm content
kubectl create secret generic my-file-realm-secret --from-file filerealm
这种方式的出处是哪里呢,当然是在官方文档中了
而我更推荐的方法是这一种(同样也在官方文档中有介绍:
新建一个文件:
vim secret-basic-auth.yaml
写入以下内容,可以自行配置username,password等字段:
apiVersion: v1
kind: Secret
metadata:
name: secret-basic-auth
type: kubernetes.io/basic-auth
stringData:
username: test # required field for kubernetes.io/basic-auth
password: test123 # required field for kubernetes.io/basic-auth
roles: superuser # optional, not part of kubernetes.io/basic-auth
创建secret:
kubectl apply -f secret-basic-auth.yaml
再新建一个文件
vim es-main.yaml
写入以下内容
apiVersion: elasticsearch.k8s.elastic.co/v1
kind: Elasticsearch
metadata:
name: es-main
spec:
version: 8.3.3
auth:
fileRealm:
- secretName: secret-basic-auth
nodeSets:
- name: default
count: 1
创建elasticsearch
kubectl apply -f es-main.yaml
在es-main创建成功之后,我们再次通过用户名密码+https的方式访问es集群
curl -u "test:test123" -k "https://localhost:9200"
{
apiVersion: elasticsearch.k8s.elastic.co/v1
"name" : "es-main-es-default-0",
"cluster_name" : "es-main",
"cluster_uuid" : "jnnz24HzR3uuTT3o6ReQDA",
"version" : {
"number" : "8.3.3",
"build_flavor" : "default",
"build_type" : "docker",
"build_hash" : "801fed82df74dbe537f89b71b098ccaff88d2c56",
"build_date" : "2022-07-23T19:30:09.227964828Z",
"build_snapshot" : false,
"lucene_version" : "9.2.0",
"minimum_wire_compatibility_version" : "7.17.0",
"minimum_index_compatibility_version" : "7.0.0"
},
"tagline" : "You Know, for Search"
}
我们可以看到此时可以成功访问的到我们的es集群。
当然了,以上只是一个简单的demo,在实际的生产环境中,还要考虑的es组件的配置要适配其他的组件,以及考虑到上下游的一个调用情况。