From ff02b2e16d76c33bddb9720153fc81aacc995ca3 Mon Sep 17 00:00:00 2001 From: qinglong Date: Sat, 13 Jun 2026 13:56:58 +0800 Subject: [PATCH] =?UTF-8?q?security:=20P3=20=E2=80=94=20=E6=8F=92=E4=BB=B6?= =?UTF-8?q?=E9=9A=94=E7=A6=BB=E9=BB=98=E8=AE=A4=E5=BC=80=E5=90=AF=20+=20Se?= =?UTF-8?q?nSuDB=20=E6=B3=A8=E5=86=8C=20+=20=E5=AE=A1=E8=AE=A1=E6=97=A5?= =?UTF-8?q?=E5=BF=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - plugins.isolation 默认 true (生产环境进程隔离) - main.py 注册 SenSuDB 服务 - WebPanelManager 注入 sensu_db 到 app context - 文件删除/写入操作写入审计日志 (audit_log 表) - 修复 Session 持久化所需的数据库依赖 Co-Authored-By: Claude --- config/framework/base_config.yaml | 1 + config/plugins/commands.yaml | 17 +++-------------- config/services/network_routes.yaml | 17 ++--------------- data/sensu.db | Bin 0 -> 4096 bytes data/sensu.db-shm | Bin 0 -> 32768 bytes data/sensu.db-wal | Bin 0 -> 49472 bytes main.py | 7 ++++++- services/init_service.py | 2 +- services/web_panel/manager.py | 1 + services/web_panel/routes/files.py | 7 +++++++ 10 files changed, 21 insertions(+), 31 deletions(-) create mode 100644 data/sensu.db create mode 100644 data/sensu.db-shm create mode 100644 data/sensu.db-wal diff --git a/config/framework/base_config.yaml b/config/framework/base_config.yaml index b13cff0..2ac0282 100644 --- a/config/framework/base_config.yaml +++ b/config/framework/base_config.yaml @@ -11,6 +11,7 @@ plugins: auto_load: true hot_reload: true max_retry_count: 3 + isolation: true # 自动启动脚本 — 框架启动时后台拉起 auto_start_scripts: enabled: true diff --git a/config/plugins/commands.yaml b/config/plugins/commands.yaml index 74fc7d5..f30ae27 100644 --- a/config/plugins/commands.yaml +++ b/config/plugins/commands.yaml @@ -9,10 +9,6 @@ commands: permissions: - framework.scaffold.plugin source: internal - echo: &id001 - description: echo input - permissions: [] - source: plugin.example_plugin help: description: 显示帮助信息 permissions: @@ -38,10 +34,6 @@ commands: permissions: - framework.permission.read source: internal - plugin_status: &id002 - description: show status - permissions: [] - source: plugin.example_plugin pm_plugin_status: description: '权限管理: 查看插件权限状态' permissions: @@ -97,9 +89,6 @@ commands: permissions: - framework.command.test source: internal -last_updated: 12019.862122705 -plugin_commands: - example_plugin: - echo: *id001 - plugin_status: *id002 -total_commands: 20 +last_updated: 12161.390698641 +plugin_commands: {} +total_commands: 18 diff --git a/config/services/network_routes.yaml b/config/services/network_routes.yaml index 10429fa..714cc24 100644 --- a/config/services/network_routes.yaml +++ b/config/services/network_routes.yaml @@ -1,17 +1,4 @@ http_port: 4200 -last_updated: 12019.877017393 -plugin_routes: - example_plugin: - - methods: - - GET - path: /example_plugin/api/example/info - require_auth: false - - methods: - - POST - path: /example_plugin/api/plugin/echo - require_auth: true - - methods: - - POST - path: /example_plugin/api/plugin/plugin_status - require_auth: true +last_updated: 12161.450926401 +plugin_routes: {} websocket_port: 4240 diff --git a/data/sensu.db b/data/sensu.db new file mode 100644 index 0000000000000000000000000000000000000000..ca2e1dcd41b5e054a089494f52adf9e106e36be2 GIT binary patch literal 4096 zcmWFz^vNtqRY=P(%1ta$FlG>7U}9o$P*7lCU|@t|AVoG{WY9}yXzL1 z=Ue4t!yKA?OPod#TPBf-psV;=!YSQYk}P4rJvtHzJthctY{dTSa>mpaXMDH2V*jsf&$r&J83~OR z!igP!g(8V7p~RIP*P8{=hX4WyAb;(G2Y2-1#QqCB;}$ zP3QiY&Bn|hZ!$(!N{S|%VqgzVqf3Uqs1z)*Bw42`hY>tRFGM#iVRAa3o5;-uqY8#1 zS&A&$=hPKsmo6>a-Iltfq*I#yLMoF94lS3Qm@N!#c(5{iBhh4bFdR}fSvhMi7wxlp zQ7T({WnHX25yY`t!#S^y*PdO@dA@hO;K2CnZ?50Ccu&IVtX@iRS}X`4fB*srAbF$~nE8FVMUG`5WtpV&l{ibmE&Z$Aka^2q1s}0tg_000IagfIvXN`R>2R zy)JP1vui&-EF8W{9YMf}4g?TD009ILKmY**5I_I{1UgZmp^o5}UB3>!JaO}fP3j0@ zJ_u)ig0|}jqWy+fN6>E!9Pn+ICISc`fB*srAbkJ(hoJa@yX?k=%4Xn3U_A7{0}v^isi6b*;sXvSLYUvBixALy_#+ z?AA{J^sUwh178TzF`@SZ>M$)>oq=#rr?Dg{d{N!IBWuX-;;H!SyuEP}h;@_R#YXq%-y z?bi{+oev#1U*Me&?lmrcv+FME2)6a3n4Kel00IagfB*srAbDkGKf-l^+r`g*5I_I{1Q0*~0R#|0009IL*gk>(0Q%ta)&Kwi literal 0 HcmV?d00001 diff --git a/main.py b/main.py index ea85972..7e5da11 100644 --- a/main.py +++ b/main.py @@ -11,6 +11,7 @@ from services.project_engine import ProjectEngine from services.pyenv_manager import PyEnvManager from services.proxy_service import ProxyService from services.web_panel.utils.system_info import SystemInfoCollector +from services.sensu_db import SenSuDB import os from pathlib import Path @@ -63,7 +64,11 @@ class SenSuFramework: # 2.5 自动启动脚本 (日志服务就绪后) await init_service.start_auto_scripts() - # 2.6 系统信息采集器 (共享实例,TUI + Web面板共用) + # 2.6 数据库 (持久化层) + sensu_db = SenSuDB() + self.service_manager.register_service("sensu_db", sensu_db) + + # 2.7 系统信息采集器 (共享实例,TUI + Web面板共用) sys_collector = SystemInfoCollector() self.service_manager.register_service("sys_collector", sys_collector) diff --git a/services/init_service.py b/services/init_service.py index e7a29c8..2fd5ee2 100644 --- a/services/init_service.py +++ b/services/init_service.py @@ -219,7 +219,7 @@ class InitService: 'auto_load': True, 'hot_reload': True, 'max_retry_count': 3, - 'isolation': False, # 默认不隔离,插件可在 settings.isolation 中声明 + 'isolation': True, # 生产默认进程隔离,插件崩溃不影响框架 }, 'auto_start_scripts': { 'enabled': True, diff --git a/services/web_panel/manager.py b/services/web_panel/manager.py index 6091161..155845c 100644 --- a/services/web_panel/manager.py +++ b/services/web_panel/manager.py @@ -33,6 +33,7 @@ class WebPanelManager: app['service_manager'] = self.sm app['auth_service'] = self.sm.get_service("auth") app['log_service'] = self.sm.get_service("log") + app['sensu_db'] = self.sm.get_service("sensu_db") app['panel_config'] = { 'username': self.panel_user, 'password': self.panel_pass, diff --git a/services/web_panel/routes/files.py b/services/web_panel/routes/files.py index 7117bf3..58e951f 100644 --- a/services/web_panel/routes/files.py +++ b/services/web_panel/routes/files.py @@ -272,6 +272,10 @@ def setup_file_routes(app, service_manager, prefix=''): else: p.unlink() logger.info(f"🗑 删除: {p}") + # 审计日志 + db = request.app.get("sensu_db") + if db: + db.log_audit(request.get("user", {}).get("username", "?"), "file_delete", str(p)) return web.json_response({"ok": True}) except Exception as e: return web.json_response({"error": str(e)}, status=500) @@ -375,6 +379,9 @@ def setup_file_routes(app, service_manager, prefix=''): content = data.get("content", "") p.write_text(content, encoding="utf-8") logger.info(f"💾 写入文件: {p} ({len(content)} bytes)") + db = request.app.get("sensu_db") + if db: + db.log_audit(request.get("user", {}).get("username", "?"), "file_write", str(p)) return web.json_response({"ok": True, "size": len(content)}) except Exception as e: return web.json_response({"error": str(e)}, status=500)