ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Sunshine Windows 双端目录映射补强设计:从裸 RPC 到可安全交付的产品化基线

Sunshine Windows 双端目录映射补强设计:从裸 RPC 到可安全交付的产品化基线 音视频【免费下载链接】foundation-sunshineSunshine fork: an enhanced sunshine, a self-hosted game streaming host for Moonlight with HDR10/HDR Vivid, virtual displays, advanced audio, optimized encoders, and a modern control panel.项目地址https://gitcode.com/gh_mirrors/sunshine5/foundation-sunshine点击查看免费下载本文是 Sunshine fork 中docs/windows_directory_mapping_design.md的配套补强记录解读围绕Moonlight 主动建立双向 WSS 文件 RPC、双端只暴露受控 mapping、后续可选接入 WinFsp 虚拟盘这条主方案系统梳理正式落地前必须纳入的传输协议、任务模型、QoS、授权、审计与 Windows 竞态安全基线。读完本文你将掌握该功能的安全设计边界、各补强项的具体形态以及当前仓库src/file_mapping/模块的真实落地状态与验证证据。一、主方案评估方向可靠但裸 RPC 不能直接交付原补强文档给出的核心结论是Moonlight 主动建立双向 WSS 文件 RPC双端只暴露受控 mapping后续可选接入 WinFsp 虚拟盘的主方案方向可靠符合远控产品从受控文件通道逐步演进到虚拟盘的成熟路径。但正式落地时不能只实现裸list/read/write。传输协议、任务模型、QoS、授权、审计和 Windows 竞态安全必须一起纳入设计基线否则在真实网络弱网、重连、恶意客户端与真实文件系统junction、占用、超长路径下都会出现可靠性或安全问题。二、必须补强项之一控制消息与文件数据分离JSON 控制面控制消息继续使用 JSON协议中需要覆盖以下消息类型hello list stat open close mkdir rename delete job_start job_status cancel error这些类型在仓库协议模型中已落地为枚举message_type_e见 src/file_mapping/file_mapping_rpc.h并额外包含result与remove。为什么文件块不能长期使用 JSON base64原文档给出三条硬理由base64 体积约增加三分之一大文件传输会产生额外 CPU 和内存拷贝binary frame 更适合做背压、限速和零拷贝优化。因此最终协议应使用WebSocket binary frame并采用JSON frame 管控制面、Binary frame 管数据面的分工JSON frame: 控制面 Binary frame: 数据面binary frame 头部至少包含protocol_version request_id job_id handle_id offset flags payload_length这一设计已在 RPC 头文件中固化为 44 字节的binary_header_t带魔数0x53464d50即 ASCII 的SFMP字段包括magic、version、flags、request_id、job_id_hash、handle_id、offset、payload_length并提供encode_binary_header/decode_binary_header见 src/file_mapping/file_mapping_rpc.h。三、必须补强项之二引入 Transfer Job 模型用户可见的上传、下载、复制不应直接暴露为一组裸 RPC而应抽象为 transfer job。原文档给出job_start示例{ type: job_start, id: 200, job_id: job-abc, operation: download, source: { side: host, mapping: host-downloads, path: games/setup.exe }, destination: { side: client, mapping: client-downloads, path: setup.exe } }job 状态集合queued running paused completed failed cancelled每个 job 至少记录job_id operation source destination total_bytes transferred_bytes state error_code error_message created_at updated_at optional_hash_or_etag仓库协议模型中对应的transfer_job_t已包含job_id、operation、source、destination、total_bytes、transferred_bytes、state、error_code、error_message且job_state_e与operation_elist/stat/read/download/upload/copy均为独立枚举并提供job_to_json/job_from_json序列化接口见 src/file_mapping/file_mapping_rpc.h。收益原文档要点UI 可以稳定显示进度用户可以取消、暂停、重试helper 崩溃或重连后任务不会误显示为完成后续可以支持队列、限速、批量传输和断点续传。四、必须补强项之三文件传输必须有 QoS文件传输必须是串流会话中的低优先级后台负载不能影响视频、音频和输入。原文档建议策略局域网默认上限: 不限或 200 Mbps 远程网络默认上限: 20 Mbps 弱网状态: 降到 5 Mbps 或暂停后台传输 用户前台主动传输: 可临时提高上限但仍不能阻塞输入/control触发降速的信号RTT 升高丢包升高视频码率被 ABR 下调解码帧率下降输入延迟升高WSS send queue 持续积压。实现要求文件传输队列与串流主循环解耦文件传输不得在 Session 主线程执行阻塞 I/O支持全局限速和单 job 限速支持cancel取消必须尽快生效。这与设计文档文件传输不进入视频、音频、输入、Limelight control stream 热路径的原则一致见 docs/windows_directory_mapping_design.md。五、必须补强项之四双向共享必须显式授权Sunshine 共享目录给 Moonlight在 Sunshine Web UI 中配置按客户端 UUID 授权默认只读。Moonlight 共享目录给 Sunshine在 moonlight-qt 中配置按主机授权首次访问建议弹窗确认。首次访问确认选项本次允许 始终允许此主机 拒绝高风险能力必须额外确认readwrite delete rename replace bulk transfer execute特别地allow_execute默认必须关闭。未来如果支持远端请求执行文件应作为独立高危能力不应混在普通目录映射里。仓库中的mapping_t结构体将allow_delete、allow_execute、follow_reparse_points作为独立布尔字段并默认false见 src/file_mapping/file_mapping.h。六、必须补强项之五Windows 路径与 TOCTOU 防护已有规则远端只能传相对路径使用mapping_id relative_pathcanonicalize 后必须仍在local_root下默认拒绝 junction、symlink、mount point 等 reparse point。这些规则在 src/file_mapping/file_mapping.cpp 中逐条实现为is_safe_relative_path与resolve_path拒绝以/、\开头、盘符前缀C:、UNC 前缀//、\\、.与..段、Windows 非法字符、以空格/点结尾的段以及保留设备名CON、PRN、AUX、NUL、COM1-COM9、LPT1-LPT9resolve_path通过weakly_canonical之后用逐段大小写不敏感比较确认候选路径仍位于 root 之下路径比较在 Windows 下按大小写不敏感处理。需要补强的点不只在 open 前检查路径打开文件后也要基于 handle 复核属性rename/delete/replace 要同时校验源路径和目标路径目录枚举结果不能被后续操作无条件信任。典型 TOCTOU 风险1. 远端请求 safe/file.txt 2. 本地检查时路径位于授权目录内 3. 本地其他进程把 safe 替换成 junction 4. 实际 I/O 逃逸到授权目录外建议措施优先使用 Windows handle-based APICreateFileW后调用GetFileInformationByHandleEx复核属性对FILE_ATTRIBUTE_REPARSE_POINT默认拒绝写入使用同目录临时文件完成后原子 renamedelete/rename 前后都进行最终路径校验对目录 handle 和文件 handle 保持最小必要权限。原文档特别强调文件打开仍需补 Windows handle-level final path 校验消除 resolve 后到 open/read 之间的 TOCTOU 窗口——这属于当前尚未完成的补强项。七、必须补强项之六增加审计日志两端都应记录安全相关事件mapping created mapping updated mapping removed file channel connected file channel disconnected list read write mkdir rename delete job started job completed job failed job cancelled access denied path escape blocked reparse point blocked日志字段timestamp local_side remote_uuid remote_name mapping_id operation relative_path result error_code bytes_transferred job_id禁止写入日志client private key raw auth token full certificate secret material unmasked credentials八、必须补强项之七虚拟盘阶段必须单独定义边界WinFsp/Dokany 是第三阶段能力不应影响第一版文件面板交付。虚拟盘阶段需要单独定义挂载前用户确认明确说明本机其他程序也能读取挂载目录挂载生命周期Moonlight 退出、串流断开、网络失败、主机撤销共享时自动卸载只读挂载的 Explorer 行为缩略图、索引器、预览器和普通程序读请求都必须受同一套限流与路径策略约束缓存策略文件锁语义一致性模型rename/replace 行为大量小文件性能随机 I/O 性能是否允许从远端盘执行程序是否允许游戏或大型应用直接运行。第一版不应承诺从远端虚拟盘直接运行游戏 从远端虚拟盘直接运行大型程序 完全等价于本地 NTFS 盘 完全等价于 SMB/RDP drive redirection九、推荐实施基线三阶段推进Phase 1 必须包含JSON 控制消息binary 文件块或至少预留 binary frame 升级点transfer job基础限速显式授权路径逃逸防护reparse point 默认拒绝审计日志。Phase 2 必须包含Moonlight 客户端目录反向共享Sunshine 通过同一条 WSS 访问客户端 mapping首次访问确认双端统一 job 状态和错误码。Phase 3 才考虑WinFsp/Dokany只读盘符或目录挂载缓存和文件锁虚拟盘性能边界。最终判断主方案先进且可行比 SMB 更适合 Sunshine/Moonlight 的连接模型无需暴露 SMB 认证面与系统服务依赖比把数据塞进 Limelight control stream 更可靠不污染串流热路径也比第一版直接做虚拟盘更稳。只要把补强项纳入基线就可以作为安全、可演进、产品体验足够好的双端目录映射方案推进。十、WSS 实现补充Simple-Web-Server 与 Boost.Beast 的分工Simple-Web-Server不应承担完整文件映射 WebSocket 数据通道保留它处理capability endpointWeb UI 管理接口配置保存健康检查。真正的文件通道应使用Boost.BeastBeast 已基于 Boost.Asio和 Sunshine 当前依赖栈契合Beast 原生支持 WebSocket frame、binary/text、ping/pong、close、read/write 异步模型可以更自然地实现 backpressure、限速和 session 生命周期。实施基线与仓库实际模块一一对应file_mapping_http: REST/discovery/config file_mapping_ws: Beast WebSocket transport file_mapping_rpc: protocol model file_mapping: local filesystem safety file_mapping::service_t: built-in feature lifecycle and capability state除非后续统一网络层否则不要在Simple-Web-Server::on_upgrade上手写完整 WebSocket 协议。设计文档还强调Simple-Web-Server只提供较底层的on_upgrade接管点完整协议ping/pong、close handshake、fragment、mask、backpressure仍需自行实现这正是改用 Beast 的原因见 docs/windows_directory_mapping_design.md。十一、当前落地状态源码级证据Sunshine 侧模块化落地Sunshine 侧已拆出src/file_mapping/内置 feature module共 21 个文件覆盖 core、config、http、operations、rpc、store、token、ws、ws_server、ws_session、service。file_mapping::service_t负责配置解析、mapping store 注入、token store、Boost.Asio/Boost.Beast WSS listener 生命周期和 capability 状态nvhttp::start()只负责启动 service 并把 GameStream HTTPS capability endpoint 转发给它。能力发现 endpoint 已从 Web UI 配置 HTTPS 端口迁移到 GameStreamnvhttpHTTPS 端口复用 paired client certificate 校验。从service_t::start()的实现可见完整启动链路src/file_mapping/service.cppfile_mapping_config::parse_mappings_json解析mappings_jsonwarning 记入日志file_mapping_store::global().replace()注入运行时 mapping 快照operations context 通过mapping_providerlambda 返回 store 快照创建token_store_t构造 Beastserver_ttoken 消费回调为token_store-consume(...)listener 启动成功后跑独立线程执行io_.run()日志输出实际绑定端口。capability 接口返回当前 capability 接口返回enabledSunshine 是否编译并尝试启用文件映射能力listeningBeast WSS listener 是否已经监听port本次启动绑定的动态端口session_url只在 Sunshine 内部有可信显式地址时返回不得根据当前 HTTPS 请求Host头拼接session_token短期一次性 WSS 连接 tokenclient_uuidSunshine 从 HTTPS 客户端证书反查 pairing store 得到的内部配对证书 UUIDerrorWSS listener 启动失败原因。make_capability_response还会额外输出transport: wss、control: json、data: binary、session_endpoint、featuresmappings、transfer_jobs、explicit_authorization、cancel_job、limitsbinary_header_size与max_protocol_version以及diagnostics块见 src/file_mapping/file_mapping_http.cpp。已补的安全点capability 每次返回短期一次性session_tokencapability 请求可以携带 MoonlightIdentityManager::getUniqueId()作为 query/header 诊断 hint但 Sunshine不把该值作为授权依据capability 通过get_client_cert_uuid_from_request()从 nvhttp HTTPS 客户端证书推导 Sunshine pairing store 内部 UUIDsession_token已绑定证书推导出的client_uuid默认 capability 只返回port、session_endpoint和session_token。客户端使用当前已连接的 Sunshine 主机地址自行组合 WSS 目标并避免记录拼接 token 后的完整 URLBeast WSS 在 WebSocket upgrade 前读取 HTTP request target并消费 tokentoken 缺失、过期、错误、重放都会拒绝进入文件映射协议Moonlighthello.client_uuid必须使用 capability 返回的client_uuid并和 token 绑定 UUID 一致hello.client_uuid必须存在于 Sunshine 已配对客户端列表Web UI / control-panel 持久化file_mappings时写入base64:json解析层继续兼容旧 raw JSON array避免sunshine.conf行解析器把 JSON 字符串里的]、#或换行当作配置语法。token 策略在 src/file_mapping/file_mapping_token.h 中有明确默认值TTL 60 秒、token 总量上限 128、单客户端最多 4 个、同客户端最小签发间隔 1 秒——这与文档短期一次性 token、token 全局/单客户端配额、签发间隔的闸门描述一致。已补的文件能力已新增file_mappings配置项使用 JSON array 注入 host mappingsfile_mapping::service_t会解析config::nvhttp.file_mappings并注入 WSS server 的 operations context已新增 Sunshine 本机管理 API 和file_mapping_store支持运行期创建、列出、更新、删除 mapping并持久化回file_mappings管理 API 写入采用失败回滚配置持久化失败时恢复旧 store避免 HTTP 返回失败但运行态已经生效第一阶段固定只读readwrite、allow_deletetrue、allow_executetrue、follow_reparse_pointstrue都不会进入运行时 storeWSS 已增加第一批资源闸门token 全局/单客户端配额、签发间隔、Beast message size limit、active session 上限、write queue 上限目录 listing 已增加默认返回数量上限operations context 默认max_list_entries 4096max_read_bytes 1 MiB见 src/file_mapping/file_mapping_operations.h并通过truncatedtrue告诉客户端需要分页/继续读取RPC 已增加最小 job modellist、stat、read回包携带job_id/job并支持job_status与cancel_job查询/取消入口capability response 已增加 diagnostics明确返回 bind address、configured/bound port、listening、client certificate、token issue/rate-limit 等状态已新增只读 RPC 执行器file_mapping_operations已支持 host mapping 的list、stat、readread当前返回 JSONresult文件数据使用 base64 编码session_core_t已在 hello 后调用真实只读执行器不再返回占位handledmapping 白名单会按peer_uuid校验mapping.clientsclient_allowed逻辑clients为空则放行非空时必须包含 peer_uuid见 src/file_mapping/file_mapping_operations.cpp。Moonlight-qt 侧当前已补已新增app/streaming/FileMappingClient原型模块挂入app.procapability 请求会携带 MoonlightIdentityManager::getUniqueId()作为client_uuidquery 和X-File-Mapping-Client-UUID头capability 响应会解析 Sunshine 返回的client_uuidWSShello.client_uuid优先使用该值避免误用 Moonlight uniqueid 或 Sunshine host uuid复用现有IdentityManager::getSslConfig()和 Sunshine 已配对服务器证书 pinning当前 Qt 安装缺少QtWebSockets模块因此客户端先使用QSslSocket实现最小 WSSTLS、HTTP Upgrade、Sec-WebSocket-Accept校验、client masked text frame、server text frame JSON 解析已提供smokeRead()可按capability - WSS - hello - list - read跑第一阶段端到端烟测FileMappingClient已改为使用 Moonlight 客户端IdentityManager::getUniqueId()作为 capability hintNvComputer::uuid是 Sunshine 主机 UUID不能用于 WSS token 绑定已在Session连接成功后接入隐藏烟测开关MOONLIGHT_FILE_MAPPING_SMOKE1并通过MOONLIGHT_FILE_MAPPING_SMOKE_MAPPING/MOONLIGHT_FILE_MAPPING_SMOKE_PATH指定测试目标烟测任务在线程池中后台执行不阻塞普通串流启动默认关闭烟测任务会在NvComputer::lock读锁保护下复制主机快照再交给后台线程避免运行时和主机状态刷新竞态capability 请求先读取 response body 再释放QNetworkReply避免 worker 线程里对象释放顺序依赖deleteLater()的隐式时机capability 失败会记录 HTTP status 和响应 body 摘要RPCtype:error会直接输出服务端message/code异常响应会记录hello/list/read三段 compact JSON便于真实端到端冒烟时定位失败点已新增独立 smoke CLI 子项目filemapping-smoke不依赖 Qt Multimedia 或完整 UI可直接命令行验证capability - WSS - hello - list - read。当前文件能力仍未完成Sunshine Web UI 还没有目录 mapping 管理页面Control Panel 目前只覆盖普通用户快速共享、列表和移除高级权限 UI 还未完整开放WSS 仍需要接入 paired client certificate verify callback当前 Beast 端口仍主要依赖 capability 签发的一次性 token文件打开仍需要补 Windows handle-level final path 校验消除 resolve 后到 open/read 之间的 TOCTOU 窗口WSS 仍需要补 handshake/idle timeout、ping/pong、异步任务中途取消和更完整的审计日志当前 job model 仍是同步执行后的状态记录长耗时目录遍历/文件传输要支持真正中途取消还需要把 executor 改成异步 job runner大文件数据还没有切换到 WebSocket binary frame写入、删除、rename、mkdir 尚未启用Moonlight-qt 文件面板、helper 进程隔离、反向客户端目录共享尚未接入Moonlight-qt 当前 WSS 实现只覆盖首轮烟测产品化前仍需补 close handshake、ping/pong、fragment、binary frame、backpressure 和任务取消。十二、当前验证状态已完成模块级语法编译core path、RPC、token、HTTP、operations、WS core、WS session、WS server、config parser已完成运行冒烟配置 JSON - mapping - sessionhello-read已新增 GTest 网络级冒烟test_file_mapping_ws_network.cpp位于 tests/unit会启动真实 WSS server并用 Beast SSL/WebSocket client 完成hello-list-read当前机器完整 CMake/GTest 被 MSYS2 UCRT 编译器构建 Boost 源码失败挡住失败发生在 Boostalloc_lib.c/dlmalloc.cpp尚未进入 Sunshine 新增代码当前机器独立 WSS 网络探针使用 Strawberry g 链接 MSYS OpenSSL 后在进入main()前以0xC00000FD退出判断为运行库混链问题网络级源码已完成语法编译待正常统一工具链执行Moonlight-qt 已完成 qmake 验证使用CONFIGconfig_SL避开当前机器缺失的 Qt Multimedia 模块后app.pro可生成 MSVC MakefileMoonlight-qt 已完成 MSVC 最小编译验证debug\filemappingclient.obj、debug\moc_filemappingclient.cpp、debug\moc_filemappingclient.obj均编译通过Moonlight-qt 已完成 Session 接入编译验证在当前机器缺少 Steam Link SDK 头文件的情况下使用临时 build 目录占位SLVideo.h后debug\session.obj编译通过用于证明新增Session接线、主机快照加锁复制和后台烟测任务没有 C 编译错误Moonlight-qt 独立 smoke CLI 已完成 qmake MSVC 编译链接验证--help和缺参 usage 自检可正常退出。十三、当前刻意保留的安全取舍与下一步安全取舍是当前实现的重要设计决策Beast WSS 目前复用 Sunshine 服务器证书只做服务器 TLSpaired Moonlight 客户端证书校验尚未直接接入 Beastssl::context第一阶段的强认证发生在nvhttpcapability 请求只有通过 GameStream HTTPS paired client certificate 校验的客户端才能拿到一次性 tokenBeast WSS 端口依赖短期一次性 token、token 绑定 UUID、hello UUID 一致性校验和 pairing store 白名单。该模型已经比 Web UI BasicAuth 方案更适合 Moonlight 真实链路但仍可进一步升级为 Beast 端也直接校验证书。因此下一步必须补增加 WSS auth/audit 日志记录 token/UUID/证书失败原因但不回显给网络端对 capability token 签发增加速率限制和失败计数评估是否将 Sunshine pairing store 中的客户端证书接入 Beast verify callback使 WSS 端口也具备 mTLS 双因子防线将真实file_mapping_smokepassed写入验收记录后再推进文件面板和 binary frame。十四、总结把补强项纳入基线再推进综合设计文档与补强文档Windows 双端目录映射的正确推进路径是以会话级双向文件 RPC 为骨架Moonlight 主动连接、复用配对证书双端只暴露受控 mapping第一版交付文件面板与稳定只读传输第二版完成客户端反向共享第三版再用 WinFsp 提供盘符体验。在正式产品化之前必须把本文梳理的七类补强项控制/数据面分离、Transfer Job、QoS、显式授权、TOCTOU 防护、审计日志、虚拟盘边界全部纳入基线——这正是src/file_mapping/模块当前架构与后续工作清单所遵循的设计基线。赞分享音视频【免费下载链接】foundation-sunshineSunshine fork: an enhanced sunshine, a self-hosted game streaming host for Moonlight with HDR10/HDR Vivid, virtual displays, advanced audio, optimized encoders, and a modern control panel.项目地址https://gitcode.com/gh_mirrors/sunshine5/foundation-sunshine点击查看免费下载相关推荐easy-vibe 初中级开发阶段全栈实战指南从前端组件化、数据库与 API到交付可上线产品easy vibe 初中级开发阶段全栈实战指南从前端组件化、数据库与 API到交付可上线产品 进入 easy vibe 的「初中级开发」Junior un教程文档RuView 生产落地路线图从 SOTA 研究循环到可交付产品的 Tier 分级工程指南RuView 生产落地路线图从 SOTA 研究循环到可交付产品的 Tier 分级工程指南 本篇技术指南以 RuView 仓库内 PRODUCTION ROAD人工智能计算机视觉物联网智能家居后端嵌入式终极指南如何用pop框架彻底解决iOS动画卡顿问题终极指南如何用pop框架彻底解决iOS动画卡顿问题 pop是一款功能强大的iOS、tvOS和OS X动画引擎它不仅支持基本的静态动画还提供了弹簧和衰减等动人工智能计算机视觉物联网智能家居后端嵌入式上一篇gspread 官方认证指南API Key、OAuth Client ID 与 Service Account 三种 Google Sheets 授权方案详解下一篇Modular Monolith 模块化单体架构学习与实践指南awesome-software-architecture 精选资源深度解读创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表