<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>故障排查 on 魔都水滴</title>
    <link>https://blog.margrop.net/tag/%E6%95%85%E9%9A%9C%E6%8E%92%E6%9F%A5/</link>
    <description>Recent content in 故障排查 on 魔都水滴</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>zh-CN</language>
    <lastBuildDate>Sun, 19 Jul 2026 22:00:00 +0800</lastBuildDate>
    <atom:link href="https://blog.margrop.net/tag/%E6%95%85%E9%9A%9C%E6%8E%92%E6%9F%A5/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>别急着装电脑管家：AI Agent 到底能替代桌面上的哪些软件？一次看懂清理、优化、改配置和维修的边界</title>
      <link>https://blog.margrop.net/post/ai-agent-replace-desktop-software/</link>
      <pubDate>Sun, 19 Jul 2026 22:00:00 +0800</pubDate>
      <guid>https://blog.margrop.net/post/ai-agent-replace-desktop-software/</guid>
      <description>&lt;blockquote&gt;&#xA;&lt;p&gt;&lt;strong&gt;先说结论&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;p&gt;AI Agent 可以替代一大批“只会点按钮”的桌面工具，但它不是把所有软件图标变成一个聊天框。它真正擅长的是：先看懂问题，再组合系统自带工具，执行一连串步骤，最后把结果解释给你。&lt;/p&gt;&#xA;&lt;p&gt;在文件格式转换、垃圾扫描、性能检查、配置修改和软件故障排查这五类任务里，AI Agent 对前两类的替代程度最高，对性能优化和配置修改属于“半自动”，对硬件维修只能做诊断助手，不能代替人拆机。&lt;/p&gt;&#xA;&lt;p&gt;本文用一条简单原则贯穿全文：&lt;strong&gt;先读，再写；先备份，再改变；先验证，再宣布成功。&lt;/strong&gt; 文中的脚本不依赖第三方服务，默认只扫描和生成报告，必须加参数并再次确认才会清理。&lt;/p&gt;&#xA;&lt;/blockquote&gt;</description>
    </item>
    <item>
      <title>Docker 容器无限重启？只因 v3.7.0 少了一个 serve —— 思源笔记 CLI 破坏性变更修复实录</title>
      <link>https://blog.margrop.net/post/siyuan-v370-docker-restart-loop-fix/</link>
      <pubDate>Thu, 02 Jul 2026 19:30:00 +0800</pubDate>
      <guid>https://blog.margrop.net/post/siyuan-v370-docker-restart-loop-fix/</guid>
      <description>&lt;blockquote&gt;&#xA;&lt;p&gt;&lt;strong&gt;先说结论&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;p&gt;把思源笔记从 v3.6.x 升级到 v3.7.0 后，Docker 容器陷入无限重启循环。&lt;code&gt;docker logs&lt;/code&gt; 显示 &lt;code&gt;Error: unknown flag: --accessAuthCode&lt;/code&gt;。根因是 v3.7.0 引入了 CLI 子命令架构，原来的顶级 flag 现在需要加一个 &lt;code&gt;serve&lt;/code&gt; 子命令。修复只需在 docker-compose.yml 的 &lt;code&gt;command&lt;/code&gt; 字段最前面加上 &lt;code&gt;&#39;serve&#39;&lt;/code&gt;，多 7 个字符，从无限重启到正常运行。&lt;/p&gt;&#xA;&lt;p&gt;本文给出完整排查过程、三种操作系统下的一键修复脚本（Windows 11 / Ubuntu 26.04 / macOS 26），以及人工执行和 AI Agent 自动配置两种方法。所有脚本只调用 Docker CLI 和 SSH，不依赖第三方服务。&lt;/p&gt;&#xA;&lt;/blockquote&gt;</description>
    </item>
    <item>
      <title>Ubuntu 关机要等 90 秒?Python asyncio 服务不肯接 SIGTERM 的排查与修复</title>
      <link>https://blog.margrop.net/post/ubuntu-shutdown-stuck/</link>
      <pubDate>Fri, 19 Jun 2026 10:58:00 +0800</pubDate>
      <guid>https://blog.margrop.net/post/ubuntu-shutdown-stuck/</guid>
      <description>&lt;blockquote&gt;&#xA;&lt;p&gt;&lt;strong&gt;先说结论&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;p&gt;这台升级到 24.04 的代理机,关机变成了一件折磨人的事:&lt;code&gt;systemctl reboot&lt;/code&gt; 之后,SSH 不掉、灯不灭,要干等 &lt;strong&gt;90 秒&lt;/strong&gt; 才进入真正的 shutdown 流程。journalctl 里很明确:&lt;code&gt;smart-proxy.service: State &#39;stop-sigterm&#39; timed out. Killing.&lt;/code&gt;——systemd 给了 SIGTERM,等 90 秒没人响应,只能 SIGKILL 强杀。&lt;/p&gt;&#xA;&lt;p&gt;根因不是 systemd 的错,也不是 Ubuntu 的错,是 &lt;strong&gt;Python 的 asyncio 服务在收到 SIGTERM 后,没有真正去结束它的子任务&lt;/strong&gt;——它正卡在某个 &lt;code&gt;socket.recv&lt;/code&gt; 上,Python 解释器根本不主动去看&amp;quot;有人叫我走&amp;quot;。&lt;/p&gt;&#xA;&lt;p&gt;修复分两步,缺一不可:&lt;strong&gt;(1)&lt;/strong&gt; 给两个 Python unit 写 systemd drop-in,把 &lt;code&gt;TimeoutStopSec&lt;/code&gt; 从默认的 90s 缩到 20s;&lt;strong&gt;(2)&lt;/strong&gt; 在 Python 服务里主动遍历 &lt;code&gt;asyncio.all_tasks()&lt;/code&gt;,收到 SIGTERM 后把所有 in-flight 的 handler &lt;code&gt;cancel()&lt;/code&gt; 掉,再用 &lt;code&gt;asyncio.wait_for(self.stop(), timeout=10)&lt;/code&gt; 包一层做兜底。改完之后,同样一次 &lt;code&gt;reboot&lt;/code&gt;,从 90 秒掉到 1 秒。&lt;/p&gt;&#xA;&lt;/blockquote&gt;</description>
    </item>
    <item>
      <title>一句话让 Claude 把 Ubuntu 22.04 升级到 24.04:一次几乎不用盯屏幕的跨 LTS 实战</title>
      <link>https://blog.margrop.net/post/upgrade-ubuntu-via-agent/</link>
      <pubDate>Fri, 19 Jun 2026 10:58:00 +0800</pubDate>
      <guid>https://blog.margrop.net/post/upgrade-ubuntu-via-agent/</guid>
      <description>&lt;blockquote&gt;&#xA;&lt;p&gt;&lt;strong&gt;先说结论&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;p&gt;这台远端机器是家里那台 24 小时开机的代理机,系统一直停在 Ubuntu 22.04.4 LTS(jammy),内核 5.15。一句&amp;quot;帮我把 192.168.103.182 升级到 ubuntu24.04&amp;quot;,Claude 就替我拆开了旧柜子,在另一个房间装上了新柜子,过程中它自己开了 tmux 守夜、自己起了 fallback sshd 备胎、自己用 &lt;code&gt;do-release-upgrade -f DistUpgradeViewNonInteractive&lt;/code&gt; 跑完了整段流水线。25 分钟后主机回来,内核已经是 6.8.0-124,所有服务依旧在听。&lt;/p&gt;&#xA;&lt;p&gt;本文不是讲 do-release-upgrade 怎么用,那是 Ubuntu 官方文档的事;本文是讲&amp;quot;当 Agent 拿到 SSH 之后,它在做什么、为什么这么做、以及哪些坑你必须提前排&amp;quot;。&lt;/p&gt;&#xA;&lt;/blockquote&gt;</description>
    </item>
    <item>
      <title>我把 AnythingLLM 装进 Docker 之后，容器像一只上紧发条的小松鼠——反复重启直到我把那个 1000:1000 给它</title>
      <link>https://blog.margrop.net/post/anythingllm-docker-deploy/</link>
      <pubDate>Wed, 17 Jun 2026 20:30:00 +0800</pubDate>
      <guid>https://blog.margrop.net/post/anythingllm-docker-deploy/</guid>
      <description>&lt;blockquote&gt;&#xA;&lt;p&gt;&lt;strong&gt;TL;DR（先说结论）&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;p&gt;AnythingLLM 这只&amp;quot;啥都能塞进去的 LLM 口袋书&amp;quot;官方就有 Docker 镜像，正常情况下 &lt;code&gt;docker run&lt;/code&gt; 一行就能起；但它里面那位 &lt;code&gt;anythingllm&lt;/code&gt; 用户很挑剔——挂给它的宿主机目录必须属于 &lt;code&gt;1000:1000&lt;/code&gt;，否则它写不动自己的 SQLite 数据库，Prisma 启动迁移会直接挂掉，容器就会进入&amp;quot;重启—挂掉—再重启&amp;quot;的死循环。修起来不到一分钟：&lt;code&gt;chown -R 1000:1000 /你的数据目录&lt;/code&gt;，再 &lt;code&gt;docker compose up -d&lt;/code&gt; 一次，它就乖乖听 &lt;code&gt;3001&lt;/code&gt; 了。&lt;/p&gt;&#xA;&lt;p&gt;本文顺道把&amp;quot;Prisma 那个 &lt;code&gt;file:../storage/anythingllm.db&lt;/code&gt; 相对路径为什么能坑死人&amp;quot;讲清楚，最后附上 Portainer stack 写法、几条常见坑、以及中英两个 demo 地址。&lt;/p&gt;&#xA;&lt;/blockquote&gt;</description>
    </item>
    <item>
      <title>PhotoPrism 启动 5 分钟还在装系统包？一次 PHOTOPRISM_INIT=intel 的踩坑与正确配置</title>
      <link>https://blog.margrop.net/post/photoprism-init-intel-stuck/</link>
      <pubDate>Sat, 13 Jun 2026 08:30:00 +0800</pubDate>
      <guid>https://blog.margrop.net/post/photoprism-init-intel-stuck/</guid>
      <description>&lt;blockquote&gt;&#xA;&lt;p&gt;&lt;strong&gt;TL;DR（先说结论）&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;p&gt;PhotoPrism Plus 镜像的 &lt;code&gt;docker-compose.yml&lt;/code&gt; 里有一行 &lt;code&gt;PHOTOPRISM_INIT: &amp;quot;intel&amp;quot;&lt;/code&gt;，看似只是给 Intel 核显开加速，实际上它在容器&lt;strong&gt;第一次启动&lt;/strong&gt;时会去 &lt;code&gt;archive.ubuntu.com&lt;/code&gt; 跑一次完整的 &lt;code&gt;apt-get dist-upgrade&lt;/code&gt;，再装 7 个 GPU / VA-API 包。这套流程 &lt;strong&gt;5–10 分钟起步&lt;/strong&gt;，整个期间容器内部没有任何进程在监听 &lt;code&gt;2342&lt;/code&gt; 端口。你的 &lt;code&gt;docker ps&lt;/code&gt; 显示 &lt;code&gt;Up&lt;/code&gt;、Portainer 一切绿、&lt;code&gt;ss -ltn&lt;/code&gt; 也看到 &lt;code&gt;0.0.0.0:2342&lt;/code&gt; 在 LISTEN——但浏览器一访问就是 &lt;strong&gt;ERR_CONNECTION_RESET / Connection reset by peer&lt;/strong&gt;。&lt;/p&gt;&#xA;&lt;p&gt;解法非常简单：&lt;strong&gt;删掉或清空那一行&lt;/strong&gt;。你 &lt;code&gt;devices&lt;/code&gt; 里已经挂上 &lt;code&gt;/dev/dri/renderD128&lt;/code&gt; 直通，驱动和 VA-API 用户态工具由宿主机提供，容器里再装一遍是纯浪费。&lt;/p&gt;&#xA;&lt;/blockquote&gt;</description>
    </item>
    <item>
      <title>Portainer 改个 stack 一直 500？我花了一晚上才明白，是 Docker 引擎里多了一个「重影」网络</title>
      <link>https://blog.margrop.net/post/portainer-500-duplicate-compose-network-enigma/</link>
      <pubDate>Sat, 13 Jun 2026 08:00:00 +0800</pubDate>
      <guid>https://blog.margrop.net/post/portainer-500-duplicate-compose-network-enigma/</guid>
      <description>&lt;blockquote&gt;&#xA;&lt;p&gt;&lt;strong&gt;先说结论&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;p&gt;Portainer 改一个 stack，浏览器上弹出 &lt;code&gt;500 Internal Server Error&lt;/code&gt;。你以为又是 YAML 写错了，回去检查 compose 语法、缩进、引号、镜像 tag，全部都对。但每次重试都是同一个 500。&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;真正的问题藏在 HTTP response body 的 &lt;code&gt;message&lt;/code&gt; 字段最深处：&lt;code&gt;network librespeed_default is ambiguous (2 matches found on name)&lt;/code&gt;。&lt;/strong&gt; 也就是说，Docker 引擎里同时存在两个 &lt;code&gt;librespeed_default&lt;/code&gt; 网络——两个 ID、两个 &lt;code&gt;Created&lt;/code&gt; 时间、两个 &lt;code&gt;com.docker.compose.config-hash&lt;/code&gt;，但名字一模一样。Compose 启动时让引擎去 lookup 名字，引擎说「我选不出来」，compose up 失败，Portainer 把这条错误原样包成 500 退给浏览器。&lt;/p&gt;&#xA;&lt;p&gt;修复办法朴素到尴尬：在引擎上&lt;strong&gt;删掉其中一个孤儿网络&lt;/strong&gt;（&lt;code&gt;docker network rm &amp;lt;id&amp;gt;&lt;/code&gt; 或在 Portainer 的 Networks 里点 Remove），再原样点一次 Update the stack，就过了。&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;p&gt;这篇文章源于一次真实的 stack 改挂载路径的过程。全程我已经把所有内网地址、镜像仓库地址、卷挂载路径、容器名、用户名密码用 &lt;code&gt;&amp;lt;PLACEHOLDER&amp;gt;&lt;/code&gt; 替换，只保留公开信息、官方源码、错误文本这些可分享的内容。&lt;/p&gt;</description>
    </item>
    <item>
      <title>OpenClaw TUI 变复读机？thinking 和回复重复的临时止血手册</title>
      <link>https://blog.margrop.net/post/openclaw-tui-duplicate-thinking-stream-patch/</link>
      <pubDate>Tue, 02 Jun 2026 10:42:00 +0800</pubDate>
      <guid>https://blog.margrop.net/post/openclaw-tui-duplicate-thinking-stream-patch/</guid>
      <description>&lt;blockquote&gt;&#xA;&lt;p&gt;&lt;strong&gt;先说结论&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;p&gt;如果你在 OpenClaw TUI 里看到同一段 thinking 重复出现、同一段回复正文连续出现两遍，先不要急着清空模型、删除 session 或者怀疑所有 provider 配置都坏了。这个问题很可能不是“历史消息太多”，也不一定是模型真的想复读，而是 OpenAI-compatible 流式响应里同时出现了增量 &lt;code&gt;delta&lt;/code&gt; 和额外的完整 &lt;code&gt;message&lt;/code&gt;，OpenClaw 某些版本在上层聚合时把两份内容都算进去了。&lt;/p&gt;&#xA;&lt;p&gt;临时解决思路很简单：备份本地安装文件，在 OpenClaw 的运行聚合层增加一个非常保守的去重保护；它只处理“同一轮、同一模型、完全重复的 text/thinking 块”，然后重启 gateway，用 marker 测试确认 TUI 和 session 落盘都只剩一份内容。&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;p&gt;本文是一份可复用的临时修复记录。所有路径、模型名、网关地址和 Token 都做了脱敏处理，真实环境请用自己的安装路径和模型名替换。不要把本文里的占位符当成真实配置直接复制。&lt;/p&gt;</description>
    </item>
    <item>
      <title>Mac 应用打不开？别急着删：可能只是 Gatekeeper 不认这个未签名工具</title>
      <link>https://blog.margrop.net/post/macos-gatekeeper-unsigned-app-fix/</link>
      <pubDate>Mon, 01 Jun 2026 07:35:00 +0800</pubDate>
      <guid>https://blog.margrop.net/post/macos-gatekeeper-unsigned-app-fix/</guid>
      <description>&lt;blockquote&gt;&#xA;&lt;p&gt;&lt;strong&gt;先说结论&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;p&gt;如果一个 macOS 工具下载后双击打不开，提示“无法验证开发者”“已损坏，无法打开”或被系统直接拦住，不要第一时间把它理解成“程序坏了”。很多时候，真正的问题是两个条件叠在一起：这个 &lt;code&gt;.app&lt;/code&gt; 带着浏览器下载留下的 &lt;code&gt;com.apple.quarantine&lt;/code&gt; 隔离属性，同时它没有 Apple 能认可的可用签名。Gatekeeper 在首次打开时看到“来自网络 + 没有可信签名”，自然会把它拦下来。&lt;/p&gt;&#xA;&lt;p&gt;对明确知道来源、只在自己机器上使用的小工具，最小修复通常是：先验证隔离属性和签名状态，再对这个 app 做本地 ad-hoc 签名，最后移除它自己的 quarantine 属性。这里的关键不是“关闭 macOS 安全”，而是只处理一个具体 app，不动全局 Gatekeeper，也不把临时本地修复误认为正式分发签名。&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;p&gt;这篇文章来自一次真实的本地排障，但所有涉及个人机器、内网、下载来源、账号、路径细节的内容都已经脱敏。文中只使用 &lt;code&gt;/Applications/&amp;lt;App&amp;gt;.app&lt;/code&gt;、&lt;code&gt;&amp;lt;App&amp;gt;&lt;/code&gt;、&lt;code&gt;&amp;lt;Vendor&amp;gt;&lt;/code&gt; 这类占位符。重点不是公开某个私有环境，而是把这类 macOS 启动失败的判断路径整理出来，方便以后遇到类似问题时少走弯路。&lt;/p&gt;</description>
    </item>
    <item>
      <title>你能 SSH 出去，却 SSH 不回来：一次被 Fail2Ban 误伤的反向访问排障实录</title>
      <link>https://blog.margrop.net/post/reverse-ssh-fail2ban-vpn-gateway-investigation/</link>
      <pubDate>Sat, 30 May 2026 15:45:00 +0800</pubDate>
      <guid>https://blog.margrop.net/post/reverse-ssh-fail2ban-vpn-gateway-investigation/</guid>
      <description>&lt;blockquote&gt;&#xA;&lt;p&gt;&lt;strong&gt;先说结论&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;p&gt;这次问题的表象很简单：本机可以主动 SSH 到远端内网机器，但远端机器反过来 SSH 回本机时，连接直接被拒绝。&lt;code&gt;sshd&lt;/code&gt; 明明在监听，路由也没断，最后却卡在“反向访问”这一步。&lt;/p&gt;&#xA;&lt;p&gt;真正的根因不是 &lt;code&gt;sshd&lt;/code&gt; 挂了，而是 &lt;code&gt;Fail2Ban&lt;/code&gt; 把承载反向连接的 &lt;strong&gt;VPN 网关地址&lt;/strong&gt; 封掉了。对本机来说，来自远端的连接并不是以“远端机器本身”的地址出现，而是以网关地址出现。于是，错误的封禁对象把整条回程链路一并打断了。&lt;/p&gt;&#xA;&lt;/blockquote&gt;</description>
    </item>
    <item>
      <title>Claude Code 一升级就全模型 400：别急着换 Key，可能是网关没跟上新版协议</title>
      <link>https://blog.margrop.net/post/claude-code-invalid-message-role-system/</link>
      <pubDate>Fri, 29 May 2026 15:30:00 +0800</pubDate>
      <guid>https://blog.margrop.net/post/claude-code-invalid-message-role-system/</guid>
      <description>&lt;blockquote&gt;&#xA;&lt;p&gt;&lt;strong&gt;先说结论&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;p&gt;这次故障的表象非常吓人：Claude Code 更新之后，不管访问哪个模型，都会立刻报 &lt;code&gt;API Error: 400 invalid params, chat content has invalid message role: system (2013)&lt;/code&gt;。如果只看错误，很容易怀疑 API Key 失效、模型下线、余额不足、代理坏了、环境变量乱了，甚至怀疑所有模型同时挂掉。真正的根因不是这些，而是新版 Claude Code 发出的请求结构和某些 Anthropic-compatible 模型网关之间出现了兼容断层：网关把不该出现在 chat content 中的 &lt;code&gt;system&lt;/code&gt; role 当成非法消息拒绝了。&lt;/p&gt;&#xA;&lt;p&gt;最小可用修复也很朴素：先用最小 prompt 复现，再对相邻版本做二分式验证。最终确认 &lt;code&gt;2.1.150&lt;/code&gt; 能正常返回，&lt;code&gt;2.1.154&lt;/code&gt; 和 &lt;code&gt;2.1.156&lt;/code&gt; 会复现 400，于是把全局 Claude Code 固定回 &lt;code&gt;2.1.150&lt;/code&gt;。这不是“玄学回滚”，而是基于证据找到最后一个已知可用版本。&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;p&gt;这篇文章记录一次 Claude Code 本地环境排障。它不是一个复杂到需要改源码的问题，但很有代表性：AI Agent 工具链越来越依赖模型网关、兼容协议、环境变量、版本更新和本地 provider 切换；当其中一层发生协议细节变化时，终端里看到的却往往只是一句抽象的 400。&lt;/p&gt;&#xA;&lt;p&gt;为了避免泄露任何隐私信息，本文不会出现真实内网地址、真实用户名、真实 token、真实私有 provider 名称、真实本机路径或私有服务域名。所有配置片段都使用 &lt;code&gt;&amp;lt;PLACEHOLDER&amp;gt;&lt;/code&gt;、&lt;code&gt;&amp;lt;MODEL_GATEWAY&amp;gt;&lt;/code&gt;、&lt;code&gt;&amp;lt;MODEL_NAME&amp;gt;&lt;/code&gt; 等占位符表示。文章重点是分享排障方法，而不是公开某个具体环境。&lt;/p&gt;</description>
    </item>
    <item>
      <title>AI 助手为什么把一句话复读四遍：一次 OpenClaw 微信通道排障复盘</title>
      <link>https://blog.margrop.net/post/openclaw-wechat-duplicate-reply-debugging/</link>
      <pubDate>Fri, 29 May 2026 11:24:29 +0800</pubDate>
      <guid>https://blog.margrop.net/post/openclaw-wechat-duplicate-reply-debugging/</guid>
      <description>&lt;blockquote&gt;&#xA;&lt;p&gt;&lt;strong&gt;先说结论&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;p&gt;这次问题看起来像“微信通道把同一条回复发了四遍”，但真正的重复发生在更早的位置：消息还没有进入微信发送层之前，OpenClaw Agent 的最终可见文本就已经被模型执行链路重复拼接了。排障的关键不是一上来改微信插件，而是把链路拆成发送层、会话层、模型路由层三段，用最小 prompt 复现，再比较“兼容网关路径”和“原生 provider 路径”的输出差异。最后的修复也很朴素：让个人 IM 通道显式走原生 provider，移除容易被误选的故障候选模型路径，重启 Gateway 后复测主会话。&lt;/p&gt;&#xA;&lt;p&gt;这篇文章不会出现任何真实内网地址、账号、token、会话 ID、个人微信标识或私有路径。所有配置片段都已经脱敏，并用 &lt;code&gt;&amp;lt;PLACEHOLDER&amp;gt;&lt;/code&gt; 形式表示。重点是分享一套可复用的排障方法，而不是公开某个具体环境的细节。&lt;/p&gt;&#xA;&lt;/blockquote&gt;</description>
    </item>
    <item>
      <title>避坑指南：新装 Ubuntu 26.04 与 PVE 9.2 别急着用！Fail2Ban 无法启动与拦截失效的终极解决办法</title>
      <link>https://blog.margrop.net/post/ubuntu-2604-pve-92-fail2ban-nftables-guide/</link>
      <pubDate>Tue, 26 May 2026 22:20:00 +0800</pubDate>
      <guid>https://blog.margrop.net/post/ubuntu-2604-pve-92-fail2ban-nftables-guide/</guid>
      <description>&lt;blockquote&gt;&#xA;&lt;p&gt;&lt;strong&gt;先说结论&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;p&gt;随着 Ubuntu 26.04 LTS 与 Proxmox VE (PVE) 9.2 的相继发布，许多运维工程师与 Host 玩家在第一时间完成了系统升级或新装。然而，在进行服务器安全加固时，你会发现一个令人抓狂的现象：&lt;strong&gt;直接沿用旧版本（如 Ubuntu 20.04/22.04 或 PVE 7.x/8.x）的 Fail2Ban 配置，不仅服务可能直接报错无法启动，甚至即使显示 Running，外部恶意扫描也根本无法被成功拦截！&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;p&gt;这并不是 Fail2Ban 软件本身出了 Bug，而是因为新版系统在底层日志架构、服务激活机制和防火墙后端上默默丢下了三颗“隐形炸弹”。本文将深度剖析这三个底层变化，并提供一套完美的、基于 &lt;code&gt;systemd-journald&lt;/code&gt; + &lt;code&gt;nftables&lt;/code&gt; 的 Fail2Ban 现代配置方案。&lt;/p&gt;&#xA;&lt;/blockquote&gt;</description>
    </item>
    <item>
      <title>新装 Ubuntu 26.04 LTS 别急着用！一步到位换上国内镜像源（阿里源与华为源 DEB822 最新格式配置教程）</title>
      <link>https://blog.margrop.net/post/ubuntu-26-apt-source-mirror-setup-guide/</link>
      <pubDate>Tue, 26 May 2026 21:00:00 +0800</pubDate>
      <guid>https://blog.margrop.net/post/ubuntu-26-apt-source-mirror-setup-guide/</guid>
      <description>&lt;blockquote&gt;&#xA;&lt;p&gt;&lt;strong&gt;先说结论&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;p&gt;Ubuntu 26.04 LTS (Resolute Raccoon) 已经正式发布。如果你刚刚安装完系统，第一件事绝对不是急着安装各种软件，而是应当立即更换国内的高速 APT 镜像源（如阿里云镜像、华为云镜像）。从 Ubuntu 24.04 开始，官方已经全面启用了全新的 &lt;strong&gt;DEB822&lt;/strong&gt; 格式配置（存放于 &lt;code&gt;/etc/apt/sources.list.d/ubuntu.sources&lt;/code&gt;），传统的 &lt;code&gt;/etc/apt/sources.list&lt;/code&gt; 文件默认已经不再生效。&lt;/p&gt;&#xA;&lt;p&gt;本文将手把手教你如何在新版 Ubuntu 26.04 中，优雅、安全地更换为阿里云与华为云镜像源，并针对可能遇到的依赖冲突、版本代号错误等“大坑”进行深度解析。&lt;/p&gt;&#xA;&lt;/blockquote&gt;</description>
    </item>
    <item>
      <title>MCP 明明没配错，为什么一启动就挂？一次 Codex MCP 故障的完整拆解</title>
      <link>https://blog.margrop.net/post/codex-mcp-startup-swift-runtime-troubleshooting/</link>
      <pubDate>Sat, 23 May 2026 06:10:00 +0800</pubDate>
      <guid>https://blog.margrop.net/post/codex-mcp-startup-swift-runtime-troubleshooting/</guid>
      <description>&lt;blockquote&gt;&#xA;&lt;p&gt;&lt;strong&gt;先说结论&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;p&gt;这次故障最容易误判的地方，是表面错误写着 “MCP Client 启动失败”“MCP Server 握手失败”，于是人很自然会去怀疑 MCP 配置、插件开关、网络、Token、JSON 格式、stdio 协议，甚至怀疑 Codex 本身挂了。但真正的根因并不在 MCP 协议层：某个 MCP Server 对应的本地二进制在启动瞬间就被 macOS 动态链接器杀掉了，根本没有机会完成 &lt;code&gt;initialize&lt;/code&gt; 握手。Client 看到的只是连接提前关闭，Server 端真正留下的线索是 &lt;code&gt;dyld: Symbol not found&lt;/code&gt;，缺的是 Swift Concurrency runtime 里的一个符号。&lt;/p&gt;&#xA;&lt;p&gt;换句话说：MCP 没有来得及失败，Server 进程先死了。&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;p&gt;这篇文章记录一次很典型、也很容易绕远路的 Agent 工具链故障：Codex 里 MCP Client / MCP Server 启动异常。它不是一个“修改配置就好”的问题，而是一个从应用层错误一路追到本地二进制、动态链接器、Swift runtime 兼容性的排障过程。&lt;/p&gt;&#xA;&lt;p&gt;为了避免泄露任何隐私信息，本文不包含真实内网地址、真实用户名、真实会话 ID、真实本机绝对路径、Token、私有仓库地址或任何业务系统名称。文中路径都使用 &lt;code&gt;~&lt;/code&gt;、&lt;code&gt;&amp;lt;USER_HOME&amp;gt;&lt;/code&gt;、&lt;code&gt;&amp;lt;PLUGIN_DIR&amp;gt;&lt;/code&gt;、&lt;code&gt;&amp;lt;PROJECT&amp;gt;&lt;/code&gt; 等占位符表示；命令输出也只保留与判断根因有关的公开技术字段。&lt;/p&gt;</description>
    </item>
    <item>
      <title>新电脑 Bitwarden 登不上，旧电脑却正常：一次 Vaultwarden 版本兼容坑的完整复盘</title>
      <link>https://blog.margrop.net/post/chrome-bitwarden-vaultwarden-login-failure-prelogin/</link>
      <pubDate>Mon, 18 May 2026 10:05:00 +0800</pubDate>
      <guid>https://blog.margrop.net/post/chrome-bitwarden-vaultwarden-login-failure-prelogin/</guid>
      <description>&lt;blockquote&gt;&#xA;&lt;p&gt;&lt;strong&gt;先说结论&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;p&gt;这次问题表面上看是“新安装的 Chrome + Bitwarden 扩展登录失败”，但根因并不在 Chrome，也不是账号密码输错，而是 &lt;strong&gt;Bitwarden 2026.4.1 客户端登录流程调用了新的 prelogin 接口，而自建 Vaultwarden 服务端还停留在 &lt;code&gt;1.35.4-alpine&lt;/code&gt;，缺少 &lt;code&gt;/identity/accounts/prelogin/password&lt;/code&gt; 接口&lt;/strong&gt;。&lt;/p&gt;&#xA;&lt;p&gt;旧电脑之所以还能用，是因为它大概率已有登录态和本地缓存，并没有重新触发完整的首次登录流程。真正的修复不是反复重装浏览器，而是先备份，再把 Vaultwarden 升级到 &lt;code&gt;1.36.0&lt;/code&gt; 或更新版本，然后用日志确认新接口不再 404。&lt;/p&gt;&#xA;&lt;p&gt;本文所有域名、路径、账号、部署目录均已脱敏，示例中统一使用 &lt;code&gt;vault.example.com&lt;/code&gt;、&lt;code&gt;/opt/vaultwarden&lt;/code&gt; 等占位值，不包含任何内网地址或私人信息。&lt;/p&gt;&#xA;&lt;/blockquote&gt;</description>
    </item>
    <item>
      <title>「标题党预警」换个国内镜像源，竟让我踩了这么大一个坑：Ubuntu 26.04 apt 依赖冲突全记录</title>
      <link>https://blog.margrop.net/post/ubuntu-26-apt-source-mirror-dependency-conflict-fix/</link>
      <pubDate>Sun, 17 May 2026 10:00:00 +0800</pubDate>
      <guid>https://blog.margrop.net/post/ubuntu-26-apt-source-mirror-dependency-conflict-fix/</guid>
      <description>&lt;blockquote&gt;&#xA;&lt;p&gt;&lt;strong&gt;先说结论&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;p&gt;换了个国内镜像源，本以为 10 分钟搞定的事，结果折腾了两个小时。本文记录了从「镜像同步延迟导致版本撕裂」到「dpkg 强制降级」再到「apt 完全恢复正常」的全过程。核心教训：镜像源不是换上去就完事了，版本一致性才是关键。如果你的系统用了大半年突然换源，99% 会遇到依赖冲突。&lt;/p&gt;&#xA;&lt;p&gt;本文所有操作基于 Ubuntu 26.04 (Plucky)，所有 IP、主机名、路径均为脱敏示例，不包含任何内网地址或敏感信息。&lt;/p&gt;&#xA;&lt;/blockquote&gt;</description>
    </item>
    <item>
      <title>OpenClaw 备份失效排查与修复实录：从两个机器同时失效到自动备份彻底恢复</title>
      <link>https://blog.margrop.net/post/openclaw-backup-failure-investigation-and-fix/</link>
      <pubDate>Mon, 13 Apr 2026 09:30:00 +0800</pubDate>
      <guid>https://blog.margrop.net/post/openclaw-backup-failure-investigation-and-fix/</guid>
      <description>&lt;p&gt;我把这次问题写成一篇完整的复盘，不是因为它足够戏剧化，而是因为它足够典型。&lt;/p&gt;&#xA;&lt;p&gt;这次出问题的不是一个单点，而是两台机器的自动备份同时失效：一台是本地的 macOS 机器，一台是远程的 VPS。两边手动执行都可以成功，备份文件也能写到 NAS，但只要放回定时任务，结果就会变得不稳定，甚至直接失败。表面看像是“定时器没触发”，实际上真正的问题分布在调度、权限、锁、日志、以及验证方式几个不同层面。&lt;/p&gt;&#xA;&lt;p&gt;对我来说，这类故障最麻烦的地方，不在于它有多难修，而在于它会制造一种很强的错觉：每一部分单独看都像没坏，拼到一起却就是不工作。&lt;/p&gt;</description>
    </item>
    <item>
      <title>把 OpenClaw 升级到 2026.3.23-2：一次真实的兼容性升级记录与排障手册</title>
      <link>https://blog.margrop.net/post/openclaw-upgrade-to-2026-3-23-compatibility-playbook/</link>
      <pubDate>Tue, 24 Mar 2026 21:20:00 +0800</pubDate>
      <guid>https://blog.margrop.net/post/openclaw-upgrade-to-2026-3-23-compatibility-playbook/</guid>
      <description>&lt;p&gt;这篇文章记录一次真实的 OpenClaw 升级过程：目标不是“把版本号改上去”这么简单，而是在&lt;strong&gt;多节点、不同安装形态、外部插件较多&lt;/strong&gt;的情况下，把 OpenClaw 从 &lt;code&gt;2026.3.8 / 2026.3.13&lt;/code&gt; 这一代稳定升级到 &lt;code&gt;2026.3.23-2&lt;/code&gt;，同时尽量保证既有消息通道、插件、服务方式、回滚路径都可控。&lt;/p&gt;&#xA;&lt;p&gt;我最终采用的是“&lt;strong&gt;先评估，再金丝雀，再复制已验证产物&lt;/strong&gt;”的策略。升级过程里真正棘手的部分，不是 OpenClaw 核心包本身，而是&lt;strong&gt;插件 SDK 兼容性、JIT 缓存、混合安装路径、边缘节点出网失败、以及不同服务绑定策略对探测命令的影响&lt;/strong&gt;。这些问题如果不提前识别，线上升级很容易看起来“版本成功了”，实际上通道已经半瘫痪。&lt;/p&gt;</description>
    </item>
  </channel>
</rss>
