news 2026/9/13 21:36:55

Qwen Code 语音私有网关白名单:security.allowedInsecureVoiceBaseUrls 配置与网络策略解析

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Qwen Code 语音私有网关白名单:security.allowedInsecureVoiceBaseUrls 配置与网络策略解析

Qwen Code 语音私有网关白名单:security.allowedInsecureVoiceBaseUrls 配置与网络策略解析

【免费下载链接】qwen-codeAn open-source AI coding agent that lives in your terminal.项目地址: https://gitcode.com/GitHub_Trending/qw/qwen-code

导读

Qwen Code 的语音转写(ASR)功能默认拒绝非回环 HTTP 端点与解析到私网地址的端点,这是安全默认值,但也让托管部署无法把语音流量路由到隔离的私有网关。本文围绕设计文档 trusted-private-voice-base-urls.md,系统讲解新增的security.allowedInsecureVoiceBaseUrls信任配置:如何精确匹配放行私有/明文语音端点、哪些地址永远无法放行、CLI 与桌面端两条解析链路的差异、以及失败回退与验证清单。读完你将掌握在受控内网中安全配置私有语音网关、并理解其安全边界与回滚行为的完整方案。

问题背景:语音流量的安全默认值与私有网关冲突

语音转写模块在出站前会对语音服务端点做两层安全检查:

  1. 拒绝非回环(non-loopback)HTTP 端点:明文传输语音音频不被允许;
  2. 拒绝解析到私网地址的端点:RFC 1918 私网、CGNAT、IPv6 unique-local 等地址默认不可达。

这两项检查是防 SSRF 与防音频明文泄露的安全默认值。但对托管(managed)部署而言,ASR 流量往往需要经过一个隔离的私有网关,网关地址因部署而异——按厂商或地区维护主机名列表无法扩展。文档明确指出,问题不是去掉检查,而是为受信端点提供一条精确、可审计的放行通道

设计文档将其实现为 Issue [#8286] 的落地内容,当前仓库中的实现事实如下:

  • CLI 侧检查逻辑位于 voice-transcriber.ts:isInsecureVoiceBaseUrlAllowed读取合并后的security.allowedInsecureVoiceBaseUrls并做精确匹配;
  • 设置项 Schema 定义于 settingsSchema.ts,默认值为空数组[]

核心设计:精确匹配的白名单,而不是通配放行

新增配置项security.allowedInsecureVoiceBaseUrls是一个默认空的完整 base URL 列表,其匹配规则非常严格:

  • 必须显式携带 scheme:每条目必须包含http://https://
  • 必须携带完整 provider 路径:仅当配置的语音 provider 的规范化 base URL 与列表条目完全相等(包括 scheme、host、port、path)时才放行;
  • 仅做 URL 序列化与尾部斜杠的规范化new URL(...).toString()后去掉尾部斜杠(见 voice-transcriber.ts 的normalizeBaseUrlnormalizeAllowedVoiceBaseUrl);
  • 不推断缺失信息:缺失 scheme 或/v1路径段不会被自动补全——自定义或区域网关必须写出完整地址;
  • 不支持通配符与主机名后缀匹配*.example.com这类写法无效。

示例(内网私有网关):

{ "security": { "allowedInsecureVoiceBaseUrls": [ "http://10.0.0.12:8080/asr/v1" ] } }

/v1推断的保留与两个表面的差异

文档特别强调了一条容易踩坑的规则:预置的/v1推断只保留给官方 DashScope 兼容模式端点(compatible-mode),且仅用于 provider 条目;桌面端 OAuth 派生与环境变量派生的 base URL 在匹配前仍走同一套旧推断逻辑。而CLI 语音解析器完全不做/v1推断

这意味着:如果希望在 CLI 与桌面端解析出相同的 DashScope provider 条目,就必须在baseUrl中显式写出/v1后缀;否则 CLI 解析出的是/v1之前的 URL,而桌面端会补上/v1,两端的白名单条目必须各自匹配各自解析后的 URL。也就是说,同一 provider 在不同表面上可能是两条不同的白名单条目

精确匹配结果随解析配置一起传递

匹配结果(allow / deny)与解析出的语音配置一起传递,因此所有出站路径应用同一个决策

  • CLI 批量转写
  • CLI 与 daemon 流式转写
  • 桌面端批量与流式转写

放行后,允许明文传输与 RFC 1918、CGNAT、IPv6 unique-local 地址;但回环别名(loopback aliases)、未指定地址(unspecified)、链路本地(link-local)范围与已知云元数据地址仍然被阻止。显式 localhost 行为保持不变。

流式传输的 WebSocket 派生路径与白名单的关系

流式传输的 WebSocket URL 由解析后的 base URL派生而来,而不是直接使用 base URL。实现位于 voice-stream-session.ts:

export function deriveWebSocketBase(baseUrl: string): string { const url = new URL(baseUrl); const wsScheme = url.protocol === 'https:' ? 'wss:' : 'ws:'; let prefix = url.pathname.replace(/\/+$/, ''); if (prefix.endsWith('/compatible-mode/v1')) { prefix = prefix.slice(0, -'/compatible-mode/v1'.length); } else if (prefix.endsWith('/v1')) { prefix = prefix.slice(0, -'/v1'.length); } return `${wsScheme}//${url.host}${prefix}`; } export function deriveStreamUrl(baseUrl: string): string { return `${deriveWebSocketBase(baseUrl)}/api-ws/v1/inference`; }

即:deriveWebSocketBase去掉末尾的/v1/compatible-mode/v1,再追加/api-ws/v1/inference(实时通道为/api-ws/v1/realtime)。因此:

  • 精确匹配保证覆盖的是 provider 端点
  • 批量请求路径原样使用该 base URL;
  • 流式传输的线上路径(wire path)是base URL 派生而来,不参与白名单匹配——派生后的 WebSocket 地址可以合法地与白名单条目不同。

这是设计上的有意选择:白名单放行的是“信任这个 provider 端点”,而不是把放行范围扩展到所有派生出的线上地址。

配置归属:受信任作用域与 Workspace 忽略

security.allowedInsecureVoiceBaseUrls属于受信任配置(trusted configuration)

  • 允许的作用域:User、System、SystemDefaults;
  • 忽略的作用域:Workspace 值被忽略并产生设置警告。

其目的很明确:防止克隆的仓库自我授权访问不安全或私有端点。源码侧由统一的“工作区受限设置”清单驱动,见 settingsUtils.ts 中的WORKSPACE_RESTRICTED_SETTINGS{ section: 'security', key: 'allowedInsecureVoiceBaseUrls' }),该清单同时驱动 Workspace 值剥离、忽略警告与设置对话框作用域过滤,三个表面不会漂移。

另外两点需要特别留意:

  1. 设置值在匹配前会经过环境变量插值——任何能控制进程环境的东西都可以提供插值后的白名单条目或 providerbaseUrl。因此进程环境本身应被视为受信任配置面的一部分
  2. 明文 HTTP 会把 provider API key(位于 Authorization 头中)暴露在网络上,Schema 描述中对此有明确警告(见 settingsSchema.ts)。

配置归属原则

谁部署网关,谁负责白名单条目。托管部署应从同一份声明式端点值同时渲染 providerbaseUrl与白名单条目。新增一个区域不需要任何 Qwen Code 改动,也不会漂移成主机名级别的宽泛放行。

DNS 信任边界:白名单中的主机名,其可信度等同于其 DNS。后续 DNS 记录变更会把放行(连同 provider 凭据)重定向到新解析的地址。当网关地址稳定时,优先使用 IP 字面量条目。

桌面端的额外解析逻辑:凭据绑定与歧义处理

桌面端语音解析与 CLI 走不同的路径:桌面端直接读取受信任设置并跨所有 provider 组扫描条目(协议无关),因为它没有 CLI 的模型注册表。这带来一个窄范围的可见性差异:

  • CLI 通过模型注册表解析语音模型,自定义 provider 组的条目仅在组 id 能解析出协议时可见(内置组 id 或providerProtocol映射);
  • 桌面端会解析出 CLI 过滤掉的条目——例如非 OpenAI 协议组(如gemini)下的语音条目、imageOnly条目、qwen-oauth组——同时扩大歧义检查范围:任一被扫描组中存在同 ID 不同 baseUrl 的条目,都会在桌面端判定模型歧义,即使该重复条目位于 CLI 永远看不到的组中、且 CLI 能正常解析;而所有保持旧回退(public HTTPS、未白名单)的重复项在两个表面都不会失败。

核心不变量:每个解析路径在两个表面上都经过网络策略检查;这些分歧只改变“哪些条目被解析”,绝不改变“对解析出的条目施加哪些检查”。

凭据选择规则

桌面端只有在条目需要网络策略决策时才把 ID 与所选语音模型完全匹配的 provider 视为权威——即其 base URL 被白名单、是明文 HTTP、私网地址或回环。这些条目在 OAuth 凭据之前解析,因此托管网关对已 OAuth 登录用户生效;同时它们在以下情况fail closed,防止意外回退到别的 provider 或区域:

  • 重复匹配(ambiguous duplicates)
  • 不支持的 scheme
  • 始终被阻止的地址
  • 缺少白名单匹配
  • 未解析的envKey

Public HTTPS 条目保持旧回退链(OAuth → 共享 DashScope provider → 环境凭据),保留既有安装的凭据优先级;无法分类的条目(缺失或不可解析的 base URL)同样走回退。无envKey的条目在无 API key 的情况下解析——这与 CLI 对无 key 本地/私有网关的处理一致,便于http://localhost这类本地 ASR 服务免凭据使用。

同 ID 条目的歧义规则与 CLI 模型注册表一致:除非是精确的(id, baseUrl)重复(首个注册的条目胜出,envKey不参与复合键,因此 envKey 不同也保留首个注册),或所有匹配条目都不需要网络策略决策(整个集合保持旧回退,如单一 public HTTPS 条目),否则视为歧义。这防止了无关模型或区域提供端点与 API key。

失败与回滚行为:fail closed 与 DNS 回环封堵

畸形条目与非匹配一律 fail closed(拒绝出站)。删除条目后,设置重载或进程重启即恢复既有的 HTTPS/public-network 要求——回滚简单直接。

两个相对旧守卫的行为变更

  1. CLI:带内嵌凭据的语音模型baseUrl(如https://user:pass@host/...直接拒绝,而不是剥离凭据后继续——userinfo 可能让 URL 解析器解析到攻击者控制的主机。实现见 voice-transcriber.ts(normalizeBaseUrlurl.username || url.password抛错)。
  2. 桌面端:IPv4-mapped IPv6 字面量(如::ffff:127.0.0.1)按其内嵌的 IPv4 地址分类,不再绕过回环封堵;应改用显式回环拼写。

回环 DNS 与本地端点

解析到回环地址的主机名始终被阻止(无论是否有白名单条目)——例如asr.localtest.me或指向本地 ASR 服务器的/etc/hosts别名;CLI 此前会放行这类 DNS 结果。要访问本地端点,必须配置显式回环 baseUrl:

http://localhost http://127.0.0.1 http://[::1]

这些拼写仍然允许。

验证清单:文档定义的验收标准

设计文档 trusted-private-voice-base-urls.md 的 Verification 一节给出完整验收标准,可直接作为回归测试依据:

  • 保持对非 localhost HTTP 与私网端点的默认拒绝;
  • CLI 与桌面端都要求白名单条目包含显式 scheme 与完整 provider 路径;
  • 仅当所选 URL 与条目精确匹配时,接受两个互不相关的区域私有网关 URL;
  • 拒绝 scheme、port、host 或 path 不匹配;
  • 即使精确列出,也拒绝非 HTTP(S) scheme;
  • 忽略并警告 Workspace 作用域条目;
  • 精确匹配后仍拒绝 link-local 与云元数据地址(含 AWS IMDS IPv6fd00:ec2::254);
  • 一致地解码 IPv4-mapped、IPv4-compatible 与 well-known-prefix NAT64(64:ff9b::/96)IPv6 字面量,使受信私网地址被接受、内嵌回环与元数据地址仍被阻止;
  • 在受信路径与默认拒绝路径上均拒绝 local-use NAT64、IETF 协议分配/Teredo 与 6to4 过渡前缀;
  • 将桌面端凭据与所选语音模型 ID 匹配到唯一无歧义的 provider;
  • 覆盖 CLI 与桌面端两条解析路径及 DNS 守卫路径。

仓库中的对应实现同样可验证这些约束:voice-transcriber.ts 的精确匹配、voice-stream-session.ts 的 WebSocket 派生、settingsSchema.ts 的 Schema 定义,以及 settingsUtils.ts 的受信作用域清单。

实践要点速查

场景结论
内网私有网关放行security.allowedInsecureVoiceBaseUrls写入完整、带 scheme、带路径的精确 URL
通配符/后缀匹配不支持,必须逐条精确列出
DashScope provider 跨表面一致显式携带/v1后缀;否则 CLI 与桌面端各匹配各的 URL
Workspace 作用域被忽略并告警,克隆仓库无法自我授权
明文 HTTP允许但会暴露 Authorization 头中的 API key,仅限受信托管端点
回环访问本地 ASRhttp://localhosthttp://127.0.0.1http://[::1]
回滚删除条目,重载/重启即恢复 HTTPS/public-network 要求
始终阻止元数据(含 AWS IMDS IPv6)、link-local、local-use NAT64、Teredo、6to4、解析到回环的主机名

配置该选项只影响出站网络策略检查,不会改变语音转写本身的行为;它在 设置 Schema 中归类于security类别,requiresRestart: false,修改后无需重启即可生效。

【免费下载链接】qwen-codeAn open-source AI coding agent that lives in your terminal.项目地址: https://gitcode.com/GitHub_Trending/qw/qwen-code

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/13 21:31:56

HDFS与YARN核心组件深度拆解:存储与调度架构实战对比

很多人一开始接触Hadoop,最容易绕晕的就是HDFS和YARN这一对搭档。光看名字,一个是存储,一个是计算调度,各司其职好像很清楚,但真正搭集群、跑任务、排查故障时才发现,这两个框架内部的组件分工远比想象中复…

作者头像 李华
网站建设 2026/9/13 21:31:45

SpringBoot民宿预订系统设计与实现:订单状态机与防超卖核心解析

民宿预定系统这个题目,这几年在我接触的计算机毕业设计里出现频率非常高,名下挂着“栖游智订”“乡舍云订”这类系统名,网上搜出来一大片,但真上手做的人都知道,难的不是增删改查,而是那些藏在业务细节里的…

作者头像 李华
网站建设 2026/9/13 21:31:42

Python排列组合实战:itertools内置函数与DFS手写实现

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/13 21:29:40

基于SpringBoot的校园零售管理系统(源码+文档+部署+讲解)

温馨提示:本人主页置顶文章(点我)开头有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:本人主页置顶文章(点我)开头有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:本人主页置顶文章(点我)开头有 CSDN 平台…

作者头像 李华
网站建设 2026/9/13 21:28:57

2026年GPU算力租用市场分析与实战指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华