一、前言
Jumpserver是一个满足4A规范的开源堡垒机,支持RDP、SSH、Mysql等多种协议代管,默认使用Mysql存储命令记录,如果管理的机器多了,或者操作很频繁,Mysql存储的命令记录过于庞大,导致无法正常通过Jumpserver Web界面完成命令审计。
Jumpserver官方提供了ElasticSearch作为命令记录存储的可选方案,在完成配置后,命令记录的默认200天存储策略无法在ElasticSearch存储生效,需要对ElasticSearch单独配置Index Lifeycle Management(以下缩写ILM),实现过期数据自动删除。
步骤大致分为:
- Docker 安装 ElasticSearch;
- 配置 Jumpserver
系统设置
/终端设置
/命令记录
,增加 ElasticSearch,主机
填充http://elastic:[email protected]:9200
并开启按日期索引
、配置为默认
; - 修改
系统设置
/终端设置
/终端管理
,设置所有终端的命令存储
是新配置的 ElasticSearch; - 配置 ElasticSearch 的 Index Lifeycle。
二、Docker安装ElasticSearch
创建数据目录和日志目录,并增加组可写权限。
mkdir /opt/jumpserver/elasticsearch/data /opt/jumpserver/elasticsearch/logs
chmod g+w /opt/jumpserver/elasticsearch/*
下载镜像,jumpserver版本3.1.1时,只支持ElasticSearch 7.17版本,实测安装 ElasticSearch 8.7的版本,Jumpserver 命令记录配置 ElasticSearch 时一直提示“无效的 Elasticsearch 配置”。
docker pull docker.elastic.co/elasticsearch/elasticsearch:7.17.9
启动容器,注意配置了ELASTIC_PASSWORD参数。
docker run --name jms_es -d -p 9200:9200 -p 9300:9300 -e cluster.name=docker-cluster -e discovery.type=single-node -e network.host=0.0.0.0 -e bootstrap.memory_lock="true" -e xpack.security.enabled="true" -e TAKE_FILE_OWNERSHIP="true" -e ES_JAVA_OPTS="-Xms512m -Xmx512m" -e ELASTIC_PASSWORD=HCWyrFCqY2bsYInoLCWk -v /opt/jumpserver/elasticsearch/data:/usr/share/elasticsearch/data -v /opt/jumpserver/elasticsearch/logs:/usr/share/elasticsearch/logs --restart=always docker.elastic.co/elasticsearch/elasticsearch:7.17.9
三、参考官方网站完成jumpserver设置
参考官方的JumpServer 堡垒机对接 Elasticsearch 集群存储命令
查看 ElasticSearch 存储状态,health 显示 yellow 状态不用关注,因为集群模式的单节点默认就是这个情况。
[root@jumpserver ~]# curl -X GET 'elastic:HCWyrFCqY2bsYInoLCWk@localhost:9200/_cat/indices?v&pretty'
health status index uuid pri rep docs.count docs.deleted store.size pri.store.size
green open .geoip_databases X_VJElHrTZ-lllyJYzC2LA 1 0 42 0 39.9mb 39.9mb
yellow open jumpserver-2023-04-07 6XK9LcF5QnyOMmLiB_FfpQ 1 1 1410 0 653.4kb 653.4kb
yellow open jumpserver-2023-04-06 QOlwEtobQXatiZeIQxPSuw 1 1 0 0 226b 226b
四、配置ElasticSearch Index 生命周期
4.1. 创建默认Index管理生命周期策略
由于已经按照日期创建Index,这里为了简单,没有考虑Index生命周期的几个阶段,直接配置了最后delete的策略时200天后删除。
curl -X PUT http://elastic:HCWyrFCqY2bsYInoLCWk@localhost:9200/_ilm/policy/terminal_command_policy?pretty \
-H "Content-Type: application/json" \
-d '
{
"policy": {
"_meta": {
"description": "used for jumpserver terminal_command"
},
"phases": {
"delete": {
"min_age": "200d",
"actions": {
"delete": {}
}
}
}
}
}'
如果命令执行正常,会返回
{
"acknowledged" : true
}
4.2. 启动索引生命周期管理
curl -X POST "elastic:HCWyrFCqY2bsYInoLCWk@localhost:9200/_ilm/start?pretty"
启动后查看生命周期管理状态
[root@jumpserver ~]# curl -X GET "elastic:HCWyrFCqY2bsYInoLCWk@localhost:9200/_ilm/status?pretty"
{
"operation_mode" : "RUNNING"
}
4.3. 检查已存在索引的 ILM 状态
[root@jumpserver ~]# curl -X GET "elastic:HCWyrFCqY2bsYInoLCWk@localhost:9200/jumpserver-2023-04-06/_ilm/explain?pretty"
{
"indices" : {
"jumpserver-2023-04-06" : {
"index" : "jumpserver-2023-04-06",
"managed" : false
}
}
}
[root@jumpserver ~]# curl -X GET "elastic:HCWyrFCqY2bsYInoLCWk@localhost:9200/jumpserver-2023-04-07/_ilm/explain?pretty"
{
"indices" : {
"jumpserver-2023-04-07" : {
"index" : "jumpserver-2023-04-07",
"managed" : false
}
}
}
其中 managed 是 false,表示并未被 ILM 管理。对于已经存在的索引需要手动添加到 ILM,为了后续新创建的索引自动添加 ILM 策略,需要创建一个模版。
4.4. 给已存在的索引添加 ILM 策略
curl -X PUT "elastic:HCWyrFCqY2bsYInoLCWk@localhost:9200/jumpserver*/_settings?pretty" -H 'Content-Type: application/json' -d'
{
"index": {
"lifecycle": {
"name": "terminal_command_policy"
}
}
}
'
参数说明:
name:配置成前文设置的 ILM 策略名称。
检查添加的状态,可以看到 managed 已经为 true, 并且多了很多生命周期相关的信息。
[root@jumpserver ~]# curl -X GET "elastic:HCWyrFCqY2bsYInoLCWk@localhost:9200/jumpserver-2023-04-06/_ilm/explain?pretty"
{
"indices" : {
"jumpserver-2023-04-06" : {
"index" : "jumpserver-2023-04-06",
"managed" : true,
"policy" : "terminal_command_policy",
"lifecycle_date_millis" : 1680789297357,
"age" : "12.42h",
"phase" : "new",
"phase_time_millis" : 1680834017796,
"action" : "complete",
"action_time_millis" : 1680834017796,
"step" : "complete",
"step_time_millis" : 1680834017796,
"phase_execution" : {
"policy" : "terminal_command_policy",
"version" : 1,
"modified_date_in_millis" : 1680833076739
}
}
}
}
[root@jumpserver ~]# curl -X GET "elastic:HCWyrFCqY2bsYInoLCWk@localhost:9200/jumpserver-2023-04-07/_ilm/explain?pretty"
{
"indices" : {
"jumpserver-2023-04-07" : {
"index" : "jumpserver-2023-04-07",
"managed" : true,
"policy" : "terminal_command_policy",
"lifecycle_date_millis" : 1680828553776,
"age" : "1.52h",
"phase" : "new",
"phase_time_millis" : 1680834017796,
"action" : "complete",
"action_time_millis" : 1680834017796,
"step" : "complete",
"step_time_millis" : 1680834017796,
"phase_execution" : {
"policy" : "terminal_command_policy",
"version" : 1,
"modified_date_in_millis" : 1680833076739
}
}
}
}
4.5. 创建模版,应用至指定类型的 index,使其遵守 ILM 策略
curl -X PUT "elastic:HCWyrFCqY2bsYInoLCWk@localhost:9200/_index_template/terminal_command_template?pretty" -H 'Content-Type: application/json' -d'
{
"index_patterns": ["jumpserver-*"],
"template": {
"settings": {
"number_of_shards": 1,
"number_of_replicas": 1,
"index.lifecycle.name": "terminal_command_policy"
}
}
}
'
参数说明:
- index_patterns: 将这个模版应用至
jumpserver-
开头的 Index - index.lifecycle.name:指定这个模版使用的 ILM 策略,这里设定为之前创建的
terminal_command_policy
五、ElasticSearch ILM 各个阶段说明
5.1. 索引生命周期(Index Lifecyle)
ILM定义了五个索引生命周期阶段:
- Hot:热,索引正在积极地被更新和查询。
- Warm: 暖,索引不再被更新,但是仍然被查询。
- Cold: 冷,索引不再被更新,并且不经常被查询。这些信息仍然需要被搜索,但是如果这些查询比较慢也没关系。
- Frozen: 冻结,索引不再被更新,并且很少被查询。这些信息仍然需要被搜索,但是如果这些查询非常慢也没关系。
- Delete:删除, 该索引不再需要了,可以安全地被删除。
一个索引的生命周期策略指定了哪些阶段是适用的,在每个阶段执行什么动作,以及何时在各阶段之间转换。
当你创建一个索引时,你可以手动应用一个生命周期策略。对于时间序列索引,你需要将生命周期策略与用于在序列中创建新索引的索引模板联系起来。
5.2. 生命周期阶段的转换
ILM根据索引的年龄在生命周期中移动索引数据。为了控制这些转换的时间,需要每个阶段设置一个min_age
。当前阶段的所有操作完成,并且索引必须比下一个阶段的最小年龄大,索引即进入下一个阶段。配置的min_age
必须在后续阶段之间增加,例如,一个最小年龄为10天的Warm阶段之后,只能是一个min_age
未设定或>=10天的 Cold阶段。
min_age
默认为0,所以ILM在当前阶段的所有操作完成后,立即将索引转移到下一个阶段。
如果一个索引有未分配的分片,并且集群健康状态为黄色,该索引仍然可以根据其索引生命周期管理策略过渡到下一个阶段。然而,由于Elasticsearch只能在绿色集群上执行某些清理任务,所以集群健康状态为黄色可能会有意想不到的副作用。
为了避免磁盘使用量增加和可靠性问题,请及时解决任何集群健康问题。
ILM定期运行,检查一个索引是否符合策略标准,并执行任何需要的步骤。为了避免竞争条件,ILM可能需要运行一次以上来执行完成一个动作所需的所有步骤。例如,如果ILM确定一个索引符合rollover标准,它就开始执行完成rollover动作所需的步骤。如果它到达一个点,不能安全地推进到下一个步骤,则停止执行。下一次ILM运行时,ILM会从它停止的地方继续执行。这意味着即使indices.lifecycle.poll_interval被设置为10分钟,并且一个索引符合rollover标准,也可能在20分钟后rollover才能完成。
5.3. 生命周期各阶段允许的动作
ILM在各个阶段支持以下行动。ILM按照列出的顺序执行这些动作。
- Hot
- Set Priority
- Unfollow
- Rollover
- Read-Only
- Shrink
- Force Merge
- Searchable Snapshot
- Warm
- Set Priority
- Unfollow
- Read-Only
- Allocate
- Migrate
- Shrink
- Force Merge
- Cold
- Set Priority
- Unfollow
- Read-Only
- Searchable Snapshot
- Allocate
- Migrate
- Freeze
- Frozen
- Searchable Snapshot
- Delete
- Wait For Snapshot
- Delete
动作含义说明:
-
Allocate
将分片移动到具有不同性能特征的节点上,并减少复制的数量。
-
Delete
永久地删除索引。
-
Force merge
减少索引段的数量,清除被删除的文档。使得索引成为只读的。
-
Freeze
冻结索引以减少其内存占用。
-
Migrate
将索引碎片移动到与当前ILM阶段相对应的数据层。
-
Read only
阻止对索引的写操作。
-
Rollover
移除该索引作为Rollover别名的写索引,并开始向新的索引编制索引。
-
Searchable snapshot
在配置的存储库中获取管理索引的快照,并将其挂载为可搜索快照。
-
Set priority
当一个索引在生命周期中移动时,降低它的优先级,以确保热索引
-
Shrink
通过将索引缩减为一个新的索引来减少主碎片的数量。
-
Unfollow
将一个追随者索引转换成一个普通的索引。在翻转、收缩或可搜索快照操作之前自动执行。
-
Wait for snapshot
在删除索引之前确保快照的存在。
5.4. 根据生命周期各阶段的说明,更新 ILM 策略
curl -X PUT http://elastic:HCWyrFCqY2bsYInoLCWk@localhost:9200/_ilm/policy/terminal_command_policy?pretty -H "Content-Type: application/json" -d '
{
"policy": {
"_meta": {
"description": "used for jumpserver terminal_command"
},
"phases": {
"warm": {
"min_age": "1d",
"actions": {
"migrate" : {
},
"readonly" : {
},
"set_priority" : {
"priority": 50
},
"allocate": {
"number_of_replicas": 1
}
}
},
"cold": {
"min_age": "90d",
"actions": {
"set_priority" : {
"priority": 30
}
}
},
"delete": {
"min_age": "200d",
"actions": {
"delete": {}
}
}
}
}
}'