最近更新
阅读最多
评论最多
博客图片修整中,看不了可以先搜索公众号“忘机山人”看。
对于 NAS 玩家来说,虚拟机绝对是标配。今天我们要介绍的主角是 QEMU。你可能会觉得它太过底层、全命令行操作太硬核,但别担心,看过这篇文章之后,你就能轻松在懒猫微服上操作它。在传统 Linux 下装 QEMU,你可能要折腾一堆 检测、各种动态库依赖。但在懒猫微服上,直接从商店下载即可。这就是全容器化的好处:环境全封闭,不会把宿主机的依赖搞坏,不用再和底层依赖打交道,这就是懒猫微服全容器化的好处,彻底解决了让人头疼的环境问题。和其他虚拟机一样,我们需要一个 ISO 镜像。QEMU 厉害的地方在于它对镜像来源几乎从不挑剔可以直接填入官网的 ISO 下载链接,边下边装,省去中间转手的麻烦。如果你的镜像在电脑里,或者在 NAS 上,那么可以直接在存放镜像的文件夹下打开终端,用一行 Python 命令把它变成“下载站”:然后在 QEMU 的镜像地址里填入:。在懒猫微服的界面上,你只需要选好分给虚拟机的 CPU 核心数和内存大小。如果你想稍微硬核一点,看看后台它是怎么运行的,其实 QEMU 常见的“加速”命令已经默默为你打好了。比如::给虚拟机分配 2GB 内存。:给虚拟机 4 核 CPU。当然你可以对这些参数进行修改,完成可以改成4C8G或者更高的配置。当然也可以安装安卓系统,我尝试运行了BlissOS,很流畅,除了必要的X86和ARM指令集转换缺失之外,其他的都可以流程运行。甚至把虚拟机内部的 5555 端口(ADB 默认调试端口)通过端口映射的工具映射出来。这样,我们在局域网内的任何一台电脑上,只需要执行这个命令就可以进行ADB调试:进行端口转发之后,就可以像操作真机一样,直接用 往虚拟机里塞 APK,或者在线的调试。安装完成之后,完全不用担心远程连接的问题,甚至还自带一个web的no-VNC。好了,安装完了,咱们从纯技术的角度聊聊 QEMU,以及它和 KVM 到底是什么关系。QEMU:全能模拟器QEMU 是一个纯软件实现的虚拟机。它的强大之处在于 “无所不拟” :它可以在 x86 架构(普通电脑)上模拟出 ARM、MIPS 甚至 PowerPC 的环境。代价: 这种“纯软件模拟”就像是找了个翻译官,每条指令都要翻译一次才能执行,所以单跑 QEMU 的速度比较慢,跑起来像在泥潭里走路。KVM:内核加速器KVM(Kernel-based Virtual Machine)是 Linux 内核的一个模块。它的作用是让虚拟机直接调用 CPU 的硬件虚拟化指令(如 Intel VT-x)。优点: 它的性能极快,几乎能发挥出硬件的真实水平。局限: 但 KVM 很“高冷”,它只管 CPU 和内存,至于怎么模拟显卡、鼠标、USB 接口,它一概不管。在懒猫微服里,我们默认用的是 QEMU-KVM 模式:KVM 负责干体力活: 接管 CPU 和内存,保证运行速度飞快。QEMU 负责干技术活: 模拟所有的外设(显卡、网卡、声卡、USB 驱动等),并提供管理功能。总结:QEMU 是大脑和管家,KVM 是强壮的肌肉。两者是黄金搭档,才有了我们在懒猫微服上流畅的虚拟机体验。既然受众觉得“太简单”,那我们就提高维度。NAS 玩家群体中,有一部分人追求的是底层掌控感和架构美学。我们要把这篇文章从“操作手册”升级为“技术深度解析”,加入性能损耗、IO 虚拟化、以及容器嵌套虚拟化(Dind/LXC-level virtualization)的讨论。以下是为你重写的硬核进阶版,文风更偏向《少数派》或专业技术周刊:深度:在容器化浪潮下,重新定义 NAS 虚拟化边界在 NAS 的圈子里,“装个虚拟机”早已经不是什么新鲜事。但当大多数人还在纠结镜像下载速度时,硬核玩家已经在思考:如何以最轻量级的开销,获得接近原生的虚拟化体验?今天我们拆解的主角是 QEMU,以及它如何在懒猫微服的架构下,实现从“底层硬核”到“开箱即用”的范式转移。一、 架构之争:为什么是容器化的 QEMU?传统 NAS 安装 QEMU 往往是一场环境灾难:内核模块冲突、缺少 依赖、甚至会因为一次系统升级导致虚拟化崩溃。懒猫微服采取了 All-in-Containers 的方案。这不仅仅是为了安装方便,更是为了解决环境一致性:依赖解耦:QEMU 及其庞大的动态库被封装在独立的镜像空间,宿主机保持“纯净态”。资源配额 (Cgroups):通过容器引擎直接限定虚拟机的资源阈值,防止 VM 内存溢出导致宿主机 OOM。底层通达:利用 设备透传,容器内的 QEMU 依然能直接驱动硬件加速,性能损耗控制在 5% 以内。二、 IO 效能与“黑客式”分发对于硬核玩家,UI 只是点缀,数据流的效率才是生命线。1. 镜像分发的“极简主义”QEMU 对镜像来源的动态支持,配合 Python 的一行代码,构建了一个临时的 P2P 分发节点:这种做法的本质是绕过磁盘 IO 的二次拷贝。镜像直接从开发机通过 HTTP 流式注入 QEMU 的虚拟磁盘镜像,这比“下载到 NAS -> 上传到目录 -> 挂载”的路径缩短了一半时间。2. ADB 隧道与端口重定向如果你在虚拟机中运行 BlissOS 或 OpenWrt,传统的 VNC 远程控制效率极低。通过懒猫微服的端口重定向 (Port Mapping),我们可以将 VM 内部的逻辑端口直接暴露在局域网:场景:将 VM 内 5555 端口映射至宿主机。价值:实现原生级别的 ADB 调试流。你在 PC 上执行 ,面对的是一个具备完整指令集、由 KVM 驱动的硬件实例。三、 硬核科普:解构 QEMU 与 KVM 的协同哲学很多玩家分不清两者的界限。从纯技术视角来看,这是一场软件模拟与硬件加速的完美共生。维度QEMU (模拟层)KVM (加速层)角色策略大脑 / 全能翻译官动力心脏 / 执行单元职责模拟 BIOS、网卡、磁盘 IO、显卡处理 CPU 指令集映射、内存寻址跨架构支持 (如 x86 模拟 ARM)不支持 (必须指令集对齐)为什么我们需要 QEMU-KVM?KVM 是 Linux 内核的一个模块,它极其强大,但也极其“纯粹”——它不处理任何 IO 交互(你无法通过 KVM 直接操作鼠标)。而 QEMU 则是 KVM 的最佳壳程序。在懒猫微服中,KVM 负责干“体力活”,让 CPU 满血运行;QEMU 负责干“脑力活”,模拟出各种总线和外设。两者通过 接口握手,构成了现代虚拟化的基石。四、 结语:折腾的本质是自由在懒猫微服上操作 QEMU,本质上是在屏蔽环境复杂性的同时,保留了底层的自定义自由。你可以根据需求,在简单的 UI 界面下随意调整 (多核调度)和 (内存配额)。这种“重剑无锋”的体验,正是为了让玩家把精力从无意义的系统排错中解放出来,投入到更有价值的业务实验中去。💡 进阶思考(QA)问:QEMU 容器化后,网络性能如何?答:默认使用 Bridge 模式,但支持开启 VirtIO 驱动,通过半虚拟化技术实现近乎万兆的内网吞吐。




Laugh
Fusion 懒猫微服使用攻略一句话概览:Fusion 是一个面向开发者的 AI 编程任务看板。它把需求、规划、执行、评审、合并放在同一个浏览器工作台里,适合把长期项目放到懒猫微服上持续运行。适合谁Fusion 适合已经有 Git 仓库、希望把 AI 编程任务拆成可跟踪流程的人。它不是普通聊天窗口,而是一个任务编排器:每条任务会经历 Planning、Todo、In Progress、In Review、Done 等阶段,配合模型 provider、Git worktree、测试命令和评审策略,把一次代码修改变成可复盘的流水线。上游项目把 Fusion 定位成 multi-node agent orchestrator,核心是让规划智能体先读取项目并生成 ,再经过执行、评审、合并等 gate。懒猫版保留这个主流程,只是把 dashboard 固定跑在微服里,项目数据落到持久化目录。上游仓库:如果只是临时问答,普通 AI Chat 更轻;如果要让 AI 围绕一个仓库持续规划、修改、审查和合并,Fusion 更合适。开始前先准备三件事准备一个 Git 仓库。Fusion 的执行和 worktree 能力依赖 Git;空目录也可以先 。准备至少一个 AI provider。OpenAI、Anthropic、OpenRouter 等凭据可以在懒猫安装参数里填,也可以稍后在 Fusion 设置里填。只想试用时,OpenRouter 里选择带 后缀的模型即可。如果要导入 GitHub Issue 或创建 PR,准备 GitHub Token。没有 GitHub 也能手动创建任务。懒猫版 Fusion 的持久化路径::项目目录、 项目数据库、任务文件、worktree。:Fusion 全局设置、provider 配置、SSH、缓存。01 首次打开:注册项目安装后打开:清空数据后第一次进入,会看到项目注册向导。推荐把项目放在 ,项目名可以写真实仓库名,也可以先用一个测试名。填写建议::用于看板和项目列表展示。:懒猫版默认使用 。:大多数情况保持默认 。需要隔离运行时再考虑 。本次测试里,先在 初始化了一个 Git 仓库,再注册项目:02 AI Setup:可以跳过,但不能忽略注册项目后,Fusion 会进入 AI Setup。这里可以配置 OpenAI、Anthropic、Google 等 provider。截图展示的是未连接 provider 的早期状态,也是新装后最常见的状态。没有 provider 时,Fusion 仍然能打开看板、创建任务、查看任务详情、使用 Git/终端相关接口;但 AI 自动规划、代码执行、审查和总结不会真正跑起来。配置 provider 时,密钥只需要保存在 Settings 或懒猫安装参数里,不需要写进任务描述、README 或提交记录。03 OpenRouter/free:低成本试跑方式如果只想先验证 Fusion 的 AI 流程,可以在懒猫安装参数里填 ,启动后再到 Settings 里把 project model 和 task model 都设成 OpenRouter 的免费模型。测试中使用的是:需要设置的模型 lane::负责把任务描述扩写成计划。:负责实际修改代码。:负责计划或代码评审。单任务 Tab:已有任务可能保留旧模型,必要时给任务本身也设置同一个 free 模型。本次实测里,Fusion 能正确读取 OpenRouter 模型列表, 返回 368 个 OpenRouter 模型;任务 也能切到 并触发规划。但 OpenRouter 免费模型在高峰期返回 429 限流,日志显示该 free 模型限制为每分钟 8 次请求,随后又返回 temporarily rate-limited upstream,因此没有生成 。这类限流不是 Fusion 安装失败。处理方式是:等一段时间后重试。换另一个 模型。降低并发,避免多个任务同时规划。点 暂停自动重试,避免免费额度一直被排队请求占用。04 Codex Subscription:更完整的 agent 测试路线如果你已经登录过本机 Codex CLI,也可以把 Fusion 的模型 lane 切到 。本次复测使用的是:实测结论比 OpenRouter/free 更完整:Codex 能完成任务规格生成、规格 review、步骤 plan review、执行、验证和自动合并。测试任务 只要求在 demo 项目的 末尾追加一行:最终任务进入 ,四个步骤全部完成,demo 仓库生成提交 ,只改了 一行。为了把执行过程看得更清楚,又跑了一条截图 demo 任务 。任务要求 Codex 新建 ,并在 末尾追加:执行中可以看到任务从 Planning 进入 ,卡片会显示当前 worktree、步骤进度、已变更文件数和运行耗时。执行完成并自动合并后,任务进入 。这里可以快速确认任务 ID、摘要、模型标记和变更文件数。点击任务卡片进入详情页, 会保留最终摘要、合并状态、提交号和变更统计。 最终生成提交 ,变更文件数为 2。 页更适合排障和复盘。这里能看到 plan review、step 状态、验证说明和 这类关键事件。05 进阶玩法:把 Hermes、OpenClaw、Paperclip 当作员工Fusion 不只是在 provider 之间切模型。Settings 里还有 Runtimes,可以把 Hermes、OpenClaw、Paperclip 连接成不同“员工”,再用任务模型、Routing 或节点路由决定某条任务交给谁做。这三类员工的定位不同::调用容器内的 CLI。适合已经在 Hermes 里配置好 provider、profile、技能和记忆的人,把 Fusion 任务转交给本地 Hermes agent 执行。需要先让 命令在 Fusion 容器的 PATH 里可用,并完成 Hermes 自己的登录或 provider 配置。:调用容器内的 CLI。它走本地 agent JSON 执行路径,适合想引入另一套 agent 行为或思考模式时使用。首次运行可能会安装依赖或初始化环境,建议先用一个 README 级别的小任务试跑。:连接 Paperclip server 或 Paperclip CLI,把 Fusion 的任务转给 Paperclip 里的某个 agent。Paperclip 更像组织化员工系统,适合需要预算、审批、审计、company/agent 归属和长期目标管理的场景。实际配置路径:打开 ,分别进入 Hermes、OpenClaw、Paperclip。按 runtime 要求填 binary path、profile、provider、API URL、API key、agent ID 或 company ID。保存后去 agent / model / routing 相关页面,把任务 lane 或特定任务指向对应 runtime。先用小任务确认连接、权限、worktree 和合并流程都正常,再让它处理真实代码。懒猫部署时要特别注意:这些 runtime 调用的是 Fusion 容器内能访问到的命令或 API,不是你电脑上的命令。截图里 Hermes 显示 ,说明入口已经识别,但当前容器还没安装 Hermes CLI。OpenClaw 也同理,需要把 CLI 放进镜像、挂载目录或旁路服务里;Paperclip 则要确保 Fusion 能访问 Paperclip API,并且 agent key 只保存在 runtime 设置里。使用心得是:不要一开始就把所有员工都打开。先保留一个主执行者,再加一个专门做 review 或调研的员工;每增加一种 runtime,都用独立的小任务验证它的权限、输出格式和超时行为。这样出问题时能快速判断是模型、runtime、Git worktree 还是 Fusion workflow 本身的问题。06 GitHub:可选,但决定 Issue/PR 工作流GitHub 步骤用于解锁 Issue 导入、PR 状态跟踪和任务关联代码变更。没有 GitHub 连接时仍可使用:手动创建任务。在看板里管理任务状态。配置模型后让 AI 围绕本地项目执行。需要 GitHub 后再从 Settings 里补配置即可。07 看板:先理解任务生命周期跳过可选配置后,会进入主看板。Fusion 的核心列::原始想法,等待 AI 生成计划。:计划明确,可以开始执行。:执行中的任务,会使用独立 worktree。:执行完成,等待合并或最终确认。:已完成。:归档记录。看板顶部如果出现 或 ,不是安装失败,只是提醒这些能力还没配置。08 第一条任务怎么写在 Planning 列的输入框里写一个明确的小任务,然后按 Enter。推荐第一条任务写成这样:好的 Fusion 任务通常包含:目标:要改什么、分析什么、验证什么。范围:涉及哪些目录、文件或模块。验收:完成后怎样判断通过。约束:不要改哪些内容、是否必须跑测试。不建议一上来写“帮我优化项目”。更好的写法是“阅读 README 和 scripts 目录,给出 3 个可执行维护任务,并说明每个任务的验证命令”。09 列表视图:适合批量管理任务多起来后,可以切到 List view。它会按生命周期分组,适合快速扫 ID、标题、状态、依赖和进度。看板视图适合日常拖动,列表视图适合批量检查。任务多时,列表比看板更容易发现卡住的项。10 任务详情:看清执行合同点击任务可以打开详情页。重点看这些 Tab::任务描述、附件、依赖。:执行日志和状态变化。:任务生成的计划、说明、交付文档。:单任务模型覆盖。:执行、评审、验证步骤。:任务运行在哪个节点。真正让 Fusion 发挥价值的是 计划、workflow gate 和 review 记录。它适合处理“要被审查和合并的代码任务”,而不是只看一次性回答。11 建议配置配置 provider 后,优先处理这些设置::给规划、执行、评审分别设默认模型。:已有任务可单独指定 provider/model,避免继续使用旧默认值。:限制并发,避免多个任务同时抢资源。:确认 worktree 数量、命名和初始化命令。:设置测试、构建、安装依赖命令。:决定自动合并还是人工确认。:有多节点时决定任务跑在哪个节点。实际项目里,先从低并发开始。等测试命令和模型稳定后,再放开更多并行任务。使用心得Fusion 的正确用法不是“让 AI 直接接管整个仓库”,而是把任务拆到足够小,让它每次只处理一个边界明确的问题。几个经验很实用:先让 Fusion 读项目并生成计划,再让它执行。计划不清楚时不要急着进 Todo。项目必须保持 Git 状态可解释。 会产生本地状态,提交前要决定哪些配置能进仓库、哪些数据库和缓存要忽略。provider 没配好之前,只做看板和任务整理,不要期待 AI 自动推进。provider 配好了也要看上游模型是否限流。有测试的项目更适合 Fusion。测试命令越稳定,自动执行和评审越有意义。风险高的任务关闭自动合并,保留人工 review。free 模型适合功能验证,不适合长时间无人值守执行。真正跑生产任务时,最好准备稳定模型和明确预算。Codex provider 跑完整流程更顺,但也更能暴露真实运行时问题。只要 executor 进入 worktree,就要确保 HOME 下的 agent session、缓存和 SSH 目录都能被运行用户写入。第一次用新 provider 时,先跑 README 级别的小任务。它能验证 planning、review、execution、merge,又不会把风险扩到业务代码。常见问题提示 No AI provider connected说明还没配置模型凭据。看板和手动任务可用,AI 规划和执行不可用。提示 GitHub not connected说明不能导入 Issue 或创建 PR,但不影响手动任务。任务执行时提示不是 Git 仓库先确认项目目录是 Git 仓库。在懒猫版里通常进入 初始化或克隆仓库。看板能打开,但任务不自动推进检查 provider、模型、任务是否还在 Planning、是否开启了需要人工确认的 gate,以及项目测试命令是否会失败。OpenRouter/free 一直 Rate limited先不要连续点重试。暂停 AI engine,等一段时间或换另一个 模型;如果要稳定跑完整 planning/execution/review 流程,建议使用有明确额度的模型。Codex 规划成功,但执行时报 权限错误检查 是否存在且归 所有。懒猫版已经在启动命令里预创建该目录;如果是旧包或手动迁移环境,补目录后重试任务即可。



博客图片修整中,看不了可以先搜索公众号“忘机山人”看。
在第四章,我们已经澄清了一件非常重要的事:懒猫 ID Token 不是加密的。它是一组“被懒猫 SSO 签名的声明”。这句话看起来很简单,但它隐含了一个巨大的问题:如果任何人都能看到 ,ENV 查看器又凭什么相信这些声明是真的?换句话说:签名到底在“证明”什么?这一章,我们就只回答这一件事。5.1 从一句最容易被误解的话开始在很多讨论中,你可能见过这样一句话:“懒猫 SSO 用私钥加密,Client 用公钥解密。”这句话在懒猫 SSO / OIDC 语境下是错误的。它把两件完全不同的事情混在了一起:加密(Encryption)签名(Signature)如果你不在这里把这两个概念彻底分开,后面所有关于 JWT、JWKS()、ID Token 校验逻辑的理解都会偏掉。5.2 加密 vs 签名:这是两套安全模型我们先用最严格、最不含糊的方式区分这两件事。加密(Encryption)目标只有一个:让别人看不到内容典型模型是:发送方用接收方的公钥加密只有接收方能用私钥解密这是 保密性(Confidentiality)。签名(Signature)目标完全不同:证明“这是谁发的”,以及“中途有没有被改”典型模型是:声明方(懒猫 SSO)用自己的私钥签名任何人(ENV 查看器、Memos、Vaultwarden……)都可以用公钥验证这是 真实性(Authenticity)+ 完整性(Integrity)。懒猫 ID Token 用的是哪一个?只用签名。懒猫 SSO 在 discovery 里写得明明白白:没有 里的加密算法字段,也没有 JWE 相关的任何东西。懒猫的设计从一开始就不试图隐藏内容。它只试图证明一件事:“这组声明,确实是由 这个懒猫 SSO 发出的,而且没有被修改。”5.3 签名要解决的核心问题站在 ENV 查看器的角度,签名必须同时解决三个问题:来源问题这些声明是不是这台盒子的 懒猫 SSO 发的?(不是别的盒子、不是自建的假 IdP)篡改问题中途有没有人把 改成 ?不可伪造问题攻击者能不能自己造一个“看起来合法”的 token,直接塞给 ENV 查看器?如果签名无法同时解决这三个问题,那整个懒猫 SSO 的安全模型就会崩塌——毕竟所有 App 都信懒猫,懒猫只要一处可伪造,全盒子的应用都可以被绕过。5.4 签名并不是“对内容做点处理”我们来看一个懒猫 ID Token 的真实签名结构():其中: 是完全可读的 是唯一的安全锚点签名不是“把 payload 加密一下”,而是一个数学等式的结果。5.5 签名在数学上到底做了什么(不绕弯)我们用最直白、但不偷懒的方式,把懒猫 ID Token 的签名过程拆开。Step 1:确定要被保护的数据在 JWT 中,被签名的数据是:注意三点:是 编码后的字符串顺序固定任意一个字符改变,结果都会变Step 2:对数据做 Hash(摘要) 里的 对应 SHA-256。对这段字符串做一次哈希运算:哈希的意义只有一个:把任意长度的数据,映射成一个固定长度、不可逆、对变化极其敏感的摘要。只要原始数据有 1 bit 变化,hash 就完全不同。Step 3:用懒猫 SSO 的私钥对 hash 进行签名这一步才是真正的“签名”:这里的关键点是:**只有懒猫 SSO(跑在盒子里的那个进程)**持有这个私钥签名过程是单向的没有这把私钥,无法伪造一个“能通过验证的 signature”懒猫官方会在升级、Key Rotation 的时候轮换这把 key,但不会把它泄漏给任何 App。如果你在 App 里“需要懒猫 SSO 的私钥”,那你已经做错了一件事。Step 4:Client 用公钥验证ENV 查看器拿到 token 后,会做对称的操作:用同样的方式计算 从 拉到的 JWKS 里,找到 header. 对应的公钥用公钥验证 是否对应这个 hash如果验证通过,数学上意味着一件事:这个 signature 只能来自对应的私钥,而这个私钥只在盒子里的身份服务 手里。5.6 为什么不能伪造签名这是整个懒猫 SSO 信任链的核心。攻击者即使:完全拿到 header 和 payload(反正它们本来就明文)完全知道算法(懒猫 discovery 里大大方方写着 )完全知道公钥( 对全世界公开)他依然做不到一件事:生成一个能通过验证的 signature因为 RSA 签名算法的安全性,建立在一个非常强的前提上:从公钥推导私钥,在计算上是不可行的。这不是工程约定,而是现代密码学的基础假设。5.7 为什么“改 1 个字符”就会彻底失败这是懒猫 ID Token 安全性的第二个关键点。如果攻击者尝试修改 payload 中的任何字段,比如把:改成:会发生什么? 改变 改变 改变但 没变(攻击者没有私钥重签)结果只有一个:签名验证失败。这保证了:懒猫 SSO 声明一旦被签名,就不可被悄悄篡改。这也意味着:你可以、并且应该信任 字段。只要签名验证通过,它就是懒猫原始发出的样子。5.8 签名解决的,只是“真实性”和“完整性”到这里,我们必须再次强调签名的边界。签名能证明:声明来自某个 OP声明未被修改但它不能证明:声明是不是发给 的(那是 )声明是否已经过期(那是 )声明是否对应你这次登录(那是 )声明是否被错误使用声明来自的是这台盒子的懒猫 SSO 还是别的(那是 )换句话说:签名只能回答“这是真的吗”,不能回答“这该不该信”。5.9 一个容易被忽略但致命的误解很多懒猫 App 里会出现这种错误逻辑:“既然签名验证通过了,那 token 就是安全的,我就可以直接读 登录用户了。”这是不成立的。在懒猫 SSO 里:签名验证是必要条件但远远不是充分条件你可以把它理解成:签名只是“验明正身”,而不是“授权使用”。5.10 本章结论(必须钉死)我们用几条不可模糊的结论结束这一章:懒猫 ID Token 使用的是数字签名(),而不是加密签名保证来源真实性和内容完整性懒猫 SSO 的私钥决定“谁能签”,公钥(发布在 )决定“谁能验证”没有懒猫 SSO 的私钥,就无法伪造任何合法 token签名通过 ≠ token 可以被使用本章小结(一句话)签名证明“这些声明只能来自这台盒子的懒猫 SSO”,但不证明“你现在就该相信它们”。

博客图片修整中,看不了可以先搜索公众号“忘机山人”看。
在第五章,我们已经确认了一件事:只要 ENV 查看器能拿到懒猫 SSO 的公钥,并成功验证签名,那它就可以确信:这些声明只能来自懒猫 SSO。但这句话里,隐藏着一个极其危险的前提:ENV 查看器拿到的“那把公钥”,真的是懒猫 SSO 的公钥。如果这一点站不住脚,前一章所有关于签名、私钥、不可伪造的结论,都会瞬间失效。于是,一个新的问题出现了:ENV 查看器从哪里拿到公钥?又凭什么相信这把公钥是对的?这正是 JWKS 存在的原因,也是懒猫 SSO 为你暴露 的意义。6.1 一个天真的、但非常危险的想法在最早期的懒猫玩法(以及很多自建 OIDC 的教程)里,你可能见过这样一种做法:“把懒猫 SSO 的公钥下载下来,写在应用的配置文件里。”从功能上看,这当然可行。但从系统设计上看,这是一个不可接受的方案。原因并不复杂。6.2 为什么“写死公钥”在懒猫里行不通第一:密钥一定会轮换懒猫官方会定期做 Key Rotation:懒猫 SSO 的私钥定期更换新旧密钥并存一段时间逐步淘汰旧密钥如果 ENV 查看器把公钥写死:每次懒猫系统更新都需要同步更新一旦漏更,就会导致整个盒子的用户登录全部失败用户根本不知道发生了什么,只会觉得“这 App 又坏了”这在工程上是不可接受的。第二:懒猫 SSO 可能同时使用多把密钥在真实的懒猫 SSO 实现中,签名者往往会:使用不同密钥签发不同 token在轮换过渡期内同时接受多把 key为不同算法维护不同 key(懒猫目前只有 ,但未来可能变)ENV 查看器如果只“认一把”,就会在合法场景下误判 token 为非法。第三:公钥不是“配置”,而是“动态信任关系”最根本的问题在于:公钥不是一个静态参数,而是懒猫 SSO 对外发布的一部分“信任接口”。它应该:可发现(通过 discovery)可更新(懒猫升级后自动跟上)可验证来源(绑定到 )这三点,单靠配置文件是做不到的。6.3 JWKS 是什么(准确但不绕)JWKS(JSON Web Key Set)并不神秘。它只是一个 JSON 格式的公钥集合,通过 HTTPS 对外发布。懒猫 SSO 的 JWKS 地址是:这个地址不是猜出来的,它由 discovery 返回的 字段决定:一个典型的返回看起来像这样:每一项,描述的都是一把 可用于验签的公钥。6.4 JWKS 解决的不是“有没有公钥”,而是三个更深的问题第一:发现(Discovery)ENV 查看器不需要提前知道公钥内容。它只需要知道:“去哪里拿。”这个“哪里”,不是随意指定的 URL,而是通过 OIDC Discovery 机制获得的:在这里,懒猫 SSO 明确告诉 ENV 查看器:我是谁()我的 token endpoint 在哪()我的公钥在哪()而这个 issuer 的值,又由你容器里的 环境变量决定——懒猫注入的这个变量,就是整个信任链的起点。第二:选择(Selection)JWT 的 header 中,有一个非常重要的字段: 的含义只有一个:“这个 token 是用哪一把 key 签的。”ENV 查看器在拿到的 JWKS 里:查找 对应的 key用这把 key 验签这使得:多 key 并存成为可能key 轮换不需要盒子重启、也不需要 App 重部署第三:更新(Rotation)JWKS 是一个可随时间变化的集合:懒猫升级引入新 key旧 key 保留一段时间ENV 查看器通过缓存 + 刷新机制逐步更新实现层面的建议(用主流 OIDC 库几乎都自带):缓存 JWKS 几分钟到几小时遇到没见过的 ,主动刷新一次刷新还找不到 → 拒绝 token,不要无限循环这让“长期运行的信任关系”成为可能——你的 App 写好一次,懒猫这边换多少次 key 都不用动它。6.5 Client 是如何使用 JWKS 的(流程级)现在我们把 JWKS 放回到实际流程中。当 ENV 查看器拿到一个 ID Token 时,它会:解析 JWT header读取 (必须是 )、从缓存的 JWKS 中查找对应公钥如果找不到:重新拉取 再次查找如果仍然找不到:拒绝这个 token注意这个结论:“找不到对应公钥”本身就是一个拒绝信号。如果你的 App 在这里写了 fallback(“找不到就跳过签名验证”),那整个懒猫 SSO 的安全模型在你这里就破了。6.6 为什么“中间人伪造 JWKS”行不通这是一个经常被提出、也非常值得认真回答的问题:“如果有人在家庭网络里拦截到 的请求,返回一套伪造的公钥,会怎样?”这个攻击模型并不成立,原因不在于 JWKS 本身,而在于:JWKS 从来不是“裸奔”的。6.6.1 HTTPS 是第一道信任根JWKS 是通过 HTTPS 获取的,而且 的证书是懒猫官方签发的可信证书。这意味着:ENV 查看器会验证 TLS 证书会验证域名会验证证书链要成功伪造 JWKS,中间人必须:控制 DNS拥有可信 CA 签发的 证书这已经超出了懒猫 SSO 的威胁模型。⚠️ 例外:如果你手贱在 App 里关掉了 TLS 验证(比如用自签证书做开发调试),这条就不成立了。别在生产配置里关 TLS 验证。6.6.2 issuer 绑定是第二道闸门ENV 查看器并不是“随便拉一个 JWKS”。它的逻辑是:“这个 JWKS 属于 这个 issuer。”而 issuer 本身,已经在 discovery 阶段被固定(来自 )。攻击者即使伪造一套 JWKS,也无法绕过: 校验 校验discovery 绑定6.6.3 公钥可以公开,但私钥无法伪造这是整个模型中最容易被忽略的一点:安全性不来自“公钥保密”,而来自“私钥不可得”。攻击者可以:复制懒猫 SSO 的公钥重发它的 JWKS声称“这是我的 key”但只要他没有懒猫 SSO 的私钥:就无法生成任何能通过验签的 token。6.7 一个非常重要的实现原则(必须强调)ENV 查看器在实现 JWKS 支持时,必须遵守一个原则:永远不要从 token 本身“学会”信任来源。具体来说:❌ 不要信任 token header 里的 ❌ 不要信任 token header 里的 ❌ 不要允许 token 指定“去哪拉公钥”❌ 不要把 做成“App 用户可配置的”(这是一个经典反面教材)JWKS 的来源,必须是:懒猫注入的 → discovery → 这是防止 Key Injection 的关键。6.8 到这里,我们真正拥有了什么在本章结束时,ENV 查看器已经具备了三项能力:能验证 token 的签名能确信使用的是懒猫 SSO 发布的公钥能适应密钥轮换而不中断服务这意味着:ENV 查看器已经能确认:“这组声明确实来自这台盒子的懒猫 SSO,且没有被篡改。”但请注意:我们仍然没有回答一个更关键的问题。6.9 合法的声明,仍然可能是错误的声明一个 token 可以:签名完全正确公钥完全可信但仍然可能:发给盒子上别的 App( 是 )用在错误的场景来自错误的 issuer(你接入了多个 OIDC,比如 Casdoor)已经过期被重放也就是说:“来源可信”≠“现在就该信任并使用这些声明”。6.10 本章结论(必须清晰)我们可以把这一章的结论总结为:懒猫 SSO 的公钥通过 发布JWKS 解决的是“公钥发现、选择与轮换”问题ENV 查看器对公钥的信任,来自 HTTPS + 绑定公钥可以公开,懒猫 SSO 的私钥不可伪造签名验证通过,只是信任链的一部分本章小结(一句话)JWKS 让“数学可信”变成了“懒猫 App 可用的可信”。


博客图片修整中,看不了可以先搜索公众号“忘机山人”看。
在第三章结束时,我们已经解决了一个关键问题:懒猫的 Authorization Code 不会被随意偷用。通过 PKCE,ENV 查看器终于可以确信一件事:来 换 token 的请求,确实来自当初那个发起授权的 Client 实例。于是,流程自然向前推进。ENV 查看器拿到了懒猫 SSO 返回的一组 token,其中最重要的一个是:在实际懒猫 SSO 返回里,它看起来像这样:很多懒猫 App 在这一刻会做一件非常“自然”的事:把 token 贴到 → 复制里面的 → 建 session → 登录完成。但在我们继续之前,必须先解决一个极其关键、却经常被误解的问题:这个 token 到底是不是“加密的”?4.1 一个常见但危险的直觉当人们第一次看到懒猫 SSO 吐出来的 JWT 时,几乎都会产生同一个直觉:“这看起来像一段乱码,应该是加密过的吧?”这种直觉非常危险。因为它会直接导致一个错误的安全假设:“既然 token 是加密的,那把它放 URL、放 localStorage、打到 container log 里,都没事。”但事实是:JWT(更准确地说,懒猫 SSO 用的 JWS)默认不是加密的。4.2 JWT 的三段结构,意味着什么一个标准的 JWT 由三部分组成:这三部分并不是“加密块”,而是:header:算法、密钥标识(懒猫里是 , )payload:一组声明(claims),包括 ……signature:对前两部分的数字签名前两部分只是 Base64URL 编码。这意味着一件非常重要的事情:任何人,只要拿到 token,都可以解码 header 和 payload。不需要密钥。不需要破解。不需要权限。你随手在 jwt.io 上把懒猫 ID Token 粘进去,能看到:全是明文。4.3 那为什么懒猫还敢把身份信息放在 token 里?这是一个必须正面回答的问题。如果 JWT 是明文的,那岂不是意味着:盒子主人的邮箱是公开的?用户所在的 (比如 )是公开的? 是公开的?答案是:是的,这些信息对“任何拿到 token 的人”都是可读的。但这里隐藏着一个非常重要的区分:可读(readable) ≠ 可伪造(forgeable)JWT 的设计,从一开始就没有试图解决“保密性”问题。它要解决的是两个完全不同的问题:完整性:内容有没有被改过(比如 有没有被塞进去)真实性:这些声明是不是由这台盒子的懒猫 SSO发出的这两个目标,不需要加密。4.4 JWT 的核心语义:声明(Claims)现在我们可以重新定义 JWT 的本质了:ID Token 不是一段加密数据,而是一组“被懒猫 SSO 签名的声明”。每一个字段,都是一个声明::这个用户在懒猫 SSO 里的稳定 ID:,说明是这台盒子签的:,说明是给 ENV 查看器的:声明什么时候失效 / / :懒猫账号的基本信息懒猫 SSO 的安全模型是:“你可以看,但你不能改;你可以拿到,但你不能伪造。”4.5 为什么“签名”比“加密”更重要我们来对比两个世界:如果 ID Token 是加密的,但没有签名攻击者看不到内容但一旦解密,就无法确认 是不是原本就有也无法确认是不是“这台盒子”发的在一个多用户、多应用共享一个懒猫 SSO 的系统里,这是灾难。如果 ID Token 是签名的,但不加密(懒猫的现实情况)攻击者可以看到 、、但任何修改都会导致签名失效没有懒猫 SSO 的私钥,无法生成“合法声明”这恰恰符合家庭服务器这种 SSO 场景的需求。4.6 一个重要的设计判断:懒猫并不假设 token 内容是秘密懒猫 SSO 的设计者非常清楚一件事:token 终究会出现在不完全可信的环境中。例如:浏览器 localStorage / sessionStorage前端 JavaScriptApp 容器的日志系统(懒猫玩家热衷开 debug)你自己用 curl 调试时复制到终端Authorization 头经过 nginx / openresty 的访问日志在这样的前提下,试图“依赖 token 的保密性”是脆弱的。于是,懒猫遵循 OIDC 的设计,做了一个非常明确的选择:不把安全性建立在“别人看不到”上,而建立在“别人改不了、造不出”上。4.7 那为什么还要 HTTPS?到这里,可能会有人产生另一个误解:“既然 JWT 不靠加密,那懒猫给我装证书让 走 HTTPS 还有什么用?”这是对职责边界的混淆。HTTPS 负责:防窃听(防止邻居抓包看到 token)防中间人篡改(防止 WiFi 被劫持后替换 token)防 code 泄漏(URL 不走 HTTPS 的话,连 code 都保不住)JWT 签名负责:防伪造(防止别的盒子上的 OP 签出来的 token 被误用)防内容被修改(防止 被塞进来)它们解决的是不同层面的问题。HTTPS 保护的是“传输”,JWT 保护的是“声明”。懒猫两者都上,缺一不可。4.8 为什么懒猫 ID Token 默认不加密在懒猫 SSO 中,ID Token 是:JWS(JSON Web Signature),不是 JWE(JSON Web Encryption)这不是因为“懒猫 SSO 做不到 JWE”,而是因为:ENV 查看器、Memos、Vaultwarden……所有 App 都需要读 payload,不能每个都维护一把加密密钥读取行为本身不是安全风险安全风险来自“错误地信任声明”如果你在这里误以为:“只要 token 是加密的,就可以少校验 / / ”那么你将直接跳过懒猫 SSO 最重要的安全设计。4.9 JWT 能解决什么,不能解决什么在继续深入之前,我们必须明确 JWT 的边界。JWT(懒猫 ID Token)能解决的:内容有没有被篡改声明是不是由某个 OP 签发JWT 不能解决的:声明是不是发给 (要靠 )声明是否仍然适用于当前请求(要靠 / )声明是否被重放声明是否来自正确的 issuer(要靠 ) 意味着什么业务权限(这是你的业务层)这些问题,全部在签名之外。4.10 一个关键过渡:从“能不能信 token”到“该不该信这些声明”到目前为止,我们只解决了一件事:这个 token 是真的。但“真的”,并不等于“适用”。一个合法签名的懒猫 ID Token,仍然可能是:发给盒子上另一个 App 的( 不是你)用在错误场景的(比如本应只给 Memos 的 token 被 ENV 查看器错误接受)已经过期的被重复使用的来自另一台盒子的懒猫 SSO(在多盒子、或者第三方 OIDC 对接的高级玩法里)所以,从下一章开始,我们要进入 JWT 的下一层意义:验证的不再是 token 本身,而是 token 里的每一个声明。4.11 本章结论(必须非常明确)我们可以用几句话,结束这一章:懒猫 ID Token 默认不是加密的,是 JWS()JWT 的安全性来自签名,而不是隐藏ID Token 是一组“被签名的声明”可读不是问题,错误信任才是问题把 token 贴到 jwt.io 解码没有任何安全风险——但你不能只靠那里看到的数据就登录用户本章小结(一句话)懒猫 ID Token 的设计目标不是“不让你看到”,而是“让你无法伪造”。

博客图片修整中,看不了可以先搜索公众号“忘机山人”看。
在第一章里,我们刻意做了一件事:完整走完了一次“正常的懒猫 SSO 登录流程”,但没有解释任何安全细节。如果你回看那个流程,会发现一个非常危险的现象:整个过程中,ENV 查看器几乎没有“主动验证”任何东西。它只是:把浏览器重定向到 等待浏览器跳回 拿到一个 换回一组 token然后,很多懒猫 App 就直接宣布:“登录成功。”这件事之所以看起来合理,是因为我们在脑海中默认了一整套“看不见的前提”。而这一章的目的,就是把这些前提全部显性化。2.1 一个被默认的信任模型当 ENV 查看器收到一个 时,通常会发生如下对话(虽然没有写在任何代码里):懒猫 SSO 说:“这个 token 代表用户 alice。”ENV 查看器心里想:“好,那她就是 alice,还是盒子主人,那我给她管理员视图。”这个逻辑的问题不在于“不合理”,而在于:它跳过了所有“为什么我应该相信你”的问题。在安全系统里,任何跳过“为什么”的设计,都会在后面以事故的形式补回来。而在家庭服务器这种主人和被邀请家人共用一个盒子的场景下,“我该不该把 Alice 当成管理员”这个判断,一旦出错,后果不可逆。2.2 把隐含假设全部摊开我们先不谈攻击者。只从逻辑完整性出发,把 ENV 查看器在“信任登录结果”时,隐含接受的假设列出来:返回的 token 真的是这台盒子上的 懒猫 SSO 发的token 在传输过程中没有被修改token 不是别人伪造的token 是发给 这个 Client 用的,而不是发给盒子上另一个应用的token 还在有效期内token 对应的是刚才那次登录,而不是别的历史请求浏览器没有被篡改家庭内网没有被劫持你会发现一个事实:流程中,并没有任何一步“天然保证”这些假设成立。换句话说:流程跑通 ≠ 假设成立2.3 为什么“看起来没问题”的系统依然不安全很多懒猫 App 开发者第一次接触这个问题时,会产生一个非常自然的反应:“这些假设在家庭内网里几乎总是成立的吧?我家又没有 APT。”这正是问题的核心。安全系统设计的第一原则是:不要基于“通常如此”来建立信任。尤其在懒猫这种场景下,“通常”其实比你想的更脆弱:盒子可能被暴露公网(很多人开了 的公网访问)盒子上跑着多个应用,它们共享同一个懒猫 SSO被邀请的家人带进来的设备你无法控制一些“炫技”级玩法(自签 SSL、自建反代、第三方 OIDC 对接)会破坏默认安全假设OIDC 的设计,建立在一个非常保守的前提之上:假设浏览器、网络、中间环境,全部是不可信的。懒猫 SSO 继承了这个前提,你作为 App 开发者也必须继承。2.4 Client 真的“什么都没验证”吗?到这里,你可能会反问一句:“那 HTTPS 呢?我的 是懒猫官方给我签的证书,不是已经很安全了吗?”这是一个非常关键的问题。HTTPS 确实解决了很多问题,但它解决的是:浏览器 ↔ 懒猫 SSO 之间的传输安全容器 ↔ 懒猫 SSO 之间的传输安全防止明文被窃听防止简单的中间人篡改但 HTTPS 不解决下面这些问题:返回的 token 是不是给 的,还是给盒子上别的 App 的token 是否来自这台盒子的懒猫 SSO,而不是攻击者在另一台盒子上部署的懒猫 SSOtoken 是否是旧的、被重放的浏览器环境是否泄露了中间 code也就是说:HTTPS 保护的是“通道”,懒猫 SSO 必须解决的是“内容”。2.5 为什么 Client 不能“信懒猫就好了”另一个常见的直觉是:“我信任懒猫这个盒子,那懒猫返回的结果我就直接信。”这句话在逻辑上是不完整的。因为它混淆了两个不同层面的“信任”:信任懒猫 SSO 这个身份源信任某个具体结果来自这个懒猫 SSO、且适用于当前 App即使你 100% 信任懒猫 SSO 本身,也不能跳过第二层。原因很简单:同一个懒猫 SSO 同时为盒子上所有 App 服务。如果 ENV 查看器不明确验证:“这是不是发给我()的?”“这是不是 Alice 刚才那次登录的结果?”那么一个合法但不相关的结果,就可能被错误使用。比如:另一个 App(哪怕是善意的)拿到了懒猫 SSO 发给它自己的 token,阴差阳错传给了 ENV 查看器,ENV 查看器如果不检查 ,就会用一个不属于自己的 token 完成登录。这不是科幻。在懒猫这种“应用彼此能互联”的架构下, 检查是基础操作。2.6 一个非常重要的转折点:信任不是一个状态,而是一个过程到目前为止,我们其实已经得到一个非常重要的结论:“登录成功”不是一个瞬间事件,而是一个逐步建立的信任过程。这个过程不是靠“感觉安全”,而是靠一连串明确的验证步骤。我们可以把它抽象成一句话:懒猫 SSO 的核心不是“身份声明”,而是“身份声明的验证链”。懒猫只是把这条链的起点和工具替你准备好了(注入环境变量、生成 client_secret、暴露 discovery),但链上的每一环都还是你自己负责执行的。2.7 验证链从哪里开始?如果你回到第一章的流程,会发现一个关键事实:在 token 出现之前,ENV 查看器已经接收过一个“关键输入”。那就是:这个 ,决定了 ENV 查看器能否拿到后续的一切。于是,一个新的问题浮现出来:如果 code 本身被滥用,后面再严格的 token 校验,还有意义吗?这不是一个修辞问题。这是 PKCE 出现的直接原因,也是懒猫 SSO 为什么在 discovery 里明确声明 的原因。2.8 本章的结论(明确而不留余地)我们可以用几句话,把这一章的核心结论说清楚:ENV 查看器不能因为“流程跑通”而信任登录结果所有信任都必须来自显式验证验证必须覆盖流程的每一个关键输入验证链必须从 token 出现之前 就开始“懒猫帮我注入了 CLIENT_SECRET”不是跳过验证的理由换句话说:如果你只验证 token,那你已经晚了一步。2.9 接下来我们要做什么在下一章中,我们将回到那个被忽略的问题:Authorization Code 暴露在浏览器里,为什么在懒猫场景下还敢用?我们会看到:code 被拦截在家庭网络里不罕见(家里装了奇怪插件、内网多设备、公网暴露)纯前端 SPA 型懒猫 App 无法保密任何 secret懒猫虽然给你注入了 ,但在某些场景下它实际上是 public 的PKCE 如何把一个“谁拿到都能用”的 code,变成“只能被最初那个 Client 使用”这是 懒猫 SSO 验证链的第一道真正闸门。本章小结(一句话)懒猫 SSO 的安全性,不来自“我信任懒猫”,而来自“我验证过这次结果”。

博客图片修整中,看不了可以先搜索公众号“忘机山人”看。
在懒猫微服这种家庭服务器系统里,登录是一个被严重低估的动作。因为它看起来实在太简单了。你打开 ,看到一个“使用懒猫账号登录”的按钮,点一下,浏览器跳到一个写着 Grant Access 的页面,你点同意,页面又跳回应用,头像出现在右上角。几秒钟之内,一切完成。如果我们只从“用户体验”的角度看,这个过程几乎没有任何值得讨论的地方。懒猫把它做得越无感越好。但如果你从安全和系统设计的角度看,这个过程恰恰是整个盒子里风险最高、假设最多、也最容易被误解的部分。在这一章里,我们什么都不“深挖”。我们只做一件事:完整走一遍一次标准的懒猫 SSO 登录流程,然后在每一个“看起来理所当然”的地方,埋下问题。这些问题,会在后面的章节里逐一被拆解。1.1 一个具体而普通的场景我们先固定一个非常具体的例子,后面所有章节都会围绕它展开。用户:,她是这台盒子的主人,邮箱 盒子名:,对外域名是 Client:懒猫 ENV 查看器,包名是 manifest 里设置了 和 所以它自己的外部地址是 登录方式:Authorization Code Flow + PKCE(懒猫 SSO 只支持这一种 response_type)IdP:懒猫 SSO(盒子自带的身份服务)issuer:Alice 在浏览器里打开 ENV 查看器,看到一个熟悉的按钮:“使用懒猫账号登录”她点击了这个按钮。1.2 第一步:浏览器被重定向点击按钮后,ENV 查看器的后端并没有自己处理登录。它做的第一件事是:把浏览器重定向到一个“外部的地方”具体来说,是跳到懒猫 SSO 的授权端点:注意:域名前缀是 ,而不是 。也就是说,浏览器离开了应用自己的子域,跳到了盒子的主域。从浏览器视角看,只发生了一件事:页面变了,子域变了,UI 也变成了懒猫那套统一的 Grant Access。到这里,一切都非常合理。ENV 查看器并不保存用户密码,也不直接验证身份。它把这件事外包给盒子里的懒猫 SSO。这也是懒猫 SSO 存在的意义:盒子里有一个角色专门负责“我是谁”,所有 App 都从它那里获取身份,而不是各自重新实现一遍登录。1.3 第二步:用户在懒猫 SSO 完成登录Alice 可能早就在懒猫官方客户端登录过,session 还在,那这一步她只会看到一个很短的 Grant Access 确认页,点一下同意就走。也可能 session 过期了,她需要重新输入密码、或者走 2FA。这些细节对 ENV 查看器来说是不可见的。从 ENV 查看器的角度看,懒猫 SSO 做了三件事:验证用户身份询问用户是否同意把部分身份信息返回给 Client(基于 )准备一个“结果”,用于告诉 Client:“这个用户已经通过验证了”关键在于:ENV 查看器并没有参与其中任何一步。它只能等待结果。1.4 第三步:浏览器“带着结果”返回 Client登录完成后,懒猫 SSO 并不会直接把结果“发”给 ENV 查看器。它做的仍然是一个浏览器跳转:浏览器地址栏里,多了两个参数:这个 ,就是所谓的 Authorization Code。从流程上看,这是一个非常自然的设计:懒猫 SSO 不直接把最终凭证交给浏览器只给一个短期、一次性的“中间凭证”ENV 查看器再用这个凭证去后台换取真正的结果懒猫 SSO 对 authorization code 的有效期卡得很短(典型是几十秒),而且一次性——用过一次就作废。到这里为止,大多数介绍 OIDC 的文章,都会轻描淡写地说一句:“然后 Client 用 code 换取 token”但我们先不要急着往下走。我们先停在这里,问一个非常基础、但经常被忽略的问题。1.5 第一个被忽略的问题:这个 code 是不是“安全的”?此刻,这个 :出现在浏览器 URL 中经过了浏览器经过了家庭网络可能被 nginx / openresty 的日志记录(懒猫里反代很常见)可能被浏览器扩展读到可能在 Referer 头里泄漏给其他请求但在流程描述中,我们默认了一个前提:只有 ENV 查看器的后端能用这个 code。问题是:这个前提成立吗?在这一章里,我们不回答这个问题。但请你记住它。因为这正是 PKCE 出现的原因——懒猫 SSO 把它写进了 ,不是装饰。1.6 第四步:Client 用 code 换取 tokenENV 查看器的后端(运行在盒子里的一个容器内)向懒猫 SSO 发起请求:注意这一步有一个非常重要的特点:它不经过浏览器,是容器到容器的内部 HTTPS 请求。懒猫 SSO 校验这个 code,然后返回一组 token:(需要请求了 )这一步,标志着真正的身份材料已经被发出。也是从这里开始,大多数应用会认为:“登录已经完成了。”但如果你站在 ENV 查看器的立场,这个结论其实来得太早。1.7 一个看起来“理所当然”的假设现在,ENV 查看器手里拿到了一个 。它是一个字符串,看起来像这样:文档告诉你:这是一个 JWT里面包含用户身份信息(、、、……)是懒猫 SSO 签发的,算法是 很多系统在这里会直接做一件事:解析 token → 取出 或 → 创建 session这一步在功能上是可行的。盒子里 99% 的情况下也确实不会出事。但在安全上,它隐藏了一整条未经验证的假设链。我们把这些假设逐条写出来:这个 token 真的是这个盒子的身份服务 发的中途没有被人修改是发给 这个 Client 用的没有过期没有被重放返回结果对应的是 Alice 刚才那次登录,而不是她上一次登录残留的 token 没有被伪造成 如果你发现:流程中并没有任何一步“自动保证”这些假设成立那你已经走在正确的方向上了。家庭服务器的环境没有你想象的那么“封闭”——浏览器、内网其他设备、被邀请来的家人的手机,都不是纯净的执行环境。1.8 本章真正要问的问题到目前为止,我们只是完整走了一遍 Happy Path。没有攻击者、没有恶意插件、没有家里误装的奇怪扩展、没有被劫持的 WiFi。但即便在这种“理想情况”下,ENV 查看器也只是被动地接收结果。于是,本章最后我们只留下一个问题:ENV 查看器凭什么相信:这个 id_token 里写的 “alice”,就真的是刚刚那个在 Grant Access 页面点同意的 alice?这个问题,不能靠“协议说可以”。也不能靠“懒猫帮我注入了 CLIENT_SECRET”。更不能靠“反正是我家,没人攻击我”。它只能靠一套明确、可验证、可失败的逻辑链来回答。1.9 接下来会发生什么在接下来的章节中,我们会做三件事:在 token 出现之前,解决“code 会不会被偷用”的问题—— 这就是 PKCE,也是懒猫 SSO 在 discovery 里明确支持 的原因在 token 出现之后,解决“token 是不是可信”的问题—— JWT、、公钥、JWKS()在使用 token 之前,解决“我该不该信这个声明”的问题—— 、、、、 等校验懒猫 SSO 的安全性,不在某一个点上。而在于:这些问题一个都没有被跳过。本章小结(不讲技术,只讲直觉)登录看起来像一个动作,但在盒子里,它其实是一条验证链的起点。在你理解这条验证链之前,“登录成功”这四个字,本身是不完整的。

博客图片修整中,看不了可以先搜索公众号“忘机山人”看。
懒猫 SSO(懒猫微服自带的 OIDC 身份服务)并不是懒猫微服给你贴的“登录按钮”,而是一套 在你自己的家庭服务器这种“半可信环境”中,为所有应用建立统一身份信任的工程流程。如果你只记住懒猫帮你注入了哪几个环境变量,却不理解每一步在防什么,这套 SSO 会“看起来能跑”,但迟早会在回调地址、token 校验、多用户等边界条件上出问题。这篇文章从端到端流程出发,基于懒猫微服实际暴露的懒猫 SSO 端点,完整梳理:懒猫 SSO 里的角色与核心概念(Client = 你的懒猫 App / IdP = 懒猫 SSO / User = 懒猫账号) 注入的那几个环境变量到底对应 OIDC 的哪些字段Authorization Code + PKCE 在懒猫里的完整时序scope、JWT / JWS、换 token、claims 校验最常见、也最真实的报错与排查思路下面所有例子都围绕同一个真实应用展开——懒猫 ENV 查看器(),部署在一个叫 的盒子上,对外域名是 ,回调路径是 。1. 懒猫 SSO 的角色与核心概念(速读版)在任何基于懒猫 SSO 的应用里,都至少有这三类角色:Client:你的懒猫 App后端 Web / 有独立容器的应用 —— Confidential Client( 由懒猫注入到容器环境变量)纯前端 SPA —— 严格意义上是 Public Client,但因为懒猫把 也注入进来了,在实操中介于两者之间(后面会专门讲这件事的边界)OP / IdP(OpenID Provider):懒猫 SSO,盒子上自带的身份服务入口永远是 User:懒猫账号(盒子主人 + 被邀请的家庭成员)几组必须分清的概念:ID Token:身份声明(你是谁,是不是盒子主人,邮箱多少)Access Token:访问资源的授权凭证(能调哪些 API)Refresh Token:用来续签,长生命周期,必须有 scope 才会下发Scope:Client 请求的授权范围(懒猫支持 )Claims:token 里的具体声明字段(懒猫 SSO 声明支持 )JWT / JWS:JWT 是格式JWS 是“签名后的 JWT”(懒猫 ID Token 的常态,签名算法是 )一句话记忆:懒猫 SSO = OAuth 2.0 + 身份层(ID Token)+ 懒猫替你注入的 Client 凭证2. 端到端主流程(Authorization Code + PKCE)懒猫 SSO discovery 里明确写了 ,也就是说——在懒猫上,除了授权码模式,别无选择。这也是现在最推荐、最安全的一种模式,适用于 Web、SPA、家庭内网应用。我们按真实时序走一遍。Step 1:Discovery(发现懒猫 SSO 的能力)容器启动时,或应用首次处理登录时,会访问:得到一份元数据,核心字段是这些(这段是实际返回,不是示意):非常重要的一点:后续所有校验,都会以这里返回的 为“信任锚点”。在懒猫里, 的规则是:常见坑:把 配成 (尾部多斜杠)→ 后面 校验直接失败把 写成 (漏掉 )→ discovery 拿不到应用跑在容器里,别去硬编码域名,而是用懒猫注入的 Step 2:/sys/oauth/auth(浏览器跳转)这是用户“看到懒猫授权页面”的那一步。一个典型的跳转 URL(由 Client 拼出来,让浏览器跳过去):关键点说明:懒猫里 等于应用包名,比如 。容器里从 读由 里的 决定,懒猫会把它拼成 scope必须有,否则退化成纯 OAuth,懒猫 SSO 不会下发 ID Token / CSRF + 重放防护,两者都是 Client 自己生成、自己校验PKCE 的 public 半(后面第三章详细讲)这一跳之后,浏览器会被懒猫 SSO 接管,用户看到的是懒猫那套统一的“登录 / 授权确认”页面(Grant Access)。常见报错: 不在白名单 —— 在懒猫里,白名单是用 隐式注册的,你没在 manifest 里写,就不会被允许忘了 openid,或请求了 之外的 scope(比如自己脑补的 )应用在懒猫上根本没启用 OIDC(manifest 里没写 )Step 3:回调(拿到 code)Grant Access 完成后,浏览器被重定向回:Client 必须做的第一件事:校验 (对上第 2 步生成的那个,对不上直接拒绝,不要进入 /token)常见情况:用户点了拒绝 / 懒猫要求重新登录(比如 session 过期、换用户)Step 4:/sys/oauth/token(换 token)这是 Client 容器与懒猫 SSO 的直连请求(从用户浏览器看不到)。其中: = = 懒猫 SSO 支持 和 两种方式,任选PKCE 校验发生在这里:返回体典型形态:最常见报错(真实世界第一名):code 过期(懒猫 SSO 默认几十秒)code 已用过(授权码是一次性的)redirect_uri 和第 2 步不一致(字符级精确匹配,包括结尾斜杠) 不匹配👉 90% 的懒猫 SSO 排障时间,都花在这里3. Token 到手以后:你必须做的校验拿到 token ≠ 可以直接 然后登录用户。3.1 验签(JWS)ID Token 是 JWS,结构是:验签流程是固定的:从 header 取 (懒猫固定 )、从 ()拉 JWKS用 找到公钥验证签名必须注意的反模式:❌ 信任 token header 里的 / (永远从 discovery 绑定的 去拿)❌ 接受 ❌ 用 以外的地方“凑”出 jwks 地址3.2 Claims 校验(ID Token Validation)这是懒猫 SSO 最核心、也最容易被省略的一步。必须校验的 claims:必须等于 (即 )必须包含 (也就是你的 App 包名,如 )当前时间 < exp(允许 clock skew,家庭服务器时钟不准也算常见情况)必须等于你最初生成并保存在 session 里的 nonce多 aud 场景下必须等于 client_id一句非常重要的话:签名验证通过,只能说明 token 是懒猫 SSO 发的,不能说明 token 现在可以被你用。4. Scope 到底在干什么?Scope 经常被误解成“权限”。在懒猫里,它真正的语义是:Client 向懒猫 SSO 声明的授权意图范围懒猫 就 5 个:表示“我要做身份认证”,没有它就退化成纯 OAuth允许返回 、允许返回 、、懒猫最有价值的一个 —— 能拿到用户属于哪些分组(比如“主账号”“家庭成员”),用来做业务层的角色判断允许下发 重要澄清:Scope ≠ 懒猫里的“用户角色”Scope ≠ 业务权限正确做法是:5. 各种授权模式怎么选?在懒猫里这张表其实很短,因为懒猫 SSO 已经替你做了决定:模式在懒猫里能不能用用途Authorization Code + PKCE✅ 默认Web / SPA / 内置应用Client Credentials❌ 懒猫 SSO 没在 里开—Device Code✅ 有 CLI / 智慧屏这类无浏览器场景Refresh Token✅ 需要 会话续期Token Exchange✅ 高级用法跨应用换 tokenImplicit❌已过时经验法则:在懒猫上,默认就选 Authorization Code + PKCE。其他模式有特殊需求再上。6. 端到端常见报错与排查思路优先检查: 是否和第 2 步字符级一致(尤其是端口、尾部斜杠、大小写)code 是否被用过(很多人在 callback 路由上写了重试逻辑,第二次触发就一定 400)PKCE verifier 是否跨 session 丢了(典型场景:callback 用了不同的进程 / cookie 丢了) 没读对(经常是容器没拿到环境变量)client 认证方式错了:懒猫只支持 和 ,别用 忘了 openid请求了 之外的 scope 里根本没写 ,懒猫没有为你这个包名注册 client / 懒猫 session 过期、用户被切换,需要重新跳一次 7. 一句话总结懒猫 SSO 的工程本质如果你一路走完,会发现:PKCE 防的是 code 被偷签名(JWKS)防的是 token 被伪造 / / 防的是 token 被误用Scope 控制的是 授权边界 里那一行 ,是你加入懒猫信任链的唯一开关懒猫 SSO 的安全性,不在某一个字段,而在一整条不可跳过的验证链。结语懒猫 SSO 从来没有承诺“帮你搞定登录”,它只是把懒猫 SSO 封装成了“不用你填 client 表单”的形态,给了你一套:在家庭服务器这种半可信环境里,逐步建立有限信任的工程方法。只要你能回答:“我为什么在这里相信这个懒猫账号?”你就已经在正确地使用懒猫 SSO了。后面九章,会把这张流程图拆开:第一章:一次“看起来很普通”的懒猫登录第二章:为什么 Client 不能信懒猫“返回结果”第三章:PKCE 在懒猫场景下为什么不能省第四章:ID Token 是声明,不是加密第五章:签名——Client 凭什么相信懒猫的声明第六章:JWKS—— 到底在干什么第七章:ID Token Validation——签名通过还不够第八章:SDK 边界——懒猫注入的变量只是地基第九章:Scope 与 Consent——懒猫的 不是你的权限第十章:失败案例与设计哲学附录 A、B:Scope 在流程中的位置;state / nonce 对照。

卓帅
基于小龙猫 + Vikunja + GTD 的个人任务管理助理这篇教程把懒猫微服中的“小龙猫”连接到 Vikunja,并用简化版 GTD 管理个人任务。分工如下:Vikunja:保存和展示任务。小龙猫:理解你的指令。GTD:提供任务整理规则。小龙猫技能:调用 Vikunja API,把任务写入系统。开始前,先在懒猫微服中安装并打开小龙猫和 Vikunja。接下来完成 5 件事:配置 Vikunja 端口转发获取 Vikunja API Token获取 Vikunja 的 OpenAPI JSON 文件让小龙猫生成 Vikunja 技能让小龙猫自动初始化 GTD 项目,并按 GTD 管理任务0. 准备条件确认下面内容已准备好。小龙猫Vikunja局域网端口转发应用1. 最终效果配置完成后,对小龙猫说:小龙猫会把任务写入 Vikunja。也可以问:或者:Vikunja 保存任务,小龙猫接收你的自然语言指令。2. 简化版 GTD这里使用 5 个 GTD 分类。先了解分类含义,不用手工创建。项目用途收件箱存放刚想到、还没整理的事情项目存放需要多个步骤才能完成的事情下一步存放现在可以执行的具体动作等待中存放需要别人回复、处理或确认的事情将来可能存放现在不做、以后可能做的想法基本流程:3. 为什么需要端口转发在懒猫微服中,每个应用都运行在独立容器里。小龙猫在一个容器里。Vikunja 在另一个容器里。它们不能直接通过 互相访问。不要把 Vikunja 地址写成:在小龙猫中, 指的是小龙猫自己的容器,不是 Vikunja 容器。让小龙猫用这个地址访问 Vikunja:这是懒猫微服应用容器之间的访问地址。4. 配置 Vikunja 端口转发目标地址:在懒猫微服的端口转发工具中新增规则:协议选择 TCP。局域网入口类型选择微服虚拟网卡。出口地址选择 。端口填写 。转发目标类型选择微服应用。微服应用选择当前安装的 Vikunja 应用。服务选择 Vikunja 服务。目标端口填写 。点击测试目标连接。测试成功后保存规则。注意:转发目标是 Vikunja,不是小龙猫。小龙猫访问地址使用 ,不要使用 或 。5. 获取 Vikunja API Token小龙猫操作 Vikunja 需要 API Token。打开 Vikunja,进入:创建新 token:名称填写 。权限选择项目和任务相关的读写权限。创建后立即复制 token。临时保存到安全位置,稍后写入小龙猫技能配置。注意:API Token 只会完整显示一次。不要把它发到公开文章、截图、群聊或不可信的地方。6. 获取 Vikunja 的 JSON 文件小龙猫需要 OpenAPI JSON 文件来调用 Vikunja API。不要在外部浏览器访问 下载文件。这个地址给小龙猫在容器内部访问 Vikunja 用,外部浏览器通常打不开。从 Vikunja 页面下载:打开 Vikunja。进入 。在 API Tokens 页面点击 。页面打开后,在顶部找到下载按钮。点击下载按钮,保存 JSON 文件。如果文件名不是 ,重命名为:下一步把这个 JSON 文件发给小龙猫。7. 让小龙猫操作 Vikunja把 发给小龙猫,让它生成 Vikunja 技能。7.1 发送 OpenAPI 文件把 发给小龙猫,然后说:7.2 保存 Vikunja 地址和 API Token技能生成后,把连接信息保存到技能配置中。对小龙猫说:不要把 API Token 公开到博客、截图、群聊或不可信的聊天记录中。7.3 设置 GTD 规则连接信息保存后,把下面规则发给小龙猫:8. 让小龙猫初始化 GTD 项目不要手工打开 Vikunja 创建项目,直接让小龙猫初始化。对小龙猫说:第一版先保持简单,不急着添加标签、筛选器或复杂规则。使用规则:新想法先进“收件箱”。多步任务放进“项目”。能直接执行的任务放进“下一步”。卡在别人那里的任务放进“等待中”。暂时不做的想法放进“将来可能”。9. 测试连接用下面 3 个动作测试。9.1 查询项目对小龙猫说:正常情况下会看到:9.2 创建测试任务继续对小龙猫说:创建完成后,打开 Vikunja 确认任务是否出现。9.3 更新测试任务再对小龙猫说:如果 Vikunja 中的任务状态已更新,连接正常。10. 日常用法把小龙猫当作任务入口。10.1 随手记录10.2 整理收件箱10.3 查看下一步10.4 管理项目10.5 跟进等待中任务11. 完整示例你对小龙猫说:小龙猫会这样处理:判断这是一个多步任务。在 Vikunja 的“项目”中创建任务:把家里的纸质资料整理成电子版。拆出下一步:找出第一批需要扫描的纸质资料。把这个下一步写入“下一步”。如果需要家人提供资料,创建一条“等待中”任务。之后问:重点:大项目不直接执行,先拆成明确的下一步。12. 常见问题12.1 为什么不能用 小龙猫和 Vikunja 是两个不同的应用容器。小龙猫中的 指向小龙猫自己的容器,不是 Vikunja 容器。使用端口转发后的地址:12.2 小龙猫访问不了 Vikunja 怎么办按顺序检查:Vikunja 是否已启动。端口转发规则是否已保存并启用。地址是否为 。API Token 是否正确。 是否已发给小龙猫。Vikunja 技能是否已生成并启用。12.3 下载不到 JSON 文件怎么办回到 Vikunja 页面操作,不要在外部浏览器访问 。按顺序检查:Vikunja 是否能正常打开。是否已经进入 。是否点击了 API Tokens 页面里的 。API 文档页面顶部是否有下载按钮。下载后的文件是否是 JSON 文件。如果 API 文档页面本身打不开,先确认 Vikunja 已启动并重新登录 Vikunja。12.4 任务被放错项目怎么办直接让小龙猫修改:或者:分类不准时,直接让小龙猫修改。12.5 要不要一开始就用标签和复杂筛选不建议。第一版先用项目承载 GTD 结构。用稳定后,再考虑标签、优先级、截止日期和筛选器。13. 最后确认完成下面检查项,表示配置成功:小龙猫可以通过 访问 Vikunja。Vikunja 中已创建 API Token。已获取 Vikunja 的 。小龙猫已生成 Vikunja 技能。技能已保存 Vikunja 地址和 API Token。小龙猫已在 Vikunja 中初始化“收件箱、项目、下一步、等待中、将来可能”。小龙猫可以创建、查询和更新 Vikunja 任务。前期只关注两件事:所有想到的任务,都有一个可靠入口。所有真正要做的事情,都能变成清楚的下一步。



卓帅
MiniTeamClawUI 接入小龙猫 OpenClaw 教程0. 准备条件0.1 环境前提已拥有一个可正常运行的小龙猫环境下的 OpenClaw 类型助手。当前应用已经安装完成,并能正常打开。0.2 前置准备确认小龙猫已完成基础配置,并且 OpenClaw 助手能够正常运行。确认 MiniTeamClawUI 已安装完成,并可以正常进入部署向导。后续需要在小龙猫助手对话区域右上角的 webshell 中查询 Gateway Token,并在需要时执行设备审批命令。0.3 参考教程如果尚未完成小龙猫的基础配置,请先参考。1. 配置小龙猫里的龙虾访问方式先在 LightOS WebShell 中发布 OpenClaw Gateway 服务,获取应用域名。后续 MiniTeamClawUI 会用这个域名连接龙虾。1.1 配置端口转发在 LightOS WebShell 中发布 OpenClaw Gateway 服务。1.1.0 打开龙虾的 WebShell打开 LightOS 应用,找到小龙猫里的 OpenClaw,也就是龙虾应用,然后打开它的 WebShell。打开 WebShell 后,在右侧终端管理面板中确认当前容器是 OpenClaw,然后点击右上角的 。1.1.1 添加服务发布在 页面中填写::选择 。:填写 。:必须填写 。:可以按自己的习惯填写,例如 。:可以按自己的习惯填写,例如 。:必须勾选。端口必须填写 ,并勾选 。填写完成后,点击 。1.1.2 找到刚发布的服务应用部署完成后,回到懒猫微服应用列表,进入 页面,找到刚才发布的应用。应用名称就是上一步在 中填写的名称。打开应用右键菜单,点击 。1.1.3 获取 OpenClaw 访问地址进入应用详情后,找到 。这个域名后续要填写到 MiniTeamClawUI。例如应用域名为:在 MiniTeamClawUI 中填写 时,需要加上 前缀,最终填写为:获取到这个访问地址后,本步骤完成。如果使用自建 OpenClaw,请填写实际可访问的 OpenClaw Gateway 地址。2. 配置 MiniTeamClawUI 连接小龙猫里的龙虾这一部分的目标是让 MiniTeamClawUI 成功连接到小龙猫中的 OpenClaw,并完成后续登录。2.1 完成部署向导初始化首次启动 MiniTeamClawUI 后,会进入部署向导页面。按照页面提示填写后,点击开始部署。填写时建议注意以下几点: 必须填写正确,否则后续网盘文件选择和附件上传可能异常。 是后续进入 MiniTeamClawUI 时使用的密码,建议提前记录。 如果没有特殊定制需求,建议保持默认值。 一般建议保持开启,便于后续团队协作时上传文件到 OpenClaw。完成后,页面会进入连接工作区的引导配置环节。2.2 填写 OpenClaw 连接信息这一步会进入 页面。按下面方式填写。2.2.1 OpenClaw 地址填写 OpenClaw Gateway 的访问地址。地址格式必须以 或 开头。如果使用小龙猫,请填写第 步获取到的应用域名,并在前面加上 。示例:如果你使用的是自建 OpenClaw,请根据实际部署环境填写 OpenClaw Gateway 访问地址。常见情况如下:局域网访问地址如果 MiniTeamClawUI 能访问 OpenClaw 所在设备的局域网地址,可以填写局域网地址,例如:填写的 IP 必须能被 MiniTeamClawUI 所在微服访问。公网访问地址如果 OpenClaw Gateway 已经通过公网域名或公网 IP 暴露,并且当前微服可以访问互联网,可以填写公网地址,例如:公网地址需要能被 MiniTeamClawUI 所在微服访问。2.2.2 Gateway 认证方式 选择:2.2.3 Gateway Token 在 OpenClaw 所在环境的终端中查询。如果使用小龙猫,就在小龙猫 WebShell 中执行。在终端中执行:输出结果通常类似于:只填写引号中的 token 值,例如:请注意:不要复制前后的引号。不要复制 这一段键名。不要把结尾逗号一起复制进去。首次连接当前工作区时, 必须填写。已保存过 token 的工作区可以留空。2.2.4 工作区访问地址填写团队成员访问这个前端工作区时使用的地址,只填写协议和域名即可。可以点击 自动填写,也可以手动填写当前 MiniTeamClawUI 应用地址:请将 替换为当前微服实例的实际名称。2.3 保存配置并继续填写完成后,核对: 与当前小龙猫或自建 OpenClaw Gateway 的实际访问地址一致。 填写的是纯 token 值。 使用的是当前应用可以正常访问的协议和域名。确认无误后,点击 。2.4 检查连接状态保存后,点击 。如果页面提示需要审批设备访问,复制页面给出的审批命令,到 OpenClaw 所在环境的终端中执行。使用小龙猫时,在小龙猫 WebShell 中执行。命令格式通常如下:示例:执行完成后,回到页面,再次点击 。页面提示连接成功,并出现 按钮后,连接完成。2.5 连接失败时的排查方法如果连接检查没有通过,检查:确认 是否填写正确,并且 MiniTeamClawUI 所在微服能够访问该地址。确认 是否填写正确,且没有包含多余引号或标点。确认 OpenClaw 当前处于运行状态。确认审批命令已经在 OpenClaw 所在环境的终端中成功执行。确认 是当前应用真实可访问的协议和域名,例如 ,不要填写路径。3. 登录并绑定懒猫账号当页面出现 后,点击进入登录流程。3.1 使用懒猫微服账号登录在登录页点击 ,然后在授权页面点击 。3.2 绑定本地账号授权完成后,页面会返回本地账号绑定界面。请填写::当前工作区中的本地账号名:该本地账号对应的密码填写后点击 。3.3 完成验证绑定成功后,如果页面进入 MiniTeamClawUI 主界面,就表示整个接入流程已经完成。建议最后确认以下内容:可以正常进入 MiniTeamClawUI 主界面。可以正常发起与 OpenClaw 相关的操作。当前账号可以正常使用文件选择、附件上传等功能。4. 常见问题4.1 服务发布后无法访问 OpenClaw 地址如果第 步获取到的 OpenClaw 地址无法访问,检查:服务发布时端口是否填写为 。服务发布时是否勾选了 。当前发布的服务是否属于小龙猫里的 OpenClaw,也就是龙虾容器。小龙猫里的 OpenClaw 是否处于正常运行状态。4.2 连接检查无法通过检查: 是否正确,并且已经加上 前缀。 是否来自第 步获取到的应用域名。 是否正确。OpenClaw 是否处于运行状态。设备审批命令是否已在小龙猫 WebShell 中执行。 是否是当前 MiniTeamClawUI 应用真实可访问的协议和域名,例如 ,不要填写路径。4.3 LightOS 环境中无法访问 MiniTeamClawUI 或 OpenClaw如果需要在 LightOS 中访问当前 MiniTeamClawUI 应用,请将 LightOS 网络模式改为 。 和 可能导致页面无法访问或连接检查失败。4.4 登录后无法正常使用附件或网盘功能检查部署向导中的 是否填写正确。5. 界面截图5.1 移动端截图5.2 PC 截图



卓帅
让懒猫微服里的“小龙猫”助手,通过 技能,连接到 AgentTODO,然后帮你查看、创建、拆分和更新待办任务。你可以把它理解成:AgentTODO 负责保存你的任务。小龙猫负责和你聊天、理解你的需求。 技能负责告诉小龙猫应该怎么调用 AgentTODO。0. 准备条件0.1 需要先安装的应用请先在懒猫微服中安装并启动下面几个应用。小龙猫AgentTODO局域网端口转发工具0.2 先在小龙猫中创建一个助手打开小龙猫后,你需要先完成这些基础配置:安装或创建一个 Agent。创建一个助手。配置好这个助手使用的 AI 模型。确认可以正常和助手对话。如果你现在还没有办法正常和小龙猫里的助手聊天,请先把小龙猫的基础配置完成,再继续后面的步骤。1. 为什么需要端口转发在懒猫微服里,每个应用都是一个独立的容器。这意味着:小龙猫是一个应用容器。AgentTODO 是另一个应用容器。它们虽然都装在同一个懒猫微服里,但并不能直接用 互相访问。很多新手最容易出错的地方,就是让小龙猫访问:这通常是不对的。因为这里的 指的是“小龙猫自己所在的容器”,不是 AgentTODO 所在的容器。所以我们需要先用“局域网端口转发工具”,把 AgentTODO 的 端口转发到微服的物理网卡 IP 上。这样小龙猫助手就可以通过一个局域网地址访问 AgentTODO。2. 配置 AgentTODO 端口转发这一部分的目标是得到一个小龙猫可以访问的 AgentTODO 地址,格式类似:其中 要替换成你自己的微服物理网卡 IP。2.1 打开局域网端口转发工具在懒猫微服中打开“局域网端口转发工具”,新增一条端口转发规则。2.2 填写基础信息和入口配置请按下面方式填写::填写 :选择 :选择 :填写 这里最重要的是 。一定要选择:这样转发出来的地址才会变成局域网里可以访问的地址。2.3 填写目标配置继续填写目标配置::选择 :选择 :选择当前 AgentTODO 所在的用户,一般保持默认即可:选择 :填写 填写完成后,点击 。如果测试成功,保存这条规则。如果测试失败,请先看后面的常见问题。2.4 记住微服物理网卡 IP保存端口转发规则后,请记住你的微服物理网卡 IP。比如你的微服物理网卡 IP 是:那么 AgentTODO 的访问地址就是:后面要把这个地址告诉小龙猫助手。请注意:不要写成 。不要写成 。不要漏掉前面的 。不要漏掉后面的端口 。3. 在小龙猫中安装 AgentTODO 技能这一部分的目标是让小龙猫助手学会怎么使用 AgentTODO。技能地址是:3.1 直接让助手安装技能打开你在小龙猫中创建好的助手,直接发送下面这段话:3.2 等待技能安装完成安装完成后,小龙猫应该会告诉你技能已经安装成功,或者可以开始使用这个技能。如果安装失败,请先确认:GitHub 地址是否复制完整。小龙猫当前是否可以正常联网。4. 告诉助手 AgentTODO 地址技能安装好以后,还需要告诉助手你的 AgentTODO 地址。假设你前面记下来的微服物理网卡 IP 是:那么你就对助手发送:请把 换成你自己的微服物理网卡 IP。发送以后,助手会根据这个地址自动推导出 AgentTODO API 地址:一般情况下,你不需要手动填写 ,只需要告诉助手 AgentTODO 页面地址即可。5. 测试是否连接成功现在用一两句话测试一下即可。5.1 查看今天的任务对助手发送:如果连接成功,助手会去 AgentTODO 中读取今天的任务,然后再回复你。如果你今天还没有任务,它可能会告诉你今天没有待办。5.2 创建一个简单任务继续测试创建任务:创建完成后,你可以打开 AgentTODO 页面(去应用列表,打开 AgentTODO 这个应用,可以看到当前的任务和管理任务),看任务是否已经出现。6. 配置完成后可以怎么用上面的步骤走完以后,基础配置就完成了。下面这些不是必须操作的流程,只是一些日常使用时可以参考的说法。你可以按自己的习惯直接和助手说。6.1 查看任务6.2 创建任务和计划6.3 记录进展6.4 查找任务7. 常见问题7.1 为什么不能用 因为小龙猫和 AgentTODO 是两个不同的应用容器。在小龙猫里, 指的是小龙猫自己的容器,不是 AgentTODO 的容器。所以小龙猫访问 时,通常找不到 AgentTODO。正确做法是使用微服物理网卡 IP,例如:7.2 端口转发测试失败怎么办建议按下面顺序检查:AgentTODO 是否已经启动。 是否选择了 。 是否选择了 。 是否填写了 。 是否选择了 。 是否选择了 。 是否选择了 。 是否填写了 。如果这些都正确,但仍然失败,可以重启 AgentTODO 后再测试一次。7.3 助手说无法连接 AgentTODO优先检查你告诉助手的地址是否正确。地址应该类似:请重点检查:IP 是否是微服物理网卡 IP。端口是否是 。前面是否有 。有没有错误地写成 或 。7.4 浏览器能打开 AgentTODO,但助手还是访问失败请确认你是在同一个网络环境下测试。有时候你的电脑浏览器能打开某个地址,不代表小龙猫所在的容器也一定能访问它。在本教程的场景中,建议使用“局域网端口转发工具”暴露出来的微服物理网卡地址,也就是:7.5 技能安装失败怎么办请检查下面几项:技能地址是否完整:小龙猫是否可以正常访问 GitHub。当前助手是否已经完成 AI 模型配置。当前助手是否支持安装技能。如果只是网络问题,可以稍后再试或者使用小猪佩奇(找 VIP 群获取)。7.6 任务创建了,但内容不是我想要的你可以直接让助手修改,例如:或者:对于比较重要的任务,建议你让助手先列出计划,确认后再创建:7.7 需要把 AgentTODO 暴露到公网吗不建议。AgentTODO 技能的默认使用场景是可信局域网。请不要把 AgentTODO 直接暴露到公网,避免不必要的安全风险。8. 最后确认如果下面几件事都能完成,就说明配置成功了:你可以通过 打开 AgentTODO。小龙猫已经安装 技能。你已经告诉助手 AgentTODO 地址。助手可以读取今天的任务。助手可以创建任务、拆分子任务、记录进展。完成以后,你就可以把小龙猫当成自己的任务助理来用了。



趁着年轻干点儿想干的事情
暴露 LightOS SSH 端口先开启 LightOS SSH 链接的功能,将端口通过局域网端口转发工具暴露到局域网中,目标配置的端口就是 LightOS SSH 端口。CC Swtich 连接 LightOS 主机点击新增 SSH,输入 ip 地址,账号、密码和转发工具中的监听端口。这样就可以在供应商页面随意切换应用的供应商了。如何切换供应商可以看到当前使用的是 CodexZH 供应商,在目标主机执行命令也是此供应商(在添加主机的时候会自动安装 cc-switch-cli)。点击切换按钮,切换到 AICodeMirror 供应商,看到切换成功的消息语就 ok 了。可以用 命令再验证一下可以看到确实切换了。随后退出 codex/claude code,再次打开就可以使用切换后的模型供应商了。如果你是云主机开发的话,可以在“主机”页面新增主机,实现一个应用控制多个主机的模型供应商切换。



卓帅
1. 使用流程概览Co-Link 的使用可以拆分为三个步骤:1.1 系统角色说明角色说明Server调度中心,负责路由请求(已部署完成)Client算力节点,执行推理任务API 调用者使用 AI 接口的程序或用户2. 访问地址说明3. 初始化账号与 Token3.1 注册账号访问 Web 控制台:完成注册并登录。3.2 获取 Token在用户面板中获取:Token用途Client Token用于节点接入API Token用于接口调用4. 接入算力节点(Client)每一台提供算力的机器都需要运行一个 Client。4.1 创建配置文件(config.yaml)4.2 启动 ClientCoLink Client 下载地址🍎 macOSIntel (amd64)Apple Silicon (arm64)🐧 LinuxAMD64ARM64下载完成之后解压后将文件放到到 同目录,然后启动客户端LinuxMacOS4.3 启动成功标志出现如下日志表示连接成功:5. 验证节点是否接入成功登录控制台后访问:如果看到节点在线,则说明接入成功。6. 调用 AI APICo-Link 完全兼容 OpenAI API。统一 API 入口为:6.1 Python 示例6.2 流式调用6.3 curl 示例运行成功7. 核心配置说明7.1 并发控制表示该节点最多同时处理 3 个请求。7.2 模型映射说明::Provider 实际模型名称:对外暴露的模型名称(API 调用使用)8. 调度机制说明Co-Link Server 会自动:选择空闲节点处理请求节点失败自动切换(最多 3 次)出错节点封禁 60 秒



趁着年轻干点儿想干的事情
前提工作clash 必须开启 tun 模式。登录 Claude 并授权点击去登录 Claude,再点击“生成登录连接”按钮,将 Claude 授权 URL 复制到已经登录 Claude 的浏览器中,没有登录则先去登录。随后点击授权,随后将浏览器的 url 贴到 auth2api 进行回调,提交完毕之后就可以看到账号了。随后到概览页面,将 Claude 的 BaseURL 复制到cherry studio 或者懒猫上的 chatbox 进行调用,并填入模型和 api key,就可以使用模型了。调用失败的原因1.可能是懒猫的 clash 代理未生效,可以在懒猫的终端 app 上传 ping 下外网试试,且建议打开 tun 模式2.调用的客户端可能开启了 vpn,建议关掉,因为可能会和懒猫微服 vpn 冲突建议1.建议使用懒猫的 chatbox 软件来聊天,这样省去公网配置,像我这样设置即可2.建议使用 Api Key 管理软件来管理你的 api key




1
smtp4dev 是一款专为开发测试设计的假邮件服务器——接收所有发来的邮件但从不真正投递,同时提供 Web 界面查看收件箱。部署在懒猫微服上,可用于本地开发环境的邮件发送调试。1. 三个协议分别干什么SMTP:发信,把邮件投递到 smtp4devIMAP:收信,在客户端读取服务器上的邮件,支持多端同步POP3:收信,偏下载式读取2. 端口转发配置(重点)以域名 为例:协议对外端口服务内端口SMTP252525IMAP1143143POP31110110加密建议:先全部使用无加密 / None,不要开 SSL/TLS,也不要 STARTTLS。然后我们通过懒猫端口转发助手把端口转发出来4. 验证代码(用 ssh 验证运行,记得吧 xxx 的域名改成自己的域名)A. SMTP 发信验证进应用可以看到收到了邮件B. IMAP 读取验证可以看到已经读到了邮件C. POP3 读取验证读到了对应内容6. 常见坑主机名别带协议前缀:只填 ,不要写 端口别填错:IMAP 是 ,POP3 是 ,不是标准的 143 / 110不要开 SSL/TLS:明文端口开了加密会导致连不上或 连接超时:检查懒猫微服端口转发规则是否已保存生效,容器是否正常运行



微服新增加了一个IPhone备份功能。可以给自己的“爱机”进行完整的备份功能。最终效果如图。可以增量备份备份的所有数据都是保存在微服中最终备份完成的数据可以随时进行下载下面我们一起来看看怎么去使用。首先将IPhone和微服使用数据线连接起来。(USB或者type-c都是可以的)。连接成功之后就能看到自己的IPhone设备如果连接后没有看到IPhone设备可以更换微服的其他USB或者type-c接口,或者是数据线连接问题,建议换条数据线进行尝试。当应用识别到了IPhone设备之后,可以点击设备右侧的配对按钮,此时应用会出现等待设备配对。在配对过程中IPhone上会弹出一个授权窗口,请点击确认授权。并输入自己的IPhone解锁密码。当IPhone上授权成功之后,应用的状态会显示当前设备的备份情况。点击设备就能进入备份页面进行备份。(这个页面也会显示当前IPhone所有的备份情况)点击右侧的开始备份会有一个提示,需要在IPhone上进行二次验证。在IPhone上输入手机密码就能通过验证。(这个提示可能会一闪而过,但是不用担心,在手机上验证就可以的。)当IPhone设备二次验证通过之后,就会进入备份状态。在左侧可以看到备份接进度。此时也可以看到创建了一个新的备份点出来。第一次备份的时间可能会比较久(因为是全量备份),建议在晚上不使用手机的时候去进行备份。而后面继续进行备份就会快很多。因为后续都是增量备份的一个模式。



博客图片修整中,看不了可以先搜索公众号“忘机山人”看。
曾几何时,中文互联网圈流行着这样一个段子,叫做中年男人三件套:NAS、软路由、充电头。我们今天就来聊聊第一个。NAS 似乎是给职业运维人员的福音,而广大的爱好者们通常都是野路子,靠着一腔孤勇或者是兴趣来维护自己的小小世界,能够借鉴参考的,也就是互联网的帖子以及各种群里的答疑而已。靠着坚持不懈,入门了 Linux 和网络,但是不求甚解,安静的文件存储,只躺在方寸之间。如果你恰好有一台懒猫微服,那么我们正好可以一起来学习这繁杂的网络,拆解这美丽的网络新世界。我从事过几年的云行业,在发烧友和职业人员之间横跳,于是心有所感,立志让爱好者可以有专业的技术,让职业人员可以真的产生兴趣。这是网络篇。首先你一定听说过 IP 地址,这是互联网通信的门牌号。我们的手机、电脑,包括懒猫微服都有一个 IP 地址。当你连上网络的时候,这个地址就被分配给了设备。准确地说,是分配给了网卡,所以懒猫微服可以用转接口来拓展第二张网卡。连上网线之后,第一步我们习惯在路由器上看 IP 地址,然后 ping 一下确认连通。懒猫微服使用 IPv6,可以用 或 。循迹(ping、telnet)我们也可以用 dig 查看域名解析的 IP 地址:在登录之前,可以用 telnet 看端口连通性,然后 SSH 上去。不过一般来说,直接 就可以登录了。登录之后,我们可以使用 ifconfig 来看网卡信息。主要有这几张网卡比较有用:enp2s0 物理网卡,连接家里路由器wlp129s0 无线网卡lo 回环接口,本机访问本机用(127.0.0.1)heiyu-0 懒猫穿透隧道,IPv6 内网穿透用docker0 Playground Docker 默认网桥或者使用 ,会更加现代一点。我们再来看一下路由表,使用 或者 来查看:路由表决定了数据包往哪里走。第一条 是默认路由,所有未知目的地的数据包都会被转发到网关 192.168.8.1(你的路由器)。路由器会通过 NAPT 来实现多台设备共用一个公网 IP 访问互联网。最后一条 是局域网直连,不需要经过网关。 是 Docker 网桥。NAPT(Network Address Port Translation)是 NAT 的一种,也叫 PAT(Port Address Translation),它允许多个内部主机共享一个公网 IP 地址,通过不同的端口号来区分不同的连接。你家路由器做的其实是 NAPT:192.168.1.100:12345 → 公网IP:50001192.168.1.101:12345 → 公网IP:50002192.168.1.102:12345 → 公网IP:50003如果你家里恰好有公网 IP,那么也可以通过在路由器上配置端口映射,将外部端口映射到内部的 IP 地址和端口上,让 NAS 可以被外网访问。比如,你想让 NAS 的 SSH 服务(默认端口 22)可以从外网访问,可以在路由器上配置端口映射,将路由器的端口(比如 2222)映射到 NAS 的 IP 地址(比如 192.168.1.100)的 22 端口上。不过懒猫微服自带了内网穿透,我们可以不用折腾这个部分了。一般来说,家庭路由器的 IP 是 192.168.X.1,所以我们的机器可能是 192.168.X.2 或者其它地址。也就是说 192.168.X.0/24 就是我们局域网的网段。192.168开头的是C类IP地址,后面/24表示子网掩码,也就是255.255.255.0二进制表示就是 11111111.11111111.11111111.00000000也就是前24位是网络号,后8位是主机号。一个子网内,主机号不能全为0或者全为1192.168.1.0 网络地址(全0)192.168.1.255 广播地址(全1)192.168.1.1-192.168.1.254 可用地址如果你的设备足够多,200 多个可能不太够用,那么就需要用更大的网段,比如 172.16.0.0/12,也就是 172.16.0.0 - 172.31.255.255 可用地址。你也可能看到过 10 开头的地址,这是 A 类私有地址,范围更大:10.0.0.0 - 10.255.255.255。好了,回到 DNS(Domain Name System)。它是互联网的核心服务之一,作为域名和 IP 地址相互映射的分布式数据库,让我们可以通过域名来访问网站,而不用记一串数字。由于懒猫做了转发,实际看到的不是真正的 IP 地址,这里我们快速略过。在局域网内也可以用 dig 查看 IPv4 地址:这里看到的地址就和路由器上显示的一样了。如果想要使用IPv6,那么你需要确保你的网络环境支持IPv6,并且你的路由器也支持IPv6。你可以通过以下命令来查看你的IPv6地址:因为 IPv4 地址已枯竭且存在 NAT 性能损耗,现代互联网依据 RFC 6724 国际标准和 Happy Eyeballs 算法,在操作系统和浏览器底层默认赋予了 IPv6 更高的连接优先级(Precedence),旨在确保连接更直接、高效的同时,通过给 IPv6 几十毫秒的“起跑优势”来实现全球网络向下一代协议的平滑过渡。下载(curl wget)那我们如果想从微服的终端下载东西呢,有 curl 和 wget。通常来讲,curl 用来请求 API,比如测试接口,如果你的懒猫微服里发布了 API 可以用 curl 简单地测试;而 wget 主要用来下载文件。直接在微服上下载,比先下到电脑再 SFTP 传过去快多了。好了,接下来就是端口。端口是一个逻辑概念,用于标识计算机上的不同服务。每个服务都会监听特定的端口,当有请求到达该端口时,系统会将请求转发给对应的服务。例如,HTTP 服务通常监听 80 端口,HTTPS 服务监听 443 端口,SSH 服务监听 22 端口。在懒猫微服中,由于服务大多运行在容器中,所以似乎只有使用 pg-docker 的时候才会注意到端口,或者在终端里临时启动 web server:那么我们如何知道哪些端口被占用呢?可以使用 netstat 或 ss 命令来查看。懒猫微服上容器多、服务杂,有时候端口冲突了,用这俩命令一查便知。我通常使用 :参数解释: 显示数字端口(不解析服务名) 只看监听状态 只看 TCP 显示进程信息日常用 就行,更快。老系统或习惯了 也没问题,结果基本一样。你可能也会看到其他人使用 lsof,同样可以查端口。lsof 除了查询端口之外,还能查询文件、进程等,这里不再赘述。测试远程端口:telnet 和 nc知道端口被谁占了,下一步就是测试远程端口通不通。比如你在懒猫微服上起了个服务,想从电脑上确认能不能连上。telnet 是最经典的方式:这就是 telnet 的用处——能看到服务返回的 banner 信息,做简单的服务识别。退出方式:按 进入命令模式,然后输入 。nc(netcat)更灵活,可以批量扫描端口:路径追踪:mtr 和 traceroute端口通了,但网络还是慢?那就要看看路径上哪一跳出了问题。比如你从懒猫微服访问外网资源很慢,想知道是家里路由器的问题还是运营商的问题。网络不通的时候,光 ping 只能告诉你"不通",但不知道卡在哪一跳。这时候就需要 traceroute 或 mtr。traceroute 是单次探测,跑一遍就结束:mtr 更强,结合了 ping 和 traceroute,持续发包,实时显示每一跳的丢包率和延迟:网络时好时坏的时候,traceroute 可能刚好跑的时候没问题就抓不到,mtr 跑几分钟就能看到哪一跳在丢包。日常排查推荐用 mtr。抓包:tshark和 tcpdump 相比,tshark 的协议解析能力更强,能直接看到 HTTP 请求内容,而 tcpdump 只能看到十六进制。懒猫微服上跑着各种服务,有时候想看看某个应用到底在发什么请求、收什么响应,tshark 就派上用场了。懒猫的系统环境如果默认没装 tshark,需要使用这个命令进行安装用 tshark 抓一个本地 HTTP 请求,看看 TCP/HTTP 到底是怎么通信的。先在一个终端启动抓包:然后另一个终端访问 ,抓到 12 个包:针对上图的结果,我也总结了一个流程图,请看:TCP 三次握手(建立连接)为什么要三次?确保双方都能收发。两次不够——服务端不知道客户端能不能收到它的回复。HTTP 请求/响应TCP 四次挥手(关闭连接)虽然抓包看只有三行,但逻辑上它们依然是四次挥手的变体。一共 12 个包,一次完整的 HTTP 请求就完成了。尾声网络之道,说繁亦繁,说简亦简。繁在协议层层叠叠,简在万变不离其宗——包从哪来,到哪去。能用 tshark 看懂三次握手,用 mtr 定位丢包,用 ss 追溯端口归属,便已胜过大多数人。所谓高手,不过是在无数次折腾中,把书本上的知识化作了指尖的肌肉记忆。而懒猫微服,恰是这样一方天地——自带穿透,容器隔离,root 权限在握,尽可放手施为。纵有闪失,重置便是,不伤筋骨。这大概就是它最大的魅力:不只是一台 NAS,更是折腾 infra、钻研安全的瑞士军刀。所有的好奇心,皆有安放之处。


F007
安装 懒猫商店搜索 选择 进行安装,或者直接点击下方查看详情。配置请求首次打开,页面如下:页面会有 和 的提示,莫慌,下面按照本教程一步一步进行详尽操作。下面进行一系列的配置如下:ssh 登录懒猫微服启用 ssh :懒猫微服-->设置--> 开启 SSHDssh 登录懒猫微服本例一 macOS 为例,打开终端,输入上图复制的ssh 命令,进入终端并输入密码。进入懒猫微服的ssh 环境登录 OpenClaw 中文版 应用的 docker执行 devices list 查看请求列表批准请求(复制 Pending 列表中的 Request ID):本例中 的 为:执行如下:截图如下:刷新web 页面即可状态已经变为 。初始化配置进入 OpenClaw 中文版 应用的 docker仍然是在 docker 中运行,上面已经进入了docker,如果已经推出,请通过以下命令重新进入执行初始化命令 openclaw onboard就是轻车熟路的操作了。



博客图片修整中,看不了可以先搜索公众号“忘机山人”看。
懒猫微服是分层文件系统,所以在之前的文章里前面我们使用用 在开机时自动安装软件,解决重启丢包的问题。但说实话,每次开机都要跑一遍 ,当面对软件包过多以及网络延迟的问题的时候,使用dkpg会卡住,这不够优雅,所以才有了这个方案。后来我换了个思路:既然懒猫微服天生就是为 Docker 而生的,为什么不直接用容器来跑这些工具呢?想想看,htop、iotop、glances 这些运维神器,本质上就是读取 和 里的系统信息。只要让容器能访问宿主机的这些文件,不就能正常工作了吗?这篇文章就来聊聊怎么用 Docker 容器跑系统监控工具。不用装软件,不怕重启丢失,一条命令就能用,用完自动清理。这让我们既享受了分层文件系统的优势,也不用再为软件持久化烦恼了。关于镜像源:本文使用了 作为镜像加速站,仅作示例,不对镜像源的可用性负责。如果某个镜像拉取失败,可以换成其他镜像源,比如 、 等。进程监控类htop - 经典进程查看器我们习惯的使用方式是 ,但在懒猫微服的分层文件系统下重启后会丢失。所以我们可以用Docker来一键设置:这条命令的作用是:启动一个包含 工具的 Docker 容器,并以交互式方式查看宿主机的进程列表。容器停止后会自动删除。 是一个用于实时查看和管理系统进程的交互式工具。我们可以逐部分解析一下这条命令::这是 Docker 命令,用来启动一个新的容器并执行指定的命令。:这个选项表示容器在停止后会被自动删除。这样可以避免容器停留在系统上,占用空间。: 表示让容器保持交互模式(interactive),即允许你输入命令。 表示分配一个伪终端(tty),让你可以以终端方式与容器交互。:这个选项使得容器能够访问宿主机的进程信息。正常情况下,容器只能看到自己内部的进程,但通过 ,容器可以查看宿主机的所有进程,这样你就可以通过 查看宿主机的进程。:这是一个 Docker 镜像的名称,它提供了一个包含 工具的容器镜像。运行这个镜像会启动 ,让你可以在容器中查看进程。为了方便,还可以在 里加个 alias,这样就能像本地命令一样直接敲 使用了。在重启之后我们看到镜像没有丢失,还在本地存在,所以这个方式是可行的。如果你经常玩docker,那么除了--pid之外一定都不陌生。对于默认来讲,--pid 的参数是 private,所以我们常说每个容器有独立的进程命名空间,容器只能看到自己内部的进程。用了**** 之后,容器就可以共享宿主机的进程命名空间。这样,容器可以查看宿主机上的所有进程,而不仅仅是容器内部的进程。所以我们可以用它来做一些监控。甚至还有,:- 容器将能够看到并与指定容器的进程共享命名空间。通常在多容器间需要共享进程信息或调试时使用。例如,一个容器需要查看另一个容器的进程或进行故障排查。当然我们这里不做仔细展开。关于 Docker 参数解释以及 alias、bashrc 的修改,这里只以 htop 为例,后面的工具不再赘述。同理我们也可以测试其他工具。glances - 全能系统监控glances 比 htop 更全面,是个「一屏看所有」的监控工具。CPU、内存、网络、磁盘、Docker 容器状态全都有。参数说明::读取宿主机进程信息:读取宿主机网络信息:让 glances 能监控 Docker 容器btop - htop 的现代化替代btop 界面更炫酷,功能也更丰富,支持鼠标操作。不过这个镜像比较冷门, 等加速站可能没缓存,所以这里直接用 Docker Hub 官方源。如果拉取慢,可以换成其他加速源试试。ctop - Docker 容器专用监控这个镜像来自 quay.io(Red Hat 的镜像仓库),国内访问通常比 Docker Hub 顺畅,可以直接拉取。ctop 专门用来监控 Docker 容器的资源占用。不过要注意,ctop 默认连接 ,这是系统 Docker 的 socket。如果你想监控 playground 里的容器,需要挂载 playground 的 socket:netshoot - 网络排障瑞士军刀netshoot 内置了 tcpdump、iftop、nmap、curl、dig 等一堆网络工具,临时排查问题特别方便。网络监控工具必须加 ,否则测的是容器网络而不是宿主机网络。进入容器后,先用 查看网卡名。懒猫微服的主网卡通常是 而不是 :注意:netshoot 里没有 nethogs,如果需要按进程查看流量,可以用 alpine 临时安装:工具选择指南工具特点适用场景htop轻量、经典快速查看进程,日常使用btop界面炫酷、支持鼠标喜欢好看界面的用户glances功能全面、一屏显示所有需要综合监控的场景ctop专注 Docker 容器监控容器资源占用netshoot网络工具箱网络排障、抓包分析理解 --pid host 的本质 的本质是让容器挂载宿主机的 ,而不是容器自己隔离的那份。容器内的监控工具之所以能工作,是因为 Linux 的系统信息都存在 虚拟文件系统里:文件内容CPU 信息内存信息运行时间内核版本系统负载进程状态常见工具的数据来源:工具读取的文件htop/top, , freedf, ps, netstat/ss, vmstat, iostat所以 能让这些工具在容器里正常工作,因为它们本质上就是读文件,共享了 就等于共享了系统信息。/proc vs /etc/os-release有个细节需要注意: 和 记录的是不同层面的信息。 是内核信息,由内核动态生成: 是发行版信息,是静态文件:打个比方: = 引擎型号(Linux 6.16) = 车的品牌(Debian Linux)同一个内核可以跑不同发行版,所以如果你想让容器里的工具显示正确的操作系统名称,需要手动挂载 。进阶:自己打包docker工具我们经常习惯使用,fastfetch 显示系统信息,但还是没有找到别人打包好的容器的版本。fastfetch 是 neofetch 的现代替代品,速度更快。我们可以用使用alpine安装二进制包的方式来运行,也可以自定义Docker images来跑:先看一个使用alpine安装的:参数说明::让 fastfetch 读到宿主机的 CPU、内存、内核信息:让 fastfetch 读到正确的操作系统名称:让 fastfetch 读到正确的主机名虽然不是很完美,但是已经可以读取到大多数的信息了,再看一个自己打包的Docker版本。构建并运行:同理我们也可以基于alpine构建基于任何软件的镜像工具,我这里再举一个例子,比如iotop。关于 /sys 文件系统除了 ,Linux 还有 虚拟文件系统,存放硬件相关信息:其他命名空间参数除了 ,Docker 还支持其他命名空间共享: 在多容器调试时很有用,可以让一个容器看到另一个容器的进程。关于 --privileged你可能注意到有些命令用了 ,这个参数会让容器获得几乎所有的宿主机权限:访问所有设备()加载内核模块修改系统配置访问完整的 和 像 iotop、nethogs 这类需要深度访问内核信息的工具,没有 可能跑不起来。但要注意,这个参数权限很大,只在信任的镜像上使用,用完记得 自动清理。总结懒猫微服的分层文件系统固然好,但是常用软件会有丢失安装的问题,所以我们用容器来跑这些监控工具,容器镜像重启不会丢失,配置一个alias和bashrc就可以完美兼容这个feature。容器里读取宿主机的参数有这三板斧:看进程用 看网络用 看磁盘用 记住这三个,大多数监控工具都能在容器里跑起来。我们只要维护bashrc里的alias就足够了。回头看看,之前用 开机自动装软件,虽然能用,但每次重启都要跑一遍 ,还会受限于软件体积和网络问题。现在换成 Docker 镜像,拉一次就永久缓存,重启秒开,彻底告别「开机等安装」的烦恼。超越systemd,不用每次开机都再安装软件~




1
在 AI 编码工具越来越多的今天,真正让人头疼的,已经不是“模型好不好用”,而是——我到底该怎么把它们稳定、合理地接进自己的工作流里。CLIProxyAPI 解决的,正是这个越来越明显、却很少被单独拿出来讨论的问题。一、一个很真实、也很常见的痛点假设你是这样一个人:你在用 Claude Code 写代码偶尔也会用 Codex / GPT有时又想试试 Gemini CLIIDE 里还装了 Cline、Amp、Roo Code 之类的 AI 编码插件问题很快就来了:有的工具要 OpenAI API Key有的工具只支持 Claude有的又要求 Gemini KeyAPI Key 不但要自己申请,还可能:有额度会过期有风控甚至根本不好搞更尴尬的是——你其实已经买了 ChatGPT Plus / Claude Pro / Gemini 订阅,但这些 CLI 工具,完全用不上你的订阅账号。于是你会发现一个很割裂的现实:网页端我已经付过钱了终端里却还要再折腾一套 API 体系这就是 CLIProxyAPI 出现的背景。二、CLIProxyAPI 是在解决什么问题?CLIProxyAPI 并不是“又一个 AI 接口”,它的定位其实非常明确:为 AI CLI / IDE 工具,提供一个统一的「账号代理层」你可以把它理解成三件事的组合:对下:管理你自己的 Claude / Codex / Gemini 等账号登录态(OAuth)对上:对外暴露 OpenAI / Claude / Gemini 兼容的 API 形式对中间:帮你做协议转换、模型路由、多账号轮询结果就是:CLI 工具只管“调用 API”账号怎么登录、怎么切、怎么轮询👉 全部交给 CLIProxyAPI你不需要再为每一个 AI 工具单独配置一套账号体系。三、它和 OneAPI / NewAPI 这类工具有什么不一样?表面看起来,它们都像是“聚合器”,但聚合的东西不一样。OneAPI / NewAPI:聚合的是「API Key」这一类工具的核心思路是:把多个模型厂商的 API Key聚合成一个统一的调用入口它们解决的是:多 Key 管理多模型切换统一调用格式但前提是: 你使用的是“开发者 API”这也意味着:API Key 有来源和合规问题使用行为受 API ToS 严格约束天然更接近“接口服务”的模式CLIProxyAPI:聚合的是「账号认证」CLIProxyAPI 走的是另一条路:不中转 API Key不卖额度不当“接口商”而是:通过 OAuth,复用你已经拥有的官方订阅账号从模型厂商视角看:你在用 Claude Code你在用 Codex你在用 Gemini CLICLIProxyAPI 只是一个本地的代理和管理层。一句话区分就是:OneAPI 在管 Key,CLIProxyAPI 在管账号。四、那这样会不会有封号风险?这是一个必须说清楚的问题。先给结论:不会因为“使用 CLIProxyAPI 这个工具”本身而被封号但仍然可能因为“使用方式不当”触发风控这是一个行为风险问题,而不是工具原罪问题。为什么说它的风险相对可控?主要有三个原因:1️⃣ 使用的是官方 OAuth 入口Claude CodeCodexGemini CLI这些本身就支持 OAuth 登录,CLIProxyAPI 只是把登录态集中管理。2️⃣ 不涉及 API 转售或额度分发不卖 Key不共享额度不对外提供服务这直接避开了订阅条款里最敏感的部分。3️⃣ 使用形态更像“真人写代码”在正常使用场景下:有交互节奏在本地 CLI / IDE 中调用不是大规模自动化任务从风控视角看,更接近高级个人用户。真正的风险来自哪里?需要明确一点:CLIProxyAPI 不能帮你突破订阅本身的使用边界。下面这些行为,用什么工具都一样危险:用个人订阅账号跑 CI / 自动任务多人共享同一个账号长时间高并发生成把订阅账号当“白嫖 API”来用一句话总结就是:风险不在“代理”,而在“你是不是在把自己当服务器用”。五、使用方式CLIProxyAPI 的配置和使用,本身并不算复杂,我们以千问为例我们在 OAuth 的地方找到千问,完成登录之后,即可看到已经保存的配置文件。点一下小机器人,还可以看到支持的模型。接下来进入到配置密钥的地方,这里的话随便设置一个就可以,然后复制这个密钥,就可以把CLI工具中的API导出使用,我们在本机上用cherry studio举例。API地址如图所示,也就是应用启动的时候所显示的地址,再填入密钥,即可正常回答六、它适合谁?不适合谁?适合你,如果你:经常用 Claude Code / Codex / Gemini CLI已经有 AI 订阅,不想再折腾 API Key希望多个 AI 编码工具共用一套账号体系更关注稳定性和长期可用性不太适合你,如果你:只在网页端聊天需要对外提供 AI 服务想用最低成本跑自动化任务七、写在最后CLIProxyAPI 不是 API 聚合器,而是 AI CLI 工具的账号中枢。它解决的不是“模型怎么调用”,而是“你已经付过的钱,怎么在终端里用得更顺”。如果你已经在用 AI 写代码,这类“基础设施级的小工具”,往往比换一个新模型,更值得花时间了解。


