给小白看的网络运维 Agent 模板,覆盖爱快、OpenWrt、iStoreOS、OpenClash、ShadowsocksR Plus+、PassWall、旁路由、DNS 分流、订阅转换、插件配置维修、OpenCode 可直接调用的 OpenWrt SSH 工具和备份回滚。
内容更新 2026-05-25网络运维 Agent 的第一原则是先备份、先只读检查、一次只改一个变量,别让小问题变成全网断线。
status、network、dns、proxy、backup 和点名单个插件的日志动作;原始系统日志只由真人本地查看。# 先由真人按下文校验 SHA-256、完整审阅并安装 wrapper,再让 Agent 做只读检查
# 不要把 raw UCI 或 raw logread 输出直接交给 Agent;其中可能包含 PPPoE、订阅或客户环境信息
openwrt-ssh ping
openwrt-ssh status
openwrt-ssh network
openwrt-ssh dns
openwrt-ssh plugin-status
openwrt-ssh subscriptions
# 定向日志必须明确一个插件,例如 openwrt-ssh plugin-logs openclash
# 原始系统日志只由真人本地查看# 只调用已校验并全文审阅的 wrapper;不要手写固定 /tmp 备份路径
openwrt-ssh backup all
# wrapper 会拒绝 symlink 和不安全权限,把敏感备份写入:
# /root/openwrt-backups(root:root,目录 700、文件 600)
# 备份可能包含 PPPoE、订阅、节点和客户环境信息,不要上传或发给 Agent。
# 问题解决并确认不再需要回滚后,由真人登录路由器清理旧备份。# macOS:先下载到临时文件、核对固定 SHA-256、完整人工审阅,再备份并替换
umask 077
tool_dir="$HOME/bin"
target="$tool_dir/openwrt-ssh"
expected="6db3d0fa4a6ce52d221b7bc24c3e739c95f3eef362c83ad05d5b3cce69b5bb0a"
mkdir -p "$tool_dir"
tmp="$(mktemp "$tool_dir/openwrt-ssh.tmp.XXXXXX")"
trap 'rm -f "$tmp"' EXIT
curl --fail --location --proto '=https' --tlsv1.2 \
https://thinktank.1a1api.top/tools/openwrt-ssh/openwrt-ssh -o "$tmp"
actual="$(shasum -a 256 "$tmp" | awk '{print $1}')"
[ "$actual" = "$expected" ] || { echo "SHA-256 mismatch" >&2; exit 1; }
cat "$tmp"
read -r -p '已完整审阅脚本,输入 yes 才安装:' confirm
[ "$confirm" = yes ] || exit 1
[ ! -e "$target" ] || cp -p "$target" "$target.bak.$(date +%Y%m%d-%H%M%S)"
chmod 700 "$tmp"
mv "$tmp" "$target"
trap - EXIT
# 确认 ~/bin 在 PATH 中;如果没有,就追加到 zsh 配置
case ":$PATH:" in *":$HOME/bin:"*) ;; *) echo 'export PATH="$HOME/bin:$PATH"' >> ~/.zshrc; export PATH="$HOME/bin:$PATH" ;; esac
# 第一次仍由真人完成专用 SSH Key 和 Host 别名;先人工核对路由器 IP 与主机指纹
mkdir -p ~/.ssh && chmod 700 ~/.ssh
ssh-keygen -t ed25519 -C "opencode-openwrt" -f ~/.ssh/openwrt_opencode
# 首次连接显示 fingerprint 时,先与路由器本机界面或本地控制台显示的主机指纹逐字比对;
# 无法带外核对就停止,不要确认主机密钥,也不要输入 root 密码。
cat ~/.ssh/openwrt_opencode.pub | ssh root@192.168.1.1 "umask 077; mkdir -p /etc/dropbear; cat >> /etc/dropbear/authorized_keys; chmod 600 /etc/dropbear/authorized_keys"
cat >> ~/.ssh/config <<'EOF'
Host openwrt-router
HostName 192.168.1.1
User root
IdentityFile ~/.ssh/openwrt_opencode
IdentitiesOnly yes
StrictHostKeyChecking yes
EOF
openwrt-ssh ping
openwrt-ssh status# Windows PowerShell:临时下载、固定 SHA-256 校验、完整人工审阅、备份后替换
$BinDir = Join-Path $env:USERPROFILE 'bin'
$Target = Join-Path $BinDir 'openwrt-ssh.ps1'
$Expected = 'dd0670e2f255f5679eda4270c73368bf6488d6c5a3e7e5763b3b2f532310a8b6'
New-Item -ItemType Directory -Force $BinDir | Out-Null
$Tmp = Join-Path $BinDir ("openwrt-ssh.{0}.tmp.ps1" -f [guid]::NewGuid())
try {
Invoke-WebRequest -Uri 'https://thinktank.1a1api.top/tools/openwrt-ssh/openwrt-ssh.ps1' -OutFile $Tmp
$Actual = (Get-FileHash -Algorithm SHA256 $Tmp).Hash.ToLowerInvariant()
if ($Actual -ne $Expected) { throw 'SHA-256 mismatch' }
Get-Content $Tmp
if ((Read-Host '已完整审阅脚本,输入 yes 才安装') -ne 'yes') { throw 'Installation cancelled' }
if (Test-Path $Target) { Copy-Item $Target "$Target.bak.$(Get-Date -Format yyyyMMdd-HHmmss)" }
Move-Item -Force $Tmp $Target
} finally {
if (Test-Path $Tmp) { Remove-Item -Force $Tmp }
}
ssh -V
# 第一次仍由真人完成专用 SSH Key 和 Host 别名;先人工核对路由器 IP 与主机指纹
New-Item -ItemType Directory -Force "$env:USERPROFILE\.ssh" | Out-Null
ssh-keygen -t ed25519 -C "opencode-openwrt" -f "$env:USERPROFILE\.ssh\openwrt_opencode"
# 首次连接显示 fingerprint 时,先与路由器本机界面或本地控制台显示的主机指纹逐字比对;
# 无法带外核对就停止,不要确认主机密钥,也不要输入 root 密码。
type "$env:USERPROFILE\.ssh\openwrt_opencode.pub" | ssh root@192.168.1.1 "umask 077; mkdir -p /etc/dropbear; cat >> /etc/dropbear/authorized_keys; chmod 600 /etc/dropbear/authorized_keys"
@"
Host openwrt-router
HostName 192.168.1.1
User root
IdentityFile ~/.ssh/openwrt_opencode
IdentitiesOnly yes
StrictHostKeyChecking yes
"@ | Add-Content "$env:USERPROFILE\.ssh\config"
# 先查看当前策略;Bypass 只对下面这个子进程生效,不要持久修改 CurrentUser / LocalMachine
Get-ExecutionPolicy -List
powershell -NoProfile -ExecutionPolicy Bypass -File $Target ping
if ($LASTEXITCODE -ne 0) { throw 'openwrt-ssh ping failed' }
powershell -NoProfile -ExecutionPolicy Bypass -File $Target status
if ($LASTEXITCODE -ne 0) { throw 'openwrt-ssh status failed' }给 OpenCode 的任务模板:
你是网络运维 Agent。不要直接 ssh,也不要要求输入路由器密码。只调用已经由真人校验 SHA-256、完整审阅并安装的工具:Mac 调用 openwrt-ssh;Windows 在确认策略后,用仅该子进程生效的 powershell -NoProfile -ExecutionPolicy Bypass -File ~/bin/openwrt-ssh.ps1。你可以直接使用 ping、status、network、dns、proxy、subscriptions、plugin-status、点名一个插件的 plugin-config / plugin-logs、config network、config dhcp、config firewall、backup、all。原始系统日志只由真人本地查看。先运行 ping、status、plugin-status、subscriptions,再根据结果决定下一步。若建议 plugin-repair,先展示证据、可能的断网/断 SSH 影响、维护窗口和回滚方案,然后停止并等待我在当次会话明确批准一个插件;你不得设置 OPENWRT_ALLOW_REPAIR 或自行运行维修。任何输出都只做尽力脱敏,分享前必须人工检查。# 订阅转换 / 插件配置:OpenCode 可直接调用的固定动作
openwrt-ssh subscriptions
openwrt-ssh plugin-status
openwrt-ssh plugin-config openclash
openwrt-ssh plugin-config passwall
openwrt-ssh plugin-config ssr
openwrt-ssh plugin-logs openclash
openwrt-ssh backup plugins
# 维修会重启服务并可能断网/断 SSH:Agent 到这里先展示证据、影响、维护窗口和回滚方案并停止。
# 用户当次明确批准 openclash 后,由真人执行一次性授权;Agent 不得代设:
OPENWRT_ALLOW_REPAIR=openclash openwrt-ssh plugin-repair openclash
openwrt-ssh dns
openwrt-ssh proxy
ssh home-router,再交给 OpenCode 执行远程命令。订阅转换不是把一个链接随便丢进去。小白要先确认自己要喂给哪个插件:OpenClash 通常要 Clash YAML,PassWall 要它能识别的节点或订阅格式,ShadowsocksR Plus+ 更偏 SSR / SS / V2Ray 兼容节点。Agent 可以帮你检查目标格式和日志,但不要让 Agent 保存完整订阅 URL。
proxies、proxy-groups、rules 这类结构。openwrt-ssh subscriptions 和 openwrt-ssh plugin-logs openclash 看是否节点为空、YAML 解析失败或下载失败。# 让 OpenCode 检查订阅转换结果,但不要把完整订阅 URL 交给它
openwrt-ssh subscriptions
openwrt-ssh plugin-config openclash
openwrt-ssh plugin-logs openclash
openwrt-ssh plugin-config passwall
openwrt-ssh plugin-logs passwall
openwrt-ssh plugin-config ssr
openwrt-ssh plugin-logs ssr
维修插件不是上来重装。先把配置备份下来,再查服务、进程、端口、订阅、日志。只有确认是插件卡住、下载失败或进程异常时,才做一次单插件软重启。
openwrt-ssh backup all。openwrt-ssh plugin-status,看服务是否存在、是否运行、有没有相关进程和监听端口。openwrt-ssh subscriptions,看订阅配置和更新日志是否异常。openwrt-ssh plugin-config openclash 或 plugin-config passwall。openwrt-ssh plugin-logs openclash。openwrt-ssh backup all
openwrt-ssh plugin-status
openwrt-ssh subscriptions
openwrt-ssh plugin-logs openclash
# Agent 在这里停止:展示证据、可能断网/断 SSH 的影响、维护窗口和回滚方案。
# 用户当次明确批准 openclash 后,由真人执行;Agent 不得设置授权变量:
OPENWRT_ALLOW_REPAIR=openclash openwrt-ssh plugin-repair openclash
openwrt-ssh dns
openwrt-ssh proxy
OpenCode、Codex、Claude Code 这类 CLI Agent 更适合调用固定工具,不适合卡在 SSH 密码输入、首次 host key 确认或二次验证页面。长期推荐 SSH Key;如果 OpenCode 当前用的是 sshpass,也要把密码放在 SSHPASS 环境变量里,让 openwrt-ssh 走固定动作。
openwrt-ssh,Windows 安装 openwrt-ssh.ps1,都使用同一个 Host 别名 openwrt-router。known_hosts;之后 OpenCode 才可用 OPENWRT_USE_SSHPASS=1 和 SSHPASS,不要把密码写进命令参数。ping、status、network、dns、proxy、subscriptions、plugin-status、点名一个插件的 plugin-config / plugin-logs、config、backup、all;原始系统日志只由真人本地查看。plugin-repair 需当次人工批准和一次性授权。BatchMode=yes,如果 SSH Key 没配好会快速失败,不会让 OpenCode 卡在密码输入。sshpass 模式时 wrapper 会强制 StrictHostKeyChecking=yes;未知或不匹配的主机密钥会失败。用 trap / finally 确保清理 SSHPASS 和模式变量。Permission denied,检查用户名、Key 是否复制到设备、文件权限、设备是否禁止 root 登录。Host key verification failed,先人工确认设备确实是自己的路由器,再处理 known_hosts,不要让 Agent 盲目删除记录。# SSH Key 模式:OpenCode 后续应该调用工具,而不是直接 ssh
openwrt-ssh ping
openwrt-ssh status
openwrt-ssh network
openwrt-ssh dns
openwrt-ssh proxy
openwrt-ssh subscriptions
openwrt-ssh plugin-status
openwrt-ssh plugin-config openclash
openwrt-ssh plugin-logs openclash
openwrt-ssh backup all
openwrt-ssh all
# sshpass 过渡模式:仅限真人已带外核对主机指纹并预置 known_hosts 后;
# wrapper 强制 StrictHostKeyChecking=yes,只用环境变量,不要用 sshpass -p 明文密码。
cleanup() { unset SSHPASS OPENWRT_USE_SSHPASS; }
trap cleanup EXIT HUP INT TERM
export OPENWRT_USE_SSHPASS=1
export SSHPASS='你的路由器密码'
openwrt-ssh ping
openwrt-ssh status
openwrt-ssh 是给 Agent 调用的包装器,不是唯一 SSH 工具。小白可以按使用者来选:真人排错用图形工具,Agent 排错用可脚本化工具,文件备份用 SFTP/SCP 工具。
ssh、scp、ssh-copy-id、~/.ssh/config,也是最适合 Agent 自动化的底层工具。SSHPASS 环境变量,不要用 sshpass -p 明文密码。plink -batch 适合脚本化,PuTTY 图形端适合真人排错。把工具放进本机后,OpenCode 的任务里就可以明确写:不要直接 ssh,只调用这个工具。SSH Key 模式会用 BatchMode=yes 快速失败;如果你明确启用 sshpass 模式,工具会通过 SSHPASS 环境变量完成密码登录。
给 OpenCode 的首次任务:
你不要直接 ssh,也不要把密码写进命令参数。只调用已经由真人校验 SHA-256、完整审阅并安装的 openwrt-ssh 工具。Mac/Linux 用 openwrt-ssh;Windows 在确认策略后,用仅该子进程生效的 powershell -NoProfile -ExecutionPolicy Bypass -File ~/bin/openwrt-ssh.ps1,不要持久修改 CurrentUser 或 LocalMachine 策略。如果我明确说当前用 sshpass,也必须确认真人已通过路由器本机界面或本地控制台带外核对主机指纹并预置 known_hosts;只读取 SSHPASS 环境变量,不要使用 sshpass -p。先运行 ping、status、plugin-status、subscriptions;定向日志必须点名一个插件,原始系统日志只由真人本地查看。如果 ping 失败,只解释 SSH Key、sshpass、Host openwrt-router、known_hosts、OpenWrt SSH 服务这几类原因,不要保存或猜测密码。如果建议维修插件,先 backup all,展示证据、影响、维护窗口和回滚方案,然后停止并等待我当次明确批准一个目标插件;你不得设置 OPENWRT_ALLOW_REPAIR 或自行运行 plugin-repair。工具仅尽力脱敏,任何输出分享前仍要人工检查。
在 macOS 上,把 openwrt-ssh 放进 ~/bin,再完成 SSH Key 和 openwrt-router Host 别名。之后 OpenCode 只需要运行 openwrt-ssh status 这类命令。
192.168.1.1。openwrt-ssh 工具并放到 ~/bin。/etc/dropbear/authorized_keys。这一步可能需要你手动输入一次路由器密码。~/.ssh/config 的 Host openwrt-router 别名。openwrt-ssh ping 和 openwrt-ssh status 验证 OpenCode 可直接调用工具。umask 077
mkdir -p ~/bin ~/.ssh && chmod 700 ~/.ssh
target="$HOME/bin/openwrt-ssh"
expected="6db3d0fa4a6ce52d221b7bc24c3e739c95f3eef362c83ad05d5b3cce69b5bb0a"
tmp="$(mktemp "$HOME/bin/openwrt-ssh.tmp.XXXXXX")"
trap 'rm -f "$tmp"' EXIT
curl --fail --location --proto '=https' --tlsv1.2 https://thinktank.1a1api.top/tools/openwrt-ssh/openwrt-ssh -o "$tmp"
actual="$(shasum -a 256 "$tmp" | awk '{print $1}')"
[ "$actual" = "$expected" ] || { echo 'SHA-256 mismatch' >&2; exit 1; }
cat "$tmp"
read -r -p '已完整审阅脚本,输入 yes 才安装:' confirm
[ "$confirm" = yes ] || exit 1
[ ! -e "$target" ] || cp -p "$target" "$target.bak.$(date +%Y%m%d-%H%M%S)"
chmod 700 "$tmp" && mv "$tmp" "$target"
trap - EXIT
case ":$PATH:" in *":$HOME/bin:"*) ;; *) echo 'export PATH="$HOME/bin:$PATH"' >> ~/.zshrc; export PATH="$HOME/bin:$PATH" ;; esac
# 安装后先人工核对路由器 IP 和 SSH 主机指纹,再创建专用 Key
ssh-keygen -t ed25519 -C "opencode-openwrt" -f ~/.ssh/openwrt_opencode
cat ~/.ssh/openwrt_opencode.pub | ssh root@192.168.1.1 "umask 077; mkdir -p /etc/dropbear; cat >> /etc/dropbear/authorized_keys; chmod 600 /etc/dropbear/authorized_keys"
openwrt-ssh ping
openwrt-ssh status
在 Windows 上,把 openwrt-ssh.ps1 放到 %USERPROFILE%\bin,再完成 SSH Key 和 openwrt-router Host 别名。之后 OpenCode 只需要运行这个 PowerShell 工具。
ssh -V,确认 Windows 已启用 OpenSSH Client。openwrt-ssh.ps1 工具并放到 %USERPROFILE%\bin。%USERPROFILE%\.ssh\openwrt_opencode。/etc/dropbear/authorized_keys。这一步可能需要你手动输入一次路由器密码。Host openwrt-router 写入 %USERPROFILE%\.ssh\config。openwrt-ssh.ps1 ping 和 openwrt-ssh.ps1 status 验证 OpenCode 可直接调用工具。ssh -V
$BinDir = Join-Path $env:USERPROFILE 'bin'
$Target = Join-Path $BinDir 'openwrt-ssh.ps1'
$Expected = 'dd0670e2f255f5679eda4270c73368bf6488d6c5a3e7e5763b3b2f532310a8b6'
New-Item -ItemType Directory -Force $BinDir | Out-Null
New-Item -ItemType Directory -Force "$env:USERPROFILE\.ssh" | Out-Null
$Tmp = Join-Path $BinDir ("openwrt-ssh.{0}.tmp.ps1" -f [guid]::NewGuid())
try {
Invoke-WebRequest -Uri 'https://thinktank.1a1api.top/tools/openwrt-ssh/openwrt-ssh.ps1' -OutFile $Tmp
$Actual = (Get-FileHash -Algorithm SHA256 $Tmp).Hash.ToLowerInvariant()
if ($Actual -ne $Expected) { throw 'SHA-256 mismatch' }
Get-Content $Tmp
if ((Read-Host '已完整审阅脚本,输入 yes 才安装') -ne 'yes') { throw 'Installation cancelled' }
if (Test-Path $Target) { Copy-Item $Target "$Target.bak.$(Get-Date -Format yyyyMMdd-HHmmss)" }
Move-Item -Force $Tmp $Target
} finally {
if (Test-Path $Tmp) { Remove-Item -Force $Tmp }
}
# 安装后先人工核对路由器 IP 和 SSH 主机指纹,再创建专用 Key
ssh-keygen -t ed25519 -C "opencode-openwrt" -f "$env:USERPROFILE\.ssh\openwrt_opencode"
type "$env:USERPROFILE\.ssh\openwrt_opencode.pub" | ssh root@192.168.1.1 "umask 077; mkdir -p /etc/dropbear; cat >> /etc/dropbear/authorized_keys; chmod 600 /etc/dropbear/authorized_keys"
# 先查看当前策略;Bypass 只对下面这个子进程生效,不要持久修改 CurrentUser / LocalMachine
Get-ExecutionPolicy -List
powershell -NoProfile -ExecutionPolicy Bypass -File $Target ping
if ($LASTEXITCODE -ne 0) { throw 'openwrt-ssh ping failed' }
powershell -NoProfile -ExecutionPolicy Bypass -File $Target status
if ($LASTEXITCODE -ne 0) { throw 'openwrt-ssh status failed' }
openwrt-ssh / openwrt-ssh.ps1 这类安全包装工具openwrt-ssh,不要把路由器密码贴进提示词。openwrt-ssh backup plugins,展示证据、影响、维护窗口和回滚方案并等待用户当次明确批准目标插件;Agent 不得设置 OPENWRT_ALLOW_REPAIR 或自行运行维修。