/rustdesk-doctor
诊断 RustDesk 连接问题。当用户说 RustDesk 连不上、无法远程、ID 不显示、注册失败时使用
$ npx -y skills add majiayu000/spellbook --skill rustdesk-doctor --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
- Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
- You can call itInvoke it directly when you want it.
- Slash command
/rustdesk-doctor
Context preview
The summary Claude sees to decide when to auto-load this skill.
诊断 RustDesk 连接问题。当用户说 RustDesk 连不上、无法远程、ID 不显示、注册失败时使用
SKILL.md
rustdesk-doctor.SKILL.mdname: rustdesk-doctor
description: 诊断 RustDesk 连接问题。当用户说 RustDesk 连不上、无法远程、ID 不显示、注册失败时使用
allowed-tools: Bash, Read, Edit, Write
metadata:
argument-hint: "[自建服务器IP,如 124.221.234.205]"
RustDesk 连接诊断工具
诊断 RustDesk 客户端无法连接服务器的问题,覆盖 Clash/TUN 代理干扰、服务器端配置、云安全组等常见根因。
用户传入的参数(如有):$ARGUMENTS
诊断流程
严格按以下步骤执行,每一步都要执行并记录结果,最后给出综合诊断。
第一步:采集客户端状态
**并行执行以下检查:**
1. **RustDesk 进程和网络连接**
ps aux | grep -i rustdesk | grep -v grep
echo "=== 网络连接 ==="
lsof -i -P -n 2>/dev/null | grep -i rustdesk
2. **RustDesk 配置文件**
CONFIG_DIR="$HOME/Library/Preferences/com.carriez.RustDesk"
echo "=== RustDesk2.toml ==="
cat "$CONFIG_DIR/RustDesk2.toml" 2>/dev/null || echo "文件不存在"
echo "=== RustDesk_local.toml ==="
cat "$CONFIG_DIR/RustDesk_local.toml" 2>/dev/null || echo "文件不存在"
3. **RustDesk 最新日志(关键行)**
LOG="$HOME/Library/Logs/RustDesk/RustDesk_rCURRENT.log"
cat "$LOG" 2>/dev/null || echo "日志不存在"
第二步:检查 Clash/代理干扰
**并行执行以下检查:**
1. **Mihomo 中 RustDesk 的连接和规则匹配**
SOCKET="/var/tmp/verge/verge-mihomo.sock"
if [ -S "$SOCKET" ]; then
curl -s --unix-socket "$SOCKET" http://localhost/connections 2>/dev/null | python3 -c "
import sys,json
data=json.load(sys.stdin)
conns=data.get('connections',[])
found=False
for c in conns:
meta=c.get('metadata',{})
proc=meta.get('process','').lower()
host=meta.get('host','').lower()
dst=meta.get('destinationIP','')
if 'rustdesk' in proc or 'rustdesk' in host or '21116' in meta.get('destinationPort','') or '21115' in meta.get('destinationPort',''):
chains=c.get('chains',[])
rule=c.get('rule','')
rp=c.get('rulePayload','')
net=meta.get('network','')
dp=meta.get('destinationPort','')
print(f'{meta.get(\"process\",\"\")} | {net} | {host or dst}:{dp} | rule={rule} {rp} | chains={chains}')
found=True
if not found:
print('Mihomo 中没有 RustDesk 相关连接')
"
else
echo "Mihomo unix socket 不存在,Clash 可能未运行"
fi2. **Mihomo 中 RustDesk 相关规则**
SOCKET="/var/tmp/verge/verge-mihomo.sock"
if [ -S "$SOCKET" ]; then
curl -s --unix-socket "$SOCKET" http://localhost/rules 2>/dev/null | python3 -c "
import sys,json
rules=json.load(sys.stdin).get('rules',[])
for r in rules:
p=str(r.get('payload','')).lower()
if 'rustdesk' in p:
print(f\"{r.get('type')},{r.get('payload')},{r.get('proxy')}\")
" || echo "无法获取规则"
echo "=== TUN 配置 ==="
curl -s --unix-socket "$SOCKET" http://localhost/configs 2>/dev/null | python3 -c "
import sys,json
c=json.load(sys.stdin)
tun=c.get('tun',{})
print('TUN enabled:', tun.get('enable'))
rea=tun.get('route-exclude-address',[])
if rea:
print('route-exclude-address:', rea)
"
fi3. **DNS 解析检查(fake-ip 检测)**
对 RustDesk 服务器域名进行 DNS 解析,检查是否返回 fake-ip (198.18.x.x):
# 如果配置了自建服务器(IP 地址),跳过域名解析
# 如果使用默认公共服务器,检查 rs-ny.rustdesk.com
nslookup rs-ny.rustdesk.com 2>&1
nslookup rustdesk.com 2>&1
4. **路由检查**
检查 RustDesk 服务器 IP 的路由走向(是否经过 TUN utun1024):
# 对配置中的服务器 IP 执行 route get
# 如果走 utun1024 → TUN 拦截
# 如果走 en0 → 直连
route -n get <服务器IP> 2>&1 | head -6
5. **Clash Verge profiles 中的 RustDesk 配置**
PROFILES_DIR="$HOME/Library/Application Support/io.github.clash-verge-rev.clash-verge-rev/profiles"
grep -ril "rustdesk" "$PROFILES_DIR/"*.yaml "$PROFILES_DIR/"*.js 2>/dev/null | while read f; do
echo "=== $(basename $f) ==="
grep -in "rustdesk" "$f"
done
第三步:网络连通性测试
**对配置中的服务器(自建或默认公共服务器)执行:**
SERVER="<服务器IP或域名>"
echo "=== TCP 21115 (NAT test) ==="
nc -z -w5 $SERVER 21115 2>&1 && echo "OK" || echo "FAIL"
echo "=== TCP 21116 (rendezvous) ==="
nc -z -w5 $SERVER 21116 2>&1 && echo "OK" || echo "FAIL"
echo "=== TCP 21117 (relay) ==="
nc -z -w5 $SERVER 21117 2>&1 && echo "OK" || echo "FAIL"
echo "=== UDP 21116 ==="
nc -z -w5 -u $SERVER 21116 2>&1 && echo "OK" || echo "FAIL(UDP 结果可能不准确)"
echo "=== 路由走向 ==="
route -n get $SERVER 2>&1 | head -6
第四步:服务器端检查(如可 SSH)
如果用户提供了自建服务器 IP 且可以 SSH,执行以下检查:
SERVER="<服务器IP>"
ssh -o ConnectTimeout=10 root@$SERVER "
echo '=== Docker 容器状态 ==='
docker ps | grep -i rust
echo '=== hbbs 日志(最后 20 行)==='
docker logs hbbs --tail 20 2>&1
echo '=== hbbr 日志(最后 10 行)==='
docker logs hbbr --tail 10 2>&1
echo '=== 端口监听 ==='
ss -ulnp | grep 21116
ss -tlnp | grep -E '2111[5-9]'
echo '=== 公钥 ==='
cat /root/id_ed25519.pub 2>/dev/null || find / -name 'id_ed25519.pub' 2>/dev/null | head -1 | xargs cat 2>/dev/null
echo '=== UFW 状态 ==='
ufw status 2>/dev/null | head -15
echo '=== 云安全组防火墙链 ==='
iptables -L INPUT -n 2>/dev/null | head -5
echo '=== 抓包测试(10秒)==='
timeout 10 tcpdump -i eth0 -c 5 udp port 21116 2>&1
"
第五步:local-ip-addr 检查
检查 RustDesk 是否把 TUN 网关 IP 当成了本机 IP:
CONFIG="$HOME/Library/Preferences/com.carriez.RustDesk/RustDesk2.toml"
LOCAL_IP=$(grep 'local-ip-addr' "$CONFIG" 2>/dev/null | awk -F"'" '{print $2}')
if [ "$LOCAL_IP" = "198.18.0.1" ]; then
echo "WARNING: local-ip-addr = 198.18.0.1 (TUN 网关假 IP)"
echo "RustDesk 启动时检测到 TUN 虚拟网卡 IP,需要在 TUN 关闭时启动 RustDesk"
REAL_IP=$(ifconfig en0 2>/dev/null | grep 'inet ' | awk '{print $2}')
echo "真实 IP 应该是: $REAL_IP"
elif [ -n "$LOCAL_IP" ]; then
echo "local-ip-addr = $LOCAL_IP"
else
echo "local-ip-addr 未设置(自动检测)"
fi综合诊断
根据采集到的所有信息,按以下判断矩阵分析:
常见问题判断矩阵
| 日志关键行 | 网络状态 | Clash 状态 | 诊断 | |-----------|---------|-----------|------| | `register_pk ... key not confirmed` 持续重试 | 端口不通 | 走 DIRECT | **TUN DIRECT UDP 转发异常或服务器不可达** | | `register_pk ... key not confirmed` 持续重试 | 端口通 | 走 Proxies | **代理节点不支持 RustDesk UDP 协议** | | `register_pk ... key not confirmed` + 服务器 tcpdump 零包 | SSH 通,其他端口不通 | - | **云安全组未放行 21115-21117/tcp 和 21116/udp** | | `Got nat response` 有回复但 `register_pk` 失败 | UDP 通,TCP 21115 不通 | 走 Proxies | **代理对裸 TCP 转发不完整,需加 IP-CIDR 规则** | | `Failed to connect to ...:21115` | TCP 不通 | - | **TCP 21115 被阻断(代理/防火墙/安全组)** | | `local-ip-addr = 198.18.0.1` | - | TUN 开启 | **TUN 假 IP 污染,关 TUN 重启 RustDesk 或清空该字段** | | `error sending request for url (https://api.rustde
Read more
name: rustdesk-doctor description: 诊断 RustDesk 连接问题。当用户说 RustDesk 连不上、无法远程、ID 不显示、注册失败时使用 allowed-tools: Bash, Read, Edit, Write metadata: argument-hint: "[自建服务器IP,如 124.221.234.205]"
RustDesk 连接诊断工具
诊断 RustDesk 客户端无法连接服务器的问题,覆盖 Clash/TUN 代理干扰、服务器端配置、云安全组等常见根因。
用户传入的参数(如有):$ARGUMENTS
诊断流程
严格按以下步骤执行,每一步都要执行并记录结果,最后给出综合诊断。
第一步:采集客户端状态
**并行执行以下检查:**
1. **RustDesk 进程和网络连接**
ps aux | grep -i rustdesk | grep -v grep echo "=== 网络连接 ===" lsof -i -P -n 2>/dev/null | grep -i rustdesk
2. **RustDesk 配置文件**
CONFIG_DIR="$HOME/Library/Preferences/com.carriez.RustDesk" echo "=== RustDesk2.toml ===" cat "$CONFIG_DIR/RustDesk2.toml" 2>/dev/null || echo "文件不存在" echo "=== RustDesk_local.toml ===" cat "$CONFIG_DIR/RustDesk_local.toml" 2>/dev/null || echo "文件不存在"
3. **RustDesk 最新日志(关键行)**
LOG="$HOME/Library/Logs/RustDesk/RustDesk_rCURRENT.log" cat "$LOG" 2>/dev/null || echo "日志不存在"
第二步:检查 Clash/代理干扰
**并行执行以下检查:**
1. **Mihomo 中 RustDesk 的连接和规则匹配**
SOCKET="/var/tmp/verge/verge-mihomo.sock"
if [ -S "$SOCKET" ]; then
curl -s --unix-socket "$SOCKET" http://localhost/connections 2>/dev/null | python3 -c "
import sys,json
data=json.load(sys.stdin)
conns=data.get('connections',[])
found=False
for c in conns:
meta=c.get('metadata',{})
proc=meta.get('process','').lower()
host=meta.get('host','').lower()
dst=meta.get('destinationIP','')
if 'rustdesk' in proc or 'rustdesk' in host or '21116' in meta.get('destinationPort','') or '21115' in meta.get('destinationPort',''):
chains=c.get('chains',[])
rule=c.get('rule','')
rp=c.get('rulePayload','')
net=meta.get('network','')
dp=meta.get('destinationPort','')
print(f'{meta.get(\"process\",\"\")} | {net} | {host or dst}:{dp} | rule={rule} {rp} | chains={chains}')
found=True
if not found:
print('Mihomo 中没有 RustDesk 相关连接')
"
else
echo "Mihomo unix socket 不存在,Clash 可能未运行"
fi2. **Mihomo 中 RustDesk 相关规则**
SOCKET="/var/tmp/verge/verge-mihomo.sock"
if [ -S "$SOCKET" ]; then
curl -s --unix-socket "$SOCKET" http://localhost/rules 2>/dev/null | python3 -c "
import sys,json
rules=json.load(sys.stdin).get('rules',[])
for r in rules:
p=str(r.get('payload','')).lower()
if 'rustdesk' in p:
print(f\"{r.get('type')},{r.get('payload')},{r.get('proxy')}\")
" || echo "无法获取规则"
echo "=== TUN 配置 ==="
curl -s --unix-socket "$SOCKET" http://localhost/configs 2>/dev/null | python3 -c "
import sys,json
c=json.load(sys.stdin)
tun=c.get('tun',{})
print('TUN enabled:', tun.get('enable'))
rea=tun.get('route-exclude-address',[])
if rea:
print('route-exclude-address:', rea)
"
fi3. **DNS 解析检查(fake-ip 检测)**
对 RustDesk 服务器域名进行 DNS 解析,检查是否返回 fake-ip (198.18.x.x):
# 如果配置了自建服务器(IP 地址),跳过域名解析 # 如果使用默认公共服务器,检查 rs-ny.rustdesk.com nslookup rs-ny.rustdesk.com 2>&1 nslookup rustdesk.com 2>&1
4. **路由检查**
检查 RustDesk 服务器 IP 的路由走向(是否经过 TUN utun1024):
# 对配置中的服务器 IP 执行 route get # 如果走 utun1024 → TUN 拦截 # 如果走 en0 → 直连 route -n get <服务器IP> 2>&1 | head -6
5. **Clash Verge profiles 中的 RustDesk 配置**
PROFILES_DIR="$HOME/Library/Application Support/io.github.clash-verge-rev.clash-verge-rev/profiles" grep -ril "rustdesk" "$PROFILES_DIR/"*.yaml "$PROFILES_DIR/"*.js 2>/dev/null | while read f; do echo "=== $(basename $f) ===" grep -in "rustdesk" "$f" done
第三步:网络连通性测试
**对配置中的服务器(自建或默认公共服务器)执行:**
SERVER="<服务器IP或域名>" echo "=== TCP 21115 (NAT test) ===" nc -z -w5 $SERVER 21115 2>&1 && echo "OK" || echo "FAIL" echo "=== TCP 21116 (rendezvous) ===" nc -z -w5 $SERVER 21116 2>&1 && echo "OK" || echo "FAIL" echo "=== TCP 21117 (relay) ===" nc -z -w5 $SERVER 21117 2>&1 && echo "OK" || echo "FAIL" echo "=== UDP 21116 ===" nc -z -w5 -u $SERVER 21116 2>&1 && echo "OK" || echo "FAIL(UDP 结果可能不准确)" echo "=== 路由走向 ===" route -n get $SERVER 2>&1 | head -6
第四步:服务器端检查(如可 SSH)
如果用户提供了自建服务器 IP 且可以 SSH,执行以下检查:
SERVER="<服务器IP>" ssh -o ConnectTimeout=10 root@$SERVER " echo '=== Docker 容器状态 ===' docker ps | grep -i rust echo '=== hbbs 日志(最后 20 行)===' docker logs hbbs --tail 20 2>&1 echo '=== hbbr 日志(最后 10 行)===' docker logs hbbr --tail 10 2>&1 echo '=== 端口监听 ===' ss -ulnp | grep 21116 ss -tlnp | grep -E '2111[5-9]' echo '=== 公钥 ===' cat /root/id_ed25519.pub 2>/dev/null || find / -name 'id_ed25519.pub' 2>/dev/null | head -1 | xargs cat 2>/dev/null echo '=== UFW 状态 ===' ufw status 2>/dev/null | head -15 echo '=== 云安全组防火墙链 ===' iptables -L INPUT -n 2>/dev/null | head -5 echo '=== 抓包测试(10秒)===' timeout 10 tcpdump -i eth0 -c 5 udp port 21116 2>&1 "
第五步:local-ip-addr 检查
检查 RustDesk 是否把 TUN 网关 IP 当成了本机 IP:
CONFIG="$HOME/Library/Preferences/com.carriez.RustDesk/RustDesk2.toml"
LOCAL_IP=$(grep 'local-ip-addr' "$CONFIG" 2>/dev/null | awk -F"'" '{print $2}')
if [ "$LOCAL_IP" = "198.18.0.1" ]; then
echo "WARNING: local-ip-addr = 198.18.0.1 (TUN 网关假 IP)"
echo "RustDesk 启动时检测到 TUN 虚拟网卡 IP,需要在 TUN 关闭时启动 RustDesk"
REAL_IP=$(ifconfig en0 2>/dev/null | grep 'inet ' | awk '{print $2}')
echo "真实 IP 应该是: $REAL_IP"
elif [ -n "$LOCAL_IP" ]; then
echo "local-ip-addr = $LOCAL_IP"
else
echo "local-ip-addr 未设置(自动检测)"
fi综合诊断
根据采集到的所有信息,按以下判断矩阵分析:
常见问题判断矩阵
| 日志关键行 | 网络状态 | Clash 状态 | 诊断 | |-----------|---------|-----------|------| | `register_pk ... key not confirmed` 持续重试 | 端口不通 | 走 DIRECT | **TUN DIRECT UDP 转发异常或服务器不可达** | | `register_pk ... key not confirmed` 持续重试 | 端口通 | 走 Proxies | **代理节点不支持 RustDesk UDP 协议** | | `register_pk ... key not confirmed` + 服务器 tcpdump 零包 | SSH 通,其他端口不通 | - | **云安全组未放行 21115-21117/tcp 和 21116/udp** | | `Got nat response` 有回复但 `register_pk` 失败 | UDP 通,TCP 21115 不通 | 走 Proxies | **代理对裸 TCP 转发不完整,需加 IP-CIDR 规则** | | `Failed to connect to ...:21115` | TCP 不通 | - | **TCP 21115 被阻断(代理/防火墙/安全组)** | | `local-ip-addr = 198.18.0.1` | - | TUN 开启 | **TUN 假 IP 污染,关 TUN 重启 RustDesk 或清空该字段** | | `error sending request for url (https://api.rustde
Cross-runtime skills for Claude Code, Codex, and multi-agent workflows.
Repo: majiayu000/spellbook
Other skills on spellbook.
- /agentsmd-optimize
Audit AND optimize a CLAUDE.md / AGENTS.md instruction file — score it against the five high-leverage patterns, flag anti-patterns, then apply approved fixes in place. Use when the user says 优化 CLAUDE.md / 优化 AGENTS.md / optimize my agent doc / 帮我改 claudemd, or after an audit
Open skill - /agentsmd-scaffold
Generate or update repository-specific AGENTS.md instruction files from real repo evidence. Use when asked to create, design, scaffold, split, or improve root or scoped AGENTS.md files for Codex/Claude/agent workflows, especially when a repo needs directory-specific rules,
Open skill - /api-design
REST/GraphQL/gRPC API design best practices. Use when designing APIs, defining contracts, handling versioning. Covers OpenAPI 3.2, GraphQL Federation, gRPC streaming.
Open skill - /app-ui-design
Mobile app UI design expert for iOS and Android. Use when designing app interfaces, creating design systems, ensuring accessibility, or following platform guidelines. Covers Material Design 3, Human Interface Guidelines, color theory, typography, and 2025 trends.
Open skill - /app-user-story-qa
End-to-end app feature inventory and user-story testing workflow with a canonical tracker. Use when the user asks to audit every feature, derive expected behavior from code, test user journeys, or explicitly fix and retest documented UX or logistical defects.
Open skill - /architecture-foundation
Design architecture foundations before implementation. Use when asked to design or refactor architecture, choose Rust/Go crate, package, module, runtime, workflow, or service boundaries, compare mature project architecture, prevent stacked one-off PRs, audit migration debt in
Open skill

