openclaw-twoway deployment
by @marshong-86
Deploy OpenClaw with a cloud gateway using Tailscale and SSH tunnel for secure local control, including auto environment check and firewall setup.
clawhub install openclaw-two-way-deployment๐ About This Skill
OpenClaw ไธ็ง้จ็ฝฒๆนๆกๅฎๆดๆ่ฝ
ๆ่ฝไฝฟ็จ่ฏดๆ
่ฟ่ก /openclaw-deploy ้ๆฉ้จ็ฝฒๆนๆก๏ผ่ชๅจๅฎๆ็ฏๅขๆฃๆตใ้ฒ็ซๅข้
็ฝฎใๆๅก้จ็ฝฒใ
ๆนๆกไธ๏ผไบ็ซฏ็ฝๅ ณ + Tailscale + SSH ้ง้ๆงๅถๆฌๅฐ
ๅฎๆดๆถๆๆต็จๅพ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ ไบ็ซฏๆๅกๅจ (Linux) โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ OpenClaw Gateway โ โ
โ โ โโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโ โ โ
โ โ โ ้้/้ฃไนฆ โ โ ๆ ธๅฟๅค็ โ โ AI ๆจกๅ API โ โ โ
โ โ โโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโ โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ SSH Server (22) Tailscale (:18789) โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โโโโโโโโโโโโโโโโโโโโโโโดโโโโโโโโโโโโโโโโโโโโโโ
โ Tailscale VPN (ๅ ๅฏ) โ
โ SSH ้ง้๏ผlocalhost:2222 โ :18789
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ ๆฌๅฐ็ต่ (Windows) โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ SSH Client (ๅๅฐ) OpenClaw CLI / VSCode โ โ
โ โ ่ฟๆฅ๏ผws://localhost:2222 โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โฒ
โ
โโโโโโโโโโโดโโโโโโโโโโ
โผ โผ
โโโโโโโโโโโโ โโโโโโโโโโโโ
โ ้้ APP โ โ ๆต่งๅจ โ
โโโโโโโโโโโโ โโโโโโโโโโโโ
ๆฐๆฎๆตๅ๏ผ 1. ้้/้ฃไนฆ โ Webhook โ ไบ็ซฏ็ฝๅ ณ (18789) 2. ไบ็ซฏ็ฝๅ ณ โ AI ๆจกๅ API โ ่ทๅๅๅค 3. ไบ็ซฏ็ฝๅ ณ โ Webhook โ ่ฟๅ้้/้ฃไนฆ 4. ๆฌๅฐ้่ฟ SSH ้ง้่ฎฟ้ฎไบ็ซฏ็ฝๅ ณ่ฟ่ก้ ็ฝฎ/็ๆง
้จ็ฝฒๅๆฃๆฅๆธ
ๅ
| ๆฃๆฅ้กน | ๆฌๅฐ | ไบ็ซฏ | ้ช่ฏๅฝไปค |
|--------|------|------|----------|
| Tailscale ่ดฆๅท | โ
ๅไธ่ดฆๅท | โ
ๅไธ่ดฆๅท | tailscale status |
| Tailscale ่ฟๆฅ | โ
ๅทฒ่ฟๆฅ | โ
ๅทฒ่ฟๆฅ | tailscale ip |
| Node.js (v18+) | โ
ๅทฒๅฎ่ฃ
| โ
ๅทฒๅฎ่ฃ
| node -v |
| SSH ๅฎขๆท็ซฏ | โ
ๅทฒ้
็ฝฎ | โ | ssh -V |
| SSH ๆๅก็ซฏ | โ | โ
ๅทฒ่ฟ่ก | systemctl status sshd |
| ้ฒ็ซๅข 18789 | โ | โ ๏ธ ้ๆพ่ก | ufw status / firewall-cmd --list-all |
| ้ฒ็ซๅข 22 | โ | โ ๏ธ ้ๆพ่ก | ufw status |
| ไบๅฎๅ
จ็ป 18789 | โ | โ ๏ธ ้ๆพ่ก | ไบๆงๅถๅฐๆฃๆฅ |
| ไบๅฎๅ
จ็ป 22 | โ | โ ๏ธ ้ๆพ่ก | ไบๆงๅถๅฐๆฃๆฅ |
ไบ็ซฏๅฎๆด้จ็ฝฒ่ๆฌ๏ผๅซ้ฒ็ซๅข + ๅฎๅ
จ็ปๆฃๆต๏ผ
bash
#!/bin/bash
plan1-cloud-gateway.sh - ๆนๆกไธ๏ผไบ็ซฏ็ฝๅ ณๅฎๆด้จ็ฝฒ
set -eecho "โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ" echo "โ ๆนๆกไธ๏ผไบ็ซฏ็ฝๅ ณ + Tailscale + SSH ้ง้ โ" echo "โ ไบ็ซฏ็ฝๅ ณๅฎๆด้จ็ฝฒ โ" echo "โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ"
============== 1. ็ณป็ป็ฏๅขๆฃๆต ==============
echo -e "\n[1/8] ็ณป็ป็ฏๅขๆฃๆต..."if [ -f /etc/os-release ]; then . /etc/os-release OS=$ID echo " ็ณป็ป๏ผ$OS ($PRETTY_NAME)" else echo " โ ๆ ๆณ่ฏๅซ็ณป็ป" exit 1 fi
if [ "$EUID" -ne 0 ]; then echo " โ ่ฏทไฝฟ็จ root ๆ้่ฟ่ก" exit 1 fi echo " โ ๆ้ๆฃๆฅ้่ฟ (root)"
ๆฃๆต SSH ๆๅก
if systemctl is-active --quiet sshd || systemctl is-active --quiet ssh; then echo " โ SSH ๆๅก๏ผ่ฟ่กไธญ" else echo " โ SSH ๆๅกๆช่ฟ่ก๏ผๆญฃๅจๅฏๅจ..." systemctl enable --now sshd 2>/dev/null || systemctl enable --now ssh 2>/dev/null || true fi============== 2. Tailscale ้ ็ฝฎ ==============
echo -e "\n[2/8] ้ ็ฝฎ Tailscale..."if ! command -v tailscale &> /dev/null; then echo " ๅฎ่ฃ Tailscale..." if [ "$OS" = "ubuntu" ] || [ "$OS" = "debian" ]; then curl -fsSL https://tailscale.com/install.sh | sh elif [ "$OS" = "centos" ] || [ "$OS" = "rhel" ] || [ "$OS" = "rocky" ]; then yum install -y yum-utils yum-config-manager --add-repo https://pkgs.tailscale.com/stable/centos/9/tailscale.repo yum install -y tailscale else echo " โ ไธๆฏๆ็็ณป็ป๏ผ่ฏทๆๅจๅฎ่ฃ ๏ผhttps://tailscale.com/download" exit 1 fi fi
systemctl enable --now tailscaled 2>/dev/null || tailscaled & sleep 3
if tailscale status 2>&1 | grep -q "connected"; then TAILSCALE_IP=$(tailscale ip | head -1) echo " โ Tailscale: ๅทฒ่ฟๆฅ ($TAILSCALE_IP)" else echo " โ Tailscale ๆช่ฟๆฅ" echo " ่ฏท่ฟ่กไปฅไธๅฝไปคๅฎๆ่ฎค่ฏ๏ผ" echo " tailscale up" AUTH_URL=$(tailscale up 2>&1 | grep -o 'https://login.tailscale.com/a/[a-zA-Z0-9]*' || echo "") if [ -n "$AUTH_URL" ]; then echo " ่ฎค่ฏ้พๆฅ๏ผ$AUTH_URL" fi read -p " ๅฎๆ่ฎค่ฏๅๆๅ่ฝฆ็ปง็ปญ..." TAILSCALE_IP=$(tailscale ip | head -1) echo " โ Tailscale: ๅทฒ่ฟๆฅ ($TAILSCALE_IP)" fi
============== 3. ้ฒ็ซๅข้ ็ฝฎ ==============
echo -e "\n[3/8] ้ ็ฝฎ้ฒ็ซๅข..."FIREWALL_CONFIGURED=false
UFW (Ubuntu/Debian)
if command -v ufw &> /dev/null; then echo " ๆฃๆตๅฐ UFW ้ฒ็ซๅข..." if ufw status | grep -q "Status: active"; then echo " UFW ๅทฒๅฏ็จ๏ผ้ ็ฝฎ่งๅ..." ufw allow 18789/tcp comment "OpenClaw Gateway" 2>/dev/null || ufw allow 18789/tcp ufw allow 22/tcp comment "SSH" 2>/dev/null || ufw allow 22/tcp ufw reload 2>/dev/null || true echo " โ UFW: 18789/tcp, 22/tcp ๅทฒๆพ่ก" FIREWALL_CONFIGURED=true else echo " UFW ๆชๅฏ็จ" fi fiFirewalld (CentOS/RHEL)
if [ "$FIREWALL_CONFIGURED" = false ] && command -v firewall-cmd &> /dev/null; then echo " ๆฃๆตๅฐ Firewalld..." if systemctl is-active --quiet firewalld; then echo " Firewalld ่ฟ่กไธญ๏ผ้ ็ฝฎ่งๅ..." firewall-cmd --permanent --add-port=18789/tcp 2>/dev/null || true firewall-cmd --permanent --add-service=ssh 2>/dev/null || true firewall-cmd --reload 2>/dev/null || true echo " โ Firewalld: 18789/tcp, ssh ๅทฒๆพ่ก" FIREWALL_CONFIGURED=true else echo " Firewalld ๆช่ฟ่ก" fi fiiptables (้็จ)
if [ "$FIREWALL_CONFIGURED" = false ] && command -v iptables &> /dev/null; then echo " ๆฃๆตๅฐ iptables..." if ! iptables -L INPUT -n 2>/dev/null | grep -q "dpt:18789"; then iptables -I INPUT -p tcp --dport 18789 -j ACCEPT 2>/dev/null || true iptables -I INPUT -p tcp --dport 22 -j ACCEPT 2>/dev/null || true echo " โ iptables: 18789/tcp, 22/tcp ๅทฒๆทปๅ " FIREWALL_CONFIGURED=true else echo " ็ซฏๅฃ่งๅๅทฒๅญๅจ" fi fiif [ "$FIREWALL_CONFIGURED" = false ]; then echo " โน ๆชๆฃๆตๅฐ้ฒ็ซๅขๅทฅๅ ท" fi
echo " โ ้่ฆ๏ผๅฆไฝฟ็จไบๆๅกๅจ (้ฟ้ไบ/่ พ่ฎฏไบ/AWS ็ญ)๏ผ่ฏท็กฎไฟไบๆงๅถๅฐๅฎๅ จ็ปๅทฒๆพ่ก๏ผ" echo " - 18789/tcp (Tailscale IP: $TAILSCALE_IP)" echo " - 22/tcp (SSH)"
============== 4. Node.js ้ ็ฝฎ ==============
echo -e "\n[4/8] ้ ็ฝฎ Node.js ็ฏๅข..."if command -v node &> /dev/null; then NODE_VER=$(node -v) echo " โ Node.js ๅทฒๅฎ่ฃ ๏ผ$NODE_VER" else echo " ๅฎ่ฃ Node.js 22..." if [ "$OS" = "ubuntu" ] || [ "$OS" = "debian" ]; then curl -fsSL https://deb.nodesource.com/setup_22.x | bash - apt-get install -y nodejs elif [ "$OS" = "centos" ] || [ "$OS" = "rhel" ] || [ "$OS" = "rocky" ]; then curl -fsSL https://rpm.nodesource.com/setup_22.x | bash - yum install -y nodejs else echo " โ ไธๆฏๆ็็ณป็ป๏ผ่ฏทๆๅจๅฎ่ฃ Node.js" exit 1 fi echo " โ Node.js ๅฎ่ฃ ๅฎๆ๏ผ$(node -v)" fi
npm config set registry https://registry.npmmirror.com 2>/dev/null || true
============== 5. OpenClaw ๅฎ่ฃ ==============
echo -e "\n[5/8] ๅฎ่ฃ OpenClaw..."if command -v openclaw &> /dev/null; then echo " โ OpenClaw ๅทฒๅฎ่ฃ " openclaw --version else echo " ๅฎ่ฃ OpenClaw..." npm install -g openclaw echo " โ OpenClaw ๅฎ่ฃ ๅฎๆ" fi
============== 6. ็ฝๅ ณ้ ็ฝฎ ==============
echo -e "\n[6/8] ้ ็ฝฎ OpenClaw ็ฝๅ ณ..."mkdir -p ~/.openclaw
cat > ~/.openclaw/openclaw.json << 'EOF' { "gateway": { "port": 18789, "mode": "local", "bind": "lan" } } EOF
echo " โ ้ ็ฝฎๆไปถ๏ผ~/.openclaw/openclaw.json"
============== 7. systemd ๆๅก้ ็ฝฎ ==============
echo -e "\n[7/8] ๅๅปบ systemd ๆๅก..."cat > /etc/systemd/system/openclaw-gateway.service << 'EOF' [Unit] Description=OpenClaw Gateway Service After=network.target tailscaled.service Wants=tailscaled.service
[Service] Type=simple User=root WorkingDirectory=/root/.openclaw ExecStart=/usr/bin/node /usr/lib/node_modules/openclaw/dist/index.js gateway --port 18789 --bind lan Restart=always RestartSec=5 StartLimitBurst=3 StartLimitIntervalSec=300
Environment=NODE_ENV=production
่ตๆบ้ๅถ
LimitNOFILE=65535 Nice=-5 OOMScoreAdjust=-500[Install] WantedBy=multi-user.target EOF
echo " โ systemd ๆๅก้ ็ฝฎๅฎๆ"
============== 8. ๅฏๅจๆๅก ==============
echo -e "\n[8/8] ๅฏๅจๆๅก..."systemctl daemon-reload systemctl enable openclaw-gateway systemctl start openclaw-gateway
echo " ็ญๅพ ๆๅกๅฏๅจ..." sleep 5
============== ้ช่ฏ ==============
echo -e "\nโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ" if systemctl is-active --quiet openclaw-gateway; then echo "โ โ ้จ็ฝฒๆๅ โ" echo "โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ"echo -e "\nใๆๅกไฟกๆฏใ" echo " ๆๅก็ถๆ๏ผ$(systemctl is-active openclaw-gateway)" echo " ๅผๆบ่ชๅฏ๏ผ$(systemctl is-enabled openclaw-gateway)"
echo -e "\nใ็ฝ็ปไฟกๆฏใ" echo " Tailscale IP: $TAILSCALE_IP" echo " ็ฝๅ ณๅฐๅ๏ผws://${TAILSCALE_IP}:18789" echo " ๆงๅถ้ขๆฟ๏ผhttp://${TAILSCALE_IP}:18789/"
echo -e "\nใ็ซฏๅฃ็ๅฌใ" ss -tlnp | grep 18789 || netstat -tlnp | grep 18789 || true
echo -e "\nใไธไธๆญฅๆไฝใ" echo " 1. ๅจๆฌๅฐ็ต่่ฟ่ก SSH ้ง้่ๆฌ (start-tunnel.ps1)" echo " 2. ๆๅจๆฌๅฐ้ ็ฝฎ่ฟ็จ็ฝๅ ณ๏ผopenclaw gateway remote set ws://${TAILSCALE_IP}:18789" echo " 3. ๆฅ็ๆฅๅฟ๏ผjournalctl -u openclaw-gateway -f"
echo -e "\nใๆฌๅฐ SSH ้ง้่ๆฌใ" echo " ๅจๆฌๅฐ PowerShell ่ฟ่ก๏ผ" echo " ssh -N -f -L 2222:${TAILSCALE_IP}:18789 root@${TAILSCALE_IP}" else echo "โ โ ้จ็ฝฒๅคฑ่ดฅ โ" echo "โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ" echo -e "\nใ้่ฏฏๆฅๅฟใ" journalctl -u openclaw-gateway --no-pager -n 20 exit 1 fi
ๆฌๅฐ SSH ้ง้่ๆฌ๏ผๆไน
่ฟ่ก + ๅผๆบ่ชๅฏ๏ผ
powershell
plan1-local-tunnel.ps1 - ๆนๆกไธ๏ผๆฌๅฐ SSH ้ง้ๆไน ้จ็ฝฒ
param( [string]$CloudIP = "" )$ErrorActionPreference = "Stop" $TaskName = "OpenClaw-SSH-Tunnel" $LocalPort = 2222 $RemotePort = 18789 $ScriptDir = "$env:USERPROFILE\.openclaw"
Write-Host "โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ" -ForegroundColor Cyan Write-Host "โ ๆนๆกไธ๏ผไบ็ซฏ็ฝๅ ณ + Tailscale + SSH ้ง้ โ" -ForegroundColor Cyan Write-Host "โ ๆฌๅฐ SSH ้ง้ๆไน ้จ็ฝฒ โ" Write-Host "โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ" -ForegroundColor Cyan
1. ๆฃๆฅ Tailscale
Write-Host "n[1/6] ๆฃๆฅ Tailscale..." -ForegroundColor Yellow
try {
$tsStatus = tailscale status 2>&1
if ($LASTEXITCODE -eq 0) {
$tsIP = (tailscale ip | Select-Object -First 1).Trim()
Write-Host " โ Tailscale: ๅทฒ่ฟๆฅ ($tsIP)" -ForegroundColor Green
} else {
Write-Host " Tailscale ๆช่ฟ่ก๏ผๆญฃๅจๅฏๅจ..." -ForegroundColor Yellow
tailscale up
Start-Sleep -Seconds 5
}
} catch {
Write-Host " โ Tailscale ๆชๅฎ่ฃ
" -ForegroundColor Red
Write-Host " ไธ่ฝฝ๏ผhttps://tailscale.com/download" -ForegroundColor Yellow
exit 1
}2. ่ทๅไบ็ซฏ IP
Write-Host "n[2/6] ้
็ฝฎไบ็ซฏ็ฝๅ
ณ..." -ForegroundColor Yellow
if ($CloudIP -eq "") {
Write-Host " ่ฏท่พๅ
ฅไบ็ซฏ็ฝๅ
ณ Tailscale IP:" -ForegroundColor Yellow
$CloudIP = Read-Host " Cloud IP"
if ($CloudIP -eq "") {
Write-Host " โ ๆช่พๅ
ฅ IP ๅฐๅ" -ForegroundColor Red
exit 1
}
}
Write-Host " ไบ็ซฏ็ฝๅ
ณ๏ผ$CloudIP:$RemotePort" -ForegroundColor Green3. ๆต่ฏ่ฟๆฅ
Write-Host "n[3/6] ๆต่ฏไบ็ซฏ่ฟๆฅ..." -ForegroundColor Yellow
$testResult = Test-NetConnection -ComputerName $CloudIP -Port $RemotePort -WarningAction SilentlyContinue -InformationLevel Quiet
if ($testResult) {
Write-Host " โ ไบ็ซฏ็ฝๅ
ณ๏ผๅฏ่พพ" -ForegroundColor Green
} else {
Write-Host " โ ๆ ๆณ่ฟๆฅไบ็ซฏ็ฝๅ
ณ" -ForegroundColor Red
Write-Host " ่ฏทๆฃๆฅ๏ผ" -ForegroundColor Yellow
Write-Host " 1. ไบ็ซฏ Tailscale ๆฏๅฆ่ฟ่ก" -ForegroundColor Yellow
Write-Host " 2. ไบ็ซฏ็ฝๅ
ณๆๅกๆฏๅฆๅฏๅจ" -ForegroundColor Yellow
Write-Host " 3. ไบๅฎๅ
จ็ปๆฏๅฆๆพ่ก 18789" -ForegroundColor Yellow
exit 1
}4. ๆธ
็ๆง้ง้
Write-Host "n[4/6] ๆธ
็ๆง้ง้่ฟ็จ..." -ForegroundColor Yellow
$sshProcesses = Get-Process | Where-Object { $_.ProcessName -eq "ssh" }
$stopped = 0
foreach ($p in $sshProcesses) {
$cmd = (Get-CimInstance Win32_Process -Filter "ProcessId = $($p.Id)" -ErrorAction SilentlyContinue).CommandLine
if ($cmd -like "*${LocalPort}*" -or $cmd -like "*${CloudIP}*") {
Stop-Process -Id $p.Id -Force -ErrorAction SilentlyContinue
$stopped++
}
}
Write-Host " ๅทฒๅๆญข $stopped ไธชๆง้ง้่ฟ็จ" -ForegroundColor Gray5. ๅๅปบๆไน ๅ่ๆฌ
Write-Host "n[5/6] ๅๅปบๆไน
ๅ้
็ฝฎ..." -ForegroundColor YellowNew-Item -ItemType Directory -Force -Path $ScriptDir | Out-Null
$tunnelScript = @"
OpenClaw SSH ้ง้ๅฏๅจ่ๆฌ
$ErrorActionPreference = "SilentlyContinue"
$sshArgs = "-N -L ${LocalPort}:${CloudIP}:${RemotePort} root@${CloudIP}"ๆฃๆฅ SSH ่ฟๆฅ
while ($true) {
Start-Process ssh -ArgumentList $sshArgs -WindowStyle Hidden -ErrorAction SilentlyContinue
Start-Sleep -Seconds 60 # ๆฃๆฅ้ง้ๆฏๅฆ้็
$test = Test-NetConnection -ComputerName localhost -Port ${LocalPort} -WarningAction SilentlyContinue -InformationLevel Quiet
if (-not $test) {
# ้ง้ๆญๅผ๏ผ้ๅฏ SSH ่ฟ็จ
Get-Process | Where-Object { $_.ProcessName -eq "ssh" -and $_.CommandLine -like "*${LocalPort}*" } | Stop-Process -Force
}
}
"@$scriptPath = "$ScriptDir\start-ssh-tunnel.ps1"
$tunnelScript | Out-File -FilePath $scriptPath -Encoding utf8 -Force
Write-Host " โ ้ง้่ๆฌ๏ผ$scriptPath" -ForegroundColor Green
6. ๅๅปบ่ฎกๅไปปๅก๏ผๅผๆบ่ชๅฏ๏ผ
Write-Host "n[6/6] ๅๅปบ่ฎกๅไปปๅก๏ผๅผๆบ่ชๅฏ๏ผ..." -ForegroundColor Yellowๅ ้คๆงไปปๅก
schtasks /Delete /TN $TaskName /F 2>$null | Out-Nullๅๅปบๆฐไปปๅก๏ผ็ณป็ปๅฏๅจๆถ + ็จๆท็ปๅฝๆถ๏ผ
$argument = "-ExecutionPolicy Bypass -WindowStyle Hidden -File"$scriptPath""
schtasks /Create /TN $TaskName /TR "powershell.exe $argument" /SC ONLOGON /RU SYSTEM /F 2>$nullif ($LASTEXITCODE -eq 0) { Write-Host " โ ่ฎกๅไปปๅก๏ผ$TaskName (ๅผๆบ่ชๅฏ)" -ForegroundColor Green } else { # ้็บงๆนๆก๏ผๅฝๅ็จๆท็ปๅฝๆถๅฏๅจ schtasks /Create /TN $TaskName /TR "powershell.exe $argument" /SC ONLOGON /F 2>$null if ($LASTEXITCODE -eq 0) { Write-Host " โ ่ฎกๅไปปๅก๏ผ$TaskName (็จๆท็ปๅฝ่ชๅฏ)" -ForegroundColor Green } else { Write-Host " โ ่ฎกๅไปปๅกๅๅปบๅคฑ่ดฅ๏ผๅฐๆๅจๅฏๅจ" -ForegroundColor Yellow } }
็ซๅณๅฏๅจ้ง้
Write-Host "n ็ซๅณๅฏๅจ SSH ้ง้..." -ForegroundColor Yellow
$sshArgs = "-N -L ${LocalPort}:${CloudIP}:${RemotePort} root@${CloudIP}"
Start-Process ssh -ArgumentList $sshArgs -WindowStyle HiddenStart-Sleep -Seconds 3
้ช่ฏ
$tunnelTest = Test-NetConnection -ComputerName localhost -Port $LocalPort -WarningAction SilentlyContinue -InformationLevel Quiet
if ($tunnelTest) {
Write-Host " โ SSH ้ง้๏ผๅทฒๅปบ็ซ (localhost:${LocalPort} -> ${CloudIP}:${RemotePort})" -ForegroundColor Green Write-Host "
nโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ" -ForegroundColor Cyan
Write-Host "โ โ ้จ็ฝฒๆๅ โ" -ForegroundColor Green
Write-Host "โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ" -ForegroundColor Cyan Write-Host "nใ้ง้ไฟกๆฏใ"
Write-Host " ๆฌๅฐ็ซฏๅฃ๏ผlocalhost:${LocalPort}"
Write-Host " ่ฟ็จๅฐๅ๏ผ${CloudIP}:${RemotePort}"
Write-Host " ่ฎกๅไปปๅก๏ผ$TaskName (ๅผๆบ/็ปๅฝ่ชๅฏ)"
Write-Host "nใไธไธๆญฅๆไฝใ" Write-Host " 1. ้ ็ฝฎ่ฟ็จ็ฝๅ ณ๏ผopenclaw gateway remote set ws://localhost:${LocalPort}" Write-Host " 2. ๆฃๆฅ็ถๆ๏ผopenclaw status" Write-Host " 3. ๆฅ็ๆฅๅฟ๏ผopenclaw logs --follow" } else { Write-Host " โ SSH ้ง้ๅปบ็ซๅคฑ่ดฅ" -ForegroundColor Red Write-Host " ่ฏทๆฃๆฅ SSH ๅฏ้ฅ้ ็ฝฎๆๆๅจ่ฟ่ก๏ผ" -ForegroundColor Yellow Write-Host " ssh -N -L ${LocalPort}:${CloudIP}:${RemotePort} root@${CloudIP}" exit 1 }
ๆนๆกไบ๏ผไบ็ซฏ็ฝๅ
ณ + Tailscale + ๆฌๅฐ่็น
ๅฎๆดๆถๆๆต็จๅพ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ ไบ็ซฏๆๅกๅจ (Linux) โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ OpenClaw Gateway (Remote ๆจกๅผ) โ โ
โ โ โโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโ โ โ
โ โ โ ้้/้ฃไนฆ โ โ WebSocket โ โ AI ๆจกๅ API โ โ โ
โ โ โ Webhook โ โ ๆๅก็ซฏ โ โ โ โ โ
โ โ โโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโ โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ Tailscale:
ๆฐๆฎๆตๅ๏ผ
1. ้้/้ฃไนฆ โ Webhook โ ไบ็ซฏ็ฝๅ
ณ
2. ไบ็ซฏ็ฝๅ
ณ โ WebSocket โ ๆฌๅฐ่็น
3. ๆฌๅฐ่็น โ ๆง่กไปปๅก โ ่ฟๅ็ปๆ โ ไบ็ซฏ็ฝๅ
ณ
4. ไบ็ซฏ็ฝๅ
ณ โ AI ๆจกๅ API โ ่ทๅๅๅค โ ่ฟๅ้้/้ฃไนฆ
้จ็ฝฒๅๆฃๆฅๆธ ๅ
| ๆฃๆฅ้กน | ๆฌๅฐ | ไบ็ซฏ | ้ช่ฏๅฝไปค |
|--------|------|------|----------|
| Tailscale ่ดฆๅท | โ
ๅไธ่ดฆๅท | โ
ๅไธ่ดฆๅท | tailscale status |
| Tailscale ่ฟๆฅ | โ
ๅทฒ่ฟๆฅ | โ
ๅทฒ่ฟๆฅ | tailscale ip |
| Node.js (v18+) | โ
ๅทฒๅฎ่ฃ
| โ
ๅทฒๅฎ่ฃ
| node -v |
| ้ฒ็ซๅข 18789 | โ | โ ๏ธ ้ๆพ่ก | ufw status |
| ไบๅฎๅ
จ็ป 18789 | โ | โ ๏ธ ้ๆพ่ก | ไบๆงๅถๅฐๆฃๆฅ |
| Token ้
็ฝฎ | โ
ไธ่ด | โ
ไธ่ด | ๆฃๆฅ้
็ฝฎๆไปถ |
ไบ็ซฏๅฎๆด้จ็ฝฒ่ๆฌ๏ผRemote ๆจกๅผ + Token ่ฎค่ฏ๏ผ
#!/bin/bash
plan2-cloud-remote-gateway.sh - ๆนๆกไบ๏ผไบ็ซฏ่ฟ็จ็ฝๅ
ณๅฎๆด้จ็ฝฒ
set -eecho "โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ"
echo "โ ๆนๆกไบ๏ผไบ็ซฏ็ฝๅ
ณ + Tailscale + ๆฌๅฐ่็น โ"
echo "โ ไบ็ซฏ่ฟ็จ็ฝๅ
ณ้จ็ฝฒ (Remote ๆจกๅผ) โ"
echo "โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ"
============== 1. ็ณป็ป็ฏๅขๆฃๆต ==============
echo -e "\n[1/7] ็ณป็ป็ฏๅขๆฃๆต..."if [ -f /etc/os-release ]; then
. /etc/os-release
OS=$ID
echo " ็ณป็ป๏ผ$OS ($PRETTY_NAME)"
else
echo " โ ๆ ๆณ่ฏๅซ็ณป็ป"
exit 1
fi
if [ "$EUID" -ne 0 ]; then
echo " โ ่ฏทไฝฟ็จ root ๆ้่ฟ่ก"
exit 1
fi
echo " โ ๆ้ๆฃๆฅ้่ฟ (root)"
============== 2. Tailscale ้
็ฝฎ ==============
echo -e "\n[2/7] ้
็ฝฎ Tailscale..."if ! command -v tailscale &> /dev/null; then
echo " ๅฎ่ฃ
Tailscale..."
if [ "$OS" = "ubuntu" ] || [ "$OS" = "debian" ]; then
curl -fsSL https://tailscale.com/install.sh | sh
else
echo " โ ไธๆฏๆ็็ณป็ป๏ผ่ฏทๆๅจๅฎ่ฃ
"
exit 1
fi
fi
systemctl enable --now tailscaled 2>/dev/null || tailscaled &
sleep 3
if tailscale status 2>&1 | grep -q "connected"; then
TAILSCALE_IP=$(tailscale ip | head -1)
echo " โ Tailscale: ๅทฒ่ฟๆฅ ($TAILSCALE_IP)"
else
echo " โ Tailscale ๆช่ฟๆฅ"
echo " ่ฟ่ก๏ผtailscale up"
read -p " ๅฎๆๅๆๅ่ฝฆ..."
TAILSCALE_IP=$(tailscale ip | head -1)
fi
============== 3. ้ฒ็ซๅข้
็ฝฎ ==============
echo -e "\n[3/7] ้
็ฝฎ้ฒ็ซๅข..."if command -v ufw &> /dev/null && ufw status | grep -q "Status: active"; then
ufw allow 18789/tcp comment "OpenClaw Gateway"
echo " โ UFW: 18789/tcp ๅทฒๆพ่ก"
elif command -v firewall-cmd &> /dev/null && systemctl is-active --quiet firewalld; then
firewall-cmd --permanent --add-port=18789/tcp
firewall-cmd --reload
echo " โ Firewalld: 18789/tcp ๅทฒๆพ่ก"
fi
echo " โ ไบๆๅกๅจๅฎๅ
จ็ป้ๆๅจๆพ่ก 18789 (Tailscale IP: $TAILSCALE_IP)"
============== 4. Node.js ้
็ฝฎ ==============
echo -e "\n[4/7] ้
็ฝฎ Node.js..."if ! command -v node &> /dev/null; then
echo " ๅฎ่ฃ
Node.js 22..."
if [ "$OS" = "ubuntu" ] || [ "$OS" = "debian" ]; then
curl -fsSL https://deb.nodesource.com/setup_22.x | bash -
apt-get install -y nodejs
else
echo " โ ไธๆฏๆ็็ณป็ป"
exit 1
fi
fi
echo " โ Node.js: $(node -v)"
npm config set registry https://registry.npmmirror.com 2>/dev/null || true
============== 5. OpenClaw ๅฎ่ฃ
==============
echo -e "\n[5/7] ๅฎ่ฃ
OpenClaw..."npm install -g openclaw
echo " โ OpenClaw: ๅทฒๅฎ่ฃ
"
============== 6. ็ๆ Token ==============
echo -e "\n[6/7] ็ๆ่ฎค่ฏ Token..."TOKEN=$(openssl rand -hex 20)
echo " โ Token: $TOKEN"
echo " โ ่ฏทไฟๅญๆญค Token๏ผๆฌๅฐ่็น้
็ฝฎ้่ฆ"
============== 7. ้
็ฝฎ็ฝๅ
ณ + systemd ==============
echo -e "\n[7/7] ้
็ฝฎ็ฝๅ
ณ (Remote ๆจกๅผ)..."mkdir -p ~/.openclaw
cat > ~/.openclaw/openclaw.json << EOF
{
"gateway": {
"port": 18789,
"mode": "remote",
"bind": "lan",
"auth": {
"mode": "token",
"token": "$TOKEN"
}
},
"security": {
"dangerouslyAllowInsecurePrivateWs": true
}
}
EOF
echo " โ ้
็ฝฎๆไปถ๏ผ~/.openclaw/openclaw.json"
echo -e "\n ๅๅปบ systemd ๆๅก..."
cat > /etc/systemd/system/openclaw-gateway.service << 'EOF'
[Unit]
Description=OpenClaw Gateway (Remote Mode)
After=network.target tailscaled.service
Wants=tailscaled.service
[Service]
Type=simple
User=root
WorkingDirectory=/root/.openclaw
ExecStart=/usr/bin/node /usr/lib/node_modules/openclaw/dist/index.js gateway --port 18789 --bind lan --allow-unconfigured
Restart=on-failure
RestartSec=10
StartLimitBurst=3
StartLimitIntervalSec=300
Environment=NODE_ENV=production
Environment=OPENCLAW_ALLOW_INSECURE_PRIVATE_WS=1
LimitNOFILE=65535
Nice=-5
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
systemctl enable openclaw-gateway
systemctl start openclaw-gateway
sleep 5
============== ้ช่ฏ ==============
echo -e "\nโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ"
if systemctl is-active --quiet openclaw-gateway; then
echo "โ โ ้จ็ฝฒๆๅ โ"
echo "โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ" echo -e "\nใๆๅกไฟกๆฏใ"
echo " ๆๅก็ถๆ๏ผ$(systemctl is-active openclaw-gateway)"
echo " ่ฟ่กๆจกๅผ๏ผremote"
echo " ่ฎค่ฏๆนๅผ๏ผtoken"
echo -e "\nใ็ฝ็ปไฟกๆฏใ"
echo " Tailscale IP: $TAILSCALE_IP"
echo " ็ฝๅ
ณๅฐๅ๏ผws://${TAILSCALE_IP}:18789"
echo " Token: $TOKEN"
echo -e "\nใ็ซฏๅฃ็ๅฌใ"
ss -tlnp | grep 18789 || true
echo -e "\nใๆฌๅฐ่็น้
็ฝฎ็คบไพ (PowerShell)ใ"
cat << POWERSHELL
$config = @{
gateway = @{
mode = "remote"
auth = @{ token = "$TOKEN" }
remote = @{ url = "ws://${TAILSCALE_IP}:18789" }
}
} | ConvertTo-Json | Out-File ~/.openclaw/openclaw.json -Encoding utf8
POWERSHELL
echo -e "\nใไธไธๆญฅๆไฝใ"
echo " 1. ๅจๆฌๅฐ่ฟ่ก plan2-local-node.ps1"
echo " 2. ๆฃๆฅ่ฟๆฅ๏ผopenclaw status"
echo " 3. ๆฅ็ๆฅๅฟ๏ผjournalctl -u openclaw-gateway -f"
else
echo "โ โ ้จ็ฝฒๅคฑ่ดฅ โ"
echo "โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ"
journalctl -u openclaw-gateway --no-pager -n 20
exit 1
fi
ๆฌๅฐ่็นๅฎๆด้จ็ฝฒ่ๆฌ
# plan2-local-node.ps1 - ๆนๆกไบ๏ผๆฌๅฐ่็นๅฎๆด้จ็ฝฒ param( [string]$CloudIP = "", [string]$Token = "" )n[1/6] ๆฃๆฅ Tailscale..." -ForegroundColor Yellow $tsStatus = tailscale status 2>&1 if ($LASTEXITCODE -ne 0) { Write-Host " Tailscale ๆช่ฟ่ก๏ผๆญฃๅจๅฏๅจ..." -ForegroundColor Yellow tailscale up Start-Sleep -Seconds 5 } $tsIP = (tailscale ip | Select-Object -First 1).Trim() Write-Host " โ Tailscale IP: $tsIP" -ForegroundColor Green$ErrorActionPreference = "Stop" $OpenClawDir = "$env:USERPROFILE\.openclaw" $NodeExe = "C:\Program Files\nodejs\node.exe" $OpenClawMjs = "$env:APPDATA\npm\node_modules\openclaw\openclaw.mjs" $TaskName = "OpenClaw-Node"
Write-Host "โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ" -ForegroundColor Cyan Write-Host "โ ๆนๆกไบ๏ผไบ็ซฏ็ฝๅ ณ + Tailscale + ๆฌๅฐ่็น โ" -ForegroundColor Cyan Write-Host "โ ๆฌๅฐ่็นๅฎๆด้จ็ฝฒ โ" Write-Host "โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ" -ForegroundColor Cyan
1. ๆฃๆฅ Tailscale
Write-Host "2. ๆฃๆฅ Node.js
Write-Host "n[2/6] ๆฃๆฅ Node.js..." -ForegroundColor Yellow if (!(Test-Path $NodeExe)) { Write-Host " โ Node.js ๆชๅฎ่ฃ " -ForegroundColor Red Write-Host " ไธ่ฝฝ๏ผhttps://nodejs.org/" -ForegroundColor Yellow exit 1 } $nodeVer = & $NodeExe -v Write-Host " โ Node.js: $nodeVer" -ForegroundColor Greenn[3/6] ๆฃๆฅ OpenClaw..." -ForegroundColor Yellow if (!(Test-Path $OpenClawMjs)) { Write-Host " ๅฎ่ฃ OpenClaw..." -ForegroundColor Yellow npm install -g openclaw --registry=https://registry.npmmirror.com if ($LASTEXITCODE -ne 0) { Write-Host " โ ๅฎ่ฃ ๅคฑ่ดฅ" -ForegroundColor Red exit 1 } } Write-Host " โ OpenClaw: ๅทฒๅฎ่ฃ " -ForegroundColor Green3. ๆฃๆฅ/ๅฎ่ฃ OpenClaw
Write-Host "4. ่ทๅไบ็ซฏไฟกๆฏ
Write-Host "n[4/6] ้ ็ฝฎ่ฟๆฅไฟกๆฏ..." -ForegroundColor Yellown[5/6] ๆต่ฏไบ็ซฏ่ฟๆฅ..." -ForegroundColor Yellow $testResult = Test-NetConnection -ComputerName $CloudIP -Port 18789 -WarningAction SilentlyContinue -InformationLevel Quiet if (!$testResult) { Write-Host " โ ๆ ๆณ่ฟๆฅไบ็ซฏ็ฝๅ ณ" -ForegroundColor Red Write-Host " ่ฏทๆฃๆฅ๏ผ" -ForegroundColor Yellow Write-Host " 1. ไบ็ซฏ Tailscale ๆฏๅฆ่ฟ่ก" -ForegroundColor Yellow Write-Host " 2. ไบ็ซฏ็ฝๅ ณๆฏๅฆๅฏๅจ" -ForegroundColor Yellow Write-Host " 3. ไบๅฎๅ จ็ปๆฏๅฆๆพ่ก 18789" -ForegroundColor Yellow exit 1 } Write-Host " โ ไบ็ซฏ็ฝๅ ณ๏ผๅฏ่พพ" -ForegroundColor Greenif ($CloudIP -eq "") { Write-Host " ่ฏท่พๅ ฅไบ็ซฏ็ฝๅ ณ Tailscale IP:" -ForegroundColor Yellow $CloudIP = Read-Host " Cloud IP" }
if ($Token -eq "") { Write-Host " ่ฏท่พๅ ฅไบ็ซฏ็ฝๅ ณ Token:" -ForegroundColor Yellow $Token = Read-Host " Token" }
Write-Host " ไบ็ซฏ็ฝๅ ณ๏ผ$CloudIP:18789" -ForegroundColor Green
5. ๆต่ฏ่ฟๆฅ
Write-Host "6. ้ ็ฝฎๅนถๅฏๅจ
Write-Host "n[6/6] ้ ็ฝฎๅนถๅฏๅจ่็น..." -ForegroundColor Yellow$env:OPENCLAW_ALLOW_INSECURE_PRIVATE_WS = "1" & "$NodeExe" "$OpenClawMjs" node run --host "$CloudIP" --port 18789 "@ | Out-File -FilePath $startScript -Encoding utf8 -ForceNew-Item -ItemType Directory -Force -Path $OpenClawDir | Out-Null
$config = @{ gateway = @{ mode = "remote" auth = @{ token = $Token } remote = @{ url = "ws://$($CloudIP):18789" } } } | ConvertTo-Json -Depth 10
$config | Out-File -FilePath "$OpenClawDir\openclaw.json" -Encoding utf8 -Force Write-Host " โ ้ ็ฝฎ๏ผ$OpenClawDir\openclaw.json" -ForegroundColor Green
ๅๅปบๅฏๅจ่ๆฌ
$startScript = "$OpenClawDir\start-node.ps1" @"ๅฏๅจ่็น
Write-Host " ๅฏๅจ่็น..." -ForegroundColor Yellow $env:OPENCLAW_ALLOW_INSECURE_PRIVATE_WS = "1" Start-Process $NodeExe -ArgumentList "$OpenClawMjs", "node", "run", "--host", $CloudIP, "--port", "18789" -WindowStyle NormalStart-Sleep -Seconds 5
Write-Host "
nโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ" -ForegroundColor Cyan Write-Host "โ โ ้จ็ฝฒๆๅ โ" -ForegroundColor Green Write-Host "โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ" -ForegroundColor CyanWrite-Host "nใ่ฟๆฅไฟกๆฏใ" Write-Host " ไบ็ซฏ็ฝๅ ณ๏ผws://$($CloudIP):18789" Write-Host " ่็น็ถๆ๏ผๅฏๅจไธญ..."
Write-Host "
nใไธไธๆญฅๆไฝใ" Write-Host " 1. ๆฃๆฅ็ถๆ๏ผopenclaw status" Write-Host " 2. ๆฅ็ๆฅๅฟ๏ผopenclaw logs --follow" Write-Host " 3. ้ ็ฝฎๅผๆบ่ชๅฏ๏ผๅฏ้๏ผ๏ผ" Write-Host " schtasks /Create /TN"$TaskName" /TR"powershell -File '$startScript'" /SC ONLOGON /F"
ๆนๆกไธ๏ผไบ็ซฏ็ฝๅ ณ + ๆฌๅฐ็ฝๅ ณๅ้จ็ฝฒ๏ผๅซๅๆญฅๅคไปฝ๏ผ
ๅฎๆดๆถๆๆต็จๅพ
โโโโโโโโโโโโโโโโ
โ ้่ฎฏ่ฝฏไปถ โ
โ (้้/้ฃไนฆ) โ
โโโโโโโโฌโโโโโโโโ
โ
โโโโโโโโโโโโโโโโโโโโโโดโโโโโโโโโโโโโโโโโโโโโ
โ โ
โผ โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ ไบ็ซฏ็ฝๅ
ณ (Primary) โ โ ๆฌๅฐ็ฝๅ
ณ (Secondary) โ
โ :18789 โ โ 127.0.0.1:18789 โ
โ โ โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโ โ โ โโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ ้้ๆไปถ (้้/้ฃไนฆ) โ โ โ โ ๆฌๅฐ้้ (ๆต่ฏ/ๅค็จ) โ โ
โ โโโโโโโโโโโโฌโโโโโโโโโโโ โ โ โโโโโโโโโโโโฌโโโโโโโโโโโ โ
โ โ โ โ โ โ
โ โโโโโโโโโโโโผโโโโโโโโโโโ โ โ โโโโโโโโโโโโผโโโโโโโโโโโ โ
โ โ AI ๆจกๅ (ไบ็ซฏ API) โ โ โ โ AI ๆจกๅ (ๆฌๅฐ API) โ โ
โ โ Claude / Qwen โ โ โ โ Ollama / LM Studio โ โ
โ โโโโโโโโโโโโฌโโโโโโโโโโโ โ โ โโโโโโโโโโโโฌโโโโโโโโโโโ โ
โ โ โ โ โ โ
โ โโโโโโโโโโโโผโโโโโโโโโโโ โ ๅๆญฅ้้ โ โโโโโโโโโโโโผโโโโโโโโโโโ โ
โ โ ๆฐๆฎๅๆญฅๆจกๅ โโโโผโโโโโโโโโโโโโโโโผโโบโ ๆฐๆฎๅๆญฅๆจกๅ โ โ
โ โ - ไผ่ฏ็ถๆ (ๅฎๆถ) โ โ Tailscale โ โ - ไผ่ฏ็ถๆ (ๅฎๆถ) โ โ
โ โ - ๆถๆฏๅๅฒ (ๅข้) โ โ (ๅ ๅฏ) โ โ - ๆถๆฏๅๅฒ (ๅข้) โ โ
โ โโโโโโโโโโโโฌโโโโโโโโโโโ โ โ โโโโโโโโโโโโฌโโโโโโโโโโโ โ
โ โ โ โ โ โ
โ โโโโโโโโโโโโผโโโโโโโโโโโ โ โ โโโโโโโโโโโโผโโโโโโโโโโโ โ
โ โ SQLite (ไบ็ซฏๅญๅจ) โ โ โ โ SQLite (ๆฌๅฐๅญๅจ) โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโ โ โ โโโโโโโโโโโโโโโโโโโโโโโ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโๆ
้่ฝฌ็งป:
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ ๆญฃๅธธ๏ผ้่ฎฏ่ฝฏไปถ โ ไบ็ซฏ็ฝๅ
ณ โ ๅค็ๅนถๅๅค โ
โ ไบ็ซฏๆ
้๏ผๆฌๅฐ็ฝๅ
ณๆฅ็ฎก โ ็ฆป็บฟ้ๅ โ ไบ็ซฏๆขๅคๅๅๆญฅ โ
โ ๆฌๅฐๆ
้๏ผไบ็ซฏ็ปง็ปญ่ฟ่ก โ ๆฐๆฎไปไบ็ซฏๆขๅค โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
powershelltailscale status้จ็ฝฒๅๆฃๆฅๆธ ๅ
| ๆฃๆฅ้กน | ๆฌๅฐ | ไบ็ซฏ | ้ช่ฏๅฝไปค | |--------|------|------|----------| | Tailscale ่ดฆๅท | โ ๅไธ่ดฆๅท | โ ๅไธ่ดฆๅท |
| | Tailscale ่ฟๆฅ | โ ๅทฒ่ฟๆฅ | โ ๅทฒ่ฟๆฅ |tailscale ip| | Node.js (v18+) | โ ๅทฒๅฎ่ฃ | โ ๅทฒๅฎ่ฃ |node -v| | ้ฒ็ซๅข 18789 | โ ๏ธ ไป ๆฌๅฐ | โ ๏ธ ้ๆพ่ก |ufw status| | ไบๅฎๅ จ็ป 18789 | โ | โ ๏ธ ้ๆพ่ก | ไบๆงๅถๅฐๆฃๆฅ | | ๅๆญฅ Token | โ ไธ่ด | โ ไธ่ด | ๆฃๆฅ้ ็ฝฎๆไปถ |ๆฌๅฐ็ฝๅ ณๅฎๆด้จ็ฝฒ๏ผๅซๅผๆบ่ชๅฏ + ๅๆญฅ้ ็ฝฎ๏ผ
plan3-local-gateway.ps1 - ๆนๆกไธ๏ผๆฌๅฐ็ฝๅ ณๅฎๆด้จ็ฝฒ๏ผๅซๅๆญฅๅคไปฝ๏ผ
param( [string]$CloudIP = "" )$ErrorActionPreference = "Stop" $OpenClawDir = "$env:USERPROFILE\.openclaw" $NodeExe = "C:\Program Files\nodejs\node.exe" $TaskName = "OpenClaw-Gateway" $SyncPort = 18790
Write-Host "โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ" -ForegroundColor Cyan Write-Host "โ ๆนๆกไธ๏ผไบ็ซฏ็ฝๅ ณ + ๆฌๅฐ็ฝๅ ณๅ้จ็ฝฒ โ" -ForegroundColor Cyan Write-Host "โ ๆฌๅฐ็ฝๅ ณๅฎๆด้จ็ฝฒ๏ผๅซๅๆญฅๅคไปฝ๏ผ โ" Write-Host "โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ" -ForegroundColor Cyan
1. ๆฃๆฅ Tailscale
Write-Host "n[1/7] ๆฃๆฅ Tailscale..." -ForegroundColor Yellow $tsStatus = tailscale status 2>&1 if ($LASTEXITCODE -ne 0) { Write-Host " Tailscale ๆช่ฟ่ก๏ผๆญฃๅจๅฏๅจ..." -ForegroundColor Yellow tailscale up Start-Sleep -Seconds 5 } $tsIP = (tailscale ip | Select-Object -First 1).Trim() Write-Host " โ Tailscale IP: $tsIP" -ForegroundColor Green2. ๆฃๆฅ Node.js
Write-Host "n[2/7] ๆฃๆฅ Node.js..." -ForegroundColor Yellow
if (!(Test-Path $NodeExe)) {
Write-Host " โ Node.js ๆชๅฎ่ฃ
" -ForegroundColor Red
exit 1
}
Write-Host " โ Node.js: $(& $NodeExe -v)" -ForegroundColor Green3. ๅฎ่ฃ
OpenClaw
Write-Host "n[3/7] ๅฎ่ฃ
OpenClaw..." -ForegroundColor Yellow
npm install -g openclaw --registry=https://registry.npmmirror.com
if ($LASTEXITCODE -ne 0) {
Write-Host " โ ๅฎ่ฃ
ๅคฑ่ดฅ" -ForegroundColor Red
exit 1
}
Write-Host " โ OpenClaw: ๅทฒๅฎ่ฃ
" -ForegroundColor Green4. ้ ็ฝฎ็ฝๅ ณ
Write-Host "n[4/7] ้
็ฝฎ็ฝๅ
ณ..." -ForegroundColor Yellowif ($CloudIP -eq "") {
Write-Host " ่ฏท่พๅ
ฅไบ็ซฏ็ฝๅ
ณ Tailscale IP:" -ForegroundColor Yellow
$CloudIP = Read-Host " Cloud IP"
}
New-Item -ItemType Directory -Force -Path $OpenClawDir | Out-Null
$config = @{
gateway = @{
port = 18789
mode = "local"
bind = "localhost"
}
sync = @{
enabled = $true
remoteUrl = "https://$($CloudIP):${SyncPort}"
token = $(openssl rand -hex 20)
direction = "bidirectional"
interval = 300
}
} | ConvertTo-Json -Depth 10
$config | Out-File -FilePath "$OpenClawDir\openclaw.json" -Encoding utf8 -Force
Write-Host " โ ้
็ฝฎ๏ผ$OpenClawDir\openclaw.json" -ForegroundColor Green
Write-Host " ๅๆญฅ้
็ฝฎ๏ผๅๅๅๆญฅ (5 ๅ้้ด้)" -ForegroundColor Green
5. ๅๅปบๅผๆบ่ชๅฏ่ๆฌ
Write-Host "n[5/7] ๅๅปบๅผๆบ่ชๅฏ้
็ฝฎ..." -ForegroundColor Yellow$startScript = "$OpenClawDir\start-gateway.ps1"
@"
$env:OPENCLAW_ALLOW_INSECURE_PRIVATE_WS = "1"
& "$NodeExe" "$OpenClawMjs" gateway run
"@ | Out-File -FilePath $startScript -Encoding utf8 -Force
ๅๅปบ่ฎกๅไปปๅก
$argument = "-ExecutionPolicy Bypass -WindowStyle Hidden -File "$startScript""
schtasks /Delete /TN $TaskName /F 2>$null | Out-Null
schtasks /Create /TN $TaskName /TR "powershell.exe $argument" /SC ONLOGON /F 2>$nullif ($LASTEXITCODE -eq 0) {
Write-Host " โ ่ฎกๅไปปๅก๏ผ$TaskName (ๅผๆบ่ชๅฏ)" -ForegroundColor Green
} else {
Write-Host " โ ่ฎกๅไปปๅกๅๅปบๅคฑ่ดฅ" -ForegroundColor Yellow
}
6. ๅฏๅจ็ฝๅ
ณ
Write-Host "n[6/7] ๅฏๅจ็ฝๅ
ณ..." -ForegroundColor Yellow$env:OPENCLAW_ALLOW_INSECURE_PRIVATE_WS = "1" Start-Process $NodeExe -ArgumentList "$OpenClawMjs", "gateway", "run" -WindowStyle Normal
Start-Sleep -Seconds 5
7. ้ช่ฏ
Write-Host "n[7/7] ้ช่ฏ็ฝๅ
ณ..." -ForegroundColor Yellow
$portTest = Test-NetConnection -ComputerName localhost -Port 18789 -WarningAction SilentlyContinue -InformationLevel Quiet
if ($portTest) {
Write-Host " โ ็ฝๅ
ณ๏ผ่ฟ่กไธญ (localhost:18789)" -ForegroundColor Green Write-Host "
nโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ" -ForegroundColor Cyan
Write-Host "โ โ ้จ็ฝฒๆๅ โ" -ForegroundColor Green
Write-Host "โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ" -ForegroundColor Cyan Write-Host "nใ่ฎฟ้ฎไฟกๆฏใ"
Write-Host " ็ฝๅ
ณๅฐๅ๏ผws://localhost:18789"
Write-Host " ๆงๅถ้ขๆฟ๏ผhttp://localhost:18789/"
Write-Host " ๅผๆบ่ชๅฏ๏ผ$TaskName"
Write-Host "nใๅๆญฅ้ ็ฝฎใ" Write-Host " ไบ็ซฏ็ฝๅ ณ๏ผ$CloudIP" Write-Host " ๅๆญฅ็ซฏๅฃ๏ผ${SyncPort}" Write-Host " ๅๆญฅๆนๅ๏ผๅๅ" Write-Host " ๅๆญฅ้ด้๏ผ300 ็ง"
Write-Host "nใไธไธๆญฅๆไฝใ"
Write-Host " 1. ๅจไบ็ซฏ่ฟ่ก plan3-cloud-gateway.sh"
Write-Host " 2. ๆฃๆฅ็ถๆ๏ผopenclaw status"
Write-Host " 3. ้
็ฝฎๅๆญฅ๏ผopenclaw sync config"
} else {
Write-Host " โ ็ฝๅ
ณๅฏๅจๅคฑ่ดฅ" -ForegroundColor Red
exit 1
}
ไบ็ซฏ็ฝๅ
ณๅฎๆด้จ็ฝฒ๏ผๅซๅๆญฅๅคไปฝ๏ผ
bash #!/bin/bash
plan3-cloud-gateway.sh - ๆนๆกไธ๏ผไบ็ซฏ็ฝๅ ณๅฎๆด้จ็ฝฒ๏ผๅซๅๆญฅๅคไปฝ๏ผ
set -eecho "โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ" echo "โ ๆนๆกไธ๏ผไบ็ซฏ็ฝๅ ณ + ๆฌๅฐ็ฝๅ ณๅ้จ็ฝฒ โ" echo "โ ไบ็ซฏ็ฝๅ ณๅฎๆด้จ็ฝฒ๏ผๅซๅๆญฅๅคไปฝ๏ผ โ" echo "โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ"
็ณป็ปๆฃๆต
if [ -f /etc/os-release ]; then . /etc/os-release OS=$ID else echo "โ ๆ ๆณ่ฏๅซ็ณป็ป" exit 1 fiif [ "$EUID" -ne 0 ]; then echo "โ ่ฏทไฝฟ็จ root ๆ้่ฟ่ก" exit 1 fi
1. Tailscale
echo -e "\n[1/7] ้ ็ฝฎ Tailscale..." if ! command -v tailscale &> /dev/null; then curl -fsSL https://tailscale.com/install.sh | sh fi systemctl enable --now tailscaled 2>/dev/null || tailscaled & sleep 3 TAILSCALE_IP=$(tailscale ip | head -1) echo " โ Tailscale: $TAILSCALE_IP"2. ้ฒ็ซๅข
echo -e "\n[2/7] ้ ็ฝฎ้ฒ็ซๅข..." if command -v ufw &> /dev/null && ufw status | grep -q "active"; then ufw allow 18789/tcp comment "OpenClaw Gateway" ufw allow 18790/tcp comment "OpenClaw Sync" echo " โ UFW: 18789, 18790 ๅทฒๆพ่ก" elif command -v firewall-cmd &> /dev/null && systemctl is-active --quiet firewalld; then firewall-cmd --permanent --add-port=18789/tcp firewall-cmd --permanent --add-port=18790/tcp firewall-cmd --reload echo " โ Firewalld: 18789, 18790 ๅทฒๆพ่ก" fi echo " โ ไบๆๅกๅจๅฎๅ จ็ป้ๆๅจๆพ่ก 18789, 18790"3. Node.js
echo -e "\n[3/7] ้ ็ฝฎ Node.js..." if ! command -v node &> /dev/null; then if [ "$OS" = "ubuntu" ] || [ "$OS" = "debian" ]; then curl -fsSL https://deb.nodesource.com/setup_22.x | bash - apt-get install -y nodejs fi fi echo " โ Node.js: $(node -v)"4. OpenClaw
echo -e "\n[4/7] ๅฎ่ฃ OpenClaw..." npm install -g openclaw --registry=https://registry.npmmirror.com echo " โ OpenClaw: ๅทฒๅฎ่ฃ "5. ้ ็ฝฎ
echo -e "\n[5/7] ้ ็ฝฎ็ฝๅ ณ๏ผๅซๅๆญฅ๏ผ..." mkdir -p ~/.openclawcat > ~/.openclaw/openclaw.json << 'EOF' { "gateway": { "port": 18789, "mode": "local", "bind": "lan" }, "sync": { "enabled": true, "port": 18790, "token": "auto-generated", "direction": "bidirectional", "interval": 300 } } EOF
echo " โ ้ ็ฝฎๆไปถ๏ผ~/.openclaw/openclaw.json"
6. systemd ๆๅก
echo -e "\n[6/7] ๅๅปบ systemd ๆๅก..."cat > /etc/systemd/system/openclaw-gateway.service << 'EOF' [Unit] Description=OpenClaw Gateway (with Sync) After=network.target tailscaled.service Wants=tailscaled.service
[Service] Type=simple User=root WorkingDirectory=/root/.openclaw ExecStart=/usr/bin/node /usr/lib/node_modules/openclaw/dist/index.js gateway --port 18789 --bind lan Restart=always Environment=NODE_ENV=production
LimitNOFILE=65535 Nice=-5
[Install] WantedBy=multi-user.target EOF
systemctl daemon-reload systemctl enable openclaw-gateway systemctl start openclaw-gateway
sleep 5
7. ้ช่ฏ
echo -e "\n[7/7] ้ช่ฏๆๅก..."echo -e "\nโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ" if systemctl is-active --quiet openclaw-gateway; then echo "โ โ ้จ็ฝฒๆๅ โ" echo "โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ"
echo -e "\nใๆๅกไฟกๆฏใ" echo " ๆๅก็ถๆ๏ผ$(systemctl is-active openclaw-gateway)" echo " ๅผๆบ่ชๅฏ๏ผ$(systemctl is-enabled openclaw-gateway)"
echo -e "\nใ็ฝ็ปไฟกๆฏใ" echo " Tailscale IP: $TAILSCALE_IP" echo " ็ฝๅ ณๅฐๅ๏ผws://${TAILSCALE_IP}:18789" echo " ๅๆญฅ็ซฏๅฃ๏ผ${TAILSCALE_IP}:18790"
echo -e "\nใ็ซฏๅฃ็ๅฌใ" ss -tlnp | grep -E "18789|18790" || true
echo -e "\nใไธไธๆญฅๆไฝใ" echo " 1. ๅจๆฌๅฐ่ฟ่ก plan3-local-gateway.ps1" echo " 2. ้ ็ฝฎๅๅๅๆญฅ๏ผopenclaw sync config" echo " 3. ๆฅ็ๅๆญฅ็ถๆ๏ผopenclaw sync status" else echo "โ โ ้จ็ฝฒๅคฑ่ดฅ โ" echo "โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ" journalctl -u openclaw-gateway --no-pager -n 20 exit 1 fi
ๆ
้ๆๆฅ
้็จ่ฏๆญ่ๆฌ
bash
#!/bin/bash
diagnostic.sh - OpenClaw ๅฟซ้่ฏๆญ
echo "โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ" echo "โ OpenClaw ่ฏๆญๆฅๅ โ" echo "โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ"
echo -e "\nใ1. ็ณป็ปไฟกๆฏใ" uname -a grep PRETTY_NAME /etc/os-release 2>/dev/null || true
echo -e "\nใ2. Tailscale ็ถๆใ" tailscale status 2>&1 | head -10 || echo "Tailscale ๆชๅฎ่ฃ /ๆช่ฟ่ก"
echo -e "\nใ3. Node.js ็ๆฌใ" node -v 2>/dev/null || echo "Node.js ๆชๅฎ่ฃ " npm -v 2>/dev/null || true
echo -e "\nใ4. OpenClaw ็ถๆใ" openclaw status 2>&1 | head -20 || echo "OpenClaw ๆชๅฎ่ฃ /ๆ ๆณ่ฟ่ก"
echo -e "\nใ5. ็ซฏๅฃ็ๅฌใ" ss -tlnp 2>/dev/null | grep -E "18789|18790" || netstat -tlnp 2>/dev/null | grep -E "18789|18790" || echo "ๆ OpenClaw ็ซฏๅฃ"
echo -e "\nใ6. ้ฒ็ซๅข็ถๆใ" if command -v ufw &> /dev/null; then ufw status 2>&1 | head -10 fi if command -v firewall-cmd &> /dev/null; then firewall-cmd --list-all 2>&1 | head -10 fi
echo -e "\nใ7. ็ฝๅ ณๆๅกใ" systemctl status openclaw-gateway --no-pager -l 2>&1 | head -15 || echo "ๆๅกๆชๅฎ่ฃ "
echo -e "\nใ8. ๆ่ฟๆฅๅฟใ"
journalctl -u openclaw-gateway --no-pager -n 10 2>&1 || echo "ๆ ๆฅๅฟ"
`
ๅธธ่ง้ฎ้ข้ๆฅ
| ้ฎ้ข | ๅฏ่ฝๅๅ | ่งฃๅณๆนๆก |
|------|----------|----------|
| ็ซฏๅฃไธ้ | ้ฒ็ซๅข้ปๆก | ufw allow 18789/tcp |
| Tailscale ๆญๅผ | ่ฎค่ฏ่ฟๆ | tailscale up --force |
| ๅๆญฅๅคฑ่ดฅ | Token ไธไธ่ด | ๆฃๆฅไธค่พน้
็ฝฎๆไปถ |
| ๆๅกๆ ๆณๅฏๅจ | ็ซฏๅฃๅ ็จ | ss -tlnp \| grep 18789` |
| Webhook ไธๅๅบ | ๅฎๅ
จ็ปๆชๆพ่ก | ไบๆงๅถๅฐๆทปๅ ๅ
ฅ็ซ่งๅ |