G9 企业安全
系列定位:A–D 讲「每个零件怎么装」,E 讲「出错怎么查」,F 讲「把零件串成场景」, G 讲「装完之后,企业要的那几件事」。 G1 讲了私有化(数据不出内网);G2–G6 讲了私有知识库(把文档喂给模型); G9 讲「这套东西给多个组用之后,怎么管人、怎么分家、怎么记账」。
第一段 章前定位
这课不教你什么:
- 不教合规。 等保几级、数据怎么分级、审计日志要留几年 —— 这些是制度与法规层面, 官方文档里没有,将来单独成文,本课不涉及。
- 不重复 G1。 G1 已经讲过「私有化 = 部署位置 + 数据流向 + 资产保护」这三件事、 CANN 层的 PMCC 模型混淆、AVI 是什么、《加固须知》那句话。本课不再展开这些。
- 不重复 G3。 G3 讲知识库搭建时,已经点过
add_knowledge(..., user_id, role)的参数含义 和white_paths是什么。本课不重讲参数,只讲它在整个权限体系里占哪一格。 - 不给一套现成的等保配置。 官方明确说加固措施要按所在组织的安全策略定, 本课给的是判断依据和清单,不是照抄的配置。
这课要教你什么:
企业安全的诉求听起来很多。落到技术实现上,先问一句话就够了: 「这个能力,官方给了吗?」
答案永远落在三档里: ① 官方给了,直接用;② 官方给了机制,策略你来定;③ 官方没给,自己接。
大部分项目出问题,不是把 ③ 做错了,是把 ② 当成了 ① —— 以为「有参数」就等于「有了系统」。
第二段 学习目标
学完这课,你应该能回答下面五个问题(能答上来就是学会了):
- 拿到一条安全需求,怎么先判断它属于「官方给了 / 官方给机制 / 官方没给」哪一档?
- 权限这件事,官方在 RAG SDK 和 MindIE Motor 两侧分别给到了哪一层? 为什么「业务用户体系」这一层永远要自己做?
- 隔离这件事,官方给的手段是什么?硬件虚拟化和软件虚拟化各自适合什么场景? 官方列的使用约束里,哪几条是动手前必须先核的?
- 审计这件事,官方在日志侧给了哪些开关?为什么「审计字段怎么设计」官方一定不会给?
- 哪些东西是官方没给出、必须按你所在组织安全策略定的? (答不上这条,说明你会把「没做的」当成「官方说有」)
第三段 全景:三件事 × 三档
企业安全落到技术上就是三件事:
- 权限(认人) —— 谁可以用、可以用到什么粒度;
- 隔离(分家) —— 两个人的活儿互不干扰、互相看不见;
- 审计(记账) —— 发生了什么、谁做的、留得住证据。
每一件事都落在三档上:
| 档 | 权限(认人) | 隔离(分家) | 审计(记账) |
|---|---|---|---|
| ① 官方给了,直接用 | 知识库归属与查询权限:user_id / role(admin / member) |
AVI 虚拟化实例(vNPU)多租户隔离 | MindIE 日志开关与轮转(MINDIE_LOG_*) |
| ② 官方给机制,策略你定 | 服务侧 TLS / API Key / 限流(MindIE Motor) | 硬件虚拟化 or 软件虚拟化、切分模板组合 | 日志级别、日志内容、落盘路径 |
| ③ 官方没给,自己接 | 认证、组织架构、会话、细粒度数据权限 | 业务租户的配额、计费、生命周期 | 审计字段、留存期限、集中收集、告警 |
一句话记住:官方给的是「零件」,不是「制度」。
user_id是一个零件,不等于你有了一套权限系统; 日志开关是一个零件,不等于你有了审计。
⚠️ 三件事不是并列的,是有顺序的:
先认人 再分家 后记账
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ 权 限 │ │ 隔 离 │ │ 审 计 │
│ 不知道谁是谁 │ ->│ 分不清谁和谁 │ ->│ 记下来也没用 │
└──────────────┘ └──────────────┘ └──────────────┘
为什么是这个顺序:隔离要按「谁」来分,审计要记「谁」做了什么。 「谁」这个身份没定下来,后面的隔离和审计都无从设计 —— 这是很多人上来先做网络加固、最后才发现身份体系没想清楚的原因。
第四段 【如果我来做】一条真实的执行路径
这一节是本课的核心。 前三段讲的是「三件事怎么分档」,这一节讲的是: 如果现在把这件事交给我,我从哪里开始、按什么顺序做、每一步凭什么判断。
4.0 先记住一句话:顺序错了会返工
安全工程最容易犯的错是顺序颠倒 —— 比如:
- 先把服务暴露出去,再想鉴权 → 要改网关、改调用方,前面白做;
- 先切了 vNPU,才发现操作系统版本不支持虚拟化 → 要重装系统;
- 先设计了审计日志,才发现连「用户是谁」都还没有 → 字段写不出来,推倒重来;
- 先上了多租户,才发现业务只需要独占一台 → 过度设计,白折腾。
所以我的顺序是:摸底 → 分三层 → 认人 → 分家 → 记账 → 盘点数据 → 收口 → 出证据。
4.1 第 0 步:先摸底(不装不改,只查三样)
目的:在你动手之前,把三个事实查清楚 —— 门开着哪些、加固项做了没有、数据落在哪。
命令 ss -lntp
含义:列出本机正在监听的所有 TCP 端口,以及是哪个进程在听 拆解:-l 只看 listening(正在等连接的)/-n 端口用数字显示(不解析成服务名,更准)/ -t 只看 TCP/-p 显示进程(process),即「谁在干这件事」 用法:
ss -lntp期望:一张表,每行一个监听端口 + 进程名 + PID。列表越短越好 不过会怎样:命令不存在 → 系统太精简,装iproute2; 看到0.0.0.0:*或:::*的监听 → 这就是「全网侦听」 ⭐ 这条对应官方《安全加固》里「端口扫描」那一节的要求: 「需要关注全网侦听的端口和非必要端口,如有非必要端口请及时关闭」。 我会把这张表逐行过一遍,每行都要能说出「为什么它必须开着」。
命令 cat /etc/login.defs | grep ALWAYS_SET_PATH
含义:检查是否配置了
ALWAYS_SET_PATH(官方《安全加固·防火墙配置》给的一项) 拆解:cat(打印文件)+|(把前一个命令的输出交给后一个)+grep(筛出含关键词的行) 用法:cat /etc/login.defs | grep ALWAYS_SET_PATH期望:打印出形如ALWAYS_SET_PATH yes的行 不过会怎样:什么都不打印 → 这一项还没配。 官方给的配法是:在/etc/login.defs文件中新增ALWAYS_SET_PATH=yes,防止越权操作; 另外为了防止普通用户通过su root继承环境变量提权, 可把/etc/default/su里的ALWAYS_SET_PATH也设为yes
查加固项是否就位(一次看完四项):我不逐条敲命令,而是列成一张核对表, 每一项的判据都来自官方文档原文(下表的「官方口径」列就是出处摘要):
| 加固项 | 官方口径(摘要) | 我怎么判它做完了 |
|---|---|---|
| umask | 建议将宿主机和容器中的 umask 设置为 027 及以上 | 两台机器上分别 umask 看到 0027 或更小权限 |
| 无属主文件 | 执行 find / -nouser -o -nogroup 查找 |
输出为空 |
| 端口 | 关注全网侦听端口,关闭 telnet、ftp 等 | 4.1 第一张表里没有这些 |
| 文件权限 | 使用 API 读文件时,文件 owner 必须为自己,且权限不大于 640 | 待读取目录里没有 644/777 的数据文件 |
摸底结论表(我会这样填):
| 查到什么 | 说明什么 | 影响后面哪一步 |
|---|---|---|
| 监听了哪些端口 | 暴露面有多大 | 4.2 分三层(服务层要不要加 TLS) |
| 加固项做了几项 | 底座牢不牢 | 4.7 收口时的验收 |
| 有几个用户/组要用这台机器 | 要不要做多租户 | 4.4 隔离(这是不可返工的一项) |
| 用户的身份从哪来(现有账号体系?) | 权限体系怎么接 | 4.3 权限 |
⚠️ 摸底阶段最后一件必查的事:用户的身份从哪来。 因为「隔离要按谁来分、审计要记谁做了」都取决于它 —— 如果这时还没有答案,后面两步都得停。 这一步必须问业务方,不是问机器。
4.2 第 1 步:先把「三层」划出来(不划会重复做)
很多人做安全做到一半发现「怎么越做越乱」,根因是没有分层。 昇腾这套栈上,和「谁可以用、能不能互相看见、能不能查到」相关的,正好是三层:
| 层 | 管什么 | 官方在这一层给了什么 | 谁负责 |
|---|---|---|---|
| 设备 / 资源层 | 一张卡怎么分给几个人 | AVI 虚拟化实例(vNPU)、容器隔离 | 算力平台 / 运维 |
| 服务层 | 谁可以调这个推理服务 | MindIE Motor 的 TLS / API Key / 限流 | 服务部署方 |
| 应用层 | 谁可以看哪个知识库、问什么 | RAG SDK 的知识库归属与查询权限 | 业务应用开发 |
划层的意义:同一个需求往往横跨三层,但每层的做法完全不同。 比如「A 部门不能看 B 部门的资料」—— 设备层用 vNPU 分家,服务层用两个服务实例 + 各自的 API Key, 应用层用知识库的
user_id/role区隔。 只做一层,就以为做完了,是这行最常见的漏项。
4.3 第 2 步:权限 —— 把官方给的用满,再补自己那一层
先看清官方到底给了多少。 官方有两句话看起来矛盾,其实是两个层次:
第一句(RAG SDK《简介》):RAG SDK 提供各模块化功能接口…… 供用户开发上层应用,不包含用户、权限等和业务强相关的功能接口。
第二句(RAG SDK《知识管理》):
KnowledgeStore提供知识库及知识库用户的增加、删除、查询等功能。
这两句说的是两件事:
| 层次 | 官方给不给 | 依据(官方接口 / 原话) |
|---|---|---|
| 知识库归属与查询权限(这个库归谁、谁能查) | ✅ 给 | user_id / role(admin / member)/ add_usr_id_to_knowledge |
| 业务级权限体系(认证、组织架构、会话、细粒度管控、审计) | ❌ 不给 | 《简介》原话:「不包含用户、权限等和业务强相关的功能接口」 |
所以我的做法是:官方的这一格用满,绝不自己再造一个轮子。
官方给的这一套,核心就是三个角色动作(都来自《知识管理》接口参考):
① 建库时指定归属 add_knowledge(knowledge_name, user_id, role)
② 给别的用户授权 add_usr_id_to_knowledge(knowledge_name, user_id, role)
③ 收回授权 delete_usr_id_from_knowledge(knowledge_name, user_id, role)
⭐ 关键判据:role 只有两个合法值
admin= 知识库管理员(可增删文档)/member= 仅有查询权限的成员。 官方原文:add_usr_id_to_knowledge的角色 「只能为知识库管理员'admin'或对知识库仅有查询权限的成员'member'」。
⭐⭐ 一个必须记住的隐藏坑:user_id 有格式要求
官方原文:
user_id需满足正则^[a-zA-Z0-9_-]{6,64}$。 意思是:只能是字母、数字、下划线、连字符,长度 6–64。 不能有中文、不能有@、不能有.。
为什么这条对权限设计是硬约束:如果你打算直接把公司邮箱当 user_id ——
它带 @ 和 .,会直接不合法。 必须先在应用层做一次映射(邮箱 → 合规 ID)。
这一层映射,官方不会替你做。
命令 python3 -c "from mx_rag.knowledge import KnowledgeStore; s=KnowledgeStore(db_path='./sql.db'); print(s.get_all_usr_role_by_knowledge('test'))"
含义:把某个知识库下的所有用户和他们的角色打出来 —— 这是权限的「账本」 拆解:
get_all_usr_role_by_knowledge(knowledge_name)返回dict{user_id: role}, key 是用户 ID,value 是角色 用法:换成你自己的库名和db_path(db_path不能用/tmp、/etc、/dev这类路径) 期望:打印出形如{'zhangsan01': 'admin', 'lisi0002': 'member'}的字典 不过会怎样:报KeyError或返回空 → 库名写错,或建库时没记在这个KnowledgeStore实例里; 报路径非法 →db_path落在官方禁用清单(/etc、/usr/bin、/sys/、/dev/、/sbin、/tmp等) ⭐ 这张表就是我的「权限现状」证据:交付时附上它,比说「我们做了权限控制」有说服力
官方没给的,就在这里,要自己接:
| 要自己做的 | 为什么官方不给 |
|---|---|
| 用户登录 / 认证(账号密码、单点登录) | 与具体企业的身份源强相关 |
| 用户目录与组织架构(部门、岗位) | 每个企业不一样 |
| 会话与令牌生命周期 | 属于应用安全 |
| 细粒度数据权限(同一库内按字段/行过滤) | role 只有 admin/member 两档,做不到 |
把业务身份映射成合规的 user_id |
见上面那条正则 |
⭐ 服务层还有个官方给的东西别浪费:MindIE Motor 提供了服务侧的认证与限流。 官方《API 参考 · 安全、认证与限流》给的三个开关:
| 能力 | 官方给的配置项 | 说明 |
|---|---|---|
| 传输加密 | infer_tls_config.enable_tls / mgmt_tls_config.enable_tls |
为 true 时,推理/管理接口端口使用 https |
| 请求鉴权 | api_key_config.header_name(默认 Authorization)、api_key_config.key_prefix(默认 Bearer) |
API Key 对 /v1/completions、/v1/chat/completions 生效 |
| 限流 | rate_limit_config.enable_rate_limit=true |
超限返回 429 |
⚠️ 官方有句话要看清:管理接口仅限 Kubernetes 集群内使用,不提供给集群外使用。 这不是建议,是设计 —— 别把管理端口往集群外映射。
4.4 第 3 步:隔离 —— 先选模式,再核约束
官方给的手段是 AVI(昇腾虚拟化实例)。 官方《功能及原理》的原话值得读两遍:
通过资源虚拟化的方式将物理机配置的 NPU 切分成若干份 vNPU(虚拟 NPU)挂载到容器中使用, 虚拟化管理方式能够实现统一不同规格资源的分配和回收处理, 满足多用户反复申请/释放的资源操作请求…… 多个用户共同使用一台服务器的 NPU,并借助容器进行资源隔离,资源隔离性好, 保证运行环境的平稳和安全,且资源分配、资源回收过程统一,方便多租户管理。
⚠️ 三件事在 G1 已讲过,这里只补 G1 没展开的「怎么选」:
| 模式 | 官方定义 | 谁支持 | 什么时候选它 |
|---|---|---|---|
| 硬件虚拟化 | vNPU 对应的 AICore、AICPU、内存等硬件资源和其他 vNPU 相互隔离,任务互不影响 | Atlas 推理系列的 vir04 / vir04_3c / vir02 / vir02_1c / vir04_3c_ndvpp / vir04_4c_dvpp |
租户之间要对彼此保密(真正的资源隔离) |
| 软件虚拟化 | 创建 vNPU 相当于创建一个虚拟实例,NPU 硬件资源相当于一个资源池 | Ascend 910 只支持软件虚拟化;Atlas 推理系列的 vir01 |
只要「隔离管理」、不要硬隔离;或型号只支持软件虚拟化 |
⭐ 一个很好记的官方细节(vir01 的分时复用):
官方原文:如果用户使用模板
vir01,NPU 分配的 vGroup 同样包含 2 个 AICore, vNPU 通过分时复用的方式使用 vGroup 资源,比如 2 个 vir01 切出的 2 个 vNPU, 每个 vNPU 会串行轮流使用 vGroup 资源(如 vNPU1 使用 1 毫秒,然后 vNPU2 使用 1 毫秒)。 记法:vir04四个核是真给你;vir01是「排队轮流用」—— 延迟敏感的任务别用它。
命令 npu-smi info -t info-vnpu -i <设备id> -c <芯片id>
含义:查某块芯片上已经切出来的 vNPU(这是隔离的「现状账」) 拆解:
npu-smi info(查信息)+-t info-vnpu(查什么:vNPU 信息)+-i(哪台设备,用npu-smi info -l查出的 NPU ID)+-c(哪块芯片,用npu-smi info -m查出的 Chip ID) 用法:npu-smi info -t info-vnpu -i 1 -c 0期望:该芯片上的 vNPU 列表(含虚拟设备号、模板等) 不过会怎样:列表为空 → 该芯片上还没建 vNPU; 报设备不存在 →-i/-c填错了,回 4.1 重查设备号 ⚠️ 官方提示:Atlas 推理系列支持返回 AICPU、Vgroup ID;Ascend 910 不支持返回 —— 少字段不是故障
⚠️ 动手切之前,官方列的「使用约束」必须先核完这四条(出自官方《使用约束》, 这几条是「不可返工」的,装完再发现要推倒重来):
| # | 官方约束原文(摘要) | 我会怎么处理 |
|---|---|---|
| 1 | 物理 NPU 虚拟化出 vNPU 后,不支持再将该物理 NPU 挂载到容器使用;若物理机上创建了虚拟机,不支持再将该物理 NPU 直通到虚拟机使用 | 先定死用途:这张卡是切分用还是整卡用,不能两用 |
| 2 | Atlas 300I Duo 推理卡上两路 NPU 的工作模式必须一致(均虚拟化或均整卡) | 规划时按整卡规划,别一半切一半不切 |
| 3 | 虚拟化实例模板用于对整台服务器上所有标卡进行资源切分,不支持不同规格的标卡混插 | 装机前核对:全机标卡必须同规格 |
| 4 | 使用 vNPU 推理可能出现性能下降;建议用 vir04+vir04_3c 或 vir04+vir02+vir02_1c 组合 |
切分方案直接照官方推荐的组合排 |
⚠️ 还有一条是「先查再买」的:官方《功能及原理》说明 AVI 适用于 「多用户多任务并行,且每个任务算力需求较小的场景」—— 如果业务是单任务吃满整卡,做虚拟化纯属自找麻烦。
官方没给的(隔离这一档里,③ 那部分):
| 要自己做的 | 说明 |
|---|---|
| 租户的配额与计费 | 官方给的是「资源分配/回收」,没有「谁用了多少、算谁的钱」 |
| 租户的生命周期(入职开、离职收) | 与应用层的用户体系绑定,官方不碰 |
| 一张卡该切成几份的业务决策 | 官方给规格,不给你的业务答案 |
4.5 第 4 步:审计 —— 先开官方开关,再审「记什么」
先明确一件事:官方没有「审计模块」这个东西。 官方在审计上给的全是日志侧的机制,「记什么、留多久、谁能看」一个字都没写。
官方给的(日志机制):
| 环境变量 | 官方说明 |
|---|---|
MINDIE_LOG_LEVEL |
日志级别,等级由低到高 DEBUG < INFORMATIONAL < WARNING < ERROR < CRITICAL,默认 info |
MINDIE_LOG_VERBOSE |
是否打印可选信息,默认 true |
MINDIE_LOG_TO_FILE |
是否写入文件,默认 true 写入 |
MINDIE_LOG_TO_STDOUT |
是否打印,默认 false 不打印 |
MINDIE_LOG_ROTATE |
日志轮转:单文件大小 1MB~500MB(默认 20MB),每进程文件个数 1~64(默认 10) |
MINDIE_LOG_PATH |
日志落盘路径,默认 ~/mindie/log/debug |
命令 export MINDIE_LOG_PATH="llm: /home/working/"
含义:把 MindIE 各组件(这里以
llm为例)的日志落到指定目录 —— 审计第一步是「日志得在你够得着的地方」 拆解:格式是 组件名称: 路径; 路径以/开头 = 绝对路径;不以/开头 = 相对~/mindie/log/debug的路径;:前不写组件名 = 对所有组件统一设置;多个组件用;隔开 用法:export MINDIE_LOG_PATH="llm: /home/working/"期望:之后启动的组件把日志写进/home/working/下 不过会怎样:没生效 →export只在当前窗口有效,换窗口就没了(要持久化写进~/.bashrc); 路径里有特殊字符 → 官方说明「路径里不能有特殊字符」 ⚠️ 官方提醒:程序不会校验日志路径是否包含软链接,请保证日志路径合理 —— 这条在审计场景很要命:软链接能被指向别处,日志等于没在你手里
命令 export MINDIE_LOG_ROTATE="-fs 500"
含义:把日志的单文件大小上限设为 500MB —— 这条直接对应官方《安全管理》里对日志的两条检查 拆解:
-fs表示每个日志文件大小(1MB~500MB)/-r表示每个进程可写文件个数(1~64); 不写组件名 = 对所有组件统一设置;示例 2 里torch: -fs 40 -r 1是只调 torch 组件 用法:export MINDIE_LOG_ROTATE="-fs 500"或export MINDIE_LOG_ROTATE="torch: -fs 40 -r 1"期望:日志按设置轮转;轮转文件命名格式为mindie-<组件名>_<进程号>_<时间>.<轮转文件编号>.log不过会怎样:数值超范围(单文件 >500MB 或进程文件数 >64)→ 设置不生效; 不设置的话是默认 20MB × 10 个 = 单进程最多 200MB, 日志空间占满又没有清理机制时,恰恰会把你最需要的那段审计期覆盖掉 ⭐ 官方《安全管理 · 日志管理》原话就是两条: 「检查系统是否可以限制单个日志文件的大小」「检查日志空间占满后,是否存在机制进行清理」
命令 find / -nouser -o -nogroup
含义:查找系统里的无属主文件 / 无属组文件(官方《安全加固》给的一项) 拆解:
find /(从根目录开始找)+-nouser(没有属主的文件)+-o(或)+-nogroup(没有属组的文件) 用法:find / -nouser -o -nogroup期望:输出为空(干净) 不过会怎样:列出文件 → 官方解释了这个现象的原因: 「因为官方 Docker 镜像与物理机上的操作系统存在差异,系统中的用户可能不能一一对应, 导致物理机或容器运行过程中产生的文件变成无属主文件」; 处理办法官方也给了:根据 uid/gid 创建相应的用户和用户组,或修改已有用户的 uid/gid 来适配,赋予文件属主 ⚠️ 为什么审计要关心这个:无属主文件 = 出事之后追不到人 —— 日志文件如果无属主,等于谁都能改
⚠️ 有一条 G1 用过的手段,本课换个角度看它:
G1 用 ss -ntp 判断「数据有没有外发」(数据流向那一档);
在审计这一档里,同一件东西是「会话现状的现场照片」 ——
出事后第一时间要能说清「当时谁和我通着」。
命令 ss -ntp
含义:列出已经建立的 TCP 连接和对应进程 —— 这是审计的第一现场 拆解:
-n端口用数字显示/-t只看 TCP/-p显示进程; 这次没有-l—— 所以看的是「已经连上的」,不是「正在监听的」(4.1 那条才有-l) 用法:ss -ntp期望:一份 ESTABLISHED 连接清单,每条都能对上「我方进程 ↔ 对方地址」 不过会怎样:出现指向公网或陌生内网地址的连接 → 先用ps -p <PID>查这个进程是谁; 把这份清单和 4.1 的ss -lntp(监听的端口)对照, 能连进来的门和实际连着的会话,应该对得上同一批来源 ⭐ 为什么它算审计:日志记的是「过去发生了什么」, 这条命令记的是「此时此刻谁还连着」—— 出事时的第一手证据。
⭐ 官方在审计这件事上,实际只给了一句「方向性」的话(MindEdge《安全加固》):
开启 Docker 守护进程和关键文件的审计功能。开启审计功能能够追溯攻击事件的根源, 此功能开启后,会造成一定的性能影响,需要用户根据业务决定是否开启。
⚠️ 注意这句话的两个特征,正是本课要说的: 1. 它说的是「操作系统层」的审计(Docker 守护进程、关键文件),不是应用层审计; 2. 它把「开不开」的决定权交给了你(「需要用户根据业务决定」)。
官方还给了一个 K8s 侧的钩子(同样出自 MindEdge《安全加固》):
修改或增加启动参数 --audit-policy-file,配置 K8s 的审计策略 ——
注意:官方只给了「用哪个参数」,策略文件写什么,官方指向的是 Kubernetes 官方文档,不是昇腾文档。
官方没给、要自己定的(这一档的 ③):
| 要自己定的 | 说明 |
|---|---|
| 审计字段(谁、何时、对哪个知识库、做了什么、结果) | 官方没有任何审计字段定义 |
| 留存期限与不可篡改性 | 官方未给出 |
| 集中收集(送进 SIEM / 日志平台) | 官方未给出 |
| 告警规则(什么算异常) | 官方未给出 |
| 审计报告格式 | 官方未给出 |
| 应用层操作审计(谁问了什么、看了哪个库) | ⚠️ RAG SDK 层面官方未提供操作审计接口 |
📌 这一整块,正文直接标明:以上均「官方未给出,需按所在组织安全策略定」。 不是我不写,是官方真的没给。 编一套字段设计出来,比不写更危险。
⭐ 有一个离「审计」最近的官方开关,顺手用上:
MxRAGCache 的 set_verbose(verbose) —— 官方说明:
「是否开启详细日志记录,默认值为 False。
True:记录 cache 过程的命中或者未命中。False:不会记录」。
这是官方少有的、能直接反映「业务问了什么」的日志开关 ——
但它记的是缓存命中与否,不是「谁问的」。 别指望它当审计用。
4.6 第 5 步:把「数据资产」盘一遍(这一步最容易被跳过)
权限、隔离、审计都做完之后,还有一件事:数据本身是不是能被人随手拿走。 官方在这里给的全是「风险提醒」,不是「解决方案」,逐条列出来:
① 缓存数据库不加密(官方原文)
RAG SDK 如果使用 Cache 对问题-答案缓存,生成的数据库未做加密存储, 如果涉及银行卡号、身份证号、护照号、口令等个人数据,请勿存放到数据库中。
⭐ 这条要在架构评审时念出来:「缓存能提速」和「缓存不能存个人数据」是同一句话的两半。
② 落盘数据有反序列化攻击面(官方原文)
本接口内部使用了 pickle 模块,有被恶意构造的数据在 unpickle 期间攻击的风险。 需要保证在被加载的落盘数据
data_save_folder是安全存储,仅可加载可信的落盘数据。
⭐ 落盘目录的官方硬约束(这其实是好消息 —— 官方给了明确的防线):
| 约束 | 官方原文(摘要) |
|---|---|
| 目录权限 | 运行用户的属组以及非运行用户不能有该目录下文件的写权限 |
| 目录属组 | 目录下的文件以及文件的上一级目录的属组必须是运行用户 |
| 位置 | 存放路径不能在 ["/etc", "/usr/bin", "/usr/lib", "/usr/lib64", "/sys/", "/dev/", "/sbin", "/tmp"] 内 |
| 其他 | 不能为软链接和相对路径 |
③ 知识库数据明文存储(官方原文)
upload_files/upload_dir:文档数据将明文存储,请注意安全风险。
④ 加载外部模型有安全风险(官方原文)
QAGenerationConfig的tokenizer:加载外部模型有安全风险,local_files_only设置为True。
⑤ 文件权限的硬要求(官方原文)
使用 API 读取文件时,用户需要保证该文件的 owner 必须为自己,且权限不大于 640, 避免发生提权等安全问题。
⭐ 把这五条翻译成一句执行判据:
「明文」是官方明说的现状,「安全存储」是官方交给你的责任。 官方把「不能放哪里」(禁用路径清单)、「权限要多少」(≤640、写权限限制) 都给得很具体 —— 那部分照做就行;剩下的「怎么加密、加密密钥怎么管」,官方没给。
4.7 最后:收口、出证据、诚实
收口用一条能跑通的完整业务流程当验收:建库 → 授权一个 member → 用 member 查一次
→ 用没被授权的 user_id 再查一次。第二次必须查不到 —— 这就是权限生效的验收。
出证据(我会留这四样):
| 证据 | 怎么来 |
|---|---|
| 监听端口清单 | 4.1 的 ss -lntp 输出,逐行标注用途 |
| vNPU 切分现状 | npu-smi info -t info-vnpu 输出 |
| 权限账本 | get_all_usr_role_by_knowledge 的输出 |
| 加固项核对表 | 4.1 那张四项表,逐项打勾 + 判据 |
诚实(这一节和别的一样重要): 官方没给答案的地方,我在报告里明写「这里要自己定」 —— 尤其审计字段、留存期限、集中收集这三块。 把「没做的」如实写进交付报告,本身就是交付能力。
第五段 怎么确认就位
原则:安全这件事,「没报错」不等于「做到了」 —— 每一项都要有一个能拿出来的判据。 下表每一项都对应第四段的一步,且判据来自官方文档原文,不是我编的。
| # | 检查项 | 命令 / 判据 | 期望(看到什么才算对) | 不过会怎样 |
|---|---|---|---|---|
| ① | 暴露面 | ss -lntp |
每一行都能说出用途;无 telnet/ftp | 有说不清的监听 → 端口扫描没做完(回 4.1) |
| ② | umask | umask |
0027 或更严 |
显示 0022 → 官方要求的 027 未生效(改 /etc/profile 后 source 一下) |
| ③ | 无属主文件 | find / -nouser -o -nogroup |
输出为空 | 有输出 → 按 uid/gid 建用户或改属主(回 4.5) |
| ④ | vNPU 现状 | npu-smi info -t info-vnpu -i <id> -c <chip_id> |
切分方案和规划一致 | 列表为空 → 还没切;多切/少切 → 与 4.4 的规划不符 |
| ⑤ | 服务侧鉴权 | 查 infer_tls_config.enable_tls / api_key_config.* |
enable_tls 为 true;API Key 已配 |
是 false → 服务是明文 HTTP,任何能连上的人都能调 |
| ⑥ | 限流 | 查 rate_limit_config.enable_rate_limit |
需要限流时为 true,超限收到 429 |
为 false → 没有限流,一个脚本就能把服务打满 |
| ⑦ | 权限账本 | get_all_usr_role_by_knowledge('<库名>') |
每个用户角色与预期一致 | 多出用户 → 有人没被收回权限;角色错 → admin / member 配反了 |
| ⑧ | 身份映射 | 抽查 user_id 是否都满足 ^[a-zA-Z0-9_-]{6,64}$ |
全部合规 | 出现邮箱/中文 → 上线必失败(回 4.3 的映射层) |
| ⑨ | 日志落到手里 | echo $MINDIE_LOG_PATH + 看实际目录 |
日志落在你指定的、非软链接的目录里 | 为空 → 用默认 ~/mindie/log/debug,可能在你够不着的地方 |
| ⑩ | 审计字段 | 逐项对照 4.5 的「要自己定」表 | 每一项都有明确的组织内规定 | 空着 → 不是在等官方,是在留窟窿 |
第 ⑩ 条是本课的差异化:前面九条都能用命令验, 只有这一条要你去问所在组织的安全策略 —— 而它恰恰是官方一个字都没给的部分。
第六段 判据 / 验收
⚠️ 本段的验收要按「三档」分别打分 —— 这是本课和别的课最大的不同:
| 档 | 验收要求 | 举例 |
|---|---|---|
| ① 官方给了 | 必须做,且做满 | 知识库 role 分好、API Key 配上、日志开关打开 |
| ② 官方给机制 | 必须做,且策略有书面依据 | 选硬件还是软件虚拟化,要能说出为什么;日志级别定成什么,要能说出依据 |
| ③ 官方没给 | 必须有「谁负责、按什么定」的结论 | 审计字段谁定、留存多久、谁看 —— 没结论 = 未验收 |
判据表:
| # | 判据 | 验证方式 | 不过说明 |
|---|---|---|---|
| ① | 每一条安全需求都能归到某一档 | 拿需求清单逐条对第三段的表 | 归不了档 → 还没看清官方给了什么 |
| ② | 官方给的都用满了 | 第五段 ⑤⑥⑦ 三条全过 | 有官方现成能力没用,自己另造了一个 |
| ③ | 没被授权的用户查不到 | 用一个未授权的 user_id 实查一次 |
权限只写在纸上,接口没拦住 |
| ④ | 租户之间互不影响 | 两个 vNPU 上同时跑任务,观察是否互相干扰 | 用了软件虚拟化而业务需要硬隔离(回 4.4) |
| ⑤ | 每一条日志去向可解释 | 逐个审计开关问「它落在哪、谁能改」 | 日志在软链接路径上 / 无属主 |
| ⑥ | 明文数据的处置有明确结论 | 对照 4.6 的五条风险提醒逐条回答「我们怎么处理」 | 只会说「以后加密」,没说谁来加 |
| ⑦ | 能说清「哪些是官方没给的」 | 把 4.5 / 4.6 的「要自己定」两张表填满 | 这条是灵魂:分不清这个,安全就没有边界 |
第 ⑦ 条为什么是灵魂:安全项目最常见的失败不是「没做」, 而是「以为官方已经做了」 —— 以为有
user_id就有权限系统,以为有日志就有审计,以为有 vNPU 就万事大吉。 能画出「官方给了 / 要自己做」这条线,这个项目才算开始可控。
第七段 出问题怎么查
排障原则:先归到「权限 / 隔离 / 审计」哪一件,再看是「官方那一格没做满」还是「自己那一层没接」。
| 你看到的现象 | 先归到哪件事 | 先查什么 |
|---|---|---|
| 任何人连上服务就能调,不用任何凭证 | 权限 · 服务层 | infer_tls_config.enable_tls 是不是 false;api_key_config.header_name 配了没有 |
| API Key 配了但调用方没带也能过 | 权限 · 服务层 | 官方说明 API Key 只对 /v1/completions、/v1/chat/completions 生效 —— 其它路径本来就不校验 |
| 一个脚本把服务打满 | 权限 · 服务层 | rate_limit_config.enable_rate_limit 是不是 true;超限应返回 429 |
user_id 报格式错 |
权限 · 应用层 | 对照正则 ^[a-zA-Z0-9_-]{6,64}$ —— 不能有中文、@、.,长度 6–64 |
| 建库时报「角色非法」 | 权限 · 应用层 | add_knowledge 的 role 只能是 admin;add_usr_id_to_knowledge 才能给 member |
| 删用户报错 | 权限 · 应用层 | delete_usr_id_from_knowledge 的 user_id 和 role 要同时对上(官方:记录不存在则报错);只剩一个用户时默认删不掉 → 需要 force=True |
| 某个部门能看到别的部门的资料 | 隔离 | 知识库的 user_id 是不是共用了同一个;设备层有没有做 vNPU 分家 |
| 两个租户任务互相拖慢 | 隔离 | 是不是用了软件虚拟化;vir01 是分时复用,本来就会互相排队 |
| 切分后想整卡用,报找不到设备 | 隔离 | 官方约束:物理 NPU 虚拟化出 vNPU 后,不支持再将该物理 NPU 挂载到容器使用 —— 要先销毁 vNPU |
| 换了 OS 版本后虚拟化不可用 | 隔离 | 4.1 摸底该查出来的:查对应产品驱动固件安装指南「算力分组场景下的安装 > 安装前必读」,确认 OS 是否支持虚拟化实例 |
| 500 系列卡上打不开虚拟化 | 隔离 | Ascend 910 只支持软件虚拟化,且仅支持 AMP 模式,不支持 SMP(iBMC 里 ipmcget -d npuworkmode 查) |
| 日志把磁盘写满了 | 审计 | MINDIE_LOG_ROTATE 是不是没配(默认单文件 20MB、每进程 10 个);官方《安全管理》要求的第二条就是「日志空间占满后有没有清理机制」 |
| 日志文件谁都能改 | 审计 | 跑了 find / -nouser -o -nogroup 没有;日志目录在不在软链接路径上(官方:程序不会校验日志路径是否包含软链接) |
| 出了事查不到是谁做的 | 审计 | 这是必然的 —— 官方没有应用层操作审计接口,RAG SDK 的 set_verbose 只记缓存命中与否,不记「谁」 |
| 缓存里出现了个人信息 | 审计 · 数据资产 | 回 4.6 第 ① 条 —— 官方明说缓存库未做加密存储,个人数据不要放进去 |
第八段 常见报错清单
⚠️ 本课的报错有它自己的特点:权限和审计的失败大多是「无声的」 —— 不报错、不告警,只是没起作用。所以下表分两种: A 类 = 会报错的(能查到原文);B 类 = 不报错的(这才是危险的那一类)。
A 类:会报错的
| 报错 / 现象 | 大概属于 | 先查什么 |
|---|---|---|
user_id 格式校验失败 |
权限 · 应用层 | 正则 ^[a-zA-Z0-9_-]{6,64}$;长度 6–64;不能含 @、.、中文 |
| 角色非法(role 不合法) | 权限 · 应用层 | add_knowledge 只收 admin;member 只能通过 add_usr_id_to_knowledge 加 |
| 删除用户报「记录不存在」 | 权限 · 应用层 | user_id 与 role 必须同时匹配;只剩一个关联用户时默认拒删(force=False) |
| 数据库路径非法 | 权限 · 应用层 | 官方禁用清单:/etc、/usr/bin、/usr/lib、/usr/lib64、/sys/、/dev/、/sbin、/tmp;不能是软链接、不能含 .. |
服务返回 429 |
权限 · 服务层 | 这是限流在正常工作,不是故障;调 rate_limit_config |
create-vnpu 报错 |
隔离 | 设备/芯片 ID 填错;vnpu_id 超范围(推理系列 [phy_id*16+100, phy_id*16+107],910 到 +115);同一设备内重复 vnpu_id |
| 容器里找不到设备(切分之后) | 隔离 | 官方约束:物理 NPU 虚拟化后不能再挂载到容器;且使用切分后的 vNPU,任务的每个 pod 请求的 NPU 设备数量仅支持 1 个 |
| 建/销毁 vNPU 后容器起不来 | 隔离 | 官方说明:静态虚拟化场景创建或销毁 vNPU,需要重启 Ascend Device Plugin |
B 类:不报错的(⚠️ 本课的重点)
| 现象 | 属于 | 为什么危险 |
|---|---|---|
| 服务是明文 HTTP,功能一切正常 | 权限 · 服务层 | enable_tls 默认不是 true 就一直是 HTTP,没人拦你、也没人告诉你 |
只有 admin,没有真正的 member |
权限 · 应用层 | 大家都能改文档,功能全通、权限全错 |
| 日志一直在写,但写到默认路径 | 审计 | 默认 ~/mindie/log/debug;换个人跑,日志就到别人家去了 |
| 默认轮转把关键期日志覆盖了 | 审计 | 20MB×10 个就滚没了;出事再回头看,最需要的那段已经不在了 |
| 缓存库里出现了身份证号 | 审计 · 数据资产 | 官方明说未加密存储且「请勿存放到数据库中」,但它不会报错 |
| 知识库文档是明文 | 审计 · 数据资产 | 官方明说「文档数据将明文存储,请注意安全风险」,同样不报错 |
| 以上全部「正常」,但你没有审计记录 | 审计 | 官方没有应用层审计接口 —— 这不是配置漏了,是没有这个能力 |
⭐ 检索技巧(E1 讲过,再用一次):
去掉具体化信息。不要搜「我们公司权限配不上」,要搜稳定特征词
(函数名 add_usr_id_to_knowledge、参数名 user_id、配置项 rate_limit_config、
报错里的错误码)。官方案例库按报错原文检索,不要按「企业安全」检索(那不是官方分类词)。
第九段 小结 + 钩子 + 自测
三句话记住本课
- 企业安全 = 权限(认人)+ 隔离(分家)+ 审计(记账);每件事都先问「官方给了吗」。
- 答案永远在三档里:官方给了直接用 / 官方给机制你定策略 / 官方没给自己接。 最常见的失败是把 ② 当成 ① —— 有参数 ≠ 有系统。
- 官方给的是「零件」,不是「制度」:
user_id是零件、vNPU 是零件、MINDIE_LOG_*是零件; 认证体系、租户配额、审计字段 —— 官方一个字都没给,那是你的活。
一句话版对照表(贴在工位上)
| 需求 | 官方给了什么 | 还差什么 |
|---|---|---|
| 谁能看哪个知识库 | user_id / role(admin / member) |
身份映射、组织架构 |
| 谁能调这个服务 | TLS / API Key / 限流(Motor) | 登录、令牌生命周期 |
| 两个组互不干扰 | AVI vNPU(硬件 / 软件虚拟化) | 配额、计费、生命周期 |
| 出事了能不能查到 | 日志开关与轮转(MINDIE_LOG_*) |
审计字段、留存、集中收集(官方未给出) |
| 缓存里要不要放个人数据 | 官方明说:未加密存储,别放 | — |
自测(不看上文)
- 「这个需求官方给了吗」——判断时落哪三档?
- 官方《简介》说不包含权限接口,但《知识管理》里有
user_id和role,怎么统一? user_id的正则是什么?为什么「直接用公司邮箱当user_id」会失败?- MindIE Motor 的服务侧鉴权,官方给的三个配置项分别是什么?超限返回什么码?
- 硬件虚拟化和软件虚拟化,哪个是真正的资源隔离?Ascend 910 支持哪个?
- 官方在「审计」这件事上,实际只给了哪两样东西?哪三样是官方未给出的?
- 官方关于缓存的那句警告,原文大意是什么?
钩子:这门课的边界在哪
G9 讲了「装完之后,企业内部怎么管」。它有意停在了技术侧 —— 因为再往前的那些(等保几级、数据怎么分级、审计留几年、日志归谁保管), 官方文档里没有,技术手册也答不了。
那部分要按你所在组织的安全策略来 —— 这不是偷懒,是责任边界。 官方自己就是这么说的:
本文中列出的安全加固措施为基本的加固建议项。用户应根据自身业务, 重新审视整个系统的网络安全加固措施……应按照所在组织的安全策略进行相关配置。
记住这句话的角色:它既是本课的结论,也是这门课敢停在哪里的理由。
附录 A 官方出处
本课所有事实、命令、参数、原话,均取自下列官方文档(取数时间:2026-10-06,实时接口)。
| # | 内容 | 官方出处 |
|---|---|---|
| 1 | RAG SDK 边界:「提供各模块化功能接口(包含向量模型垂域微调数据生成、检索、知识管理等功能)供用户开发上层应用,不包含用户、权限等和业务强相关的功能接口」 | MindSDK 26.1.0 · RAG SDK《简介》→ zh/mindsdk/2610/rag/ragug/docs/zh/introduction.md |
| 2 | 知识库归属与查询权限:KnowledgeStore 提供知识库及知识库用户的增删查;add_knowledge(knowledge_name, user_id, role);user_id 需满足正则 ^[a-zA-Z0-9_-]{6,64}$;role 默认 'admin' |
MindSDK 26.1.0 · RAG SDK《接口参考 · 知识管理》→ …/api/knowledge_management.md |
| 3 | admin / member 两个角色:add_usr_id_to_knowledge 的角色「只能为知识库管理员 'admin' 或对知识库仅有查询权限的成员 'member'」;delete_usr_id_from_knowledge(..., force=False);get_all_usr_role_by_knowledge → dict{user_id: role};check_knowledge_exist → bool |
同上 |
| 4 | 知识库级权限的边界:add_file / delete_file / delete_all / upload_files / upload_dir 均标注「仅知识库管理员有权限操作」;KnowledgeDB 有 white_paths(上传文档的白名单路径列表,上传路径需在白名单下才能成功) |
同上 |
| 5 | 缓存不加密的官方警告:「RAG SDK 如果使用 Cache 对问题-答案缓存,生成的数据库未做加密存储,如果涉及银行卡号、身份证号、护照号、口令等个人数据,请勿存放到数据库中」 | MindSDK 26.1.0 · RAG SDK《接口参考 · 使用说明》→ …/api/README.md |
| 6 | 缓存落盘的安全要求(pickle 风险):「本接口内部使用了 pickle 模块,有被恶意构造的数据在 unpickle 期间攻击的风险。需要保证在被加载的落盘数据 data_save_folder 是安全存储,仅可加载可信的落盘数据」;目录权限约束(非运行用户不能有写权限、属组必须是运行用户);禁用路径清单 ["/etc","/usr/bin","/usr/lib","/usr/lib64","/sys/","/dev/","/sbin","/tmp"] |
MindSDK 26.1.0 · RAG SDK《接口参考 · 缓存模块》→ …/api/cache_module.md |
| 7 | 缓存日志开关:MxRAGCache.set_verbose(verbose),默认 False;True 记录 cache 过程的命中或者未命中 |
同上 |
| 8 | 文档明文存储:upload_files / upload_dir 功能描述「文档数据将明文存储,请注意安全风险」;QAGenerationConfig 的 tokenizer「加载外部模型有安全风险,local_files_only 设置为 True」 |
MindSDK 26.1.0 · RAG SDK《接口参考 · 知识管理》/《缓存模块》 |
| 9 | RAG SDK《安全加固》全文:安全要求(文件 owner 必须为自己,权限不大于 640)/加固须知(基本建议项,按所在组织的安全策略)/防火墙配置(/etc/login.defs 加 ALWAYS_SET_PATH=yes)/设置 umask(宿主机和容器 027 及以上)/无属主文件(find / -nouser -o -nogroup)/端口扫描(关注全网侦听端口,关闭 telnet、ftp)/防DoS(按 IP 限制连接速率、iptables、优化 sysctl) |
MindSDK 26.1.0 · RAG SDK《安全加固》→ zh/mindsdk/2610/rag/ragug/docs/zh/security_hardening.md |
| 10 | AVI 功能及原理:「将物理机配置的 NPU 切分成若干份 vNPU 挂载到容器中使用……满足多用户反复申请/释放的资源操作请求」「多个用户共同使用一台服务器的 NPU,并借助容器进行资源隔离,资源隔离性好……方便多租户管理」;硬件资源 = AICore / AICPU / 内存 | 昇腾虚拟化实例(AVI)3.0.0 · 用户指南《功能及原理》→ zh/computepoweralloca/300/cpaug/cpaug/cpaug_00002.html |
| 11 | 虚拟化模式:硬件虚拟化(AICore、AICPU、内存等硬件资源和其他 vNPU 相互隔离,任务互不影响)/软件虚拟化(虚拟实例从资源池调用硬件资源);Ascend 910 只支持软件虚拟化;Atlas 推理系列 vir04/vir04_3c/vir02/vir02_1c/vir04_3c_ndvpp/vir04_4c_dvpp 为硬件虚拟化,vir01 为软件虚拟化(vGroup 分时复用);Atlas 推理系列最多 4 个 vGroup、每个 vGroup 至少 2 个 AICore |
同上《虚拟化模式》→ …/cpaug_00007.html |
| 12 | 应用场景与方案:适用于「多用户多任务并行,且每个任务算力需求较小的场景」;三种方案(原生 Docker / Ascend Docker Runtime / 集群调度组件 Ascend Device Plugin + Volcano) | 同上《应用场景及方案》→ …/cpaug_00003.html |
| 13 | 使用约束:物理 NPU 虚拟化后不能再挂载到容器、不能直通到虚拟机;Atlas 300I Duo 两路 NPU 工作模式必须一致;不支持不同规格标卡混插;性能下降时建议 vir04+vir04_3c 或 vir04+vir02+vir02_1c;Ascend 910 仅支持 AMP,不支持 SMP(ipmcget -d npuworkmode / ipmcset -d npuworkmode -v 0) |
同上《使用约束》→ …/cpaug_00008.html |
| 14 | 创建 vNPU 与查询:npu-smi set -t vnpu-mode -d <0/1>;npu-smi set -t create-vnpu -i <id> -c <chip_id> -f <vnpu_config> [-v <vnpu_id>] [-g <vgroup_id>];npu-smi info -t info-vnpu -i <id> -c <chip_id>;vnpu_id 范围:推理系列 [phy_id*16+100, phy_id*16+107]、910 到 +115 |
同上《创建vNPU》→ …/cpaug_00010.html |
| 15 | MindIE Motor 安全、认证与限流:infer_tls_config.enable_tls / mgmt_tls_config.enable_tls 为 true 时推理/管理接口用 https;API Key(api_key_config.header_name 默认 Authorization、api_key_config.key_prefix 默认 Bearer)对 /v1/completions、/v1/chat/completions 生效;rate_limit_config.enable_rate_limit=true 启用限流,超限返回 429;管理接口仅限 K8s 集群内使用,不提供给集群外 |
MindIE 3.1.0 · MindIE Motor《API 参考 · 接口说明》→ zh/mindie/310/mindiemotor/motordev/docs/zh/user_guide/api/README.md |
| 16 | MindIE 日志参数:MINDIE_LOG_LEVEL(DEBUG < INFORMATIONAL < WARNING < ERROR < CRITICAL,默认 info)/MINDIE_LOG_VERBOSE(默认 true)/MINDIE_LOG_TO_FILE(默认 true)/MINDIE_LOG_TO_STDOUT(默认 false)/MINDIE_LOG_ROTATE(单文件 1MB~500MB 默认 20MB;每进程 1~64 个默认 10 个)/MINDIE_LOG_PATH(默认 ~/mindie/log/debug) |
MindIE 3.1.0 ·《日志参考 · 其他操作》→ zh/mindie/310/ref/logreference/docs/zh/user_guide/log/setting_log_path.md、…/configuring_log_rotation.md |
| 17 | MindIE 安全管理 · 日志管理两条检查:「检查系统是否可以限制单个日志文件的大小」「检查日志空间占满后,是否存在机制进行清理」;集合通信安全风险:Gloo、DataDist、HCCL 暂不支持 TLS 认证 | MindIE 3.1.0 ·《安全与加固 · 安全管理》→ zh/mindie/310/ref/security_hardening/docs/zh/user_guide/install/security_management_and_hardening/security_management.md |
| 18 | 审计相关的官方口径:「开启 Docker 守护进程和关键文件的审计功能。开启审计功能能够追溯攻击事件的根源,此功能开启后,会造成一定的性能影响,需要用户根据业务决定是否开启」;K8s 侧:修改或增加启动参数 --audit-policy-file 配置 K8s 审计策略(具体配置参考 Kubernetes 官方文档);容器运行加固(启用 apparmor / SELinux、--live-restore、以非 root 用户启动、避免通过环境变量或 ConfigMap 传递敏感信息) |
MindEdge 26.0.0 · MindEdge Framework《安全加固》→ zh/mindedge/2600/mef/mefug/docs/zh/user_guide/security_hardening.md |
⚠️ 以下内容在官方文档中查不到对应章节 —— 本课因此没写,明列为「待你按所在组织安全策略定」:
| # | 官方未给出 | 正文里的处理 |
|---|---|---|
| 1 | 审计字段设计(谁、何时、对哪个知识库、做了什么、结果) | 4.5 明写「官方未给出,需按所在组织安全策略定」,只给「要自己定」这张表 |
| 2 | 审计日志的留存期限与不可篡改机制 | 同上,未写 |
| 3 | 审计日志的集中收集(SIEM)与告警规则 | 同上,未写 |
| 4 | 应用层的操作审计接口 | 明确写出「RAG SDK 层面官方未提供操作审计接口」;只有 set_verbose(缓存命中与否)这一个最近的东西,并已说明它记的不是「谁」 |
| 5 | 认证、组织架构、会话与令牌生命周期 | 归入 4.3 的「要自己接」表,未给方案 |
| 6 | 细粒度数据权限(同库内按字段/行过滤) | 归入 4.3 的表,并指出 role 只有 admin/member 两档,做不到 |
| 7 | 租户配额、计费、生命周期 | 归入 4.4 的「官方没给」表 |
| 8 | 数据加密方案与密钥管理 | 只如实转述官方「未加密存储 / 明文存储 / 安全存储是你的责任」,未给加密方案 |
| 9 | 等保级别、数据分级、合规要求 | 第一段已声明本课不涉及,属制度层面 |
| 10 | AICPU / Vgroup ID 字段在 Ascend 910 上缺失的处理 | 官方只说「不支持返回」,未说替代方案,本课照此标注 |
⚠️ 另有两处「归纳」而非官方原文,正文已标注类型: - 第三段的「三件事 × 三档」框架与第四段的分层(设备/资源层 · 服务层 · 应用层) 是本课的归纳,官方没有这套说法; -
ss/cat/find/grep属通用 Linux / 系统工具,非昇腾专用命令;MINDIE_LOG_*才是昇腾侧的环境变量。
附录 B 命令详解(本课涉及的命令)
G1–G4 已解释过的命令(
npu-smi info -l/-m、create-vnpu、vnpu-cfg-recover、destroy-vnpu、.run --check、curl、export、source、cat、ls)此处不重复。 本附录只详解本课新引入的几条。
B.1 find / -nouser -o -nogroup
命令 find / -nouser -o -nogroup
含义:在整台机器上找出没有属主 / 没有属组的文件 —— 官方《安全加固》给的安全检查项 拆解:
find(查找文件)+/(从根目录开始,即全盘)+-nouser(筛出「属主不在系统用户表里」的文件)+-o(逻辑「或」)+-nogroup(筛出「属组不在系统组表里」的文件) 用法:find / -nouser -o -nogroup; 只查某个目录时把/换成那个目录,如find /home -nouser -o -nogroup期望:输出为空 —— 空就是干净 不过会怎样:列出文件 → 按官方给的办法处理: 「根据文件的 uid 和 gid 创建相应的用户和用户组,或者修改已有用户的 uid、用户组的 gid 来适配,赋予文件属主」 ⭐ 为什么它对审计重要:无属主文件 = 谁都能改 = 出事追不到人。 尤其要拿它去查日志目录。
B.2 MINDIE_LOG_PATH(日志落盘路径)
命令 export MINDIE_LOG_PATH="llm: /home/working/"
含义:指定 MindIE 各组件的日志落在哪个目录 —— 审计的前提是「日志在你手里」 拆解:格式
_组件名称_: _路径_;以/开头 = 绝对路径, 不以/开头 = 相对~/mindie/log/debug的路径;:前不写组件名 = 所有组件统一; 多组件用;隔开(后者覆盖前者) 用法:export MINDIE_LOG_PATH="llm: /home/working/"; 只调一个组件的相对路径:export MINDIE_LOG_PATH="llm: llm"期望:组件启动后把日志写进指定目录(相对路径则落在~/mindie/log/debug下) 不过会怎样:换了个终端就没了 →export只对当前窗口有效,要持久化得写进~/.bashrc; 路径含特殊字符 → 官方说明「路径里不能有特殊字符」 ⚠️ 官方提醒:程序不会校验日志路径是否包含软链接,请保证日志路径合理 —— 软链接能被指向别处,在审计场景里这等于日志没在你手里
B.3 MINDIE_LOG_ROTATE(日志轮转)
命令 export MINDIE_LOG_ROTATE="-fs 500"
含义:设置日志的轮转(单个文件多大、每个进程最多留几个)—— 直接决定你能往回查多久 拆解:
-fs= 每个日志文件大小,范围 1MB~500MB;-r= 每个进程可写日志文件个数,范围 1~64; 不写组件名 = 对所有组件统一设置 用法:export MINDIE_LOG_ROTATE="-fs 500"(全组件单文件上限 500MB);export MINDIE_LOG_ROTATE="torch: -fs 40 -r 1"(只调 torch:单文件 40MB、每进程 1 个) 期望:日志按设置轮转;轮转文件命名格式为mindie-<组件名>_<进程号>_<时间>.<轮转文件编号>.log不过会怎样:数值超范围(如单文件 600MB、进程文件数 100)→ 设置不生效; 什么都不设就是默认:单文件 20MB × 每进程 10 个 —— 一次故障如果产生超过 200MB 日志,最前面那段(往往是最早的异常)就被滚掉了 ⭐ 官方《安全管理 · 日志管理》的两条检查,对应的就是这两个参数: 「能否限制单个日志文件大小」「日志空间占满后有没有清理机制」
B.4 ss -lntp(本课的用法)
命令 ss -lntp
含义:列出本机正在监听的 TCP 端口和对应进程 —— 用来回答「我开了几扇门」 拆解:
-l只看 listening/-n端口用数字显示/-t只看 TCP/-p显示进程 用法:ss -lntp;只想看有没有某个端口时配grep:ss -lntp | grep 8080期望:每行一个监听端口 + 进程名 + PID;行数越少越好,每行都能解释用途 不过会怎样:命令不存在 → 装iproute2; 看到0.0.0.0:*/:::*→ 这是「全网侦听」, 官方《安全加固 · 端口扫描》要求「关注全网侦听的端口和非必要端口,如有非必要端口请及时关闭」 ⚠️ 与 G1 的用法区分:G1 用它看已建立连接(ss -ntp,判断数据有没有外发); 本课用它看监听端口(ss -lntp,判断暴露面有多大)。-l这一位就是区别。
B.5 cat ... | grep ...(检查加固项)
命令 cat /etc/login.defs | grep ALWAYS_SET_PATH
含义:检查某个加固项配了没有 —— 这是本课反复用到的模式 拆解:
cat 文件(打印文件内容)+|(管道:把左边输出交给右边)+grep 关键词(只留下含关键词的行) 用法:cat /etc/login.defs | grep ALWAYS_SET_PATH; 同类用法:cat /etc/sudoers | grep targetpw(MindEdge《安全加固》给的提权检查项) 期望:打印出含关键词的行,如ALWAYS_SET_PATH yes不过会怎样:什么都不打印 → 这一项没配。 官方给的配法是:在/etc/login.defs新增ALWAYS_SET_PATH=yes,防止越权操作
B.6 get_all_usr_role_by_knowledge(权限账本)
命令 python3 -c "from mx_rag.knowledge import KnowledgeStore; s=KnowledgeStore(db_path='./sql.db'); print(s.get_all_usr_role_by_knowledge('test'))"
含义:打印某个知识库下的全部用户与角色 —— 这是权限的「现状账本」,交付时要附的证据 拆解:
KnowledgeStore(db_path)(知识库管理类)→get_all_usr_role_by_knowledge(knowledge_name)返回dict{user_id: role}用法:把db_path和库名换成你自己的;db_path不能在/etc、/usr/bin、/sys/、/dev/、/sbin、/tmp这些路径下,也不能是软链接或含..期望:一个字典,如{'zhangsan01': 'admin', 'lisi0002': 'member'}不过会怎样:返回空或报错 → 库名写错,或db_path指到了另一个库; 值不是admin/member→ 赋值时写错了角色名(合法值只有这两个) ⭐ 同类的还有check_knowledge_exist(knowledge_name, user_id)返回 bool, 适合写成自动化核对脚本的一条断言
(本课完)