SuperAPI AI Directory

rustdesk-doctor

General & other

View repository

Updated 10-16 00:04

About this skill

RustDesk Connection Diagnostic Tool

Diagnose the issue of the RustDesk client being unable to connect to the server, covering common root causes such as Clash/TUN proxy interference, server-side configuration, and cloud security groups.

Parameters passed in by the user (if any): $ARGUMENTS

Diagnostic Process

Strictly follow the steps below, execute each step and record the results, and finally provide a comprehensive diagnosis.

Step 1: Collect client status

Execute the following checks in parallel:

  1. RustDesk process and network connections
ps aux | grep -i rustdesk | grep -v grep
echo "=== 网络连接 ==="
lsof -i -P -n 2>/dev/null | grep -i rustdesk
  1. RustDesk configuration file
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 "文件不存在"
  1. Latest RustDesk logs (key lines)
LOG="$HOME/Library/Logs/RustDesk/RustDesk_rCURRENT.log"
cat "$LOG" 2>/dev/null || echo "日志不存在"

Step 2: Check Clash/proxy interference

Execute the following checks in parallel:

  1. RustDesk connections and rule matching in Mihomo
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 可能未运行"
fi
  1. RustDesk-related rules in Mihomo
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)
"
fi
  1. DNS resolution check (fake-ip detection)

Perform DNS resolution on the RustDesk server domain and check whether it returns a fake-ip (198.18.x.x):

# 如果配置了自建服务器(IP 地址),跳过域名解析
# 如果使用默认公共服务器,检查 rs-ny.rustdesk.com
nslookup rs-ny.rustdesk.com 2>&1
nslookup rustdesk.com 2>&1
  1. Route check

Check the route of the RustDesk server IP (whether it goes through TUN utun1024):

# 对配置中的服务器 IP 执行 route get
# 如果走 utun1024 → TUN 拦截
# 如果走 en0 → 直连
route -n get <服务器IP> 2>&1 | head -6
  1. RustDesk configuration in Clash Verge profiles
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

Step 3: Network connectivity test

For the server in the configuration (self-hosted or default public server), execute:

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

Step 4: Server-side check (if SSH is available)

If the user provides a self-hosted server IP and SSH is available, execute the following checks:

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
"

Step 5: local-ip-addr check

Check whether RustDesk has mistaken the TUN gateway IP for the local 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

Comprehensive Diagnosis

Based on all the collected information, analyze according to the following judgment matrix:

Common Issue Judgment Matrix

Key log lines Network status Clash status Diagnosis
register_pk ... key not confirmed Continuous retries Port unreachable Goes through DIRECT TUN DIRECT UDP forwarding abnormal or server unreachable
register_pk ... key not confirmed Continuous retries Port reachable Goes through Proxies Proxy node does not support the RustDesk UDP protocol
register_pk ... key not confirmed + zero packets in server tcpdump SSH reachable, other ports unreachable - Cloud security group has not allowed 21115-21117/tcp and 21116/udp
Got nat response Has replies but register_pk fails UDP reachable, TCP 21115 unreachable Goes through Proxies Proxy forwarding of raw TCP is incomplete; an IP-CIDR rule needs to be added
Failed to connect to ...:21115 TCP unreachable - TCP 21115 is blocked (proxy/firewall/security group)
local-ip-addr = 198.18.0.1 - TUN enabled TUN fake IP contamination; disable TUN and restart RustDesk or clear this field
error sending request for url (https://api.rustdesk.com/...) HTTPS unreachable Goes through DIRECT The official RustDesk API is blocked and needs to go through a proxy
DNS resolution returns 198.18.x.x - fake-ip mode rustdesk.com needs to be added to fake-ip-filter or changed to +.rustdesk.com

Common Solutions

Solution A: DIRECT UDP unreachable in TUN mode

The DIRECT exit of TUN may not correctly forward UDP. Solution:

  1. Add route-exclude-address in Merge.yaml to make the server IP completely bypass TUN:
tun:
  route-exclude-address:
    - <服务器IP>/32
  1. Or make RustDesk traffic go through the proxy (delete the DIRECT rule in the subscription)

Solution B: The subscription configuration includes a rustdesk.com DIRECT rule

The subscription may include DOMAIN-SUFFIX,rustdesk.com,DIRECT. If you want it to go through the proxy:

In the delete section of the rules profile, add:

delete:
  - DOMAIN-SUFFIX,rustdesk.com,DIRECT

Solution C: The cloud security group does not have the port open

Security groups such as Tencent Cloud/Alibaba Cloud filter at the cloud platform level, and iptables and UFW cannot see it. You need to add it in the cloud console:

Protocol Port Source
TCP 21115-21117 0.0.0.0/0
UDP 21116 0.0.0.0/0

Solution D: local-ip-addr is polluted by the TUN fake IP

When RustDesk starts, it detects the network adapter IP, and in TUN mode it will get 198.18.0.1. Solution:

  1. Turn off TUN → start RustDesk (let it detect the real IP) → then turn on TUN
  2. Or manually clear RustDesk2.toml in local-ip-addr:
[options]
local-ip-addr = ''

Solution E: The proxy node does not support the RustDesk protocol

RustDesk uses UDP + raw TCP (not HTTP/TLS), and some proxy nodes do not support it. Solution:

  1. Switch to a proxy node that supports UDP
  2. For the raw TCP port (21115), you need to add an IP-CIDR rule so that Mihomo can route it:
prepend:
  - IP-CIDR,<服务器IP>/32,Proxies,no-resolve

RustDesk Port Description

Port Protocol Purpose
21114 TCP API / Web console (new version)
21115 TCP NAT type detection
21116 TCP+UDP Rendezvous server (registration, signaling)
21117 TCP Relay forwarding
21118 TCP WebSocket
21119 TCP WebSocket relay

Notes

  • All diagnostic operations are read-only and do not modify any configuration
  • Inform and confirm with the user before modifying the configuration
  • Confirm user authorization before SSHing to the server
  • Troubleshooting priority: cloud security group > proxy/TUN interference > server side > client configuration
  • Output all diagnostic information in Chinese