Elkeid - Bytedance Cloud Workload Protection Platform

Elkeid 是一款可以满足 主机,容器与容器集群,Serverless 等多种工作负载安全需求的开源解决方案,源于字节跳动内部最佳实践。

随着企业的业务发展,多云、云原生、多种工作负载共存的情况愈发凸显,我们希望可以有一套方案可以满足不同工作负载下的安全需求,因此 Elkeid 诞生了。

Introduction

Elkeid 具备以下主要能力:

  • Elkeid 不仅具备传统的 HIDS(Host Intrusion Detection System) 的对于主机层入侵检测和恶意文件识别的能力,且对容器内的恶意行为也可以很好的识别,部署在宿主机即可以满足宿主机与其上容器内的反入侵安全需求,并且 Elkeid 底层强大的内核态数据采集能力可以满足大部分安全运营人员对于主机层数据的渴望。

  • 对于运行的业务 Elkeid 具备 RASP 能力可以注入到业务进程内进行反入侵保护,不仅运维人员不需要再安装一个 Agent,业务也无需重启。

  • 对于 K8s 本身 Elkeid 支持接入K8s Audit LogK8s 系统进行入侵检测和风险识别。

  • Elkeid 的规则引擎 Elkeid HUB 也可以很好的和外部多系统进行联动对接。

Ekeid 将这些能力都很好的融合在一个平台内,满足不同工作负载的复杂安全需求的同时,还能实现多组件能力关联,更难得的是每个组件均经过字节跳动海量数据和多年的实战检验。

Elkeid Community Edition Description

需要注意的是 Elkeid 开源版本 和完整版本存在差异,目前已开源的能力主要包括:

  • 全部端上能力,即端上数据/资产/部分采集能力,内核态数据采集能力,RASP 探针部分等,并与字节跳动内部版本一致;
  • 全部接入层能力,即 Agent Center,服务发现等,并与字节跳动内部版本一致;
  • 提供社区版规则引擎即 Elkeid HUB,并配套少量策略作为示例使用;
  • 提供社区版 Elkeid Console 与部分配套能力。

因此需要具备完整的反入侵与风险感知能力,还需要自行基于 Elkeid HUB 进行策略构建和对 Elkeid 采集的数据进行二次加工等工作。

Elkeid Architecture

Elkeid Host Ability

  • Elkeid Agent 用户态 Agent,负责管理各个端上能力组件并与 Elkeid Agent Center 通信
  • Elkeid Driver 负责 Linux Kernel 层采集数据,兼容容器,并能够检测常见 Rootkit
  • Elkeid RASP 支持 CPython、Golang、JVM、NodeJS、PHP 的运行时数据采集探针,支持动态注入到运行时
  • Elkeid Agent Plugin List
    • Driver Plugin: 负责与 Elkeid Driver 通信,处理其传递的数据等
    • Collector Plugin: 负责端上的资产/关键信息采集工作,如用户,定时任务,包信息等
    • Journal Watcher: 负责监测systemd日志的插件,目前支持ssh相关日志采集与上报
    • Scanner Plugin: 负责在端上进行静态检测恶意文件的插件,支持 Yara
    • RASP Plugin: 分析系统进程运行时,上报运行时信息,处理下发的 Attach 指令,收集各个探针上报的数据
    • Baseline Plugin: 负责在端上进行基线风险识别的插件
  • Elkeid 数据说明
  • Elkeid 数据接入

Elkeid Backend Ability

  • Elkeid AgentCenter 负责与 Agent 进行通信并管理 Agent 如升级,配置修改,任务下发等
  • Elkeid ServiceDiscovery 后台中的各组件都会向该组件定时注册、同步服务信息,从而保证各组件相互可见,便于直接通信
  • Elkeid Manager 负责对整个后台进行管理,并提供相关的查询、管理接口
  • Elkeid Console Elkeid 前端部分
  • Elkeid HUB 策略引擎

Elkeid Function List

功能Elkeid Community EditionElkeid Enterprise Edition
Linux 数据采集能力:white_check_mark::white_check_mark:
RASP 探针能力:white_check_mark::white_check_mark:
K8s Audit Log 采集能力:white_check_mark::white_check_mark:
Agent 控制面:white_check_mark::white_check_mark:
主机状态与详情:white_check_mark::white_check_mark:
勒索诱饵:ng_man::white_check_mark:
资产采集:white_check_mark::white_check_mark:
高级资产采集:ng_man::white_check_mark:
容器集群资产采集:white_check_mark::white_check_mark:
暴露面与脆弱性分析:ng_man::white_check_mark:
主机/容器 基础入侵检测少量样例:white_check_mark:
主机/容器 行为序列入侵检测:ng_man::white_check_mark:
RASP 基础入侵检测少量样例:white_check_mark:
RASP 行为序列入侵检测:ng_man::white_check_mark:
K8S 基础入侵检测少量样例:white_check_mark:
K8S 行为序列入侵检测:ng_man::white_check_mark:
K8S 威胁分析:ng_man::white_check_mark:
告警溯源(行为溯源):ng_man::white_check_mark:
告警溯源(驻留溯源):ng_man::white_check_mark:
告警白名单:white_check_mark::white_check_mark:
多告警聚合能力:ng_man::white_check_mark:
威胁处置(进程):ng_man::white_check_mark:
威胁处置(网络):ng_man::white_check_mark:
威胁处置(文件):ng_man::white_check_mark:
文件隔离箱:ng_man::white_check_mark:
漏洞检测少量情报:white_check_mark:
漏洞情报热更新:ng_man::white_check_mark:
基线检查少量基线:white_check_mark:
RASP 热补丁:ng_man::white_check_mark:
病毒扫描:white_check_mark::white_check_mark:
用户行为日志分析:ng_man::white_check_mark:
插件管理:white_check_mark::white_check_mark:
系统监控:white_check_mark::white_check_mark:
系统管理:white_check_mark::white_check_mark:
Windows 支持:ng_man::white_check_mark:
蜜罐:ng_man::oncoming_automobile:
主动防御:ng_man::oncoming_automobile:
云查杀:ng_man::oncoming_automobile:
防篡改:ng_man::oncoming_automobile:

Front-end Display (Community Edition)

安全概览

容器集群安全告警

容器集群工作负载信息


主机概览

资产指纹

安全告警

漏洞信息

基线检查

病毒扫描

后端监控

后端服务监控

Console User Guide

Quick Start

Contact us && Cooperation

Lark Group

About Elkeid Enterprise Edition

Elkeid 企业版本支持单独策略售卖,也支持完全完整能力售卖。

如果对Elkeid企业版感兴趣请联系: elkeid@bytedance.com

Elkeid Docs

For more details and latest updates, see Elkeid docs.

License

  • Elkeid Driver: GPLv2
  • Elkeid RASP: Apache-2.0
  • Elkeid Agent: Apache-2.0
  • Elkeid Server: Apache-2.0
  • Elkeid Console: Elkeid License
  • Elkeid HUB: Elkeid License

同时,Elkeid 也是 404Team 星链计划2.0中的一环,如果对星链计划感兴趣的小伙伴可以点击下方链接了解。 https://github.com/knownsec/404StarLink2.0-Galaxy

ElkeidUP

Elkeid 自动化部署工具

Component List

资源配置手册

Instructions

  • 部署所用的后端服务器需要仅供Elkeid使用
  • 部署所用的后端服务器需要保证内网互通,也仅支持内网部署
  • 部署所用的后端服务器部署时需要有 root 用户权限
  • 部署所用的后端服务器只能使用:Centos7 及以上;Ubuntu16 及以上;Debian9 及以上
  • 执行elkeidup的服务器需要能以root用户免密码ssh到所有的后端服务器上
  • 部署过程不可以手动打断
  • 仅可以使用局域网IP,不要使用 127.0.0.1 或者 hostname 或者公网IP
  • 安装后不要删除 ~/.elkeidup 目录
  • 不要修改任何组件的密码,包括Elkeid Console(Manager)初始默认用户

自动下载缺失预编译ko服务开启提示

服务背景: Elkeid Driver是在内核态工作的,由于内核要求加载的内核模块与内核版本强绑定,我们又无法占用客户机的资源在安装agent时在客户机上编译ko。因此,我们在release包中提供了预编译的ko,避免每次都需要手动编译ko,目前共计包含3435个预编译ko。但依旧存在两个问题无法解决,一是无法实时更新,上游发行版更新内核后,我们无法也没有人力同步更新预编译的ko到release中,二是覆盖范围有限,可能会遇见我们未曾使用过的发行版所使用的内核。为此,我们提供了自动下载缺失预编译ko的功能,此功能主要是通知到我们相关同学,该ko有客户在试用,尽快从上游更新或覆盖该发行版。 若您选择同意开启此服务,我们需要同时收集一些基础运行信息,以便我们根据不同需求的用户定制优先级排期,并给出合理的资源占用评估。填写的email信息仅用于区分来源身份,真实email或昵称均可。具体信息如下:

  1. 缺失预编译ko的内核版本,服务器架构(仅为arm64或amd64二选一,不涉及任何其他cpu机器信息)。
  2. agent center上agent的连接数,每30min收集一次。
  3. agent center上agent的qps,包含send和receive,每30min收集一次,取30min的平均值。
  4. hub input qps,每30min收集一次,取30min的平均值。
  5. redis qps,每30min收集一次,取30min的平均值。
  6. redis 内存占用,每30min收集一次,实时数值。
  7. kafka 生产和消费的qps,每30min收集一次,取30min的平均值。
  8. mongodb qps,每30min收集一次,取30min的平均值。

若您不同意开启此服务,您依旧可以使用release包中提供的预编译ko,其他功能不受影响。具体操作为在release界面下载ko_1.7.0.9.tar.xz,然后替换package/to_upload/agent/component/driver/ko.tar.xz,deploy期间会将ko解压到/elkeid/nginx/ElkeidAgent/agent/component/driver/ko目录中。相关收集信息和下载ko的代码均在已开源的manager代码中,是否开启相关功能取决于manager运行时conf目录下的elkeidup_config.yaml文件。若您在部署期间开启了此服务,但是需要在之后的流程中关闭,您可以将elkeidup_config.yaml文件中的report.enable_report设置为false,之后重启manager即可。

附:相关功能位于manager代码中的以下位置:

  • 开关位于internal/monitor/report.go的InitReport()函数中,清空此函数内容,即可关闭功能入口。
  • 收集信息项位于internal/monitor/report.go的heartbeatDefaultQuery结构中。
  • 自动下载ko功能位于biz/handler/v6/ko.go的SendAgentDriverKoMissedMsg函数中。

Elkeid 完整部署(推荐)

Elkeid 完整部署

Elkeid HUB 单独部署

Elkeid HUB 单独部署

Elkeid 升级和扩容

Raw Data Usage Tutorial

Elkeid 完整部署

1、单机docker快速部署 (单机测试环境推荐)

注:宿主机请优先使用centos 7.x 或 debian 9/10,容器内的服务依赖了systemd,而systemd使用了cgroup,容器内外systemd版本相差过大会导致容器内的systemd运行异常,无法启动相应服务。

1.1、导入镜像

# 从release下载的是分卷的镜像,需要先合并镜像
wget https://github.com/bytedance/Elkeid/releases/download/v1.9.1.4/elkeidup_image_v1.9.1.tar.gz.00
wget https://github.com/bytedance/Elkeid/releases/download/v1.9.1.4/elkeidup_image_v1.9.1.tar.gz.01
wget https://github.com/bytedance/Elkeid/releases/download/v1.9.1.4/elkeidup_image_v1.9.1.tar.gz.02
wget https://github.com/bytedance/Elkeid/releases/download/v1.9.1.4/elkeidup_image_v1.9.1.tar.gz.03
cat elkeidup_image_v1.9.1.tar.gz.* > elkeidup_image_v1.9.1.tar.gz

#导入镜像
docker load -i elkeidup_image_v1.9.1.tar.gz

1.2、运行容器

docker run -d --name elkeid_community \
  --restart=unless-stopped \
  -v /sys/fs/cgroup:/sys/fs/cgroup:ro \
  -p 8071:8071 -p 8072:8072 -p 8080:8080 \
  -p 8081:8081 -p 8082:8082 -p 8089:8080  -p 8090:8090\
  --privileged \
  elkeid/all-in-one:v1.9.1

1.3、设置对外IP

使用本机IP,不能使用127.0.0.1。

docker exec -it elkeid_community bash

cd /root/.elkeidup/

# 命令为交互式
./elkeidup public {ip}


./elkeidup agent init
./elkeidup agent build
./elkeidup agent policy create

cat ~/.elkeidup/elkeid_passwd

部署过程中遇到Elkeid社区版信息收集声明,请参考自动下载缺失预编译ko服务开启提示Agent Install Remark

1.4、访问前端console并安装Agent

顺利安装完成后,/root/.elkeidup/elkeid_passwd文件记录了各组件的密码和相关的url。

初始密码在构建镜像的时候已经固定了的,为了安全性请不要用于生产环境

字段说明
elkeid_consoleconsole账号密码
elkeid_hub_frontendhub前端账号密码
grafanagrafana账号密码
grafanagrafana 地址
elkeid_hub_frontendelkeid hub前端地址
elkeid_consoleelkeid console地址
elkeid_service_discovery服务发现地址

访问elkeid_console,按照Console使用手册-安装配置 界面的命令进行Agent安装部署。

2、使用elkeidup进行完整部署

2.1、配置目标机器root用户ssh免密登录

如果部署机器为本机,依旧需要配置本机免密登录,登录耗时需要小于1s。 可用以下命令进行验证,两次date命令的输出结果需要相同。

date && ssh root@{ip} date
# 输出时间差小于1s

2.2、解压release产物并配置目录

  • 下载release产物(分卷压缩包),并合并压缩包
wget https://github.com/bytedance/Elkeid/releases/download/v1.9.1.4/elkeidup_package_v1.9.1.tar.gz.00
wget https://github.com/bytedance/Elkeid/releases/download/v1.9.1.4/elkeidup_package_v1.9.1.tar.gz.01
wget https://github.com/bytedance/Elkeid/releases/download/v1.9.1.4/elkeidup_package_v1.9.1.tar.gz.02
cat elkeidup_package_v1.9.1.tar.gz.* > elkeidup_package_v1.9.1.tar.gz

也可以参考从源码构建 Elkeid,自行编译和构建package包。

如果之前安装过,请删除/root/.elkeidup/elkeid文件夹,避免造成干扰

  • 解压release产物并配置目录
mkdir -p /root/.elkeidup && cd /root/.elkeidup
mv {DownloadDir}/elkeidup_package_v1.9.1.tar.gz elkeidup_package_v1.9.1.tar.gz
tar -xf elkeidup_package_v1.9.1.tar.gz
chmod a+x /root/.elkeidup/elkeidup

2.3、生成并修改config.yaml

ip为本机非127.0.0.1 ip,若不为单机部署,请参考资源手册修改config.yaml

cd /root/.elkeidup
./elkeidup init --host {ip}
mv config_example.yaml config.yaml

2.4、部署

cd /root/.elkeidup

# 命令为交互式
./elkeidup deploy

部署过程中遇到Elkeid社区版信息收集声明,请参考自动下载缺失预编译ko服务开启提示Agent Install Remark

2.5、构建Agent

cd /root/.elkeidup

./elkeidup agent init
./elkeidup agent build
./elkeidup agent policy create

2.6、访问前端console并安装Agent

顺利安装完成后,执行cat /root/.elkeidup/elkeid_passwd将看到各组件的随机生成的密码和相关的url。

字段说明
elkeid_consoleconsole账号密码
elkeid_hub_frontendhub前端账号密码
grafanagrafana账号密码
grafanagrafana 地址
elkeid_hub_frontendelkeid hub前端地址
elkeid_consoleelkeid console地址
elkeid_service_discovery服务发现地址

访问elkeid_console,按照Console使用手册-安装配置 界面的命令进行Agent安装部署。

3、Agent Install Remark

  • Driver模块依赖预编译ko,具体支持列表参考:ko_list
  • 正常情况下,在Agent安装完成后,需要10min左右Driver模块才能正常工作(涉及到KO自动下载和安装)。
  • Driver是否存在的方式:lsmod | grep hids_driver
    • 如果测试机器kernel版本不在支持列表中,请自行编译ko文件和生成sign文件(sha256),并将其导入Nginx中。
    • 如果在执行elkeidup deploy中未同意声明,也需要自行编译ko或下载Release中对应的预编译ko(支持列表)和sign文件,并将其导入Nginx中。

3.1、ko导入Nginx方法

ko/sign文件的格式应该遵循:hids_driver_1.7.0.10_{uname -r}_{arch}.ko/sign格式, 文件需要放置在nginx对应服务器的:/elkeid/nginx/ElkeidAgent/agent/component/driver/ko下,并修改权限chown -R nginx:nginx /elkeid/nginx。放置完成后,重启Agent即可。

4、HTTPS配置

请参考Elkeid https配置文档

5、重装指定组件

如果部分组件有更新,或者重新编译了部分组件,可以使用elkeidup reinstall命令重新安装指定组件。 例如 release:v1.9.1.1 中更新了Hub社区版,可以使用以下命令进行重新安装。

# {v1.9.1.1} 为 v1.9.1.1 解压后的package目录
# reinstall hub
cp {v1.9.1.1}/package/hub/hub.tar.gz /root/.elkeidup/package/hub/hub.tar.gz
cp {v1.9.1.1}/package/hub_leader/hub_leader.tar.gz /root/.elkeidup/package/hub_leader/hub_leader.tar.gz

/root/.elkeidup/elkeidup reinstall --component Hub
/root/.elkeidup/elkeidup reinstall --component HubLeader

Elkeid HUB 单独部署

如果需要单独部署HUB,可以使用elkeidup中的--hub_only参数,具体步骤如下:

1、配置目标机器root用户ssh免密登录

如果部署机器为本机,依旧需要配置本机免密登录,登录耗时需要小于1s。 可用以下命令进行验证,两次date命令的输出结果需要相同。

date && ssh root@{ip} date
# 输出时间差小于1s

2、下载release产物并配置目录

mkdir -p /root/.elkeidup && cd /root/.elkeidup
wget https://github.com/bytedance/Elkeid/releases/download/v1.9.4/elkeidup_hub_v1.9.1.tar.gz -O elkeidup.tar.gz && tar -xf elkeidup.tar.gz
chmod a+x /root/.elkeidup/elkeidup

3、生成并修改config.yaml

ip为本机非 127.0.0.1 ip,若不为单机部署,请参考部署资源手册修改config.yaml

cd /root/.elkeidup
## 生成hub only 配置
./elkeidup init --host {ip} --hub_only
mv config_example.yaml config.yaml

4、部署

cd /root/.elkeidup

# 命令为交互式
./elkeidup deploy --hub_only

## status
./elkeidup status --hub_only

## undeploy
./elkeidup undeploy --hub_only

5、访问HUB前端

顺利安装完成后,执行cat /root/.elkeidup/elkeid_passwd将看到各组件的随机生成的密码和相关的url。

字段说明
elkeid_hub_frontendhub前端账号密码
grafanagrafana账号密码
grafanagrafana 地址
elkeid_hub_frontendelkeid hub前端地址
elkeid_service_discovery服务发现地址

访问 elkeid_hub_frontend,参照 Elkeid HUB 社区版快速上手教程 使用。

6、HTTPS配置

请参考Elkeid https配置文档

Elkeid CWPP v1.9.1 社区版 资源配置手册

版本

社区版v1.9.1

架构介绍

注:目前受社区版限制,Hub部分仅支持单机部署

arch

组件详情

组件名称测试环境下最小部署方式生产环境建议部署方式组件使用端口说明
Redis单台三台,哨兵模式(仅支持3台,更大规模集群需要自行部署后替换)6379 26379缓存数据库
Mongodb单台三台,副本集模式(仅支持3台,更大规模集群需要自行部署后替换)27017 9982数据库
Kafka单台按Agent量进行计算(自动化部署情况下仅支持3台,多台需要自行部署后替换)2181 9092 12888 13888消息通道
Nginx单台单台或多台均可,下载功能建议使用内部CDN,若需要外部接入,建议使用自建LB8080 8081 8082 8071 8072 8089 8090文件服务器及反向代理
Service Discovery单台两至三台8088服务发现
HUB单台社区版仅支持单台(生产环境是否使用社区版,请进行额外评估)8091 8092规则引擎
HUB Leader单台社区版仅支持单台(生产环境是否使用社区版,请进行额外评估)12310 12311规则引擎集群控制层
HIDS Manager单台两至三台6701HIDS控制层
Agent Center单台按Agent量进行计算6751 6752 6753HIDS接入层
Prometheus单台单台或两台均可9090 9993 9994 9981 9983 9984监控用数据库
Prometheus Alermanager与Prometheus共用服务器-
Grafana单台单台8083监控面板
Kibana单台单台5601ES面板
NodeExporter不需指定单独的服务器,所有机器都需要部署该监控服务-9990监控探针
ProcessExporter不需指定单独的服务器,所有机器都需要部署该监控服务-9991监控探针

配置文件说明

  1. ssh_host 为通用配置,表示该组件在哪些机器上进行部署,若为数组类型,说明该组件支持集群部署,否则只支持单机部署,具体限制见配置文件注释。
  2. quota为通用配置,最终会转变为cgroup限制。
  3. 单机测试环境下,所有机器都填同一地址即可。
# redis 单台或3台,3台时为哨兵模式
redis:
  install: true
  quota: 1C2G
  ssh_host:
    - redis-1
    - redis-2
    - redis-3

# MongoDB 单台或3台,3台时为副本集模式
mongodb:
  install: true
  quota: 2C4G
  ssh_host:
    - monogo-1
    - monogo-2
    - monogo-3

# MongoDB 单台或3台,3台时为进群模式
kafka:
  install: true
  topic: hids_svr
  partition_num: 12 # 默认单topic分区数
  quota: 2C4G
  ssh_host:
    - kafka-1
    - kafka-2
    - kafka-3

# leader 社区版目前仅支持单机模式
leader:
  install: true
  quota: 1C2G
  ssh_host: leader-1

# nginx 单台多台即可,但其他组件默认只会使用第一台
nginx:
  install: true
  quota: 1C2G
  ssh_host:
    - nginx-1
    - nginx-2
  domain: # 指向nginx机器的域名,仅支持单个
  public_addr: # nginx机器的公网IP,仅支持单个

# sd 单台多台即可
service_discovery:
  install: true
  quota: 1C2G
  ssh_host:
    - sd-1
    - sd-2

# hub 社区版目前仅支持单机模式
hub:
  install: true
  quota: 2C4G
  ssh_host: hub-1

# manager 单台多台即可
manager:
  install: true
  quota: 2C4G
  ssh_host:
    - manager-1

# ac 单台多台即可
agent_center:
  install: true
  grpc_conn_limit: 1500 # 单个AC的最大连接数限制
  quota: 1C2G
  ssh_host:
    - ac-1

# prometheus 单台多台即可,默认只会请求第一台,第二台处于双写状态,不会被查询
prometheus:
  quota: 1C2G
  ssh_host:
    - prometheus-1

# grafana 仅支持一台
grafana:
  quota: 1C2G
  ssh_host: grafana-1

从源码构建 Elkeid CWPP

当前社区版本中,部分组件尚未开源,主要是Elkeidup和Hub的相关组件目前仅能提供社区版二进制,所以无法提供从零到一提供完全从源码构建的构建手册。您可以通过在安装前替换package中的指定文件,或安装后替换可执行程序的方式,达到运行从源码构建的可执行程序的效果。具体文件位置和对应关系说明如下。

安装前替换

Agent

Agent部分在elkeidup deploy过程中会从源码build,所以替换package中的以下文件即可,建议解压该文件,确认该文件与目录结构与替换前的文件相同。

package/agent/v1.9.1/agent/elkeid-agent-src_1.7.0.24.tar.gz

Driver Plugin

Driver plugin同样会在elkeidup deploy过程中会从源码build,所以同样替换package中的以下文件即可,建议解压该文件,确认该文件与目录结构与替换前的文件相同。

package/agent/v1.9.1/driver/driver-src_1.0.0.15.tar.gz

其他agent plugin

其他agent plugin都是预编译好的,按照各plugin的文档,编译好后替换对应的文件即可。注意plugin存在plg格式和tar.gz格式,plg格式为可执行文件,tar.gz为压缩包。版本号目前写死在elkeidup中,需要保持一致,请勿更改。

package/agent/v1.9.1/driver/driver-src_1.0.0.15.tar.gz
package/agent/v1.9.1/baseline/baseline-default-aarch64-1.0.1.23.tar.gz
package/agent/v1.9.1/baseline/baseline-default-x86_64-1.0.1.23.tar.gz
package/agent/v1.9.1/collector/collector-default-aarch64-1.0.0.140.plg
package/agent/v1.9.1/collector/collector-default-x86_64-1.0.0.140.plg
package/agent/v1.9.1/etrace/etrace-default-x86_64-1.0.0.92.tar.gz
package/agent/v1.9.1/journal_watcher/journal_watcher-default-aarch64-1.0.0.23.plg
package/agent/v1.9.1/journal_watcher/journal_watcher-default-x86_64-1.0.0.23.plg
package/agent/v1.9.1/rasp/rasp-default-x86_64-1.9.1.44.tar.gz
package/agent/v1.9.1/scanner/scanner-default-aarch64-3.1.9.6.tar.gz
package/agent/v1.9.1/scanner/scanner-default-x86_64-3.1.9.6.tar.gz

ko

默认deploy时不会降预编译的ko拷贝到nginx中,在release界面同时会提供预编译的ko,下载预编译的ko或自行编译ko后,替换以下文件即可,文件为tar.xz格式,解压后有一个ko文件夹,格式必须相同。

package/to_upload/agent/component/driver/ko.tar.xz

Manager & ServiceDiscovery & AgentCenter

编译好对应的二进制,解压以下路径的tar.gz,然后替换好二进制后打包回tar.gz即可。

# manager
package/manager/bin.tar.gz
# service discovery
package/service_discovery/bin.tar.gz
# agent center
package/agent_center/bin.tar.gz

安装后替换

Agent 相关

Agent部分均可以通过前端上传,具体见agent发布文档

ko

拷贝对应ko和sing文件到以下目录即可,之后执行命令修改目录权限

# ko 目录
/elkeid/nginx/ElkeidAgent/agent/component/driver/ko

# 修改权限
chown -R nginx:nginx /elkeid/nginx

Manager & ServiceDiscovery & AgentCenter

暂停服务,替换对应的二进制文件,然后重启服务

# manager
systemctl stop elkeid_manager
mv new_manager_bin /elkeid/manager/manager
systemctl start elkeid_manager

# service discovery
systemctl stop elkeid_sd
mv new_sd_bin /elkeid/service_discovery/sd
systemctl start elkeid_sd

# agent center
systemctl stop elkeid_ac
mv new_ac_bin /elkeid/agent_center/agent_center
systemctl start elkeid_ac

Elkeidup 社区版升级指南 1.7.1 --> 1.9.1

前言

首先需要配置elkeidup 1.7.1 与 1.9.1 版本共存,然后按情况进行切换。

详细操作请同时参照1.7.1 与 1.9.1 的文档。

# rename .elkeidup dir
cd /root
mv .elkeidup .elkeidup_v1.7.1
ln -s .elkeidup_v1.7.1 .elkeidup

# copy cert to v1.9.1
mkdir -p /root/.elkeidup_v1.9.1
cp -r /root/.elkeidup_v1.7.1/elkeid_password /root/.elkeidup_v1.9.1
cp -r /root/.elkeidup_v1.7.1/cert /root/.elkeidup_v1.9.1
# download v1.9.1 package to /root/.elkeidup_v1.9.1

切换到 1.7.1

rm /root/.elkeidup && ln -s /root/.elkeidup_v1.7.1 /root/.elkeidup

切换到 1.9.1

rm /root/.elkeidup && ln -s /root/.elkeidup_v1.9.1 /root/.elkeidup

后端

v1.9.1后端目前无法与v1.7.1兼容,需要卸载v1.7.1后端后重新安装v1.9.1。

备份数据

根据需要选择备份数据:

  1. 备份 MongoDB:目录位于 /elkeid/mongodb 仅是备份DB,备份的数据无法直接使用,如果有恢复需求,目前尚无自动化脚本,需要手动转换。
  2. 备份Hub策略:目录位于 /elkeid/hub 策略可以在Hub web界面中进行导入。

卸载v1.7.1

在卸载v1.7.1后端后,Agent将在1min后自动关闭所有插件,并进入守护状态,直到新的后端被安装

# 按照前言操作切换到 v1.7.1

cd /root/.elkeidup 
./elkeidup undeploy

安装v1.9.1

在安装v1.9.1后端后,Agent将在1min内重连,但此时还尚未加载任何插件,您可以在Console上看到这个状态

# 按照前言操作切换到 v1.9.1
# 安装文档详见v1.9.1 安装文档
cd /root/.elkeidup 
./elkeidup deploy

Agent

确认配置及状态

  • /root/.elkeidup_v1.7.1/cert /root/.elkeidup_v1.9.1/cert 两个目录内的所有文件内容均保持一致

  • /root/.elkeidup_v1.7.1/elkeid_server.yaml /root/.elkeidup_v1.9.1/elkeidup_config.yaml 两个文件中,下述相关配置均保持一致。

    •   注:具体字段filed值以v1.9.1为准,请勿直接覆盖。

    • nginx

      • domain
      • ssh_host
      • public_addr
    • mg

      • ssh_host
  • 确认后端更新完成后,所有v1.7.1的Agent均已成功上线

Build v1.9.1组件

./elkeidup agent init
./elkeidup agent build
./elkeidup agent policy create

下发任务

可根据需要进行灰度升级,此时新上线/重连的客户端会自动拉取最新配置升级,其他客户端需要手动同步配置升级

  1. Elkeid Console - 任务管理 界面,点击“新建任务”,选择单台主机,点击下一步,选择“同步配置”任务类型,点击确认。随后,在此页面找到刚刚创建的任务,点击运行,观察升级后的主机是否符合预期。
  2. Elkeid Console - 任务管理 界面,点击“新建任务”,选择全部主机,点击下一步,选择“同步配置”任务类型,点击确认。随后,在此页面找到刚刚创建的任务,点击运行,即可对存量旧版本Agent进行升级。

Elkeid 社区版 扩容指南

ServiceDiscovery

自身扩容(依赖elkeidup)

  1. 修改config.yaml 在sd中添加其他的host,登录条件与安装时相同。
  2. 执行以下命令 elkeidup reinstall --component ServiceDiscovery --re-init

自身扩容(手动操作)

  1. 拷贝已安装好SD机器的 /elkeid/service_discovery 到待扩容机器上。
  2. 更新全部SD的配置文件 /elkeid/service_discovery/conf/conf.yaml 的 Cluster.Members项,该项为所有sd实例的数组,每台sd都要填写全部实例的地址。
  3. 执行新SD实例的 /elkeid/service_discovery/install.sh ,会自动启动sd。
  4. 重启所有旧的sd实例 systemctl restart elkeid_sd

同步修改上下游配置

sd目前同时被AgentCenter,Manager和Nginx所依赖,扩容SD后,需要同步重启。

  • AgentCenter: 配置文件位于/elkeid/agent_center/conf/svr.yml 的 sd.addrs,重启命令 systemctl restart elkeid_ac
  • Manager: 配置文件位于/elkeid/manager/conf/svr.yml 的 sd.addrs,重启命令 systemctl restart elkeid_manager
  • Nginx: 配置文件位于/elkeid/nginx/nginx/nginx.conf 的 upstream sd_list,重启命令 systemctl restart elkeid_nginx

AgentCenter

自身扩容(依赖elkeidup)

  1. 修改config.yaml 在ac中添加其他的host,登录条件与安装时相同。
  2. 执行以下命令 elkeidup reinstall --component AgentCenter --re-init

自身扩容(手动操作)

  1. 拷贝已安装好AC机器的 /elkeid/agent_center 到待扩容机器上。
  2. 执行新AC实例的 /elkeid/agent_center/install.sh ,会自动安装和启动AC。

同步修改上下游配置

若agent通过服务发现的方式连接到AC,则不需要手动同步上下游配置。

若agent通过编码的AC地址连接AC,需要重新编译agent,将新的AC地址加入到agent连接配置中。

Elkeid https configuration documentation

1. Overview

  • By default, the Elkeid Console listens on ports 8082 and 8072, and the Elkeid HUB listens on ports 8081 and 8071.
  • If HTTPS is required, ports 8072 and 8071 can be used for access.
Elkeid ConsoleElkeid HUB Console
HTTPhttp://{{NignxIP}}:8082http://{{NignxIP}}:8081
HTTPShttps://{{NignxIP}}:8072https://{{NignxIP}}:8072

2. Use an internal enterprise certificate

The self-signed certificate generated during installation is located in the '/elkeid/nginx/nginx' directory on the machine where nginx is located, and includes the following two files:

server.key
server.crt

After replacing the above two files, do the following:

chown -R nginx: nginx /elkeid/nginx
systemctl restart elkeid_nginx

3. Use the self-signed certificate generated at deployment time

When Elkeid is deployed, it can only use a self-signed certificate. Due to the security settings of chrome, it cannot be accessed directly. All you need to manually trust the certificate to access it using https. The specific operation is as follows: The following example hypotheses that the server where nginx is located is console.elkeid.org and has a configuration of /etc/hosts or dns parsing.

3.1, Macos

  1. Access https://console.elkeid.org:8072/ Export Certificate cert1 cert2
  2. Import the exported certificate and trust it cert3 cert4 cert5
  3. Click Keychain Access, Trust Certificate cert6
  4. Visit https://console.elkeid.org:8072/ again cert7 cert8

Elkeid Console 主机安全保护平台使用手册

版本

社区版v1.9.1

安全概览

通过安全概览能快速了解覆盖范围,告警势态,运营情况(安全告警与安全风险处置情况)等的整体安全态势。

资产概览

查看当前在覆盖的主机和容器集群信息。

入侵告警

展示未处理告警的数量以及最近7天内的变化趋势。

漏洞风险

展示未处理漏洞的数量以及最近7天内的变化趋势。

基线风险

展示TOP3的基线风险数量。

主机风险分布

展示当前存在待处理告警、高可利用漏洞和基线风险的主机占比。

Agent 概览

展示Agent的在线情况和资源占用情况。

后端服务状态

展示后端服务的负载。

资产中心

运营人员可以通过资产中心对资产数,Agent运行情况,资产上详细信息进行查看。

主机列表

展示主机资产的列表以及各主机的风险情况。

点击"主机名称"可以进入查看此主机的资产信息和风险信息。

点击页面中各标签可以查看主机各类相关数据,目前支持下列数据。

  • 安全告警
  • 漏洞风险
  • 基线风险
  • 运行时安全告警
  • 病毒查杀
  • 性能监控
  • 资产指纹

资产指纹

通过该功能查看各主机的开放端口,运行进程,系统用户,定时任务,系统服务,系统软件等详情。

点击页面中各标签可以查看相应资产数据,目前支持下列资产数据:

  • 容器
  • 开放端口
  • 运行进程
  • 系统用户
  • 定时任务
  • 系统服务
  • 系统软件
  • 系统完整性校验
  • 应用
  • 内核模块

点击各行的"主机名称"可以跳转到相应主机的详情页,查看此主机资产指纹数据

容器集群

展示已经接入容器集群防护能力的容器集群信息。

主机和容器防护

入侵检测

告警列表

告警列表可以查看当前环境内存在的安全告警列表。

点击"摘要"可以查看告警关键摘要信息。

点击”处理”可以进行告警的处理,目前处理操作支持"加白","已人工处理"和“误报”。

点击各行的“影响资产”可以跳转到关联的主机详情页面查看相关数据。

白名单

主机和容器防护告警的白名单。

风险防范

漏洞列表

漏洞列表页面可以查看当前环境内存在的安全漏洞风险,默认只显示高风险漏洞的信息,用户通过立即检查来检测环境中最新存在的安全漏洞。

在漏洞列表数据右侧点击详情可以查看漏洞信息以及影响的资产列表。

漏洞信息也可以通过处置与忽略进行标记。

基线检查

基线检查页面可以查看当前环境内存在的安全基线风险,可以通过立即检查来查看环境中最新存在的安全基线问题。

在基线列表右侧点击详情可以看到相应的基线详情。

点击加白名单可以进行加白操作。

应用运行时安全防护

运行状态

展示运行时安全组件的覆盖情况。

配置管理

进行运行时安全组件的配置管理。

入侵检测

告警列表

运行时安全检测发现的安全告警展示。

白名单

运行时安全检测告警过滤白名单规则展示。

容器集群防护

入侵检测

告警列表

容器集群防护发现的安全告警展示。

白名单

容器集群防护告警过滤白名单规则展示。

病毒扫描

病毒扫描

显示检测到的病毒文件信息。

白名单

对病毒检测结果进行过滤的白名单列表。

系统管理

任务管理

该功能主要用于重启客户端、同步配置等管理。

点击”新建任务“,可以进行任务的配置。

除"重启客户端"类型任务外,其他类型任务需要先在"组件管理"和"组件策略"界面进行Agent和插件的配置,才能进行相应操作。

组件管理

用于对Agent和相应插件进行升级配置的管理。

点击”新建组件“可以选择组件的类型是Agent还是插件,然后进行相应配置。

点击发布版本按钮,可以通过上传对应架构与发行版的组件文件生成版本实例。

组件策略

通过管理组件策略,调整Agent实际生效的组件版本,进而实现更新、卸载等操作。

点击新建策略,通过选择组件名称及相匹配的版本,将对应策略添加至策略组中。

通过屏蔽规则使得部分主机不加载(生效)对应组件。

安装配置

可以通过部署帮助来实现Agent的部署和卸载。

用户管理

可以在用户管理中对Elkeid Console进行管理,如修改密码,新增与删除用户。

点击"新增用户"可以设置增加新的用户,设置密码的时候请注意密码强度的要求。

容器集群配置

进行容器集群防护能力接入的配置。

通知管理

告警通知以及过期通知的配置管理,支持飞书,钉钉等。

系统监控

后端监控

查看后端服务所在主机的CPU,内存,磁盘和网络流量等使用情况。

后端服务

查看后端各服务模块的QPS,CPU和内存的使用情况。

服务告警

显示最近1小时/24小时发现的服务异常告警。

Elkeid HUB 社区版快速上手教程

本教程的前置条件

在开始本教程之前,请检查:

  • 已经按照部署文档,使用elkeidup正确部署了 HUB。
  • 至少有一个可以使用的数据输入源(Input)和数据存储的输出源(Output)。在HIDS场景中,数据输入源为 AgentCenter 配置文件中指定的 kafka ,输出源可以使用 ES 或 Kafka ,本教程中以 ES 为例。

e.g. 社区版默认已配置输入源(hids,k8s)可在前端看到,方便测试使用

Step 1. 访问并登录前端

使用部署前端机器的 IP 即可访问前端,登录信息为elkeidup部署创建的用户名和密码。

Step 2. 编写策略

基本概念介绍

RuleSet是HUB实现检测/响应的核心部分,可以根据业务需要对输入的数据进行检测响应,配合插件还能实现报警的直接推送或对消息的进一步处理。因此如果有额外的业务需要可能需要自行编写部分规则。

RuleSet是通过XML格式来描述的规则集,RuleSet分为两种类型rulewhitelistrule为如果检测到会继续向后传递,whitelist则为检测到不向后传递,向后传递相当于检出,因此whitelist一般用于白名单。

Ruleset里可以包含一条或多条rule,多个rule之间的关系是'或'的关系,即如果一条数据可以同时命中多条rule。

使用前端编写规则

进入规则页->规则集页面,可以看到当前收藏的RuleSet和全部RuleSet。

当Type为Rule时会出现未检测时丢弃字段,意味未检测到是否丢弃,默认是True即为未检测到即丢弃,不向下传递,在这里我们设为True。创建完成后,在创建好的条目上点击规则按钮,进入该Ruleset详情。在RuleSet详情中点击新建会弹出表单编辑器。

HUB已经默认开放了数十条规则,可以查看已经编写的规则,进行相关策略编写

也可以根据Elkeid HUB 社区版使用手册 进行编写.编写完成后,可以在项目页新建project,将编写好的规则与输入输出进行组合.

下图即为hids告警处理的过程:数据按照dsl的顺序,依次经过RULESET.hids_detect、RULESET.hids_filter等规则进行处理,最后再通过RULESET.push_hids_alert推送到CWPP console.

完成以上步骤后,进入规则发布页面,会显示出刚才修改的全部内容,每一个条目对应着一个组件修改,点击 Diff 可以查看修改详情。检查无误后,点击提交,将变更下发到HUB集群。

任务提交后,会自动跳转到任务详情页面,显示当前任务执行进度。

配置下发完成后,需要启动刚才新建的两个项目,进入规则发布->项目操作页面,分别启动全部已有的 项目。

进阶操作

配置ES Index查看报警

此步骤适用于OutputType使用ES的用户,Kafka用户可以自行配置。

建议先使用反弹shell等恶意行为触发一下告警流,让至少一条数据先打入ES,从而在Kibana上可以配置Index Pattern。
  1. 在输出页配置es类型的输出,可开启AddTimestamp,方便在kibana页面配置相关索引

  1. 编辑hids项目,加入刚编些好的es输出

  1. 提交变更

  1. 首先进入ES 的 stack management,选择kibana 的index patterns,点击 create index patten

  1. 输入之前填入的ES output index name,以星号 * 作为后缀,这里以默认推荐优先,分别为alert 或者 raw_alert
    • 如果这时index中存在数据(即已经触发过告警流),那么应能正确匹配到alert或者 raw_alert index

  1. 配置时间字段
    • 如果这时index中存在数据(即已经触发过告警流),那么应能正确匹配到timestamp字段,否则此处无下拉选择框

  1. 去浏览数据
    • 进入discover 看板,选择刚才创建的 alert* 看板,调整右侧时间,即可看到告警

示例

sqlmap检测规则编写

在本教程中,会尝试在前端中编写一条规则,为检查执行sqlmap命令的规则.

在该检测场景中,我们只需要关注Execve相关的信息,因此我添加了data_type为59的过滤字段,因此该规则只会对data_type为59的数据进行处理。之后我添加了一个CheckNode,检查数据中argv字段中是否包含'sqlmap',编写完的效果如下:

可以看到分别设置了三个CheckNode来进行检测,一是直接检测argv中是否包含sqlmap,二是检测exe字段是否包含python,三是使用正则来进行匹配是否为单独的word,当这三个同时满足,就会触发报警,编写好后,点击保存。

我们单独为该测试规则建立一个Output和Project,如下图所示:

进入测试环境执行sqlmap相关指令,在kibana中添加对应的index pattern,稍微等待一会就可以找到对应的报警结果。

可以看到出现了报警。

推送飞书插件编写

规则写完了,如果我想在发生该事件的时候飞书提醒我该如何实现呢?RuleSet并不支持这项功能,此时可以通过编写插件来实现。

创建并使用Python 插件的步骤如下:

  1. 点击创建按钮

  1. 按照需求,填写信息

  1. 点击确认,完成创建

  1. 编辑插件

默认为只读状态,需要点击编辑才能进行编辑

编辑后点击保存

  1. 在Rule中添加action

  1. 同策略发布相同,在策略发布界面发布策略

这样每当这个rule的条件被触发,就会调用这个插件进行报警。

Elkeid CWPP 应用运行时防护 (RASP) 使用指南

本指南涵盖以下功能:

  • 通过 CWPP 对 应用运行时 组件进行运维。
  • 控制 RASP 植入探针到目标进程中,完成运行时行为采集。
  • 植入配置
  • 阻断/过滤 配置
  • 查看 CWPP 的告警事件。

安装/更新 RASP 组件

  1. 确保组件列表中包含 rasp 组件。

RASP_compoment

如果没有 rasp 组件,需要新建组件,组件名为 rasp。

RASP_new_compoment_1

注意!由于 Agent 机制,插件名称与插件二进制名称应该一致。

发布版本,上传 tar.gz 格式的压缩包。 请使用 1.9.1.* 版本的插件。 压缩包地址:bytedance/Elkeid: releases

RASP_github_release_1

  1. 确保组件策略中包含 rasp 组件 RASP_policy_1

  2. 同步策略到机器。 RASP_sync_1 RASP_sync_2

运行状态

部署 RASP 组件后,RASP 将会自动分析机器进程,对符合植入探针条件的进程信息将会上报到 运行状态。 RASP_process_1 右侧详情链接支持查看进程其他信息 RASP_process_2

配置

配置哪些进程将会开启 RASP 保护

点击新建配置 RASP_config_1 每条配置的各表单项目间为与的关系 每条配置间为或的关系

表单项目是否必选含义解释备注
主机标签划定本条配置的适用的主机标签范围主机标签与资产管理中的标签一致
IP对机器IP进行匹配
进程命令行对进程命令行进行正则匹配
环境变量对进程的环境变量进行匹配可多个环境变量 多个间为与的关系
运行时类型本条配置适用于哪种运行时可多选
是否开启注入本条配置筛选的进程是否开启 RASP 防护默认为否

每条配置还可以配置阻断与过滤

  • 阻断:对某个Hook函数的某个参数进行正则表达式匹配
    • 正则表达式匹配到时,函数抛出异常阻断该函数运行。
    • 正则表达式没有匹配到时,函数正常运行。
  • 过滤:对某个Hook函数的参数进行正则表达式匹配
    • 包含:只上报匹配到的参数数据
    • 不包含:只上报匹配到以外的参数数据

入侵检测

RASP 探针植入目标进程后,将会持续上报应用行为,发现异常行为后将会产生事件与告警。

RASP_alert_1

  • 右侧告警数据可以检查参数详情与调用栈

RASP_alert_2

社区版与企业版能力差异

Elkeid Console社区版v1.9.1和企业版能力对比

功能 Elkeid Community Edition Elkeid Enterprise Edition
Linux 数据采集能力
RASP 探针能力
K8s Audit Log 采集能力
Agent 控制面
主机状态与详情
勒索诱饵 🙅‍♂️
资产采集
高级资产采集 🙅‍♂️
容器集群资产采集
暴露面与脆弱性分析 🙅‍♂️
主机/容器 基础入侵检测 少量样例
主机/容器 行为序列入侵检测 🙅‍♂️
RASP 基础入侵检测 少量样例
RASP 行为序列入侵检测 🙅‍♂️
K8S 基础入侵检测 少量样例
K8S 行为序列入侵检测 🙅‍♂️
K8S 威胁分析 🙅‍♂️
告警溯源(行为溯源) 🙅‍♂️
告警溯源(驻留溯源) 🙅‍♂️
告警白名单
多告警聚合能力 🙅‍♂️
威胁处置(进程) 🙅‍♂️
威胁处置(网络) 🙅‍♂️
威胁处置(文件) 🙅‍♂️
文件隔离箱 🙅‍♂️
漏洞检测 少量情报
漏洞情报热更新 🙅‍♂️
基线检查 少量基线
RASP 热补丁 🙅‍♂️
病毒扫描
用户行为日志分析 🙅‍♂️
插件管理
系统监控
系统管理
Windows 支持 🙅‍♂️
蜜罐 🙅‍♂️ 🚘
主动防御 🙅‍♂️ 🚘
云查杀 🙅‍♂️ 🚘
防篡改 🙅‍♂️ 🚘

Elkeid HUB 社区版和企业版能力对比

功能 Elkeid HUB Community Edition Elkeid HUB Enterprise Edition
完全规则编写能力(详见Elkedi HUB社区版使用指南):
基础检测(等于/包含/以……开头/正则等)
阈值/频率/GROUP  BY检测
多关键词检测
数组/复杂结构检测
CEP 节点检测能力
字段添加/修改/删除
插件联动能力

系统/用户管理能力
集群部署能力
多工作空间
输入/输出/规则集/项目组建操作能力
负载、规则监控能力
组件数据抽样能力
规则测试能力
数据表(MYSQL/REDIS/ClickHouse/Mongodb/ES)消费/规则关联能力
自定义插件能力
插件供外部调用能力
日志/事件监控能力
溯源/持久化能力

开源策略说明

HIDS开源策略列表

告警ID 告警名 描述 告警类型 数据类型 等级
hidden_module_detect Hidden kernel module Hidden Kernel Module Detected 后门驻留 Hooks critical
bruteforce_single_source_detect Bruteforce from single-source Bruteforce from single source address 暴力破解 Log Monitor medium
bruteforce_multi_source_detect Bruteforce from multi-sources Bruteforce from multiple source addresses 暴力破解 Log Monitor medium
bruteforce_success_detect Bruteforce success Bruteforce login attempt ended with succesful password login 暴力破解 Log Monitor critical
binary_file_hijack_detect1 Binary file hijack Common binary file hijacking, file creation detection 变形木马 execve medium
binary_file_hijack_detect2 Binary file hijack Common binary file Hijacking, file renaming detection 变形木马 execve critical
binary_file_hijack_detect3 Binary file hijack Common binary file hijacking, file linkage detection 变形木马 execve critical
user_credential_escalation_detect User credential escalation Non-root user escalate to root privilege 提权攻击 Log Monitor medium
privilege_escalation_suid_sgid_detect_1 User credential escalation Non-root user escalete privilege with suid/sgid 提权攻击 Log Monitor medium
privilege_escalation_suid_sgid_detect_2 User credential escalation Non-root user escalete privilege with suid/sgid 提权攻击 execve medium
reverse_shell_detect_basic Reverse shell Reverse Shell With Connection 代码执行 execve critical
reverse_shell_detect_argv Reverse shell Reverse-shell-like argv during execution 代码执行 execve high
reverse_shell_detect_exec Reverse shell Reverse shell with exec 代码执行 execve high
reverse_shell_detect_pipe Reverse shell Reverse shell with pipe 代码执行 execve high
reverse_shell_detect_perl Reverse shell Reverse shell with Perl 代码执行 execve high
reverse_shell_detect_python Reverse shell Reverse shell with Python 代码执行 execve high
bind_shell_awk_detect Bind shell with awk Suspecious bind shell with awk 代码执行 execve high
pipe_shell_detect Double-piped reverse shell Double-piped reverse shell 代码执行 execve high
suspicious_rce_from_consul_service_detect Suspecious RCE like behavior Suspecious RCE like behaviors from Consul service 试探入侵 execve high
suspicious_rce_from_mysql_service_detect Suspecious RCE like behavior Suspecious RCE like behaviors from mysql service 试探入侵 execve high
dnslog_detect1 Suspecious query to dnslog Suspecious dnslog like query on hosts 试探入侵 execve high
dnslog_detect2 Suspecious query to dnslog Suspecious dnslog like query on hosts 试探入侵 execve high
container_escape_mount_drive_detect Container escape with mounted drive Unnecessary behavior inside contianer, mount drive 提权攻击 execve high
container_escape_usermode_helper_detect Container escape with usermodehelper Suspecious contianer escape with usermode helper 提权攻击 execve high
signature_scan_maliciou_files_detect Malicious files Detected abnormal files with maliciou singnature 静态扫描 execve high

K8S开源策略列表

k8s 开源策略列表

策略一级类别 策略二级类别 策略三级类别 / 告警名称(风险名称) 告警描述 告警类型 严重等级 ATT&CK ID 风险说明 处置建议(含关注字段)
异常行为 认证/授权失败 匿名访问 匿名用户访问 试探入侵 high T1133 检测到匿名用户访问集群,可能有人对集群进行探测攻击。 1. 通过 UserAgent,操作,请求 URI 等字段判断该操作是否是敏感操作,如果是则可能是有人对集群进行攻击,请通过源 IP 字段以及该 IP 关联的资产信息等来定位发起者身份,进一步排查。
2. 如果不是,则可以考虑对其进行加白处理(注意:建议结合多个字段进行加白,避免导致漏报)

关注字段:UserAgent,账户/模拟账户,动作,资源
认证失败 枚举/获取 secrets,认证失败 试探入侵 low T1133 枚举、获取集群保密字典(Secret)时出现认证失败。攻击者可能会尝试获取集群 secrets 用于后续攻击。 1. 请先结合客户端的 UserAgent、账户/模拟账户等字段初步判断是否为业务、研发/运维的行为
2. 如果是重复出现的预期行为,且经排查后判断安全风险可控,可以考虑对其进行加白(注意:建议结合多个字段进行加白,避免导致漏报)
3. 如果是非预期行为,请通过源 IP 字段以及该 IP 关联的资产信息等来定位发起者身份,进一步排查

关注字段:UserAgent, 账户/模拟账户,动作,资源名字
授权失败 枚举/获取 secrets,授权失败 试探入侵 medium T1133 枚举、获取集群保密字典(Secret)时出现授权失败。攻击者可能会尝试获取 secrets 用于后续攻击。 1. 请先结合客户端的 UserAgent、账户/模拟账户等字段初步判断是否为业务、研发/运维的行为
2. 如果是重复出现的预期行为,且经排查后判断安全风险可控,可以考虑对其进行加白(注意:建议结合多个字段进行加白,避免导致漏报)
3. 如果是非预期行为,请通过源 IP 字段以及该 IP 关联的资产信息等来定位发起者身份,进一步排查

关注字段:UserAgent, 账户/模拟账户,动作,资源名字
凭据滥用 凭据滥用 利用 kubectl 滥用 ServiceAccount 试探入侵 critical T1078, T1133 通过 kubectl 客户端工具以 SA 账户身份访问 k8s API Server。攻击者窃取到某个 SA token 后,然后通过 kubectl 工具,附带窃取的 token 向 API Server 发起请求来进行攻击。 1. 请先通过UserAgent、账户/模拟账户、动作、资源等字段确认是否为预期业务行为
2. 如果是重复出现的预期行为,且经排查后判断安全风险可控,可以考虑对其进行加白(注意:建议结合多个字段进行加白,避免导致漏报)
3. 如果是非预期行为,请通过源 IP 字段以及该 IP 关联的资产信息等来定位发起者身份,进一步排查

关注字段:UserAgent,账户/模拟账户,动作,资源
外部代码执行 外部代码执行 与 API Server 交互,在 pods 内执行命令 代码执行 medium T1609 通过 pods/exec (即 kubectl exec 对应的子资源)在容器内执行任意命令(创建交互式 bash、执行其他命令)。攻击者可能会通过创建 pods/exec 子资源在容器中执行任意命令,从而实现横向移动攻击、凭据窃取等。本策略记录所有的 pods/exec 行为。 1. 请先通过UserAgent、账户/模拟账户、执行命令等字段确认是否为预期业务行为
2. 如果是重复出现的预期行为,且经排查后判断安全风险可控,可以考虑对其进行加白(注意:建议结合多个字段进行加白,避免导致漏报)
3. 如果是非预期行为,请通过源 IP 字段以及该 IP 关联的资产信息等来定位发起者身份,进一步排查

关注字段:UserAgent,账户/模拟账户,执行命令
威胁资源 Workloads 部署 特权容器 创建具有特权容器的工作负载 提权攻击 critical T1611, T1610 监测到有特权容器创建。攻击者可能会通过创建特权容器来横向移动并获取宿主机的控制权。业务在部署服务时,也可能会创建特权容器,如果容器被攻击,则可以轻易实现逃逸,因此非必要不创建。 1. 请先通过容器所属的业务等字段确认是否为预期业务行为
2. 如果是重复出现的预期行为,且经排查后判断安全风险可控,可以考虑对其进行加白(注意:建议结合多个字段进行加白,避免导致漏报)
3. 如果是非预期行为,请通过源 IP 字段以及该 IP 关联的资产信息等来定位发起者身份,进一步排查

关注字段:容器所属的业务,UserAgent, 账户/模拟账户
挂载宿主机敏感文件 创建挂载宿主机敏感文件的工作负载 提权攻击 critical T1611, T1610 创建的容器挂载了宿主机上的敏感目录或文件,比如根目录目录,/proc目录等。

攻击者可能会创建挂载宿主机敏感目录、文件的容器来提升权限,获取宿主机的控制权并躲避检测。当合法的业务创建挂载宿主机敏感目录、文件的容器时,也会给容器环境带来安全隐患。

针对前者需要进一步排查异常,针对后者需联系业务进行持续的安全合规整改。
1. 请先通过容器所属的业务等字段确认是否为预期业务行为
2. 如果是重复出现的预期行为,且经排查后判断安全风险可控,可以考虑对其进行加白(注意:建议结合多个字段进行加白,避免导致漏报)
3. 如果是非预期行为,请通过源 IP 字段以及该 IP 关联的资产信息等来定位发起者身份,进一步排查

关注字段:容器所属的业务,UserAgent,账户/模拟账户,镜像
RoleBinding、ClusterRoleBinding 创建 创建不安全的 ClusterRole 创建绑定大权限 ClusterRole 的 ClusterRoleBinding 后门驻留 high T1078 创建的 ClusterRoleBinding 绑定了敏感的 ClusterRole,即将某个用户、用户组或服务账户赋予敏感的 ClusterRole 的权限。攻击者可能会为持久化、隐蔽性而创建绑定大权限 ClusterRole 的 ClusterRoleBinding。集群管理员或运维人员也可能会因安全意识不足而创建绑定大权限 ClusterRole 的 ClusterRoleBinding。根据权限最小化原则和 k8s 安全攻防实践,此类 ClusterRoleBinding 会给集群引入较大的安全风险,因此应该极力避免。 1. 请先结合客户端的 UserAgent、账户/模拟账户等字段初步判断是否为业务、研发/运维的行为
2. 如果是运维人员在进行角色绑定,则可以将告警设置为已处理。
3. 如果是重复出现的预期行为,且经排查后判断安全风险可控,可以考虑对其进行加白(注意:建议结合多个字段进行加白,避免导致漏报)
4. 如果是非预期行为,请通过源 IP 字段以及该 IP 关联的资产信息等来定位发起者身份,进一步排查

关注字段:UserAgent, 账户/模拟账户,主体名字,角色名字
漏洞利用行为 N/A 疑似 CVE-2020-8554 疑似存在通过创建、更新 Service 的 externalIPs 来利用 CVE-2020-8554 的利用行为 信息搜集 high T1557 检测到 CVE-2020-8554 的利用特征——创建、更新 Service 并设置 externalIPs。此漏洞的利用途径之一为 创建、更新 Service 时设置了恶意 spec.externalIPs 从而实现中间人攻击。根据实践,Service 的 ExternalIP 属性很少被使用。因此当发生这种行为时,需要运营人员进一步核实 ExternalIP 是否为合法的 IP 地址。 1. 请先通过UserAgent、账户/模拟账户等字段以及原始日志中的 requestObject.spec.externalIPs 的值确认是否为预期业务行为
2. 如果是重复出现的预期行为,且经排查后判断安全风险可控,可以考虑对其进行加白(注意:建议结合多个字段进行加白,避免导致漏报)
3. 如果是非预期行为,请通过源 IP 字段以及该 IP 关联的资产信息等来定位发起者身份,进一步排查

关注字段:UserAgent, 账户/模拟账户,  requestObject.spec.externalIPs

K8S开源策略编写说明

数据源

K8S策略基于K8S Audit Logs数据,具体的Audit Policy可以在平台中下载。在Console中配置好后,数据会经Agent Center上开启的Webhook写入到Kafka的k8stopic。也可以直接使用HUB中自带的k8s INPUT作为数据源。

开源策略说明

Project

在v1.9.1社区版中,我们编写了一部分示例策略用于开源,对应的HUB Project为kube_example和kube_workload。kube_example存放的策略为基础策略,kube_workload存放的为需要对数据进行处理后再进行检测的策略。

  • kube_example
  INPUT.k8s --> RULESET.kube_detect
  RULESET.kube_detect --> RULESET.kube_alert_info
  RULESET.kube_alert_info --> RULESET.kube_add_cluster_info
  RULESET.kube_add_cluster_info --> RULESET.kube_push_alert
  • kube_workload
  INPUT.k8s --> RULESET.kube_workloads
  RULESET.kube_workloads --> RULESET.kube_filter_workloads
  RULESET.kube_filter_workloads --> RULESET.kube_handle_workloads
  RULESET.kube_handle_workloads --> RULESET.kube_detect_workloads
  RULESET.kube_detect_workloads  --> RULESET.kube_alert_info
  RULESET.kube_alert_info --> RULESET.kube_add_cluster_info
  RULESET.kube_add_cluster_info --> RULESET.kube_push_alert

Ruleset

下面为一些调用HUB内置插件的规则集进行补充说明,其余规则可以直接在HUB前端进行查看。

kube_alert_info规则集对检出的告警添加告警数据字段,同时调用Kube_add_info插件添加告警的基础信息。该插件为HUB内置Modify插件,因此可以按需调用。

kube_add_cluster_info规则集调用Manager接口通过集群id获取集群信息,该流程通过调用KubeAddClusterInfo插件实现。该插件为HUB内置Modify插件。

kube_push_alert规则集调用Manager接口推送告警,该流程通过调用KubePushMsgToLeader插件实现。该插件为HUB内置Action插件。

下图为告警内容说明: 告警说明 workload相关检测策略通过Python Plugin进行实现,该插件于kube_handle_workloads中调用。

编写建议

在编写其余告警策略时,需要分别调用kube_alert_infokube_add_cluster_infokube_push_alert进行告警的信息填充,集群信息添加,告警的推送。如果新增告警类型,需要在kube_alert_info中进行添加,补充相关字段。

Elkeid - Bytedance Cloud Workload Protection Platform

Elkeid 是一款可以满足 主机,容器与容器集群,Serverless 等多种工作负载安全需求的开源解决方案,源于字节跳动内部最佳实践。

随着企业的业务发展,多云、云原生、多种工作负载共存的情况愈发凸显,我们希望可以有一套方案可以满足不同工作负载下的安全需求,因此 Elkeid 诞生了。

Introduction

Elkeid 具备以下主要能力:

  • Elkeid 不仅具备传统的 HIDS(Host Intrusion Detection System) 的对于主机层入侵检测和恶意文件识别的能力,且对容器内的恶意行为也可以很好的识别,部署在宿主机即可以满足宿主机与其上容器内的反入侵安全需求,并且 Elkeid 底层强大的内核态数据采集能力可以满足大部分安全运营人员对于主机层数据的渴望。

  • 对于运行的业务 Elkeid 具备 RASP 能力可以注入到业务进程内进行反入侵保护,不仅运维人员不需要再安装一个 Agent,业务也无需重启。

  • 对于 K8s 本身 Elkeid 支持接入K8s Audit LogK8s 系统进行入侵检测和风险识别。

  • Elkeid 的规则引擎 Elkeid HUB 也可以很好的和外部多系统进行联动对接。

Ekeid 将这些能力都很好的融合在一个平台内,满足不同工作负载的复杂安全需求的同时,还能实现多组件能力关联,更难得的是每个组件均经过字节跳动海量数据和多年的实战检验。

Elkeid Community Edition Description

需要注意的是 Elkeid 开源版本 和完整版本存在差异,目前已开源的能力主要包括:

  • 全部端上能力,即端上数据/资产/部分采集能力,内核态数据采集能力,RASP 探针部分等,并与字节跳动内部版本一致;
  • 全部接入层能力,即 Agent Center,服务发现等,并与字节跳动内部版本一致;
  • 提供社区版规则引擎即 Elkeid HUB,并配套少量策略作为示例使用;
  • 提供社区版 Elkeid Console 与部分配套能力。

因此需要具备完整的反入侵与风险感知能力,还需要自行基于 Elkeid HUB 进行策略构建和对 Elkeid 采集的数据进行二次加工等工作。

Elkeid Architecture

Elkeid Host Ability

  • Elkeid Agent 用户态 Agent,负责管理各个端上能力组件并与 Elkeid Agent Center 通信
  • Elkeid Driver 负责 Linux Kernel 层采集数据,兼容容器,并能够检测常见 Rootkit
  • Elkeid RASP 支持 CPython、Golang、JVM、NodeJS、PHP 的运行时数据采集探针,支持动态注入到运行时
  • Elkeid Agent Plugin List
    • Driver Plugin: 负责与 Elkeid Driver 通信,处理其传递的数据等
    • Collector Plugin: 负责端上的资产/关键信息采集工作,如用户,定时任务,包信息等
    • Journal Watcher: 负责监测systemd日志的插件,目前支持ssh相关日志采集与上报
    • Scanner Plugin: 负责在端上进行静态检测恶意文件的插件,支持 Yara
    • RASP Plugin: 分析系统进程运行时,上报运行时信息,处理下发的 Attach 指令,收集各个探针上报的数据
    • Baseline Plugin: 负责在端上进行基线风险识别的插件
  • Elkeid 数据说明
  • Elkeid 数据接入

Elkeid Backend Ability

  • Elkeid AgentCenter 负责与 Agent 进行通信并管理 Agent 如升级,配置修改,任务下发等
  • Elkeid ServiceDiscovery 后台中的各组件都会向该组件定时注册、同步服务信息,从而保证各组件相互可见,便于直接通信
  • Elkeid Manager 负责对整个后台进行管理,并提供相关的查询、管理接口
  • Elkeid Console Elkeid 前端部分
  • Elkeid HUB 策略引擎

Elkeid Function List

功能Elkeid Community EditionElkeid Enterprise Edition
Linux 数据采集能力:white_check_mark::white_check_mark:
RASP 探针能力:white_check_mark::white_check_mark:
K8s Audit Log 采集能力:white_check_mark::white_check_mark:
Agent 控制面:white_check_mark::white_check_mark:
主机状态与详情:white_check_mark::white_check_mark:
勒索诱饵:ng_man::white_check_mark:
资产采集:white_check_mark::white_check_mark:
高级资产采集:ng_man::white_check_mark:
容器集群资产采集:white_check_mark::white_check_mark:
暴露面与脆弱性分析:ng_man::white_check_mark:
主机/容器 基础入侵检测少量样例:white_check_mark:
主机/容器 行为序列入侵检测:ng_man::white_check_mark:
RASP 基础入侵检测少量样例:white_check_mark:
RASP 行为序列入侵检测:ng_man::white_check_mark:
K8S 基础入侵检测少量样例:white_check_mark:
K8S 行为序列入侵检测:ng_man::white_check_mark:
K8S 威胁分析:ng_man::white_check_mark:
告警溯源(行为溯源):ng_man::white_check_mark:
告警溯源(驻留溯源):ng_man::white_check_mark:
告警白名单:white_check_mark::white_check_mark:
多告警聚合能力:ng_man::white_check_mark:
威胁处置(进程):ng_man::white_check_mark:
威胁处置(网络):ng_man::white_check_mark:
威胁处置(文件):ng_man::white_check_mark:
文件隔离箱:ng_man::white_check_mark:
漏洞检测少量情报:white_check_mark:
漏洞情报热更新:ng_man::white_check_mark:
基线检查少量基线:white_check_mark:
RASP 热补丁:ng_man::white_check_mark:
病毒扫描:white_check_mark::white_check_mark:
用户行为日志分析:ng_man::white_check_mark:
插件管理:white_check_mark::white_check_mark:
系统监控:white_check_mark::white_check_mark:
系统管理:white_check_mark::white_check_mark:
Windows 支持:ng_man::white_check_mark:
蜜罐:ng_man::oncoming_automobile:
主动防御:ng_man::oncoming_automobile:
云查杀:ng_man::oncoming_automobile:
防篡改:ng_man::oncoming_automobile:

Front-end Display (Community Edition)

安全概览

容器集群安全告警

容器集群工作负载信息


主机概览

资产指纹

安全告警

漏洞信息

基线检查

病毒扫描

后端监控

后端服务监控

Console User Guide

Quick Start

Contact us && Cooperation

Lark Group

About Elkeid Enterprise Edition

Elkeid 企业版本支持单独策略售卖,也支持完全完整能力售卖。

如果对Elkeid企业版感兴趣请联系: elkeid@bytedance.com

Elkeid Docs

For more details and latest updates, see Elkeid docs.

License

  • Elkeid Driver: GPLv2
  • Elkeid RASP: Apache-2.0
  • Elkeid Agent: Apache-2.0
  • Elkeid Server: Apache-2.0
  • Elkeid Console: Elkeid License
  • Elkeid HUB: Elkeid License

同时,Elkeid 也是 404Team 星链计划2.0中的一环,如果对星链计划感兴趣的小伙伴可以点击下方链接了解。 https://github.com/knownsec/404StarLink2.0-Galaxy

License Project Status: Active – The project has reached a stable, usable state and is being actively developed.

关于 Elkeid Agent

Agent提供端上组件的基本能力支撑,包括数据通信、资源监控、组件版本控制、文件传输、机器基础信息采集等。

Agent本身不提供安全能力,作为一个插件底座以系统服务的方式运行。各类功能插件的策略存放于服务器端的配置,Agent接收到相应的控制指令及配置后对自身及插件进行开启、关闭、升级等操作。

Agent与Server之间采用bi-stream gRPC进行通信,基于自签名证书开启双向TLS验证,保障信道安全。其中,Agent -> Server 方向信息流动称为数据流,Server -> Agent 方向信息流动一般为控制流,使用protobuf的不同message类型。Agent本身支持客户端侧服务发现,也支持跨Region级别的通信配置,实现一个Agent包在多个网络隔离的环境下进行安装,基于底层一个TCP连接,在上层实现了Transfer与FileOp两种数据传输服务,支撑了插件本身的数据上报与Host中的文件交互。

Plugins作为安全能力插件,与Agent的进程关系一般为“父——子”进程。以两个pipe作为跨进程通信方式,plugins lib提供了Go与Rust的两个插件库,负责插件端信息的编码与发送。值得一提的是,插件发送数据后,会被编码为Protobuf二进制数据,Agent接收到后无需二次解编码,再其外层拼接好Header特征数据,直接传输给Server,一般情况下Server也无需解码,直接传输至后续数据流中,使用时进行解码,一定程度上降低了数据传输中多次编解码造成的额外性能开销。

Agent采用Go实现,在Linux下,通过systemd作为守护方式,受cgroup限制控制资源使用,支持aarch64与x86-64架构,最终编译、打包为deb与rpm包分发,格式均符合systemd及Debian、RHEL规范,可以直接提供至对应的软件仓库中进行后续版本维护。在后续版本中,将会发布用于Windows平台下的Agent。

运行时要求

Agent及Plugin提供的大部分功能需要以root权限运行在宿主机(Host)层面,在权限受限的容器中,部分功能可能会存在异常。

快速开始

通过 elkeidup 的完整部署,可以直接得到用于Debian/RHEL系列发行版的安装包,并按照 Elkeid Console - 安装配置 界面的命令进行安装部署。

手动编译

环境要求

  • Go >= 1.18
  • nFPM
  • 成功部署的 Server (包含所有组件)

确认相关配置

  • 需要确保 transport/connection 目录下的 ca.crtclient.keyclient.crt 三个文件与Agent Center conf 目录下的同名文件保持一致。
  • 需要确保 transport/connection/product.go 文件中的参数都配置妥当:
    • 如果是手动部署的Server:
      • serviceDiscoveryHost["default"] 需被赋值为 ServiceDiscovery 服务或代理服务的内网监听地址与端口,例如:serviceDiscoveryHost["default"] = "192.168.0.1:8088"
      • privateHost["default"] 需被赋值为 AgentCenter 服务或代理服务的内网监听地址与端口,例如:privateHost["default"] = "192.168.0.1:6751"
      • 如有Server的公网接入点,publicHost["default"] 需被赋值为 AgentCenter 服务或代理服务的外网监听地址与端口,例如:publicHost["default"]="203.0.113.1:6751"
    • 如果是通过 elkeidup 部署的Server,可以根据部署Server机器的 ~/.elkeidup/elkeidup_config.yaml 文件获得对应配置:
      • 在配置文件中找到 Nginx 服务的IP,具体的配置项为 nginx.sshhost[0].host
      • 在配置文件中找到 ServiceDiscovery 服务的IP,具体的配置项为 sd.sshhost[0].host
      • serviceDiscoveryHost["default"] 需被赋值为 ServiceDiscovery 服务的IP,并将端口号设置为8088,例如:serviceDiscoveryHost["default"] = "192.168.0.1:8088"
      • privateHost["default"] 需被赋值为 Nginx 服务的IP,并将端口号设置为8090,例如:privateHost["default"] = "192.168.0.1:8090"

编译

在Agent根目录,执行:

BUILD_VERSION=1.7.0.24 bash build.sh

在编译过程中,脚本会读取 BUILD_VERSION 环境变量设置版本信息,可根据实际需要进行修改。

编译成功后,在根目录的 output 目录下,应该可以看到2个deb与2个rpm文件,它们分别对应不同的系统架构。

版本升级

  1. 如果没有创建过客户端类型的组件,请在 Elkeid Console-组件管理 界面新建对应组件。
  2. Elkeid Console - 组件管理 界面,找到“elkeid-agent”条目,点击右侧“发布版本”,填写版本信息并上传对应平台与架构的文件,点击确认。
  3. Elkeid Console - 组件策略 界面,(如有)删除旧的“elkeid-agent”版本策略,点击“新建策略”,选中刚刚发布的版本,点击确认。后续新安装的Agent均会自升级到最新版本。
  4. Elkeid Console - 任务管理 界面,点击“新建任务”,选择全部主机,点击下一步,选择“同步配置”任务类型,点击确认。随后,在此页面找到刚刚创建的任务,点击运行,即可对存量旧版本Agent进行升级。

License

Elkeid Agent is distributed under the Apache-2.0 license.

License Project Status: Active – The project has reached a stable, usable state and is being actively developed.

后台架构图

概述

Elkeid 后台大体包含5个模块:

  1. AgentCenter(AC),负责与Agent进行通信,采集Agent数据并简单处理后汇总到消息队列集群,同时也负责对Agent进行管理包括Agent的升级,配置修改,任务下发等。同时AC也对外提供HTTP接口,Manager通过这些HTTP接口实现对AC和Agent的管理和监控。
  2. ServiceDiscovery(SD),后台中的各个服务模块都需要向SD中心定时注册、同步服务信息,从而保证各个服务模块中的实例相互可见,便于直接通信。由于SD维护了各个注册服务的状态信息,所以当服务使用方在请求服务发现时,SD会进行负载均衡。比如Agent请求获取AC实例列表,SD直接返回负载压力最小的AC实例。
  3. Manager,负责对整个后台进行管理并提供相关的查询、管理接口。包括管理AC集群,监控AC状态,控制AC服务相关参数,并通过AC管理所有的Agent,收集Agent运行状态,往Agent下发任务,同时manager也管理实时和离线计算集群。
  4. Elkeid Console: Elkeid 前端部分。
  5. Elkeid HUB :Elkeid HIDS RuleEngine。

简单来说就是AgentCenter收集Agent数据,Elkeid HUB对这些数据进行分析和检测,Manager管理着AgentCenter和这些计算模块,ServiceDiscovery把这些所有的服务、节点都串联了起来,通过Elkeid Console可查看告警和资产数据等。

功能特点

  • 百万级Agent的后台架构解决方案
  • 分布式,去中心化,集群高可用
  • 部署简单,依赖少,便于维护

完整部署文档

编译

  1. AgentCenter(AC): 在Elkeid/server/agent_center目录执行 ./build.sh,将会在在output目录下生成产物bin.tar.gz
  2. ServiceDiscovery(SD):在Elkeid/server/service_discovery目录执行 ./build.sh将会在在output目录下生成产物bin.tar.gz
  3. Manager:在Elkeid/server/manager目录执行 ./build.sh,将会在在output目录下生成产物bin.tar.gz

版本升级

参照从源码构建 Elkeid CWPP的后端部分,来部署或升级即可。

Console User Guide

License

Elkeid Server are distributed under the Apache-2.0 license.

License Project Status: Active – The project has reached a stable, usable state and is being actively developed.

About Elkeid(AgentSmith-HIDS) Driver

Elkeid Driver 主要是为信息安全需求而设计的。

Elkeid Driver 主要通过 Kprobe Hook Kernel Function 来提供丰富而准确的数据收集功能,包括内核级进程执行探测,特权升级监控,网络审计等等。 并且支持 Linux Namespace,因此对容器监控有着很好的实现。与传统的 User Space HIDS 相比,Elkeid 由于驱动的存在提供了更全面的信息,并提高了性能。

凭借其出色的数据收集能力,Elkeid Driver 还可以支持沙盒,蜜罐和审计等需求。

如果发现 Bug 欢迎提 Issue 或 加入飞书公开群参与讨论。

快速尝试

首先需要安装 Linux Headers,Linux Headers 的版本必须等于 uname -r

# clone and build
git clone https://github.com/bytedance/Elkeid.git
cd Elkeid/driver/LKM/
make clean && make
< CentOS only: run build script instead >
sh ./centos_build_ko.sh

# load and test (should run as root)
insmod hids_driver.ko
dmesg | tail -n 20
test/rst -q
< "CTRL + C" to quit >

# unload
rmmod hids_driver

我们提供部分预编译好的 Ko 文件

我们提供了一些预编译好的 Elkeid 内核模块,这些 Ko 文件包括了 Debian / CentOS / Ubuntu 等发行版的不同内核版本。

获取方式

如果所有链接都获取失败,则说明 预编译的 Ko 中,不包含当前系统的内核版本所需的 Ko 文件,需要自行编译。

wget "http://lf26-elkeid.bytetos.com/obj/elkeid-download/ko/hids_driver_1.7.0.10_$(uname -r)_amd64.ko"

内核模块的测试方法

可以通过 LTP 或者 KASAN 这两个方法对内核模块进行测试.

这里提供 LTP测试用例 文件

关于 Linux 发行版的兼容性

发行版版本号x64 架构内核内核后缀
Debian8,9,103.16~5.4.X-
Ubuntu14.04,16.04,18.04,20.043.12~5.4.Xgeneric
CentOS6.X,7.X,8.X2.6.32.0~5.4.Xel6,el7,el8
Amazon24.9.X~4.14.Xamzn2
AlibabaCloudLinux34.19.X~5.10.Xal7,al8
EulerOSV2.03.10.X-

关于 ARM64 (AArch64) 支持

  • 支持

关于 Linux Kernel Version 兼容性

  • Linux Kernel Version >= 2.6.32 && <= 6.3

关于容器兼容性

SourceNodename
Hosthostname
Dockercontainer name
K8spod name

Hook List

HookDataTypeNoteDefault
write1OFF
open2OFF
mprotect10only PROT_EXECOFF
nanosleep35OFF
connect42ON
accept43OFF
bind49ON
execve59ON
process exit60OFF
kill62OFF
rename82ON
link86ON
ptrace101only PTRACE_POKETEXT or PTRACE_POKEDATAON
setsid112ON
prctl157only PR_SET_NAMEON
mount165ON
tkill200OFF
exit_group231OFF
memfd_create356ON
dns query601ON
create_file602ON
load_module603ON
update_cred604only old uid ≠0 && new uid == 0ON
unlink605OFF
rmdir606OFF
call_usermodehelper_exec607ON
file_write608OFF
file_read609OFF
usb_device_event610ON
privilege_escalation611ON
port-scan detection612tunable via module param: psad_switchOFF

Anti Rootkit List

RootkitDataTypeDefault
interrupt table hook703ON
syscall table hook701ON
proc file hook700ON
hidden kernel module702ON

关于驱动数据传输

驱动数据协议

上述 Hook 点每命中一次,均会生成一条日志记录,记录之间使用 '\x17' 作为间隔符。

每条记录包含多个数据项,数据项之间使用 '\x1e' 作为间隔符。

一条记录数据通常由公共数据私有数据组合而成,而值得注意的是,Anti-rootkit 没有公共数据

公共数据

-------------------------------------------------------------------------------
|1        |2  |3  |4  |5   |6   |7   |8  |9   |10      |11       |12 |13      |
-------------------------------------------------------------------------------
|data_type|uid|exe|pid|ppid|pgid|tgid|sid|comm|nodename|sessionid|pns|root_pns|
-------------------------------------------------------------------------------

Write Data (1)

-----------
|14   |15 | 
-----------
|file||buf|
-----------

Open Data (2)

---------------------
|14   |15  |16      | 
---------------------
|flags|mode|filename|
---------------------

Mprotect Data (10)

-----------------------------------------------------
|14           |15       |16        |17     |18      |
-----------------------------------------------------
|mprotect_prot|owner_pid|owner_file|vm_file|pid_tree|
-----------------------------------------------------

Nanosleep Data (35)

----------
|14 |15  |
----------
|sec|nsec|
----------

Connect Data (42)

-----------------------------------
|14       |15 |16   |17 |18   |19 |
-----------------------------------
|sa_family|dip|dport|sip|sport|res|
-----------------------------------

Accept Data (43)

-----------------------------------
|14       |15 |16   |17 |18   |19 |
-----------------------------------
|sa_family|dip|dport|sip|sport|res|
-----------------------------------

Bind Data (49)

-------------------------
|14       |15 |16   |17 |
-------------------------
|sa_family|sip|sport|res|
-------------------------

Execve Data (59)

-----------------------------------------------------------------------------------------------------
|14  |15      |16   |17    |18 |19   |20 |21   |22       |23      |24 |25        |26 |27        |28 |
-----------------------------------------------------------------------------------------------------
|argv|run_path|stdin|stdout|dip|dport|sip|sport|sa_family|pid_tree|tty|socket_pid|ssh|ld_preload|res|
-----------------------------------------------------------------------------------------------------

Note:

  • socket_exe/dip/dport/sip/sport/sa_family 来自于进程所持的 fd 信息

  • ssh/ld_preload 来自于进程的环境变量信息

Process Exit Data (60)

该数据没有私有数据,仅有公共数据

Kill Data (62)

----------------
|14        |15 |
----------------
|target_pid|sig|
----------------

Rename Data (82)

-------------------------
|14      |15      |16   |
-------------------------
|old_name|new_name|sb_id|
-------------------------
-------------------------
|14      |15      |16   |
-------------------------
|old_name|new_name|sb_id|
-------------------------

Ptrace Data (101)

----------------------------------------------
|14            |15        |16  |17  |18      |
----------------------------------------------
|ptrace_request|target_pid|addr|data|pid_tree|
----------------------------------------------

Setsid Data (112)

该数据没有私有数据,仅有公共数据

Prctl Data (157)

_________________
|14    |15      | 
-----------------
|option|new_name|
-----------------

Mount Data (165)

_____________________________________
|14      |15 |16       |17    |18   | 
-------------------------------------
|pid_tree|dev|file_path|fstype|flags|
-------------------------------------

Tkill Data (200)

----------------
|14        |15 |
----------------
|target_pid|sig|
----------------

Exit Group Data (231)

该数据没有私有数据,仅有公共数据

Memfd Create Data (356)

______________
|14    |15   | 
--------------
|fdname|flags|
--------------

Dns Query Data (601)

--------------------------------------------------
|14   |15       |16 |17   |18 |19   |20    |21   |
--------------------------------------------------
|query|sa_family|dip|dport|sip|sport|opcode|rcode|
--------------------------------------------------

Create File data (602)

----------------------------------------------------------
|14 	  |15 |16   |17 |18   |19       |20        |21   |
----------------------------------------------------------
|file_path|dip|dport|sip|sport|sa_family|socket_pid|sb_id|
---------------------------------------------------------

Load Module Data (603)

---------------------------
|14      |15      |16     |
---------------------------
|ko_file|pid_tree|run_path|
---------------------------

Update Cred Data (604)

----------------------
|14      |15     |16 | 
----------------------
|pid_tree|old_uid|res|
----------------------
------
|14  |
------
|file|
------

Rmdir Data (606)

------
|14  |
------
|file|
------

call_usermodehelper_exec Data (607)

-------------------------
|1        |2  |3   |4   |
-------------------------
|data_type|exe|argv|wait|
-------------------------

File Write Data (608)

------------
|14  |15   |
------------
|file|sb_id|
------------
需要通过 Diver Filter 加入待观察列表,详情见 "关于 Driver Filter" 部分

File Read Data (609)

------------
|14  |15   |
------------
|file|sb_id|
------------
需要通过 Diver Filter 加入待观察列表,详情见 "关于 Driver Filter" 部分

USB Device Event Data (610)

-----------------------------------------
|14          |15          |16    |17    |
-----------------------------------------
|product_info|manufacturer|serial|action|
-----------------------------------------
action = 1 is USB_DEVICE_ADD
action = 2 is USB_DEVICE_REMOVE

Privilege Escalation (611)

------------------------------
|14   |15      |16    |17    |
------------------------------
|p_pid|pid_tree|p_cred|c_cred|
------------------------------
p_cred = uid|euid|suid|fsuid|gid|egid|sgid|fsgid
c_cred = uid|euid|suid|fsuid|gid|egid|sgid|fsgid

Port-scan attack detection (612)

------------------------------------------
|1   |2        |3  |4    |5  |6    |7    |
------------------------------------------
|type|sa_family|sip|sport|dip|dport|flags|
------------------------------------------

Proc File Hook (700)

-----------------------
|1        |2          |
-----------------------
|data_type|module_name|
-----------------------

Syscall Table Hook Data (701)

--------------------------------------
|1        |2          |3             |
--------------------------------------
|data_type|module_name|syscall_number|
--------------------------------------

Hidden Kernel Module Data (702)

-----------------------
|1        |2          |
-----------------------
|data_type|module_name|
-----------------------

Interrupt Table Hook Data (703)

----------------------------------------
|1        |2          |3               |
----------------------------------------
|data_type|module_name|interrupt_number|
----------------------------------------

关于 Driver Filter

Elkeid 驱动程序支持白名单以过滤出不需要的数据。我们提供两种类型的白名单,'exe' 白名单和 'argv' 白名单。 'exe' 白名单作用于 execve/create file/dns query/connect hook,而 'argv' 白名单仅作用于 execve hook。 出于性能和稳定性方面的考虑,'exe' 和 'argv' 白名单容量为 64。

白名单的字符串驱动位于: /dev/hids_driver_allowlist

OperationsFlagExample
ADD_EXECVE_EXE_SHITELISTY(89)echo Y/bin/ls > /dev/someone_allowlist
DEL_EXECVE_EXE_SHITELISTF(70)echo F/bin/ls > /dev/someone_allowlist
DEL_ALL_EXECVE_EXE_SHITELISTw(119)echo w/del_all > /dev/someone_allowlist
EXECVE_EXE_CHECKy(121)echo y/bin/ls > /dev/someone_allowlist && dmesg
ADD_EXECVE_ARGV_SHITELISTm(109)echo m/bin/ls -l > /dev/someone_allowlist
DEL_EXECVE_ARGV_SHITELISTJ(74)echo J/bin/ls -l > /dev/someone_allowlist
DEL_ALL_EXECVE_ARGV_SHITELISTu(117)echo u/del_all > /dev/someone_allowlist
EXECVE_ARGV_CHECKz(122)echo z/bin/ls -l > /dev/someone_allowlist && dmesg
PRINT_ALL_ALLOWLIST.(46)echo ./print_all > /dev/someone_allowlist && dmesg
ADD_WRITE_NOTIFIW(87)echo W/etc/passwd > /dev/someone_allowlist or echo W/etc/ssh/ > /dev/someone_allowlist support dir
DEL_WRITE_NOTIFIv(120)echo v/etc/passwd > /dev/someone_allowlist
ADD_READ_NOTIFIR(82)echo R/etc/passwd > /dev/someone_allowlist or echo R/etc/ssh/ > /dev/someone_allowlist support dir
DEL_READ_NOTIFIs(115)echo s/etc/passwd > /dev/someone_allowlist
DEL_ALL_NOTIFIA(65)echo A/del_all_file_notift > /dev/someone_allowlist

Filter define is:

#define ADD_EXECVE_EXE_SHITELIST 89         /* Y */
#define DEL_EXECVE_EXE_SHITELIST 70         /* F */
#define DEL_ALL_EXECVE_EXE_SHITELIST 119    /* w */
#define EXECVE_EXE_CHECK 121                /* y */
#define PRINT_ALL_ALLOWLIST 46              /* . */
#define ADD_EXECVE_ARGV_SHITELIST 109       /* m */
#define DEL_EXECVE_ARGV_SHITELIST 74        /* J */
#define DEL_ALL_EXECVE_ARGV_SHITELIST 117   /* u */
#define EXECVE_ARGV_CHECK 122               /* z */

#define ADD_WRITE_NOTIFI 87                 /* W */
#define DEL_WRITE_NOTIFI 120                /* v */
#define ADD_READ_NOTIFI 82                  /* R */
#define DEL_READ_NOTIFI 115                 /* s */
#define DEL_ALL_NOTIFI 65                   /* A */

关于 Elkeid Driver 性能

Testing Environment(VM):

CPUIntel(R) Xeon(R) Platinum 8260 CPU @ 2.40GHz 8 Core
RAM16GB
OS/KernelDebian9 / Kernel Version 4.14

Testing Load:

syscallltp
connect./runltp -f syscalls -s connect -t 5m
bind./runltp -f syscalls -s bind -t 5m
execve./runltp -f syscalls -s execve -t 5m
security_inode_create./runltp -f syscalls -s open -t 5m
ptrace./runltp -f syscalls -s ptrace -t 5m

Key kprobe Handler Testing Result(90s)

hook function nameAverage Delay(us)TP99(us)TP95(us)TP90(us)
connect_syscall_handler0.74543.50171.9041.43
connect_syscall_entry_handler0.06750.30.1630.1149
udp_recvmsg_handler9.129068.704318.535715.9528
udp_recvmsg_entry_handler0.58827.56310.78110.3665
bind_handler2.255810.05258.19967.041
bind_entry_handler0.47041.01800.82340.6739
execve_entry_handler6.926212.28249.4378.638
execve_handler15.210236.090325.927223.068
security_inode_create_pre_handler1.55237.94545.58063.1441
ptrace_pre_handler0.20390.46480.2540.228

udp_recvmsg_handler 仅工作在端口为 53 或 5353 的情况

测试原始数据: Benchmark Data

关于部署

可以使用 DKMS 或者提前编译好 ko 文件然后进行下发

  • install driver: insmod hids_driver.ko
  • remove driver: first you need kill userspace agent and rmmod hids_driver.ko

已知问题

License

Elkeid kernel module are distributed under the GNU GPLv2 license.

Elkeid RASP

Introduction

  • Analyze the runtime used by the process.
  • The following probes are supported for dynamic attach to process:
    • CPython
    • Golang
    • JVM
    • NodeJS
    • PHP
  • Compatible with Elkeid stack.

Install

  • build manually: GUIDE
    1. CMake 3.17+
    2. GCC 8+
    3. MUSL toolcahin 1.2.2 (download via CDN: link)
    4. RUST toolchain 1.40+
    5. JDK 11+(for Java probe)
    6. Python2 + Python3 + pip + wheel + header files (for python probe)
    7. PHP header files
    8. make and install
git submodule update --recursive --init

make -j$(nproc) build \
    STATIC=TRUE \
    PY_PREBUILT=TRUE \
    CC=/opt/x86_64-linux-musl-1.2.2/bin/x86_64-linux-musl-gcc \
    CXX=/opt/x86_64-linux-musl-1.2.2/bin/x86_64-linux-musl-g++ \
    LD=/opt/x86_64-linux-musl-1.2.2/bin/x86_64-linux-musl-ld \
    CARGO_TARGET_X86_64_UNKNOWN_LINUX_MUSL_LINKER=/opt/x86_64-linux-musl-1.2.2/bin/x86_64-linux-musl-ld \
    GNU_CC=/opt/gcc-10.4.0/bin/gcc \
    GNU_CXX=/opt/gcc-10.4.0/bin/g++ \
    PHP_HEADERS=/path/to/php-headers \
    PYTHON2_INCLUDE=/path/to/include/python2.7 \
    PYTHON3_INCLUDE=/path/to/include/python3 \
    VERSION=0.0.0.1

sudo make install
  • build with docker:
curl -fsSL https://lf3-static.bytednsdoc.com/obj/eden-cn/laahweh7uhwbps/php-headers.tar.gz | tar -xz -C rasp/php

docker run --rm -v $(pwd):/Elkeid \
    -v /tmp/cache/gradle:/root/.gradle \
    -v /tmp/cache/librasp:/Elkeid/rasp/librasp/target \
    -v /tmp/cache/rasp_server:/Elkeid/rasp/rasp_server/target \
    -v /tmp/cache/plugin:/Elkeid/rasp/plugin/target \
    -e MAKEFLAGS="-j$(nproc)" hackerl/rasp-toolchain \
    make -C /Elkeid/rasp build \
    STATIC=TRUE \
    PY_PREBUILT=TRUE \
    CC=/opt/x86_64-linux-musl-1.2.2/bin/x86_64-linux-musl-gcc \
    CXX=/opt/x86_64-linux-musl-1.2.2/bin/x86_64-linux-musl-g++ \
    LD=/opt/x86_64-linux-musl-1.2.2/bin/x86_64-linux-musl-ld \
    CARGO_TARGET_X86_64_UNKNOWN_LINUX_MUSL_LINKER=/opt/x86_64-linux-musl-1.2.2/bin/x86_64-linux-musl-ld \
    GNU_CC=/opt/gcc-10.4.0/bin/gcc GNU_CXX=/opt/gcc-10.4.0/bin/g++ \
    PHP_HEADERS=/Elkeid/rasp/php/php-headers \
    PYTHON2_INCLUDE=/usr/local/include/python2.7 \
    PYTHON3_INCLUDE=/usr/local/include/python3 \
    VERSION=0.0.0.1

Run

  • for single process inject
sudo env RUST_LOG=<loglevel> /etc/elkeid/plugin/RASP/elkeid_rasp -p <pid>
  • with Elkied Agent (multi target)

Documentation is being written.

License

Elkeid RASP are distributed under the Apache-2.0 license.

License Project Status: Active – The project has reached a stable, usable state and is being actively developed.

关于 Elkeid Agent

Agent提供端上组件的基本能力支撑,包括数据通信、资源监控、组件版本控制、文件传输、机器基础信息采集等。

Agent本身不提供安全能力,作为一个插件底座以系统服务的方式运行。各类功能插件的策略存放于服务器端的配置,Agent接收到相应的控制指令及配置后对自身及插件进行开启、关闭、升级等操作。

Agent与Server之间采用bi-stream gRPC进行通信,基于自签名证书开启双向TLS验证,保障信道安全。其中,Agent -> Server 方向信息流动称为数据流,Server -> Agent 方向信息流动一般为控制流,使用protobuf的不同message类型。Agent本身支持客户端侧服务发现,也支持跨Region级别的通信配置,实现一个Agent包在多个网络隔离的环境下进行安装,基于底层一个TCP连接,在上层实现了Transfer与FileOp两种数据传输服务,支撑了插件本身的数据上报与Host中的文件交互。

Plugins作为安全能力插件,与Agent的进程关系一般为“父——子”进程。以两个pipe作为跨进程通信方式,plugins lib提供了Go与Rust的两个插件库,负责插件端信息的编码与发送。值得一提的是,插件发送数据后,会被编码为Protobuf二进制数据,Agent接收到后无需二次解编码,再其外层拼接好Header特征数据,直接传输给Server,一般情况下Server也无需解码,直接传输至后续数据流中,使用时进行解码,一定程度上降低了数据传输中多次编解码造成的额外性能开销。

Agent采用Go实现,在Linux下,通过systemd作为守护方式,受cgroup限制控制资源使用,支持aarch64与x86-64架构,最终编译、打包为deb与rpm包分发,格式均符合systemd及Debian、RHEL规范,可以直接提供至对应的软件仓库中进行后续版本维护。在后续版本中,将会发布用于Windows平台下的Agent。

运行时要求

Agent及Plugin提供的大部分功能需要以root权限运行在宿主机(Host)层面,在权限受限的容器中,部分功能可能会存在异常。

快速开始

通过 elkeidup 的完整部署,可以直接得到用于Debian/RHEL系列发行版的安装包,并按照 Elkeid Console - 安装配置 界面的命令进行安装部署。

手动编译

环境要求

  • Go >= 1.18
  • nFPM
  • 成功部署的 Server (包含所有组件)

确认相关配置

  • 需要确保 transport/connection 目录下的 ca.crtclient.keyclient.crt 三个文件与Agent Center conf 目录下的同名文件保持一致。
  • 需要确保 transport/connection/product.go 文件中的参数都配置妥当:
    • 如果是手动部署的Server:
      • serviceDiscoveryHost["default"] 需被赋值为 ServiceDiscovery 服务或代理服务的内网监听地址与端口,例如:serviceDiscoveryHost["default"] = "192.168.0.1:8088"
      • privateHost["default"] 需被赋值为 AgentCenter 服务或代理服务的内网监听地址与端口,例如:privateHost["default"] = "192.168.0.1:6751"
      • 如有Server的公网接入点,publicHost["default"] 需被赋值为 AgentCenter 服务或代理服务的外网监听地址与端口,例如:publicHost["default"]="203.0.113.1:6751"
    • 如果是通过 elkeidup 部署的Server,可以根据部署Server机器的 ~/.elkeidup/elkeidup_config.yaml 文件获得对应配置:
      • 在配置文件中找到 Nginx 服务的IP,具体的配置项为 nginx.sshhost[0].host
      • 在配置文件中找到 ServiceDiscovery 服务的IP,具体的配置项为 sd.sshhost[0].host
      • serviceDiscoveryHost["default"] 需被赋值为 ServiceDiscovery 服务的IP,并将端口号设置为8088,例如:serviceDiscoveryHost["default"] = "192.168.0.1:8088"
      • privateHost["default"] 需被赋值为 Nginx 服务的IP,并将端口号设置为8090,例如:privateHost["default"] = "192.168.0.1:8090"

编译

在Agent根目录,执行:

BUILD_VERSION=1.7.0.24 bash build.sh

在编译过程中,脚本会读取 BUILD_VERSION 环境变量设置版本信息,可根据实际需要进行修改。

编译成功后,在根目录的 output 目录下,应该可以看到2个deb与2个rpm文件,它们分别对应不同的系统架构。

版本升级

  1. 如果没有创建过客户端类型的组件,请在 Elkeid Console-组件管理 界面新建对应组件。
  2. Elkeid Console - 组件管理 界面,找到“elkeid-agent”条目,点击右侧“发布版本”,填写版本信息并上传对应平台与架构的文件,点击确认。
  3. Elkeid Console - 组件策略 界面,(如有)删除旧的“elkeid-agent”版本策略,点击“新建策略”,选中刚刚发布的版本,点击确认。后续新安装的Agent均会自升级到最新版本。
  4. Elkeid Console - 任务管理 界面,点击“新建任务”,选择全部主机,点击下一步,选择“同步配置”任务类型,点击确认。随后,在此页面找到刚刚创建的任务,点击运行,即可对存量旧版本Agent进行升级。

License

Elkeid Agent is distributed under the Apache-2.0 license.

Baseline

基线插件通过已有或自定义的基线策略对资产进行检测,来判断资产上的基线安全配置是否存在风险。基线插件每天定时扫描一次,同时也可以通过前端进行立即检查。

平台兼容性

  • centos 6,7,8
  • debian 8,9,10
  • ubuntu 14.04-20.04
    (其余版本以及发行版理论兼容)

需要的编译环境

  • Go >= 1.18

编译

rm -rf output
mkdir output
# x86_64
go build -o baseline main.go
tar -zcvf baseline-linux-x86_64.tar.gz baseline config
mv baseline-linux-x86_64.tar.gz output/
# arch64
GOARCH=arm64 go build -o baseline main.go
tar -zcvf baseline-linux-x86_64.tar.gz baseline config
mv baseline-linux-x86_64.tar.gz output/

编译成功后,在根目录的 output 目录下,应该可以看到2个deb与2个rpm文件,它们分别对应不同的系统架构。

版本升级

  1. 如果没有创建过客户端类型的组件,请在 Elkeid Console-组件管理 界面新建对应组件。
  2. Elkeid Console - 组件管理 界面,找到“collector”条目,点击右侧“发布版本”,填写版本信息并上传对应平台与架构的文件,点击确认。
  3. Elkeid Console - 组件策略 界面,(如有)删除旧的“collector”版本策略,点击“新建策略”,选中刚刚发布的版本,点击确认。后续新安装的Agent的插件均会自升级到最新版本。
  4. Elkeid Console - 任务管理 界面,点击“新建任务”,选择全部主机,点击下一步,选择“同步配置”任务类型,点击确认。随后,在此页面找到刚刚创建的任务,点击运行,即可对存量旧版本插件进行升级。

基线配置

常规配置

基线插件的规则通过yaml文件配置,其中主要包括以下字段(建议参照config文件下实际配置对比):

check_id: 检查项id(int)
type: "类型(英文)"
title: "标题(英文)"
description: "描述(英文)"
solution: "解决方案(英文)"
security: "安全等级(high/mid/low)"
type_cn: "类型"
title_cn: "标题"
description_cn: "描述"
solution_cn: "解决方案"
check: # 检查规则(详见自定义规则)
    rules:
    - type: "file_line_check"
        param:
        - "/etc/login.defs"
        filter: '\s*\t*PASS_MAX_DAYS\s*\t*(\d+)'
        result: '$(<=)90'

自定义规则

每个检查项配置中的"check.rules"字段即为匹配规则,下边对每个字段进行解释:

rules.type

检查方式,目前baseline插件适配的内置检测规则(src/check/rules.go)包括如下几种:
| 检测规则 | 含义 | 参数 | 返回值 | | ---- | ---- | ---- | ---- | | command_check | 运行命令行语句 | 1:命令行语句
2:特殊参数(如ignore_exit 认为当命令行报错时认为通过检测) | 命令运行结果 | file_line_check | 遍历文件,逐行匹配 | 1:文件绝对路径
2:该行的flag(用于快速筛选行,减轻正则匹配的压力)
3:该文件的注释符(默认为#) | true/false/正则筛选值 | file_permission | 检测文件权限是否符合安全配置 | 1: 文件绝对路径
2: 文件最小权限(基于8进制,如644) | true/false | if_file_exist | 判断文件是否存在 | 1: 文件绝对路径 | true/false | file_user_group | 判断文件用户组 | 1: 文件绝对路径
2: 用户组id | true/false | file_md5_check | 判断文件MD5是否一致 | 1: 文件绝对路径
2: MD5 | true/false | func_check | 通过特殊基线规则判断 | 1: 目标规则 | true/false

rules.param

规则参数数组

rules.require

规则前提条件:一些安全基线配置可能会存在检测前提条件,如果满足了先决条件后才会存在安全隐患,如:

rules:
  - type: "file_line_check"
    require: "allow_ssh_passwd"
    param:
        - "/etc/ssh/sshd_config"
    filter: '^\s*MaxAuthTries\s*\t*(\d+)'
    result: '$(<)5'

allow_ssh_passwd: 允许用户通过ssh密码登录

rules.result

检测结果,支持int,string,bool类型结果, 其中被*$()*为特殊检测语法,以下为部分语法示例: | 检测语法 | 说明 | 示例 | 示例含义 | | ---- | ---- | ---- | ---- | | $(&&) | 包含条件 | ok$(&&)success| 结果为ok或success | | $(<=) | 常见运算符 | $(<=)4| 结果小于等于4 | | $(not) | 结果取反 | $(not)error| 结果不为error |

复杂示例:

$(<)8$(&&)$(not)2  :  目标小于8且目标不为2

check.condition

由于规则的rule可能存在多个,因此可以通过condition字段定义规则之间的关系
all: 全部规则命中,则通过检测
any: 任一规则命中,则通过检测
none: 无规则命中,则通过检测

下发任务

任务下发

{
    "baseline_id": 1200, // 基线id
    "check_id_list":[1,2,3] // 扫描检查项列表(空列表为全部扫描)
}

结果回传

{
    "baseline_id": 1200,    // 基线id
    "status": "success",    // 检测状态success|error
    "msg": "",  // 错误原因
    "check_list":[
        "check_id": 1,  // 检查项id
        "type": "",     // 类型(英文)
        "title": "",   // 检查项标题(英文)
        "description": "",  // 检查项描述(英文)
        "solution": "",     // 解决方案(英文)
        "type_cn": "",     // 类型
        "title_cn": "",     // 检查项标题
        "description_cn": "",   // 检查项描述
        "solution_cn": "",  // 解决方案
        "result": "",   // 检查结果
        "msg": "",   // 错误原因
    ]
}

检查结果:

SuccessCode 		= 1  // 成功
FailCode 		= 2  // 失败
ErrorCode 		= -1 // 其他错误
ErrorConfigWrite	= -2 // 配置编写不规范
ErrorFile		= -3 // 文件读写异常

License Project Status: Active – The project has reached a stable, usable state and is being actively developed.

关于collector插件

collector周期性采集主机上的各类资产信息,并进行关联分析,目前支持以下资产类型:

  • 进程:支持对exe md5的哈希计算,后续可关联威胁情报分析,另外与容器信息进行关联,支撑后续数据溯源功能。(跨容器)
  • 端口:支持tcp、udp监听端口的信息提取,以及与进程、容器信息的关联上报。另外基于sock状态及其关系,分析对外暴露服务,向上支撑主机暴露面分析功能。(跨容器)
  • 账户:除了基本的账户字段外,基于弱口令字典进行端上hash碰撞检测弱口令,向上提供了Console的弱口令基线检测功能。另外,会关联分析sudoers配置,一同上报。
  • 软件:支持系统软件包、pypi包、jar包,向上支撑漏洞扫描功能。(部分跨容器)
  • 容器:支持docker、cri/containerd等多种运行时下的容器信息采集。
  • 应用:支持数据库、消息队列、容器组件、Web服务、DevOps工具等类型的应用采集、目前支持30+中常见应用的版本、配置文件的匹配与提取。(跨容器)
  • 硬件:支持网卡、磁盘等硬件信息的采集。
  • 系统完整性校验:通过将软件包文件哈希与Host实际文件哈希进行对比,判断文件是否有被更改。
  • 内核模块:采集基本字段,以及内存地址、依赖关系等额外字段。
  • 系统服务、定时任务:兼容不同发行版下的服务及cron位置的定义,并对核心字段进行解析。

运行时要求

支持主流的Linux发行版,包括CentOS、RHEL、Debian、Ubuntu、RockyLinux、OpenSUSE等。支持x86-64与aarch64架构。

快速开始

通过 elkeidup 的完整部署,此插件默认开启。

手动编译

环境要求

  • Go >= 1.18

编译

在Agent根目录,执行:

BUILD_VERSION=1.7.0.140 bash build.sh

在编译过程中,脚本会读取 BUILD_VERSION 环境变量设置版本信息,可根据实际需要进行修改。

编译成功后,在根目录的 output 目录下,应该可以看到2个deb与2个rpm文件,它们分别对应不同的系统架构。

版本升级

  1. 如果没有创建过客户端类型的组件,请在 Elkeid Console-组件管理 界面新建对应组件。
  2. Elkeid Console - 组件管理 界面,找到“collector”条目,点击右侧“发布版本”,填写版本信息并上传对应平台与架构的文件,点击确认。
  3. Elkeid Console - 组件策略 界面,(如有)删除旧的“collector”版本策略,点击“新建策略”,选中刚刚发布的版本,点击确认。后续新安装的Agent的插件均会自升级到最新版本。
  4. Elkeid Console - 任务管理 界面,点击“新建任务”,选择全部主机,点击下一步,选择“同步配置”任务类型,点击确认。随后,在此页面找到刚刚创建的任务,点击运行,即可对存量旧版本插件进行升级。

License

collector is distributed under the Apache-2.0 license.

关于driver插件

driver 插件对 内核模块 进行管理,并利用用户态数据进行补充、过滤,最终生成不同的系统事件,支撑相关告警功能。

运行时要求

支持主流的Linux发行版,包括CentOS、RHEL、Debian、Ubuntu、RockyLinux、OpenSUSE等。支持x86-64与aarch64架构。

主机的内核版本需要在支持的的列表中,如果不在,需要单独编译并上传,详见 说明

快速开始

通过 elkeidup 的完整部署,此插件默认开启。

手动编译

环境要求

确认相关配置

  • 需要确保 src/config.rsDOWNLOAD_HOSTS 变量已配置为实际部署的Nginx服务地址:
    • 如果是手动部署的Server:需要确保将其配置为Nginx文件服务的地址,例如:pub const DOWNLOAD_HOSTS: &'static [&'static str] = &["http://192.168.0.1:8080"];
    • 如果是通过 elkeidup 部署的Server,可以根据部署Server机器的 ~/.elkeidup/elkeidup_config.yaml 文件获得对应配置,具体配置项为 nginx.sshhost[0].host,并将端口号设置为8080,例如:pub const DOWNLOAD_HOSTS: &'static [&'static str] = &["http://192.168.0.1:8080"];

编译

在根目录,执行:

BUILD_VERSION=1.0.0.15 bash build.sh

在编译过程中,脚本会读取 BUILD_VERSION 环境变量设置版本信息,可根据实际需要进行修改。

编译成功后,在根目录的 output 目录下,应该可以看到2个plg文件,它们分别对应不同的系统架构。

版本升级

  1. 如果没有创建过客户端类型的组件,请在 Elkeid Console-组件管理 界面新建对应组件。
  2. Elkeid Console - 组件管理 界面,找到“collector”条目,点击右侧“发布版本”,填写版本信息并上传对应平台与架构的文件,点击确认。
  3. Elkeid Console - 组件策略 界面,(如有)删除旧的“collector”版本策略,点击“新建策略”,选中刚刚发布的版本,点击确认。后续新安装的Agent的插件均会自升级到最新版本。
  4. Elkeid Console - 任务管理 界面,点击“新建任务”,选择全部主机,点击下一步,选择“同步配置”任务类型,点击确认。随后,在此页面找到刚刚创建的任务,点击运行,即可对存量旧版本插件进行升级。

License

driver plugin is distributed under the Apache-2.0 license.

关于Journal Watcher插件

Journal Watcher 通过读取 sshd 的日志,并进行解析,生成sshd登陆、gssapi事件。

运行时要求

支持主流的Linux发行版,包括CentOS、RHEL、Debian、Ubuntu、RockyLinux、OpenSUSE等。支持x86-64与aarch64架构。

快速开始

通过 elkeidup 的完整部署,此插件默认开启。

手动编译

环境要求

编译

在根目录,执行:

BUILD_VERSION=1.7.0.23 bash build.sh

在编译过程中,脚本会读取 BUILD_VERSION 环境变量设置版本信息,可根据实际需要进行修改。

编译成功后,在根目录的 output 目录下,应该可以看到2个plg文件,它们分别对应不同的系统架构。

版本升级

  1. 如果没有创建过客户端类型的组件,请在 Elkeid Console-组件管理 界面新建对应组件。
  2. Elkeid Console - 组件管理 界面,找到“collector”条目,点击右侧“发布版本”,填写版本信息并上传对应平台与架构的文件,点击确认。
  3. Elkeid Console - 组件策略 界面,(如有)删除旧的“collector”版本策略,点击“新建策略”,选中刚刚发布的版本,点击确认。后续新安装的Agent的插件均会自升级到最新版本。
  4. Elkeid Console - 任务管理 界面,点击“新建任务”,选择全部主机,点击下一步,选择“同步配置”任务类型,点击确认。随后,在此页面找到刚刚创建的任务,点击运行,即可对存量旧版本插件进行升级。

License

journal_watcher plugin is distributed under the Apache-2.0 license.

Elkeid-Scanner

1. 关于 Scanner 插件

当前版本 1.9.X

Scanner 使用 clamav 引擎对系统进程和敏感目录进行周期扫描,以发现可疑静态文件(UPX/挖矿二进制/后门/木马/可疑脚本文件/...)。

1.1. 平台兼容性

Elkeid Agent相同,目前预编译产物已支持 x86_64、Aarch64。

1.2. Agent/后端 兼容性

向前兼容: 1.7.X、1.8.X

2. 构建

开源版本通过 Github Action 自动构建,完整编译环境与遍历流程可参考对应 Dockerfile。用户可通过 Dockerfile 创建 Docker 自动执行编译步骤。

2.1. Docker 完整docker编译环境 & 编译产物

  • aarch64

    {
        "id_list":[
            "xxxxxxxx"
        ],
        "data":{
            "config":[
                {
                    "name":"scanner",
                    "version":"3.1.9.6",
                    "download_url":[
                        "http://lf3-elkeid.bytetos.com/obj/elkeid-download/plugin/scanner/scanner-default-aarch64-3.1.9.6.tar.gz",
                        "http://lf6-elkeid.bytetos.com/obj/elkeid-download/plugin/scanner/scanner-default-aarch64-3.1.9.6.tar.gz",
                        "http://lf9-elkeid.bytetos.com/obj/elkeid-download/plugin/scanner/scanner-default-aarch64-3.1.9.6.tar.gz",
                        "http://lf26-elkeid.bytetos.com/obj/elkeid-download/plugin/scanner/scanner-default-aarch64-3.1.9.6.tar.gz"
                    ],
                    "type": "tar.gz",
                    "sha256": "d75a5c542a2d7c0900ad96401d65833833232fcf539896ac2d2a95619448850b",
                    "signature": "1089b8fdcb69eac690323b0d092d8386901ded2155a057bf4d044679a2b83a9c",
                    "detail":""
                }
            ]
        }
    }
    
  • x86_64

    {
        "id_list":[
            "xxxxxxxx"
        ],
        "data":{
            "config":[
                {
                    "name":"scanner",
                    "version":"3.1.9.6",
                    "download_url":[
                        "http://lf3-elkeid.bytetos.com/obj/elkeid-download/plugin/scanner/scanner-default-x86_64-3.1.9.6.tar.gz",
                        "http://lf6-elkeid.bytetos.com/obj/elkeid-download/plugin/scanner/scanner-default-x86_64-3.1.9.6.tar.gz",
                        "http://lf9-elkeid.bytetos.com/obj/elkeid-download/plugin/scanner/scanner-default-x86_64-3.1.9.6.tar.gz",
                        "http://lf26-elkeid.bytetos.com/obj/elkeid-download/plugin/scanner/scanner-default-x86_64-3.1.9.6.tar.gz"
                    ],
                    "type": "tar.gz",
                    "sha256": "e17e7380233c64172c767aa7587a9e303b11132e97c0d36a42e450469c852fdf",
                    "signature": "527c6ea0caac3b0604021de5aa2d34e4b9fae715e5e6cdd37e8f485869f923c2",
                    "detail":""
                }
            ]
        }
    }
    

2.2. 编译

# x86_64
docker build -t scanner -f docker/Dockerfile.x86_64 ../../ 
docker create --name scanner scanner
docker cp scanner:/Elkeid/plugins/scanner/output/scanner-x86_64.tar.gz ./
docker rm -f scanner

# aarch64
docker build -t scanner -f docker/Dockerfile.aarch64 ../../ 
docker create --name scanner scanner
docker cp scanner:/Elkeid/plugins/scanner/output/scanner-aarch64.tar.gz ./
docker rm -f scanner

3. 自定义编译配置(可选)

在下列文件中,有一些常量,可根据实际情况进行配置(出于性能考虑,除规则外,建议保持默认)。

3.1. 检控扫描目录配置

  • SCAN_DIR_CONFIG 定义扫描目录,以及递归深度
  • SCAN_DIR_FILTER 定义过滤目录,按照前缀匹配过滤扫描白名单

3.2. 引擎配置

  • CLAMAV_MAX_FILESIZE 定义扫描的文件的最大文件大小,跳过大文件

3.3. 可选 : 1. Clamav Database配置

通过如下 url 获取默认 database(解压密码为 clamav_default_passwd):

wget http://lf26-elkeid.bytetos.com/obj/elkeid-download/18249e0cbe7c6aca231f047cb31d753fa4604434fcb79f484ea477f6009303c3/archive_db_default_20220817.zip

#wget http://lf3-elkeid.bytetos.com/obj/elkeid-download/18249e0cbe7c6aca231f047cb31d753fa4604434fcb79f484ea477f6009303c3/archive_db_default_20220817.zip

#wget http://lf6-elkeid.bytetos.com/obj/elkeid-download/18249e0cbe7c6aca231f047cb31d753fa4604434fcb79f484ea477f6009303c3/archive_db_default_20220817.zip

#wget http://lf9-elkeid.bytetos.com/obj/elkeid-download/18249e0cbe7c6aca231f047cb31d753fa4604434fcb79f484ea477f6009303c3/archive_db_default_20220817.zip

clamav scanner 插件会在启动时,从 TMP_PATH/archive_db_default_XXXX.zip 使用默认密码 ARCHIVE_DB_PWD, 加载本地database 。同时, 从 ARCHIVE_DB_VERSION_FILE 文件中检查 ARCHIVE_DB_VERSION ,并且检查密码 ARCHIVE_DB_PWD.

更过逻辑细节参考代码 src/model/engine/updater.rs

3.4. 可选 : 2. database 中的规则

默认的 database 包括裁剪过的 clamav 官方数据库,以及开源的 yara 规则。

root@hostname$ ls
main.ldb  main.ndb  online_XXXXX.yar

在 debian9+ 或 ubuntu18+的 linux 中,可以通过如下方式,从最新的 clamav 官方数据库中生成裁剪过的 clamav 数据库。

root@hostname$ bash ./db_updater.sh

更多细节参考 clamav 官方文档

  • Notice
    • There are currently a few limitations on using YARA rules within ClamAV

4. 插件任务

scanner 插件任务支持

  • 指定目录扫描
  • 全盘扫描
  • 快速扫描

详情参考Elkeid 前端使用文档

5. 上报数据类型

数据类型6000-扫描任务结束字段含义
1status扫描任务结束状态: failed 失败,succeed 成功
2msg日志
数据类型6001-检出静态文件字段含义
1types检出文件类型
2class恶意样本分类
3name恶意样本家族
4exe检出文件目录
5static_file检出文件目录
6exe_size检出文件 大小
7exe_hash检出文件 32kb xxhash
8md5_hash检出文件 md5 hash
9create_at检出文件 创建时间
10modify_at检出文件 最后修改时间
11hit_datayara命中数据(如果命中了Yara才会有此字段)
12token任务 token(全盘扫描任务才会有此字段)
数据类型6002-检出进程exe字段含义
1typesexe文件类型
2class恶意样本分类
3name恶意样本家族
4exeexe文件目录
5static_fileexe文件目录
6exe_sizeexe文件 大小
7exe_hashexe文件 32kb xxhash
8md5_hashexe文件 md5 hash
9create_atexe文件 创建时间
10modify_atexe文件 最后修改时间
11hit_datayara命中数据(如果命中了Yara才会有此字段)
12pid进程 id
13ppid父进程 id
14pgid进程组 id
15tgid线程组 id
16argv执行命令行
17comm进程名
18sessionidproc/pid/stat/sessionid
19uid用户ID
20pns进程 namespace
21token任务 token(全盘扫描任务才会有此字段)
数据类型6003-目录扫描任务字段含义
1types检出文件类型
2class恶意样本分类
3name恶意样本家族
4exe检出文件目录
5static_file检出文件目录
6exe_size检出文件 大小
7exe_hash检出文件 32kb xxhash
8md5_hash检出文件 md5 hash
9create_at检出文件 创建时间
10modify_at检出文件 最后修改时间
11hit_datayara命中数据(如果命中了Yara才会有此字段)
12token任务 token
13error错误信息 (任务出错时不为空)

6. 已知问题

  • Creation time / birth_time is not available for some filesystems
error: "creation time is not available for the filesystem
  • Centos7 default compile tool-chains didn't work, high version of tool-chains needed.

7. License

Scanner plugin is distributed under the Apache-2.0 license.

RASP plugin

制品形式

  • 包含有 rasp 插件以及各 runtime 探针的 tar.gz 压缩包。
  • 可在 bytedance/Elkeid: release 页面下载最新的制品。

组成

RASP 插件包含以下部件:

├── rasp 插件主入口,由 agent 启动,与 agent 双向通信,与探针双向通信。
├── settings.toml 插件配置文件。
├── elkeid_rasp 仅用于对指定进程进行探针植入与通信使用,数据输出到 stdout。
├── lib-1.9.1.68 包含有各探针的目录,与版本号一致。
│     ├── golang
│     ├── java
│     ├── node
│     ├── pangolin
│     ├── php
│     ├── python
│     └── rasp_server
├── nsenter
└── NSMount

Elkeid HUB

Elkeid HUB 是一款由 Elkeid Team 维护的规则/事件处理引擎,支持流式/离线(社区版尚未支持)数据处理。 初衷是通过标准化的抽象语法/规则来解决复杂的数据/事件处理与外部系统联动需求。

Core Components

  • INPUT 数据输入层,社区版仅支持Kafka
  • RULEENGINE/RULESET 对数据进行检测/外部数据联动/数据处理的核心组件
  • OUTPUT 数据输出层,社区版仅支持Kafka/ES
  • SMITH_DSL 用来描述数据流转关系

Application Scenarios

  • Simple HIDS

  • IDS Like Scenarios

  • Multiple input and output scenarios

Advantages

  • 高性能
  • 依赖极少
  • 支持复杂数据处理
  • 插件支持
  • 支持有状态逻辑
  • 支持外部系统/数据联动

Elkeid Internal Best Practices

  • 使用 Elkeid HUB 处理 Elkeid HIDS/RASP/Sandbox/K8s auditing 等原始数据,TPS 1.2亿条+/秒,HUB 调度实例 6000+

Elkeid-HUB Function List

Ability ListElkeid Community EditionElkeid Enterprise Edition
流式数据处理:white_check_mark::white_check_mark:
数据输入输出能力:white_check_mark::white_check_mark:
完整前端支持:white_check_mark::white_check_mark:
监控能力:white_check_mark::white_check_mark:
插件支持:white_check_mark::white_check_mark:
Debug支持:white_check_mark::white_check_mark:
离线数据处理:ng_man::white_check_mark:
持久化能力:ng_man::white_check_mark:
Workspace:ng_man::white_check_mark:
集群模式:ng_man::white_check_mark:
在线升级策略:ng_man::white_check_mark:

Front-end Display (Community Edition)

Overview

Edit Rule

Edit HUB Project

Edit HUB Python Plugin

Submission Rules

Getting Started

Elkeid HUB Handbook

Handbook

Demo Config

Demo

Elkeid HIDS Rule and Project (Just Example)

Elkeid Project

(Need to use with Elkeid)

LICENSE (Not Business Friendly)

LICENSE

Contact us && Cooperation

Elkeid HUB 社区版使用指南

适用版本

Elkeid HUB 社区版

1 概述

Elkeid Hub 是为了解决各领域内的 数据上报-实时流处理与事件处理 中的 实时处理 的需求而诞生的产品,适用于如信息安全领域中的入侵检测/事件处理与编排等场景。

2 Elkeid HUB 优势

  • 高性能,且支持分布式横行扩展
  • 策略编写简单易懂,相关同学只需专注数据处理本身且学习成本很低
  • 支持插件,可以更好的处理复杂需求
  • 部署简单,依赖少

3 Elkeid HUB 组件概述

Elkeid HUB 组件主要分为一下几种:

  • Input:数据通过Input组件消费后进入到Elkeid HUB,目前支持Kafka
  • Output:数据通过Output组件将Elkeid HUB中流转的数据推送到HUB之外,目前支持ES/Kafka
  • RuleSet:数据处理的核心逻辑将通过RuleSet编写,如检测(支持正则,多模匹配,频率等多种检测方式)/白名单/调用Plugin
  • Plugin:用户可以自定义任意检测/响应逻辑,来满足一些复杂场景的需求,如发送告警到钉钉/飞书;与CMDB联动进行数据补充;联动Redis进行一些缓存处理等。编写完成后可以在RuleSet中调用这些插件
  • Project:通过Project来构建一组Elkeid HUB逻辑,通常是由一个Input+一个或多个RuleSet+一个或多个Output组成

4 Elkeid Input/输入源

4.1 Input配置建议

  • 输入源目前仅支持Kafka作为数据输入源,数据格式支持Json任意字符分割的日志两种。
  • 数据源类型建议:
    • 其他安全产品的告警日志,HUB可以有效的对其进行二次处理,如联动其他基础组件做到对告警数据的缺失部分弥补,也可以通过自定义Action(规则引擎支持)来实现对告警进行自动化处理已完成告警-处置的闭环操作
    • 基础日志,如HTTP镜像流量/Access日志/HIDS数据等。通过规则引擎,联动模块和异常检测模块对原始数据进行安全分析/入侵检测/自动化防御等操作
    • 审计日志,如:登陆,原始的SQL请求,敏感操作等日志。HUB可以对其进行自定义的审计功能

4.2 Input配置说明

配置字段:

字段说明
InputID不可重复,描述一个input,只能英文+"_/-"+数字组成
InputName描述该input的name,可以重复,可以使用中文
InputType目前只支持Kafka
DataTypejson/protobuf/custom/grok
KafkaBootstrapServersKafkaBootstrapServers,IP:PORT,使用,分割
KafkaGroupId消费时使用的GroupID
KafkaOffsetResetearliest或latest
KafkaCompressionkafka内数据压缩算法
KafkaWorkerSize并发消费数
KafkaOtherConf支持其他配置,具体配置见:https://github.com/edenhill/librdkafka/blob/master/CONFIGURATION.md
KafkaTopics消费Topic,支持多Topic
GrokPatternDataType为grok时有意义,数据会根据GrokPattern来解析并向后传递
DataPatternDataType为custom时有意义,描述数据格式
SeparatorDataType为custom时有意义,分割数据所用符号
以上全部字段均为必填项

配置举例(DataType: json):

InputID: wafdeny
InputName: wafdeny
InputType: kafka
DataType: json
TTL: 30
KafkaBootstrapServers: secmq1.xxx.com:9092,secmq2.xxx.com:9092,secmq3.xxx.com:9092,secmq4.xxx.com:9092
KafkaGroupId: smith-hub
KafkaOffsetReset: latest
KafkaCompression: none
KafkaWorkerSize: 3
KafkaOtherConf: ~

KafkaTopics:
  - wafdeny

5 Elkeid Output/输出

5.1 Output配置建议

目前默认HUB的默认策略报警不走Output,使用插件直接与Manager交互写入数据库,如果需要配置原始告警可以考虑配置Output

由于HUB是一款流数据处理工具,不具备存储能力,建议配置数据存储的输出源,如ES、Hadoop、SOC、SIEM等平台。目前支持的Output类型有:

  • Kafka
  • Elasticsearch

5.2 Output配置说明

配置字段:

字段说明
OutputID不可重复,描述一个output,只能英文+"_/-"+数字组成
OutputName描述该output的name,可以重复,可以使用中文
OutputTypees或kafka
AddTimestamptrue或false,开启后还在最终结果处新增timestamp字段并附上时间戳(如果已有该字段会覆盖)格式为:2021-07-05T11:48:14Z
KafkaBootstrapServersOutputType为kafka时有意义
KafkaTopicsOutputType为kafka时有意义
KafkaOtherConfOutputType为kafka时有意义
ESHostOutputType为es时有意义,支持数组
ESIndexOutputType为kafka时有意义
配置举例(es):
OutputID: es_abnormal_dbcloud_task
OutputName: es_abnormal_dbcloud_task
OutputType: es
ESHost:
  - http://10.6.24.60:9200
ESIndex: abnormal_dbcloud_task

配置举例(kafka):

OutputID: dc_sqlhunter
OutputName: dc_sqlhunter
OutputType: kafka
KafkaBootstrapServers: 10.6.210.112:9092,10.6.210.113:9092,10.6.210.126:9092
KafkaTopics: mysqlaudit_alert
KafkaOtherConf: ~

6 Elkeid HUB RuleSet/规则集

RuleSet是HUB实现核心检测/响应动作的部分,需要根据具体业务需求来实现,下图是RuleSet在HUB中的简单工作流程:

6.1 RuleSet

HUB RuleSet是通过XML来描述的规则集

RuleSet存在两种类型,rulewhitelist,如下:

<root ruleset_id="test1" ruleset_name="test1" type="C">
... ....
</root>
<root ruleset_id="test2" ruleset_name="test2" type="rule" undetected_discard="true">
... ...
</root>

其中RuleSet的是固定的模式,不可随意变更,其他属性:

字段说明
ruleset_id不可重复,描述一个ruleset,只能英文+"_/-"+数字组成
ruleset_name描述该ruleset的name,可以重复,可以使用中文
type为rule或者whitelist,其中rule代表着的检测到继续向后传递,whitelist则为检测到不向后传递;向后传递的概念可以简单的理解为该ruleset的检出事件
undetected_discard仅在rule为rule时有意义,意为未检测到是否丢弃,若为true,则未被该ruleset检测到则丢弃,若为false,则为未被该rulset检测到也继续向后传递

6.2 Rule

接下来我们来了解rule的具体语法,通常ruleset是由一个或多个rule组成的,需要注意的是多个rule之间的关系是'或'的关系,即如果一条数据可以命中其中的一条或多条rule。

<root ruleset_id="test2" ruleset_name="test2" type="rule" undetected_discard="true">

    <rule rule_id="rule_xxx_1" author="xxx" type="Detection">
        ... ...
    </rule>

    <rule rule_id="rule_xxx_2" author="xxx" type="Frequency">
        ... ...
    </rule>

</root>

一个rule的基本属性有:

字段说明
rule_id在同一个ruleset中不可重复,标识一个rule
author标识rule的作者
typerule有两种类型,一种是Detection,是无状态的检测类型规则;另一种是Frequency,是在Detection的基础上对数据流进行频率的相关检测

我们先来看两种不同类型规则的简单示例。

我们先假设从Input传入到Ruleset的数据样例为:

{
    "data_type":"59",
    "exe":"/usr/bin/nmap",
    "uid":"0"
}

6.2.1 Detection 简单例子

<rule rule_id="detection_test_1" author="EBwill" type="Detection">
   <rule_name>detection_test_1</rule_name>
   <alert_data>True</alert_data>
   <harm_level>high</harm_level>
   <desc affected_target="test">这是一个Detection的测试</desc>
   <filter part="data_type">59</filter>
   <check_list>
       <check_node type="INCL" part="exe">nmap</check_node>
   </check_list>
</rule>

其中detection_test_1这个规则的意义是:当有数据的data_type为59,且exe中存在nmap的时候,数据继续向后传递。

6.2.2 Frequency 简单例子

<rule rule_id="frequency_test_1" author="EBwill" type="Frequency">
   <rule_name> frequency_test_1 </rule_name>
   <alert_data>True</alert_data>
   <harm_level>high</harm_level>
   <desc affected_target="test">这是一个Frequency的测试</desc>
   <filter part="data_type">59</filter>
   <check_list>
       <check_node type="INCL" part="exe">nmap</check_node>
   </check_list>
   <node_designate>
       <node part="uid"/>
   </node_designate>
   <threshold range="30" local_cache="true">10</threshold>
</rule>

其中frequency_test_1这个规则的意义是:当有数据的data_type为59,且exe中存在nmap的时候,进入到频率检测:当同一个uid,在30秒内出现了 >= 10以上行为则告警,且在这过程中使用当前HUB实例自身缓存。

我们可以看到,实际上Frequency只是比Detection多了node_designate以及threshold字段,也就是说,无论什么规则,都会需有最基础的一些字段,我们接下来就先来了解这些通用的基础字段。

6.2.3 通用字段描述

字段说明
rule_name代表rule的名字,与rule_id不同的是可以使用中文或其他方式来更好的表达rule的含义,可以重复
alert_data为True或False,如果为True,则会将该rule的基础信息增加到当前的数据中向后传递;若为False,则不会将该rule的信息增加到当前的数据中
harm_level表达该rule的危险等级,可以为 info/low/a/high/critical
desc用于提供这个rule本身的描述,其中affected_target是该rule针对的组件信息,用户自行填写,并无强制规定限制

filter

对数据的第一层过滤,part表示对数据中的哪个字段进行过滤,具体内容为检测内容,义为part中是否存在 检测数据,如果RuleSet的类型为rule存在则继续向下执行rule的逻辑,如果不存在则不向下检测;RuleSet类型为whitelist时则相反,即存在则跳过检测,不存在则继续。

filter只能存在一个,且默认也仅支持“存在”的逻辑检测

check_listcheck_list内可以存在0或多个check_node,一个rule只能存在一个check_list,其中check_node的逻辑为'且'即为'and',如果RuleSet的类型为rule则需要其中check_node全部通过才可以继续向下,如果为whitelist则相反,即其中check_node全部不通过才可以继续向下
check_nodecheck_node是一个具体的检测项

6.2.4 alert_data

我们依然以上面的Decetion的例子为例:

待检测数据:

{
    "data_type":"59",
    "exe":"/usr/bin/nmap",
    "uid":"0"
}

RuleSet:

<root ruleset_id="test2" ruleset_name="test2" type="rule" undetected_discard="true">
<rule rule_id="detection_test_1" author="EBwill" type="Detection">
   <rule_name>detection_test_1</rule_name>
   <alert_data>True</alert_data>
   <harm_level>high</harm_level>
   <desc affected_target="test">这是一个Detection的测试</desc>
   <filter part="data_type">59</filter>
   <check_list>
       <check_node type="INCL" part="exe">nmap</check_node>
   </check_list>
</rule>
</root>

如果其中alert_data为True,则该RuleSet会向后传递以下数据,会增加SMITH_ALERT_DATA字段,其中包括HIT_DATA用来描述命中规则的详情,以及RULE_INFO即规则本身的基本信息:

{
    "SMITH_ALERT_DATA":{
        "HIT_DATA":[
            "test2 exe:[INCL]: nmap"
        ],
        "RULE_INFO":{
            "AffectedTarget":"all",
            "Author":"EBwill",
            "Desc":"这是一个Detection的测试",
            "DesignateNode":null,
            "FreqCountField":"",
            "FreqCountType":"",
            "FreqHitReset":false,
            "FreqRange":0,
            "HarmLevel":"high",
            "RuleID":"test2",
            "RuleName":"detection_test_1",
            "RuleType":"Detection",
            "Threshold":""
        }
    },
    "data_type":"59",
    "exe":"/usr/bin/nmap",
    "uid":"0"
}

alert_data为False,则会向后传递以下数据,即原始数据:

{
    "data_type":"59",
    "exe":"/usr/bin/nmap",
    "uid":"0"
}

6.2.5 check_node

check_node的基本结构如下:

<check_node type="检测类型" part="待检测路径">
   检测内容
</check_node>
6.2.5.1 检测类型

目前支持以下几种检测类型:

类型说明
END待检测路径中的内容 以 检测内容 结尾
NCS_END待检测路径中的内容 以 检测内容 结尾,大小写不敏感
START待检测路径中的内容 以 检测内容 开头
NCS_START待检测路径中的内容 以 检测内容 开头,大小写不敏感
NEND待检测路径中的内容 不以 检测内容 结尾
NCS_NEND待检测路径中的内容 不以 检测内容 结尾,大小写不敏感
NSTART待检测路径中的内容 不以 检测内容 开头
NCS_NSTART待检测路径中的内容 不以 检测内容 开头,大小写不敏感
INCL待检测路径中的内容 存在 检测内容
NCS_INCL待检测路径中的内容 存在 检测内容,大小写不敏感
NI待检测路径中的内容 不存在 检测内容
NCS_NI待检测路径中的内容 不存在 检测内容,大小写不敏感
MT待检测路径中的内容 大于 检测内容
LT待检测路径中的内容 小于 检测内容
REGEX对 待检测路径中的内容 进行 检测内容 的正则匹配
ISNULL待检测路径中的内容 为空
NOTNULL待检测路径中的内容 不为空
EQU待检测路径中的内容 等于 检测内容
NCS_EQU待检测路径中的内容 等于 检测内容,大小写不敏感
NEQ待检测路径中的内容 不等于 检测内容
NCS_NEQ待检测路径中的内容 不等于 检测内容,大小写不敏感
CUSTOM针对 待检测路径中的内容 进行 检测内容 指定的 自定义插件检测
CUSTOM_ALLDATA针对 待检测数据 进行 检测内容 指定的 自定义插件检测;该方式下part可以为空,因为不依赖该字段,是将整个数据传递到插件进行检测
我们接下来说明下part的使用方法,该方法与filter的part使用方法一致。
6.2.5.2 part

假设待检测数据为:

{
    "data":{
        "name":"EBwill",
        "number":100,
        "list":[
            "a1",
            "a2"
        ]
    },
    "class.id":"E-19"
}

对应的part描述方式如下:

data               =       "{\"name\":\"EBwill\",\"number\":100,\"list\":[\"a1\",\"a2\"]
data.name          =       "EBwill"
data.number        =       "100"
data.list.#_0      =       "a1"
data.list.#_1      =       "a2"
class\.id          =       "E-19"

需要注意的是如果待检测key中存在"."需要用""转义

6.2.5.3 高级用法之check_data_type

假设待检测数据为

{
    "stdin":"/dev/pts/1",
    "stdout":"/dev/pts/1"
}

假设我们需要检测 stdin 等于 stdout,即我们的检测内容来源于待检测数据,那么我们需要使用check_data_type="from_ori_data" 来重新定义检测内容的来源是来自于待检测数据而不是填写的内容,如下:

<check_node type="EQU" part="stdin" check_data_type="from_ori_data">stdout</check_node>
6.2.5.4 高级用法之logic_type

假设待检测数据为

{
    "data":"test1 test2 test3",
    "size": 96,
}

当我们需要检测data中是否存在 test1 或 test2 的时候,我们可以写正则来实现,也可以通过定义logic_type来实现check_node支持"AND"或者"OR"逻辑,如下:

<!-- data中存在test1 或 test2 -->
<check_node type="INCL" part="data" logic_type="or" separator="|">
    <![CDATA[test1|test2]]>
</check_node>

<!-- data中存在test1 和 test2 -->
<check_node type="INCL" part="data" logic_type="and" separator="|">
    <![CDATA[test1|test2]]>
</check_node>

其中logic_type用来描述逻辑类型,支持"and"和"or",separator用于自定义标识切割检测数据的方式

6.2.5.5 高级用法之foreach

当我们需要对数组有较复杂的检测时可能可以通过foreach来解决。

假设待检测数据为

{
    "data_type":"12",
    "data":[
        {
            "name":"a",
            "id":"14"
        },
        {
            "name":"b",
            "id":"98"
        },
        {
            "name":"c",
            "id":"176"
        },
        {
            "name":"d",
            "id":"172"
        }
    ]
}

我们想将id > 100且顶层的data_type等于12的数据的obj筛选出来,那么可以先通过foreach进行遍历,然后再对遍历后的数据进行判断,如下:

<check_list foreach="d in data">
    <check_node type="MT" part="d.id">100</check_node>
    <check_node type="EQU" part="data_type">12</check_node>
</check_list>

则会向后传递多条数据:

{
    "data_type":"12",
    "data":[
        {
            "name":"c",
            "id":"176"
        }
    ]
}

以及

{
    "data_type":"12",
    "data":[
        {
            "name":"d",
            "id":"172"
        }
    ]
}

我们通过下图来更好的理解foreach这个高级用法

假设待检测数据为

{
    "data_type":"12",
    "data":[
        1,
        2,
        3,
        4,
        5,
        6,
        7
    ]
}

我们想筛选出data中小于5的数据,那么需要这样编写:

<check_list foreach="d in data">
    <check_node type="LT" part="d">5</check_node>
</check_list>
6.2.5.6 高级用法之cep

默认情况下,checknode之间的关系and,满足所有checknode的检测条件时,数据才会检出,当需要自定义checknode之间的关系时,可以使用cep来解决。

假设待检测数据为

{
    "data_type":"12",
    "comm":"ETNET",
    "node_name":"p23",
    "exe":"bash",
    "argv":"bash"
}

我们希望将node_name等于p23或comm等于ETNET,且exe 和 argv 等于bash ,这样的数据过滤出来,如下:

<check_list cep="(a or b) and c">
    <check_node part="comm" group="a" type="INCL" check_data_type="static">ETNET</check_node>
    <check_node part="nodename" group="b" type="INCL" check_data_type="static">p23</check_node>
    <check_node part="exe" group="c" type="INCL" check_data_type="static">bash</check_node>
    <check_node part="argv" group="c" type="INCL" check_data_type="static">bash</check_node>
</check_list>

可以为check_node声明为group ,再在cep中编写对group的条件。支持orand

6.2.6 Frequency 字段

Frequency的逻辑在check_list之后,但数据通过了filter和check_list之后,如果当前rule的类型为Frequency则会进入到Frequency的特殊检测逻辑。Frequency存在两个字段,node_designatethreshold,如下:

<node_designate>
    <node part="uid"/>
    <node part="pid"/>
</node_designate>
<threshold range="30">5</threshold>
6.2.6.1 node_designate

其中node_designate是代表group_by,上方样例的含义是对 uid 和 pid 这两个字段进行group_by。

6.2.6.2 threshold

**threshold是描述频率检测的具体检测内容:多长时间内(range)出现多少次(threshold)。**如上样例中即表达:同一uid与pid在30秒内出现5次即为检出,其中range的单位是秒。

如上图,由于仅仅在10s内就出现了5次,那么在剩下的20s内出现的全部pid=10且uid=1的数据都会告警,如下:

但是这个问题可能会导致告警数据过多,因此支持一个叫做:hit_reset的参数,使用方式如下:

<node_designate>
    <node part="uid"/>
    <node part="pid"/>
</node_designate>
<threshold range="30" hit_reset="true" >5</threshold>

当hit_reset为true时,每次满足threshold策略后,时间窗口将会重制,如下:

在频率检测的场景中,还有一种问题是性能问题,由于这种有状态的检测需要保存一些中间状态,这部分中间状态的数据我们是存在redis中,但是如果数据量过大,对redis会有一定的影响,因此我们频率检测也支持使用使用HUB自己的Local Cache来存储这些中间状态的数据,但是也会失去全局性,开启的方式是设置local_cache参数为true

<node_designate>
    <node part="uid"/>
    <node part="pid"/>
</node_designate>
<threshold range="30" local_cache="true" hit_reset="true" >5</threshold>

失去全局性的原因是该Cache只服务于所属的HUB实例,如果是集群模式下,Local Cache并不互相共享,但是会带来一定的性能提升。

6.2.6.3 高级用法之count_type

有些情况下我们计算频率不是想计算“出现了多少次”,而会有一些其他的需求,如出现了多少类,**出现的字段内数据和是多少。**我们先来看第一个需求,出现了多少类。

假设待检测数据为

{
    "sip":"10.1.1.1",
    "sport":"6637",
    "dip":"10.2.2.2",
    "dport":"22"
}

当我们想写一个检测扫描器的规则时,我们其实往往不关心某一个IP访问了多少次其他资产,而是访问了多少不同的其他资产,当这个数据较大时,可能存在网络扫描探测的可能性,假设我们规定,3600秒内,同一IP访问的不同IP数超过100种就记录下来,那么他的频率部分规则应该这样编写:

<node_designate>
    <node part="sip"/>
</node_designate>
<threshold range="3600" count_type="classify" count_field="dip">100</threshold>

这时候count_type需要为classifycount_field则为类型计算依赖的字段,即dip。

第二个场景假设待检测数据为

{
    "sip":"10.1.1.1",
    "qps":1
}

假设我们需要筛选出3600s内qps总和大于1000的数据,那么我们可以这样编写:

<node_designate>
    <node part="sip"/>
</node_designate>
<threshold range="3600" count_type="sum" count_field="qps">1000</threshold>

count_type为空时默认计算次数,当为classify时计算的是类型,为sum时计算的是求和

6.2.7 append

当我们想对数据进行一些增加信息的操作时,可以使用append来进行添加数据的操作,append的语法如下:

<append type="append类型" rely_part="依赖字段" append_field_name="增加字段名称">增加内容</append>
6.2.7.1 append之STATIC

假设待检测数据为

{
    "alert_data":"data"
}

假设该数据已经通过了filter/check_list/频率检测(若有),这时候我们想增加一些固定的数据到该数据中,如:data_type:10,那么我们可以通过以下方式增加:

<append type="static" append_field_name="data_type">10</append>

我们将会得到以下数据:

{
    "alert_data":"data",
    "data_type":"10"
}
6.2.7.2 append之FIELD

假设待检测数据为

{
    "alert_data":"data",
    "data_type":"10"
}

如果我们想对该数据增加一个字段:data_type_copy:10(来源于数据中的data_type字段),那么我们可以按以下方式编写:

<append type="field" rely_part="data_type" append_field_name="data_type_copy"></append>
6.2.7.3 append之CUSTOM

假设待检测数据为

{
    "sip":"10.1.1.1",
    "sport":"6637",
    "dip":"10.2.2.2",
    "dport":"22"
}

如果我们想通过外部API查询sip的CMDB信息,那我们在这种场景下无法通过简单的规则来实现,需要借助Plugin来实现,Plugin的具体编写方式将在下文进行说明,在这里我们先介绍如果在RuleSet中调用自定义Plugin,如下:

<append type="CUSTOM" rely_part="sip" append_field_name="cmdb_info">AddCMDBInfo</append>

在这里我们将会把rely_part中字段的数据传递到AddCMDBInfo插件进行数据查询,并将插件返回数据append到cmdb_info数据中,如下:

{
    "sip":"10.1.1.1",
    "sport":"6637",
    "dip":"10.2.2.2",
    "dport":"22",
    "cmdb_info": AddCMDBInfo(sip) --> cmdb_info中的数据为插件AddCMDBInfo(sip)的返回数据
}
6.2.7.4 append之CUSTOM_ALLORI

假设待检测数据为

{
    "sip":"10.1.1.1",
    "sport":"6637",
    "dip":"10.2.2.2",
    "dport":"22"
}

如果我们想通过内部权限系统的API查询sip与dip的权限关系,那此时也是需要通过插件来实现这一查询,但是我们的该插件的入参不唯一,我们需要将待检测数据完整的传入该插件,编写方式如下:

<append type="CUSTOM_ALLORI" append_field_name="CONNECT_INFO">AddConnectInfo</append>

我们可以得到:

{
    "sip":"10.1.1.1",
    "sport":"6637",
    "dip":"10.2.2.2",
    "dport":"22",
    "CONNECT_INFO": AddConnectInfo({"sip":"10.1.1.1","sport":"6637","dip":"10.2.2.2","dport":"22"}) --> CONNECT_INFO中的数据为插件AddConnectInfo的返回数据
}
6.2.7.5 append之GROK

append支持针对指定字段进行grok解析,并将解析后数据append到数据流中:

<append type="GROK" rely_part="data" append_field_name="data2"><![CDATA[
%{COMMONAPACHELOG}]]></append>

以上的例子会将data数据进行%{COMMONAPACHELOG} 解析后新增data2字段,存入解析后数据。

6.2.7.6 其他

append可以在一条rule中存在多个,如下:

<rule rule_id="rule_1" type="Detection" author="EBwill">
    ...
    <append type="CUSTOM_ALLORI" append_field_name="CONNECT_INFO">AddConnectInfo</append>
    <append type="field" rely_part="data_type"></append>
    <append type="static" append_field_name="data_type">10</append>
    ...
</rule>

6.2.8 del

当我们需要对数据进行一些裁剪的时候,可以使用del字段进行操作。

假设待检测数据为

{
    "sip":"10.1.1.1",
    "sport":"6637",
    "dip":"10.2.2.2",
    "dport":"22",
    "CONNECT_INFO": "false"
}

假设我们需要将字段CONNECT_INFO移除,那我按如下方式编写即可:

<del>CONNECT_INFO</del>

可以得到如下数据:

{
    "sip":"10.1.1.1",
    "sport":"6637",
    "dip":"10.2.2.2",
    "dport":"22"
}

del可以编写多个,需要用";"隔开,如下:

<del>CONNECT_INFO;sport;dport</del>

即可得到如下数据:

{
    "sip":"10.1.1.1",
    "dip":"10.2.2.2"
}

6.2.9 modify

当我们需要对数据进行复杂处理时,通过append和del无法满足需求,如对数据进行拍平操作,对数据的key进行变化等,这时候可以使用modify来进行操作,需注意modify仅支持插件,使用方式如下:

<modify>插件名称</modify>

流程如下图:

6.2.10 Action

当我们需要做一些特殊操作,如联动其他系统,发送告警到钉钉/Lark/邮件,联动WAF封禁IP等操作的时候,我们可以通过Action来实现相关的操作,需注意仅支持插件,使用方式如下:

<action>emailtosec</action>

插件emailtosec的入参会是当前的数据,其他的操作可以按需求编写。

action也是支持多个插件,使用方式如下,需要按";"隔开:

<action>emailtosec1;emailtosec2</action>

在上面的例子中emailtosec1与emailtosec2都会被触发运行。

6.3 检测/执行顺序

需要注意的是数据在通过Rule的过程中是动态的,即如果通过了append那么接下来如果是del那么del接收到的数据是append生效后的数据。

6.3.1 Rule之间的关系

同一RuleSet中的Rule为"OR"的关系,假设RuleSet如下:

<root ruleset_id="test2" ruleset_name="test2" type="rule" undetected_discard="true">
<rule rule_id="detection_test_1" author="EBwill" type="Detection">
   <rule_name>detection_test_1</rule_name>
   <alert_data>True</alert_data>
   <harm_level>high</harm_level>
   <desc affected_target="test">这是一个Detection的测试1</desc>
   <filter part="data_type">59</filter>
   <check_list>
       <check_node type="INCL" part="exe">redis</check_node>
   </check_list>
</rule>
<rule rule_id="detection_test_2" author="EBwill" type="Detection">
   <rule_name>detection_test_2</rule_name>
   <alert_data>True</alert_data>
   <harm_level>high</harm_level>
   <desc affected_target="test">这是一个Detection的测试2</desc>
   <filter part="data_type">59</filter>
   <check_list>
       <check_node type="INCL" part="exe">mysql</check_node>
   </check_list>
</rule>
</root>

假设数据的exe字段为 mysql-redis,那么会detection_test_1于detection_test_2都会被触发且会产生两条数据向后传递,分别隶属这两条规则

6.4 更多的例子

<rule rule_id="critical_reverse_shell_rlang_black" author="lez" type="Detection">
    <rule_name>critical_reverse_shell_rlang_black</rule_name>
    <alert_data>True</alert_data>
    <harm_level>high</harm_level>
    <desc kill_chain_id="critical" affected_target="host_process">可能存在创建 R 反弹shell的行为</desc>
    <filter part="data_type">42</filter>
    <check_list>
        <check_node type="INCL" part="exe">
            <![CDATA[exec/R]]>
        </check_node>
        <check_node type="REGEX" part="argv">
            <![CDATA[(?:\bsystem\b|\bshell\b|readLines.*pipe.*readLines|readLines.*writeLines)]]>
        </check_node>
    </check_list>
    <node_designate>
    </node_designate>
    <del />    
    <action />
    <alert_email />
    <append append_field_name="" rely_part="" type="none" />
</rule>
<rule rule_id="init_attack_network_tools_freq_black" author="lez" type="Frequency">
    <rule_name>init_attack_network_tools_freq_black</rule_name>
    <freq_black_data>True</freq_black_data>
    <harm_level>medium</harm_level>
    <desc kill_chain_id="init_attack" affected_target="service">存在多次使用网络攻击工具的行为,可能存在中间人/网络欺骗</desc>
    <filter part="SMITH_ALETR_DATA.RULE_INFO.RuleID">init_attack_network</filter>
    <check_list>
    </check_list>
    <node_designate>
        <node part="agent_id" />
        <node part="pgid" />
    </node_designate>
    <threshold range="30" local_cache="true" count_type="classify" count_field="argv">3</threshold>
    <del />
    <action />
    <alert_email />
    <append append_field_name="" rely_part="" type="none" />
</rule>
<rule rule_id="tip_add_info_01" type="Detection" author="yaopengbo">
    <rule_name>tip_add_info_01</rule_name>
    <harm_level>info</harm_level>
    <threshold/>
    <node_designate/>
    <filter part="data_type">601</filter>
    <check_list>
        <check_node part="query" type="CUSTOM">NotLocalDomain</check_node>
    </check_list>
    <alert_data>False</alert_data>
    <append type="FIELD" rely_part="query" append_field_name="tip_data"></append>
    <append type="static" append_field_name="tip_type">3</append>
    <append type="CUSTOM_ALLORI" append_field_name="tip_info">AddTipInfo</append>
    <del/>
    <alert_email/>
    <action/>
    <desc affected_target="tip">dns新增域名tip检测信息</desc>
</rule>

6.5 规则编写建议

  • filter的良好运用可以大大降低性能压力,filter的编写目标应该是让尽可能少的数据进入CheckList
  • 尽可能少的使用正则

7 Elkeid HUB Plugin/插件

Elkeid HUB Plugin用于解除部分Ruleset在编写过程的限制,提高HUB使用的灵活性。通过编写plugin,可以实现部分编写Ruleset无法完成的操作。同时,如果需要和当前尚不支持的第三方组件进行交互,只能通过编写plugin来实现。

Elkeid HUB目前同时支持Golang Plugin和Python Plugin。当前存量Plugin采用Golang开发,通过Golang Plugin机制进行加载,由于局限性较大,当前不再对外开放,但在Ruleset编写中仍可使用存量Golang Plugin。目前仅对外开放Python Plugin。

Python Plugin本质是在HUB运行过程中,通过另外一个进程执行Python 脚本,并将执行结果返回给Elkeid HUB。

Plugin总计有6种类型,均在Ruleset编写文档中介绍过,以下会结合上文的例子对每种plugin展开介绍。 Plugin的类型命名与在Ruleset中的标签名并不一一对应,实际使用中请严格以文档为准。

7.1 通用参数介绍

7.1.1 格式

每个Plugin都是一个Python Class,plugin加载时,HUB会实例化这个Class,并对该Class的name,type,log,redis四个变量进行赋值,每次plugin执行时,会调用该class的plugin_exec方法。

Class 如下:

class Plugin(object):

    def __init__(self):
        self.name = ''
        self.type = ''
        self.log = None
        self.redis = None
    
    def plugin_exec(self, arg, config):
        pass

7.1.2 init

__init__方法中包含以下四个变量:

  • name: Plugin Name
  • type: Plugin Type
  • log: logging
  • redis: redis client

如果有自己的init逻辑,可以加在后面

7.1.3 plugin_exec

plugin_exec方面有两个参数,arg和config。

  • arg就是该plugin执行时接受的参数。根据plugin类型的不同,arg是string或dict()。

针对Action,Modify,Origin,OriginAppend四种类型的plugin,arg是dict()。

针对Append,Custom两种类型的plugin,arg是string。

  • config是plugin可以接受的额外参数,目前只有Action和Modify支持,如果在Ruleset中有指定,会通过config参数传递给plugin。

例如:在ruleset中添加了extra标签,HUB会以dict的形式以config入参调用plugin_exec方法。extra中使用:作为kv的分隔符 ;作为每组kv的分隔符

<action extra="mail:xxx@bytedance.com;foo:bar">PushMsgToMatao</action>
config = {"mail":"xxx@bytedance.com"}

7.2 example

7.2.1 Plugin之Action

在rule中的作用见6.2.10。

Action用于实现数据通过当前rule之后执行一些额外操作。

一个Action plugin接收的是整个数据流的拷贝。返回的是action是否执行成功。action是否执行成功不会影响数据流是否继续向下走,只会在HUB的日志中体现。

实现参考

class Plugin(object):


    def __init__(self):
        self.name = None
        self.type = None
        self.log = None
        self.redis = None


    def plugin_exec(self, arg, config):
        # 例:请求某个回调地址
        requests.post(xxx)
        result = dict()
        result["done"] = True
        return result

7.2.2 Plugin之Append

在rule中的作用见6.2.7.3

Append和OriginAppend类似,均是可以自定义Append操作,不同的是Append接受的数据流中确定的某个属性值,而OriginAppend接受的是整个数据流的拷贝。两者的返回值均会写入到数据流中指定属性中。

实现参考

class Plugin(object):
    def __init__(self):
        self.name = None
        self.type = None
        self.log = None
        self.redis = None
    def plugin_exec(self, arg, config):
        result = dict()
        result["flag"] = True
        # 在原arg后面加上__new__后缀
        result["msg"] = arg + "__new__"
        return result

7.2.3 Plugin之Custom

在rule中的作用见6.2.5.2中的Custom

CUSTOM用于实现自定义CheckNode。CheckNode中虽然预定义了10余种常见的判断方式,但在实际rule编写过程中,必然无法完全覆盖,所以开放了plugin拥有书写更灵活的判断逻辑。

该plugin接收的参数是数据流中指定的属性值,返回的是是否命中以及写入hit中部分。

实现参考

class Plugin(object):
    def __init__(self):
        self.name = None
        self.type = None
        self.log = None
        self.redis = None
    def plugin_exec(self, arg, config):
        result = dict()
        # 若arg长度为10
        if arg.length() == 10:
            result["flag"] = True
            result["msg"] = arg
        else:
            result["flag"] = True
            result["msg"] = arg
        return result

7.2.4 Plugin之Modify

在rule中的作用见6.2.9

Modify是所有plugin中灵活度最高的plugin,当编写ruleset或其他plugin无法满足需求时,可以使用modify plugin,获得对数据流的完全操作能力。

Modify插件的入参是当前数据流中的一条数据。返回分两种情况,可以返回单条数据,也可以返回多条数据。

返回单条数据时,Flag为true,数据在Msg中,返回多条数据时,MultipleDataFlag为true,数据在数组MultipleData中。若Flag和MultipleDataFlag同时为true,则无意义。

实现参考1:

class Plugin(object):
    def __init__(self):
        self.name = None
        self.type = None
        self.log = None
        self.redis = None
    def plugin_exec(self, arg, config):
        result = dict()
        # 随意修改数据,例如加个字段
        arg["x.y"] = ["y.z"]
        result["flag"] = True
        result["msg"] = arg
        return result

实现参考2:

class Plugin(object):
    def __init__(self):
        self.name = None
        self.type = None
        self.log = None
        self.redis = None
    def plugin_exec(self, arg, config):
        result = dict()
        # 将该条数据复制成5分
        args = []
        args.append(arg)
        args.append(arg)
        args.append(arg)
        args.append(arg)
        args.append(arg)
        result["multiple_data_flag"] = True
        result["multiple_data"] = args
        return result

7.2.5 Plugin之Origin

在rule中的作用见6.2.5.2中的CUSTOM_ALLORI

Custom插件的进阶版,不再是对数据流中的某个字段进行check,而是对数据流中的整条数据进行check。入参由单个字段变成了整个数据流。

实现参考

class Plugin(object):
    def __init__(self):
        self.name = None
        self.type = None
        self.log = None
        self.redis = None
    def plugin_exec(self, arg, config):
        result = dict()
        # 若arg["a"]和arg["b"]长度长度都为10
        if arg["a"].length() == 10 and arg["b"].length() == 10:
            result["flag"] = True
            result["msg"] = ""
        else:
            result["flag"] = False
            result["msg"] = ""
        return result

7.2.6 Plugin之OriginAppend

在rule中的作用见6.2.7.4

Append插件的进阶版,不再是对数据流中的某个字段进行判断然后append,而是对数据流中的整条数据进行判断。入参由单个字段变成了整个数据流。

实现参考

class Plugin(object):
    def __init__(self):
        self.name = None
        self.type = None
        self.log = None
        self.redis = None
    def plugin_exec(self, arg, config):
        result = dict()
        result["flag"] = True
        # 合并两个字段
        result["msg"] = arg["a"] + "__" + arg["b"]
        return result

7.3 Plugin 开发流程

plugin的运行环境为pypy3.7-v7.3.5-linux64,如果希望python脚本正常运行,需要在此环境下进行测试。

HUB自身引入了部分基础依赖,但远无法覆盖python常用package,当有需要时,需要用户通过如下方式自行安装。

  1. venv位于/opt/Elkeid_HUB/plugin/output/pypy下,可以通过以下命令切换到venv中,执行pip install进行安装。
source /opt/Elkeid_HUB/plugin/output/pypy/bin/activate
  1. 在plugin的init方法中调用pip module,进行安装

7.3.1 创建Plugin

  1. 点击创建plugin按钮

  1. 按照需求,填写信息

  1. 点击Confirm,完成创建

  1. 查看Plugin

  1. 下载plugin

Plugin创建成功时会自动下载Plugin,之后也可以点击界面上的下载按钮再次下载

7.3.2 在线开发&测试Plugin

单击Name或者点击View Plugin按钮,会弹出Plugin.py预览界面,可以在此界面预览&编辑代码。

编辑器默认处于只读模式,单击Edit按钮,编辑器会转换为读写模式,此时可以编辑Plugin。

编辑完成后,可以点击Confirm按钮进行保存,或者点击Cancel按钮放弃更改。

点击Confirm按钮后,改动不会实时生效,和Ruleset类似,同样需要Publish操作。

7.3.3 本地开发Plugin

解压创建plugin时的自动下载的zip包,可以使用IDE打开,执行test.py即可测试plugin。

测试无误后,需要手动压缩会zip文件进行上传。

压缩时需要注意,确保所有文件都在zip的根目录下。

7.3.4 上传Plugin

  1. 点击界面的上传按钮

  1. 同策略发布相同,在策略发布界面发布策略

7.4 Plugin 常见开发依赖

7.4.1 requests

Elkeid HUB 默认引入了requests库,可以使用requests库实现http请求。

参考代码如下:

import requests
import json
def __init__(self):
    ...
    
def plugin_exec(self, arg, config):
    p_data = {'username':user_name,'password':user_password}    
    p_headers = {'Content-Type': 'application/json'}
    r = requests.post("http://x.x.x.x/", data=json.dumps(p_data), headers=p_headers)
    result["flag"] = True
    result["msg"] = r.json()['data']
    return result

7.4.2Redis

Plugin Object在执行完__init__方法后,执行plugin_exec方法前,HUB会将redis连接设置到self.redis中,之后可以在plugin_exec方法中调用redis。该redis为HUB自身配置的redis,使用的库为 https://github.com/redis/redis-py。

参考代码如下:

redis_result = self.redis.get(redis_key_prefix + arg)

self.redis.set(redis_key_prefix + arg, json.dumps(xxx), ex=random_ttl())

7.4.3Cache

Elkeid HUB 默认引入了cacheout库,可以使用cacheout库实现本地cache,或配合redis实现多级cache。cacheout文档参考https://pypi.org/project/cacheout/ 。

简单示例:

from cacheout import LRUCache
class Plugin(object):
    def __init__(self):
        ...
        self.cache = LRUCache(maxsize=1024 * 1024)
        ...
        
    def plugin_exec(self, arg, config):
        ...
        cache_result = self.cache.get(arg)
        if cache_result is None:
           pass
        ...
        self.cache.set(arg, query_result, ttl=3600)
        ...

配合redis实现多级cache:

from cacheout import LRUCache
class Plugin(object):
    def __init__(self):
        ...
        self.cache = LRUCache(maxsize=1024 * 1024)
        ...
        
    def plugin_exec(self, arg, config):
        ...
        cache_result = self.cache.get(arg)
        if cache_result is None:
            redis_result = self.redis.get(redis_key_prefix + arg)
            if redis_result is None:
                # fetch by api
                ...
                self.redis.set(prefix + arg, json.dumps(api_ret), ex=random_ttl())
                self.cache.set(arg, ioc_query_source, ttl=3600)
            else:
                # return
                ...
        else:
            # return
            ...

8 Project/项目

8.1 Project

Project 是被执行策略的最小单元,主要描述数据流内的数据过程。从Input开始到Output或RuleSet结束,我们先来看一个例:

INPUT.hids --> RULESET.critacal_rule
RULESET.critacal_rule --> RULESET.whitelist
RULESET.whitelist --> RULESET.block_some
RULESET.whitelist --> OUTPUT.hids_alert_es

我们来描述一下这个Project的配置:

INPUT.hids 从远端消费数据 传递到 RULESET.critacal_rule

RULESET.critacal_rule 检出的数据 传递到 RULESET.whitelist

RULESET.whitelist 检出的数据 传递到 RULESET.block_someOUTPUT.hids_alert_es

其中RULESET.block_some可能是通过action联动其他组件进行一些封禁操作,OUTPUT.hids_alert_es显而易见是将数据打到外界的es中

8.2 关于ElkeidDSL语法

在HUB中有一下几个概念:

名称/操作符介绍SmithDSL表示方法
INPUT数据输入源INPUT.输入源IDINPUT.test1
OUTPUT数据库输出源OUTPUT.输出源IDOUTPUT.test2
RULESET规则集RULESET.规则集IDRULESET.test3
—>数据传递—>INPUT.A1 —> RULESET.A

8.3 关于数据传递

数据传递尽可以使用:-->来表示.

如我们想将数据输入源HTTP_LOG传递到规则集HTTP:

INPUT.HTTP_LOG --> RULESET.HTTP

如果我们想让以上的告警通过数据输出源SOC_KAFKA输出的话:

INPUT.HTTP_LOG --> RULESET.HTTP  
RULESET.HTTP --> OUTPUT.SOC_KAFKA

如果我们想让以上的告警通过数据输出源SOC_KAFKA和SOC_ES输出的话:

INPUT.HTTP_LOG --> RULESET.HTTP  
RULESET.HTTP --> OUTPUT.SOC_KAFKA
RULESET.HTTP --> OUTPUT.SOC_ES

9 Elkeid HUB 前端使用指南

前端主要包括首页,RuleEdit(规则页),Publish(规则发布),Status(日志/状态),User Management(系统管理),Debug(规则测试)五个部分。这部分只介绍前端页面的使用,具体的规则配置和字段含义,请参考前面章节。

9.1 使用流程

  1. 规则发布:
  • 规则页-->输入源/输出/规则集/插件/项目 进行相关的编辑和修改。

  • 再到规则发布-->规则发布页面将规则发布到hub集群。

  1. 项目操作
  • 规则发布-->项目操作页面start/stop/restart对应的project。

9.2 首页

首页主要包括HUB状态信息QPS信息HUB占用信息工具栏。工具栏包括中英文切换,页面模式切换与通知栏信息。

QPS信息展示了整体的Input和Output的qps信息,数据30秒更新一次。这里只是作为大盘展示,如需查看更加详细的信息,可到规则页-->项目-->项目详情页面查看。

HUB占用信息通过分析ruleset使用的cpu时间来对HUB占用情况进行分析,会给出HUB占用信息的条形图,包含规则集使用的CPU时间以及比例,通过该条形图可以分析哪些规则集占用了大量资源,从而进行针对性地优化。

9.3 Rule Edit/规则页

所有的规则(包括Input/Output/Ruleset/Plugin/Project)增删查改都在RuleEdit里面进行。

这里编辑后的规则并不会自动发布到HUB集群,如需发布,请到Publish-->RulePublish页面进行操作。

为了便于快速找到自己相关的配置,配置列表会分为两个Tab,My Subscription展示用户收藏的配置信息、另一个则展示全部的配置(如input)。用户可以先去全部配置找到需要管理的配置并收藏该配置方便下次修改。

9.3.1 Input/输入源

输入源页面支持新增、文件导入:

  1. 新增:点击新增,会出现如下页面,具体的字段含义可参考上文Elkeid Input章节。

  1. 文件导入:首先根据需求创建一个input文件,目前支持yml格式的。举例如下。
InputID: test_for_example
InputName: test_for_example
InputType: kafka
DataType: json
TTL: 30
KafkaBootstrapServers: test1.com:9092,test2.com:9092
KafkaGroupId: hub-01
KafkaOffsetReset: latest
KafkaCompression: none
KafkaWorkerSize: 3
KafkaOtherConf: ~

KafkaTopics:
  - testtopic

然后点击导入,选择要导入的文件,弹出框后再 确认导入,即可。

  1. 采样

点击采样,可以获取到输入源运行过程中的采样数据。

9.3.2 Output/输出

输出的使用与输入源类似,支持elasticsearch、kafka、influxdb三种类型。

9.3.3 RuleSet/规则集

  1. 规则集页面

同样的,规则集也支持页面新增和文件导入,同时也支持全量导出全部规则。

采样 按钮可以查看这个规则的输入/输出样例数据(如果这个规则一直没数据进入,则会无数据)。

测试会对非加密的规则集进行测试,以测试数据为输入,记录数据流入规则集后的命中概况。如果选择染色规则,那么会记录命中的具体数据。(对数据库存在负载,建议考量测试数据的数目大小使用),如果规则集正在运行,可以使用载入数据载入采样数据,进行测试。详见规则测试/Debug页面

创建副本 按钮会以当前规则集为模版,创建一个副本集规则,会在rulesetid和rulesename加上_copy后缀:

规则集内搜索提供了对所有规则集的全局搜索。会匹配所有规则集中对应的规则ID。对搜索的结果用户可以跳转到编辑或删除该rule。

  1. 规则页面

点击各个规则集的规则集ID按钮可以查看其详情,进入到rule的编辑页面。

新建按钮是对当前规则集来增加一条规则。这里支持XML编辑表格编辑两种方式,可通过点击表单编辑XML编辑进行切换。

测试按钮支持对单一规则进行测试,采样按钮可从Hub导入样例数据(如果有的话),点击执行,则会将样例数据发送到Hub实例进行测试。测试不会影响到线上的数据流。

9.3.4 Plugin/插件

详情见7.3 Plugin开发流程

9.3.5 Project/项目

项目也支持页面新增和文件导入。Running/Stopped/Unknown分别代表正在运行/未在运行/未知该项目的机器数。特别的,状态数据每30s更新一次。

点击项目ID进入项目详情页面。可以查看项目详情信息,Input lag(仅限kafka),各个组件的qps信息。同时在节点图处右键点击节点可以查看节点SampleData或跳转到节点详情。

测试按钮会对不包含加密规则集的项目进行测试,测试流程同规则集测试。

9.4 Publish/规则发布

所有涉及到对hub集群的变更的操作都在这个页面下。

9.4.1 RulePublish/规则发布

这里进行规则发布,编辑后的规则变更操作,在这个页面能看到。

提交更改,则将变更发布到HUB集群;撤销更改,则丢弃所有变更,将规则回滚到上一个稳定版本(上次提交变更的版本)。

点击diff会查看该变动的详细信息

提交更改后,会自动跳转到Task Detail页面。可以查看成功失败机器数,失败的错误信息,以及本次task的变更详情及diff。

9.4.2 Project Operation/项目操作

这个页面用来控制项目的启动,停止和重启。所有新增的项目默认都是停止状态,需要到此页面进行手动开启。

9.4.3 Task/任务列表

任务列表页面展示了所有向hub集群下发过的任务。

9.5 Status/状态页

状态用于展示HUB的运行状态,错误事件以及leader操作记录。

9.5.1 Event/HUB事件

Event为HUB产生的错误信息,leader收集错误信息并进行汇总聚合,因此每条信息可能是多个hub机器在一段时间内共同发生的错误,在列表中可以看到event等级,主机数,位置以及信息。在上方可以根据时间和Event类型进行筛选。点击左侧小箭头可以展开查看错误详情。

每条错误信息包含了错误的详细信息,trace,以及hub机器的ip:port。

9.5.3 Log/操作日志

Log用来记录对HUB的修改操作。Log中包含URL,操作用户,IP,时间等信息,在上方可以通过时间来进行筛选。

9.6 System Management/系统管理

这个页面用来管理HUB用户,用户可以新建用户,删除用户,以及对用户的权限进行管理

9.6.1 用户管理

点击添加用户可以新建用户,在界面中设置用户的用户名,密码,以及用户等级,用户等级共分为6级,分别是admin、manager、hub readwirte、hub readonly。

  • admin用户可以访问全部的页面和接口
  • manager 用户可以访问除用户管理外的页面和接口
  • hub readwrite 用户可以使用hub相关的普通页面和接口,并拥有读写权限
  • hub readonly 用户可以使用hub相关的普通页面和接口,并拥有只读权限

9.8 Debug/规则测试

用于对已经编写好的规则/规则集/项目进行测试,测试其功能是否符合预期。

DataSource(数据)、Debug Config(配置)、Debug Task(任务)关联如下:

每个配置包含一份数据,与一个测试组件(规则、规则集或项目)。配置创建任务时会给它分配一个Host,任务被执行时,也仅会在该Host上被执行。

9.8.1 Data Source/数据

数据源,可以理解成类型可配置的、限制消费数据数目的输入源

  • 类型:数据源类型,共两种:
    1. debug_user_input(自定义):用户输入数据源;
    2. debug_topic(流式):实际输入源,该类型的数据限制消费50条输入源。
  • 关联配置:关联配置列表,展示使用了该数据源的Debug Config
  • 关联输入源:表示该数据源代表的输入源,仅类型为debug_topic时不为空。

9.8.2 Debug Config/配置

字段说明:

  • 类型:配置类型,表示是根据哪种测试组件创建的配置
  • 染色规则 : 表示“染色”的rule节点,选择需要“染色”的rule后,经过这条rule的数据会带上染色字段标记。可以不选择,此时该配置生成的任务将不会收集具体的数据。
  • 状态 :配置状态:
    • 全部配置 准备完成,此时可以创建任务
    • 未确认 可能未配置数据或者数据被删除,需要创建数据才可以创建数据
    • 测试概况 未配置染色规则,此时可以创建任务,但不会收集具体的数据,只能看到每个节点(input/ruleset/output)的概况数据,如In/Out(流入rule的数据数目,流出该规则的数据数目).

9.8.3 Debug Task/任务

字段说明:

  • 任务状态:状态
    • 未定义:未定义,可能是hub升级或退出导致任务被删除,此时无法查看结果
    • 已准备:已准备就绪,此时点击启动任务可以执行任务
    • 运行中:运行中
    • 已完成:运行成功,此时点击查看结果可以查看结果

结果页:

  • 左上:DSL图。方便查看测试的project 结构,左上角为任务ID
  • 左下:概览结果。展示了各个节点数据的流入/流出情况。
    • In:数据流入条数
    • Out:数据流出条数
    • LabelIn:染色数据流入条数
    • LabelOut:染色数据流出跳出
  • 右:详情结果。可以查看本次任务的染色数据,支持分页查询