【架构与设计】安全设备联动服务设计方案
背景
对于资源库、资产库、情报库、威胁库等其他业务模块,需要与技防设备进行联动的场景;各业务分别描述自己的联动需求,统一由联动服务来创建联动剧本、剧本编排、剧本执行,由联动服务来直接对接技防设备;各自业务只需要关注模块业务,不需要关注设备交互方式。
技术选型
编程语言
java
关系型数据库
MySQL 存储联动剧本/联动能力执行结果
缓存
redis 存储联动模板文件
剧本编排与执行工具
ansible
数据模型设计
关键用例
组件图
活动图
联动引擎与业务模块交互分析图
模板抽象设计
联动能力模板
device_linkage_abilities:
- ability_code: blacklist
ability_name: 黑名单
# 能力共同参数
params:
- key: product_code
type: string
- key: device_ip
type: string
- key: device_port
type: string
- key: target
type: string
support_devices:
# code规则 产品code:版本号 版本号可以无
# 来描述 一个唯一的实体:某产品,或某产品的某个版本,用以关联ansible模板、api模板,或是 设备管理中的设备 - product_code: "fw:xxx"
- product_code: "fw:xxx"
params:
- key: device_version
type: string
exclude_devices:
- 1.1.1.1
- ability_code: ip_banned
ability_name: IP封禁
# 能力共同参数
params:
- key: product_code
type: string
- key: device_ip
type: string
- key: device_port
type: string
- key: target
type: string
support_devices:
- product_code: "fw:xxxx"
params:
- key: device_version
type: string
exclude_devices:
- 1.1.1.1
联动能力执行模板
device_linkage_execute:
- product_code: "fw:xxx"
linkage_abilities:
- ability: blacklist
exec_tool: api
requet_api_code: device_block
- ability: ip_banned
exec_tool: ansible
playbook: firewall-demo-playbook11.yml
cmd: "ansible-playbook -i /tmp/host.ini /tmp/firewall-demo-playbook.yml --extra-vars target_ips='{{device_ip_arr}}'"
- ability: query_strategy
exec_tool: ansible
playbook: firewall-demo-playbook11.yml
cmd: "XXXXX"
联动剧本模板
script:
- script_code: demo1
script_name: 测试剧本
cron: "" # cron表达式
exec_model: 1 #执行模式,1:自动 0:手动
enable: true # 是否启用
exec_items:
- linkage_abilitiy: query_strategy
product_code: "fw:xxx"
params:
- device_ip: 1.1.1.1
- device_port: 22
- exec_tool: ansible
playbook: firewall-demo-playbook11.yml
params:
- device_ip: 1.1.1.1
- device_port: 22
host模板
[device]
host ansible_host={{device_ip}}
;host指定设备ip
[ansible_host]
host1 ansible_host={{ansible_host}}
;host指定ansible安装主机
playbook模板
- name: firewall-demo
hosts: device
gather_facts: no # 禁用事实收集
tasks:
- name: 测试ssh
shell: echo "test"
register: ssh_output # 保存 命令执行结果 输出到变量 ssh_output
vars:
ansible_ssh_user: {{ansible_user_name}}
ansible_ssh_pass: {{ansible_user_password}}
ansible_ssh_common_args: "-o StrictHostKeyChecking=no" # 忽略 SSH 主机密钥检查
- name: print
debug:
var: ssh_output
api配置模板
[
{
"request_api_code": "api_demo1",
"content": {
"method": "GET",
"url": "http://127.0.0.1:8080/xxx",
"body": {
"device_id": "{id}",
"device_type": "{device_type}",
"name": "{device_name}",
"ip": "{ip}",
"device_version": "{version}",
"port": "{port}"
}
}
}
]
接口设计
获取能力列表接口
API Path
xxx/device-linkage-abilities
请求协议
http
请求方法
GET
请求参数
参数名 | 说明 | 必填 | 类型 |
---|---|---|---|
ability_code | 能力编码 | 否 | string |
product_code | 设备产品编码 | 否 | string |
请求示例
curl http:127.0.0.1:8080/xxx/device-linkage-abilities?ability_code=xxx&product_code=xxx&device_ip=xxx
响应参数 Array
参数名 | 类型 | 说明 | 可选值 | ||
---|---|---|---|---|---|
ability_code | string | 能力编码 | |||
ability_name | string | 能力名称 | |||
params | array | 能力共同参数 | |||
key | string | 参数名称 | |||
type | string | 参数类型 | string\int\float\object\array | ||
support_devices | array | 适用设备范围 | |||
product_code | string | 设备产品编码 | |||
devices | array | 设备信息 | |||
device_id | string | 设备id | |||
device_name | string | 设备名称 | |||
device_ip | string | 设备ip |
响应示例
[
{
"ability_code": "blacklist",
"ability_name": "黑名单",
"params": [
{
"key": "device_ip",
"type": "string"
},
{
"key": "device_port",
"type": "string"
}
],
"support_devices": [
{
"product_code": "fw:xxx",
"devices": [
{
"device_id": "sss",
"device_name": "设备A",
"device_ip": "4.4.4.4"
}
]
}
]
}
]
获取设备能力接口
API Path
xxx/device-linkage-abilities/device
请求协议
http
请求方法
GET
请求参数 device_ip和device_id至少填写一个
参数名 | 说明 | 必填 | 类型 |
---|---|---|---|
device_ip | 设备ip | 是 | string |
device_id | 设备id | 否 | string |
请求示例
curl http:127.0.0.1:8080/xxx/device-linkage-abilities/device?device_ip=xxx&device_id=xxx
响应参数 Array
参数名 | 类型 | 说明 | 可选值 | ||
---|---|---|---|---|---|
device_id | string | 设备id | |||
device_name | string | 设备名称 | |||
device_ip | string | 设备ip | |||
abilities | array | 能力集合 | |||
ability_code | string | 能力编码 | |||
ability_name | string | 能力名称 | |||
params | array | 能力共同参数 | |||
key | string | 参数名称 | |||
type | string | 参数类型 | string\int\float\object\array |
响应示例
{
"device_id": "xxx",
"device_name": "xxx",
"device_ip": "xxxx",
"abilities": [
{
"ability_code": "sss",
"ability_name": "xx",
"params": [
{
"key": "device_ip",
"type": "string"
},
{
"key": "device_port",
"type": "string"
}
]
}
]
}
能力执行接口
API Path
xxx/device-linkage-abilities/execute
请求协议
http
请求方法
POST
请求body参数 Object product_code和device_ip二选一(要么按照设备类型执行能力,要么按照设备执行能力)
参数名 | 说明 | 必填 | 类型 |
---|---|---|---|
ability_code | 能力编码 | 是 | string |
product_code | 设备产品编码 | 否 | string |
device_ip | 设备ip | 否 | array |
params | 能力共同参数 | 否 | object |
请求示例
curl -XPOST -H "Content-Type: application/json"
http:127.0.0.1:8080/xxx/device-linkage-abilities/execute
-d ’
{
"ability_code": "xxx",
"product_code": "xxx",
"device_ip": [
"8.8.8.8"
],
"params": {
"device_ip": "2.2.2.2",
"device_port": "22"
}
}
’
响应示例
{
"execute_id": "执行id"
}
获取能力执行结果接口
API Path
xxx/device-linkage-abilities/query
请求协议
http
请求方法
GET
请求参数
参数名 | 说明 | 必填 | 类型 | 默认值 |
---|---|---|---|---|
ability_code | 能力编码 | 是 | string | |
ability_name | 能力名称 | 否 | string | |
product_code | 设备产品编码 | 否 | string | |
device_ip | 设备ip(多个ip用英文逗号分隔) | 否 | string | |
order_by | 排序参数,支持执行开始和执行结束时间排序(-exec_start_time表示按照执行开始时间倒序排序) | 否 | string | -exec_end_time |
offset | 偏移量 | 是 | int | |
limit | 分页大小 | 是 | int |
请求示例
curl http:127.0.0.1:8080/xxx/device-linkage-abilities/query?ability_code=xxx&offset=0&limit=10
响应参数 Object
参数名 | 类型 | 说明 | 可选值 | ||
---|---|---|---|---|---|
items | array | ||||
ability_code | string | 能力编码 | |||
ability_name | string | 能力名称 | |||
device_ip | array | 设备ip | |||
exec_status | int | 执行状态 | 1: 执行成功 2:执行中 3: 执行失败 | ||
exec_start_time | date | 执行开始时间 | |||
exec_end_time | date | 执行结束时间 | |||
data | object | 执行结果信息 | |||
total | int | 总记录数 |
响应示例
{
"items": [
{
"ability_code": "",
"ability_name": "",
"device_ip": [],
"exec_status": 1,
"exec_start_time": "",
"exec_end_time": "",
"data": {
}
}
],
"total": 1
}
获取剧本列表接口
API Path
xxx/device-linkage-scripts
请求协议
http
请求方法
GET
请求参数
参数名 | 说明 | 必填 | 类型 |
---|---|---|---|
script_code | 剧本编码 | 否 | string |
script_group | 剧本分组 | 否 | string |
请求示例
curl http:127.0.0.1:8080/xxx/device-linkage-scripts?script_code=xxx&script_group=xxx
响应参数 Array
参数名 | 类型 | 说明 | 可选值 | ||
---|---|---|---|---|---|
script_code | string | 剧本编码 | |||
script_name | string | 剧本名称 | |||
script_group | string | 剧本分组 | |||
params | array | 剧本参数 | |||
key | string | 参数名称 | |||
type | string | 参数类型 | string\int\float\object\array |
响应示例
[
{
"script_code": "demo1",
"script_name": "测试",
"script_group": "demo",
"params": [
{
"key": "device_ip",
"type": "string"
},
{
"device_port": "string",
"type": "string"
}
]
}
]
模板剧本执行接口
API Path
xxx/device-linkage-scripts/execute
请求协议
http
请求方法
POST
请求body参数 Array script_code和script_group二选一(要么按照剧本编码执行剧本,要么按照剧本分组执行剧本)
参数名 | 说明 | 必填 | 类型 |
---|---|---|---|
script_code | 剧本编码 | 否 | string |
script_group | 剧本分组 | 否 | string |
params | 剧本参数 | 否 | object |
请求示例
curl -XPOST -H "Content-Type: application/json"
http:127.0.0.1:8080/xxx/device-linkage-abilities/execute
-d ’
{
"script_code": "xxx",
"script_group": "xxxx",
"params": {
"device_ip": "2.2.2.2",
"device_port": "22"
}
}
’
响应示例
{
"execute_id": "执行id"
}
业务剧本执行接口
API Path
xxx/device-linkage-scripts/execute:batch
请求协议
http
请求方法
POST
请求body参数 Array
参数名 | 说明 | 必填 | 类型 | 可选值 | |
---|---|---|---|---|---|
script_code | 剧本编码 | 是 | string | ||
exec_model | 执行模式 | 是 | int | 执行模式(1:自动 0:手动) | |
cron | cron表达式 | object | exec_model=1时必填;cron值为时间戳时表示指定某个时刻执行一次;cron值为cron表达式时表示周期自动执行 | ||
abilities | 能力集合 | 否 | array | ||
ability_code | 能力编码 | 是 | string | ||
product_code | 设备产品编码 | 否 | string | ||
device_ip | 设备ip | 否 | array | ||
params | 能力共同参数 | 是 | object |
请求示例
curl -XPOST -H "Content-Type: application/json"
http:127.0.0.1:8080/xxx/device-linkage-abilities/execute:batch
-d ’
{
"script_code": "xxx",
"script_group": "xxx",
"abilities": [
{
"ability_code": "xxx",
"product_code": "xxx",
"device_ip": [
"8.8.8.8"
],
"params": {
"device_ip": "2.2.2.2",
"device_port": "22"
}
}
]
}
’
响应示例
{
"execute_id": "执行id"
}
获取剧本执行结果接口
API Path
xxx/device-linkage-scripts/query
请求协议
http
请求方法
GET
请求参数
参数名 | 说明 | 必填 | 类型 | 默认值 |
---|---|---|---|---|
script_code | 剧本编码 | 是 | string | |
script_name | 剧本名称 | 否 | string | |
script_group | 剧本分组 | 否 | string | |
order_by | 排序参数,支持执行开始和执行结束时间排序(-exec_start_time表示按照执行开始时间倒序排序) | 否 | string | -exec_end_time |
offset | 偏移量 | 是 | int | |
limit | 分页大小 | 是 | int |
请求示例
curl http:127.0.0.1:8080/xxx/device-linkage-abilities/query?ability_code=xxx&offset=0&limit=10
响应参数 Object
参数名 | 类型 | 说明 | 可选值 | ||
---|---|---|---|---|---|
items | array | ||||
script_code | string | 剧本编码 | |||
script_name | string | 剧本名称 | |||
script_group | array | 剧本分组 | |||
exec_status | int | 执行状态 | 1: 执行成功 2:执行中 3: 执行失败 | ||
exec_start_time | date | 执行开始时间 | |||
exec_end_time | date | 执行结束时间 | |||
data | object | 执行结果信息 | |||
total | int | 总记录数 |
响应示例
{
"items": [
{
"script_code": "",
"script_name": "",
"script_group": "",
"exec_status": 1,
"exec_start_time": "",
"exec_end_time": "",
"data": {
}
}
],
"total": 1
}
根据执行id获取执行结果接口
API Path
xxx/device-linkage/query/{execute_id}
请求协议
http
请求方法
GET
请求示例
curl http:127.0.0.1:8080/xxx/device-linkage/123455
响应示例
{
"id": "123455",
"exec_model": "执行模式(1:自动 0:手动)",
"exec_type": "执行类型(1:能力 2:剧本)",
"script_code": "剧本编码",
"ability_code": "能力编码",
"exec_status": "执行状态(1: 执行成功 2:执行中 3: 执行失败)",
"exec_start_time": "执行开始时间",
"exec_end_time": "执行结束时间",
"data": {
}
}
MQ消息结构设计
{
"id": "执行id 唯一",
"exec_model": "执行模式(1:自动 0:手动)",
"exec_type": "执行类型(1:能力 2:剧本)",
"script_code": "剧本编码",
"ability_code": "能力编码",
"exec_status": "执行状态(1: 执行成功 2:执行中 3: 执行失败)",
"exec_start_time": "执行开始时间",
"exec_end_time": "执行结束时间",
"data": {
}
}