Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
LLM-Filter
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
2026_NGIT
LLM-Filter
Commits
0e2c0172
Commit
0e2c0172
authored
Jan 03, 2026
by
uuo00_n
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat(security-service): 添加MongoDB支持以实现分析结果持久化和历史查询功能
添加MongoDB数据库连接配置和持久化逻辑 实现安全分析和攻击建议的历史记录存储 新增历史查询接口和文档说明
parent
77ca28f8
Changes
9
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
178 additions
and
24 deletions
+178
-24
docker-compose.yml
docker-compose.yml
+4
-0
SECURITY_SERVICE.md
microservices/security-service/SECURITY_SERVICE.md
+23
-12
endpoints.py
microservices/security-service/app/api/v1/endpoints.py
+45
-3
config.py
microservices/security-service/app/core/config.py
+4
-0
database.py
microservices/security-service/app/core/database.py
+21
-0
main.py
microservices/security-service/app/main.py
+11
-1
payloads.py
microservices/security-service/app/schemas/payloads.py
+13
-0
analysis.py
microservices/security-service/app/services/analysis.py
+55
-8
requirements.txt
microservices/security-service/requirements.txt
+2
-0
No files found.
docker-compose.yml
View file @
0e2c0172
...
@@ -100,6 +100,10 @@ services:
...
@@ -100,6 +100,10 @@ services:
-
JWT_SECRET=llm_filter_secure_secret_key_2025_update_must_be_32_bytes
-
JWT_SECRET=llm_filter_secure_secret_key_2025_update_must_be_32_bytes
-
DIFY_API_URL=http://datacenter.dldzxx.cn:8089/v1
-
DIFY_API_URL=http://datacenter.dldzxx.cn:8089/v1
-
DIFY_API_KEY=app-xTl0Ri6ir7cAuvngDtFe3hKP
-
DIFY_API_KEY=app-xTl0Ri6ir7cAuvngDtFe3hKP
-
MONGODB_URL=mongodb://mongo:27017
-
MONGODB_DB_NAME=security_service_db
depends_on
:
-
mongo
networks
:
networks
:
-
llm-network
-
llm-network
...
...
microservices/security-service/SECURITY_SERVICE.md
View file @
0e2c0172
...
@@ -173,21 +173,32 @@ Content-Type: application/json
...
@@ -173,21 +173,32 @@ Content-Type: application/json
当前版本的 Security Service:
当前版本的 Security Service:
-
不写入任何数据库(PostgreSQL / MongoDB)
-
**数据持久化**
:分析结果(风险分析与攻击建议)会异步存储到
**MongoDB**
数据库中。
-
不记录历史分析结果或报告
-
**历史查询**
:提供接口查询历史分析记录。
-
所有分析基于:
-
请求中传入的设备数据
-
实时从 Dify 获取的分析结果
后续如果需要:
## 7. 历史查询接口
-
可以将分析结果落库到 PostgreSQL 或 MongoDB
### 7.1 安全分析历史
-
典型扩展:
-
安全日报历史查询
-
风险趋势分析
-
设备安全基线与偏离检测
## 7. 快速调试示例(curl)
-
方法:
`GET`
-
URL:
`/api/v1/security/analysis/history`
-
参数:
-
`start_date`
(可选): 开始时间 (ISO 8601)
-
`end_date`
(可选): 结束时间 (ISO 8601)
-
`limit`
(可选): 返回数量限制,默认 20
-
响应:包含
`total`
和
`items`
(AnalysisHistoryItem)
### 7.2 攻击建议历史
-
方法:
`GET`
-
URL:
`/api/v1/security/attack-advice/history`
-
参数:
-
`start_date`
(可选): 开始时间 (ISO 8601)
-
`end_date`
(可选): 结束时间 (ISO 8601)
-
`limit`
(可选): 返回数量限制,默认 20
-
响应:包含
`total`
和
`items`
(AttackAdviceHistoryItem)
## 8. 快速调试示例(curl)
确保容器已启动后,可以在宿主机直接运行:
确保容器已启动后,可以在宿主机直接运行:
...
...
microservices/security-service/app/api/v1/endpoints.py
View file @
0e2c0172
from
fastapi
import
APIRouter
,
Depends
from
fastapi
import
APIRouter
,
Depends
,
Query
from
app.schemas.payloads
import
*
from
app.schemas.payloads
import
*
from
app.services.analysis
import
SecurityService
from
app.services.analysis
import
SecurityService
from
app.services.rss
import
RSSService
from
app.services.rss
import
RSSService
from
app.core.security
import
get_current_admin
from
app.core.security
import
get_current_admin
from
app.core.database
import
db
from
datetime
import
datetime
,
timezone
router
=
APIRouter
()
router
=
APIRouter
()
service
=
SecurityService
()
service
=
SecurityService
()
...
@@ -10,11 +12,51 @@ rss_service = RSSService()
...
@@ -10,11 +12,51 @@ rss_service = RSSService()
@
router
.
post
(
"/analysis"
,
response_model
=
SecurityAnalysisResponse
)
@
router
.
post
(
"/analysis"
,
response_model
=
SecurityAnalysisResponse
)
async
def
analyze_risks
(
request
:
SecurityAnalysisRequest
,
admin
:
dict
=
Depends
(
get_current_admin
)):
async
def
analyze_risks
(
request
:
SecurityAnalysisRequest
,
admin
:
dict
=
Depends
(
get_current_admin
)):
return
await
service
.
analyze_risks
(
request
.
devices
)
result
=
await
service
.
analyze_risks
(
request
.
devices
)
# 异步存储结果到 MongoDB
if
db
.
db
is
not
None
:
log_entry
=
result
.
model_dump
()
log_entry
[
"created_at"
]
=
datetime
.
now
(
timezone
.
utc
)
await
db
.
db
.
security_analysis_logs
.
insert_one
(
log_entry
)
return
result
@
router
.
get
(
"/analysis/history"
,
response_model
=
HistoryQueryResponse
)
async
def
get_analysis_history
(
start_date
:
Optional
[
datetime
]
=
Query
(
None
,
description
=
"开始时间 (ISO 8601)"
),
end_date
:
Optional
[
datetime
]
=
Query
(
None
,
description
=
"结束时间 (ISO 8601)"
),
limit
:
int
=
Query
(
20
,
ge
=
1
,
le
=
100
,
description
=
"返回数量限制"
),
admin
:
dict
=
Depends
(
get_current_admin
)
):
"""
查询安全分析历史记录
"""
return
await
service
.
get_analysis_history
(
start_date
,
end_date
,
limit
)
@
router
.
post
(
"/attack-advice"
,
response_model
=
AttackAdviceResponse
)
@
router
.
post
(
"/attack-advice"
,
response_model
=
AttackAdviceResponse
)
async
def
get_attack_advice
(
request
:
AttackAdviceRequest
,
admin
:
dict
=
Depends
(
get_current_admin
)):
async
def
get_attack_advice
(
request
:
AttackAdviceRequest
,
admin
:
dict
=
Depends
(
get_current_admin
)):
return
await
service
.
get_attack_advice
(
request
.
attack_type
,
request
.
target_device
,
request
.
logs
)
result
=
await
service
.
get_attack_advice
(
request
.
attack_type
,
request
.
target_device
,
request
.
logs
)
# 异步存储结果到 MongoDB
if
db
.
db
is
not
None
:
log_entry
=
result
.
model_dump
()
log_entry
[
"created_at"
]
=
datetime
.
now
(
timezone
.
utc
)
await
db
.
db
.
attack_advice_logs
.
insert_one
(
log_entry
)
return
result
@
router
.
get
(
"/attack-advice/history"
,
response_model
=
HistoryQueryResponse
)
async
def
get_attack_advice_history
(
start_date
:
Optional
[
datetime
]
=
Query
(
None
,
description
=
"开始时间 (ISO 8601)"
),
end_date
:
Optional
[
datetime
]
=
Query
(
None
,
description
=
"结束时间 (ISO 8601)"
),
limit
:
int
=
Query
(
20
,
ge
=
1
,
le
=
100
,
description
=
"返回数量限制"
),
admin
:
dict
=
Depends
(
get_current_admin
)
):
"""
查询攻击建议历史记录
"""
return
await
service
.
get_attack_advice_history
(
start_date
,
end_date
,
limit
)
@
router
.
get
(
"/report"
,
response_model
=
SecurityReportResponse
)
@
router
.
get
(
"/report"
,
response_model
=
SecurityReportResponse
)
async
def
generate_report
(
admin
:
dict
=
Depends
(
get_current_admin
)):
async
def
generate_report
(
admin
:
dict
=
Depends
(
get_current_admin
)):
...
...
microservices/security-service/app/core/config.py
View file @
0e2c0172
...
@@ -12,6 +12,10 @@ class Settings(BaseSettings):
...
@@ -12,6 +12,10 @@ class Settings(BaseSettings):
DIFY_API_URL
:
str
=
"http://datacenter.dldzxx.cn:8089/v1"
DIFY_API_URL
:
str
=
"http://datacenter.dldzxx.cn:8089/v1"
DIFY_API_KEY
:
str
=
"app-lkK33EQOVXXrjD9x3SKbItr7"
DIFY_API_KEY
:
str
=
"app-lkK33EQOVXXrjD9x3SKbItr7"
# MongoDB 配置
MONGODB_URL
:
str
=
"mongodb://localhost:27017"
MONGODB_DB_NAME
:
str
=
"security_service_db"
class
Config
:
class
Config
:
case_sensitive
=
True
case_sensitive
=
True
...
...
microservices/security-service/app/core/database.py
0 → 100644
View file @
0e2c0172
from
motor.motor_asyncio
import
AsyncIOMotorClient
from
app.core.config
import
settings
class
Database
:
client
:
AsyncIOMotorClient
=
None
db
=
None
def
connect
(
self
):
self
.
client
=
AsyncIOMotorClient
(
settings
.
MONGODB_URL
)
self
.
db
=
self
.
client
[
settings
.
MONGODB_DB_NAME
]
print
(
f
"Connected to MongoDB at {settings.MONGODB_URL}"
)
def
close
(
self
):
if
self
.
client
:
self
.
client
.
close
()
print
(
"MongoDB connection closed"
)
db
=
Database
()
async
def
get_database
():
return
db
.
db
microservices/security-service/app/main.py
View file @
0e2c0172
from
fastapi
import
FastAPI
from
fastapi
import
FastAPI
from
contextlib
import
asynccontextmanager
from
app.api.v1.endpoints
import
router
as
security_router
from
app.api.v1.endpoints
import
router
as
security_router
from
app.core.config
import
settings
from
app.core.config
import
settings
from
app.core.database
import
db
app
=
FastAPI
(
title
=
settings
.
PROJECT_NAME
)
@
asynccontextmanager
async
def
lifespan
(
app
:
FastAPI
):
# Startup
db
.
connect
()
yield
# Shutdown
db
.
close
()
app
=
FastAPI
(
title
=
settings
.
PROJECT_NAME
,
lifespan
=
lifespan
)
# 注册路由
# 注册路由
app
.
include_router
(
security_router
,
prefix
=
f
"{settings.API_V1_STR}/security"
,
tags
=
[
"Security"
])
app
.
include_router
(
security_router
,
prefix
=
f
"{settings.API_V1_STR}/security"
,
tags
=
[
"Security"
])
...
...
microservices/security-service/app/schemas/payloads.py
View file @
0e2c0172
from
typing
import
List
,
Optional
,
Any
,
Union
from
typing
import
List
,
Optional
,
Any
,
Union
from
pydantic
import
BaseModel
from
pydantic
import
BaseModel
from
datetime
import
datetime
class
DeviceInfo
(
BaseModel
):
class
DeviceInfo
(
BaseModel
):
id
:
str
id
:
str
...
@@ -51,3 +52,15 @@ class RSSItem(BaseModel):
...
@@ -51,3 +52,15 @@ class RSSItem(BaseModel):
class
RSSFeedResponse
(
BaseModel
):
class
RSSFeedResponse
(
BaseModel
):
items
:
List
[
RSSItem
]
items
:
List
[
RSSItem
]
class
AnalysisHistoryItem
(
SecurityAnalysisResponse
):
id
:
str
created_at
:
datetime
class
AttackAdviceHistoryItem
(
AttackAdviceResponse
):
id
:
str
created_at
:
datetime
class
HistoryQueryResponse
(
BaseModel
):
total
:
int
items
:
List
[
Union
[
AnalysisHistoryItem
,
AttackAdviceHistoryItem
]]
microservices/security-service/app/services/analysis.py
View file @
0e2c0172
...
@@ -5,6 +5,7 @@ from typing import List, Dict, Any, Optional
...
@@ -5,6 +5,7 @@ from typing import List, Dict, Any, Optional
from
pydantic
import
ValidationError
from
pydantic
import
ValidationError
from
app.schemas.payloads
import
*
from
app.schemas.payloads
import
*
from
app.core.config
import
settings
from
app.core.config
import
settings
from
app.core.database
import
db
import
logging
import
logging
logger
=
logging
.
getLogger
(
__name__
)
logger
=
logging
.
getLogger
(
__name__
)
...
@@ -66,17 +67,63 @@ class SecurityService:
...
@@ -66,17 +67,63 @@ class SecurityService:
async
def
monitor_risks
(
self
)
->
RiskMonitorResponse
:
async
def
monitor_risks
(
self
)
->
RiskMonitorResponse
:
"""
"""
任务:漏洞监测
[MOCK] 实时风险监控
"""
"""
# 注意:此处应从外部漏洞库或配置获取关注列表
return
RiskMonitorResponse
(
recent_vulns
=
[]
detected_vulnerabilities
=
[
"CVE-2024-0001 (Critical)"
,
"Weak SSH Config"
],
compliance_risks
=
[
"Password policy outdated"
,
"Unencrypted backup found"
],
ai_assessment
=
"System security posture is stable but requires attention on recent CVEs."
)
async
def
get_analysis_history
(
self
,
start_date
:
datetime
=
None
,
end_date
:
datetime
=
None
,
limit
:
int
=
20
)
->
HistoryQueryResponse
:
"""
查询安全分析历史
"""
if
db
.
db
is
None
:
return
HistoryQueryResponse
(
total
=
0
,
items
=
[])
inputs
=
{
query
=
{}
"task_type"
:
"monitor"
,
if
start_date
or
end_date
:
"context_data"
:
json
.
dumps
(
recent_vulns
,
ensure_ascii
=
False
)
query
[
"created_at"
]
=
{}
}
if
start_date
:
query
[
"created_at"
][
"$gte"
]
=
start_date
if
end_date
:
query
[
"created_at"
][
"$lte"
]
=
end_date
total
=
await
db
.
db
.
security_analysis_logs
.
count_documents
(
query
)
cursor
=
db
.
db
.
security_analysis_logs
.
find
(
query
)
.
sort
(
"created_at"
,
-
1
)
.
limit
(
limit
)
items
=
[]
async
for
doc
in
cursor
:
doc
[
"id"
]
=
str
(
doc
.
pop
(
"_id"
))
items
.
append
(
AnalysisHistoryItem
(
**
doc
))
return
HistoryQueryResponse
(
total
=
total
,
items
=
items
)
async
def
get_attack_advice_history
(
self
,
start_date
:
datetime
=
None
,
end_date
:
datetime
=
None
,
limit
:
int
=
20
)
->
HistoryQueryResponse
:
"""
查询攻击建议历史
"""
if
db
.
db
is
None
:
return
HistoryQueryResponse
(
total
=
0
,
items
=
[])
return
await
self
.
_call_llm
(
inputs
,
RiskMonitorResponse
)
query
=
{}
if
start_date
or
end_date
:
query
[
"created_at"
]
=
{}
if
start_date
:
query
[
"created_at"
][
"$gte"
]
=
start_date
if
end_date
:
query
[
"created_at"
][
"$lte"
]
=
end_date
total
=
await
db
.
db
.
attack_advice_logs
.
count_documents
(
query
)
cursor
=
db
.
db
.
attack_advice_logs
.
find
(
query
)
.
sort
(
"created_at"
,
-
1
)
.
limit
(
limit
)
items
=
[]
async
for
doc
in
cursor
:
doc
[
"id"
]
=
str
(
doc
.
pop
(
"_id"
))
items
.
append
(
AttackAdviceHistoryItem
(
**
doc
))
return
HistoryQueryResponse
(
total
=
total
,
items
=
items
)
async
def
_call_llm
(
self
,
inputs
:
Dict
[
str
,
Any
],
model_cls
):
async
def
_call_llm
(
self
,
inputs
:
Dict
[
str
,
Any
],
model_cls
):
try
:
try
:
...
...
microservices/security-service/requirements.txt
View file @
0e2c0172
...
@@ -6,3 +6,5 @@ python-jose[cryptography]==3.3.0
...
@@ -6,3 +6,5 @@ python-jose[cryptography]==3.3.0
httpx==0.27.0
httpx==0.27.0
python-dotenv==1.0.1
python-dotenv==1.0.1
feedparser>=6.0.10
feedparser>=6.0.10
motor==3.3.2
pymongo<4.7
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment