开发者文档

从批量部署客户端到把设备状态接进你现有的运维系统,都在这里。接口与自托管配置都会随版本更新。

快速上手

第一次连接只需要三步,不需要记 IP 和端口,也不需要配置路由器。

  • 在被控电脑上安装客户端并登录,设备会自动出现在列表里;
  • 在主控端(电脑、手机或浏览器)打开客户端,点一下目标设备发起连接;
  • 被控端确认后即可开始操作,可勾选「记住此设备」避免每次都确认。
bash — 用 CLI 注册一台无界面服务器
# 在服务器上安装并注册为被控端
curl -fsSL https://get.ggremote.com/agent | sh

ggremote-agent register \
  --token gr_agent_**************** \
  --name "prod-db-01" \
  --tags "env=prod,role=db" \
  --unattended            # 允许无人值守访问(会提示设置独立密码)

# 确认状态
ggremote-agent status
# → {"device_id":"dev_8f31c7","status":"online","peers":0}

关于无人值守:启用后即使无人坐在被控机前也能连入。 这是运维场景的必需能力,但请在后台同时配置好设备分组授权,避免权限过宽。

CLI 批量部署

无界面版(Agent)适合批量下发。下面是一个 Ansible 片段,用于给一批服务器注册为被控端。

yaml — Ansible 批量注册被控端
- hosts: db_servers
  become: true
  vars:
    ggremote_token: "{{ vault_ggremote_token }}"
  tasks:
    - name: 安装 ggremote agent
      ansible.builtin.shell: curl -fsSL https://get.ggremote.com/agent | sh
      args:
        creates: /usr/local/bin/ggremote-agent

    - name: 注册为被控端
      ansible.builtin.command:
        cmd: >
          ggremote-agent register
          --token {{ ggremote_token }}
          --name {{ inventory_hostname }}
          --tags "env=prod,role=db"
          --unattended --password-stdin
      args:
        stdin: "{{ vault_unattended_password }}"
      register: reg
      changed_when: "'already registered' not in reg.stdout"

自托管部署

自托管部署会替换掉我们的中继与信令服务,客户端仍然照常使用,只是连接的服务器换成了你自己的地址。 自托管版本仅企业版提供,需要授权文件。

bash — Docker Compose 部署
# 1. 拉取部署文件
curl -fsSL https://get.ggremote.com/selfhost | sh

# 2. 配置域名、证书与授权
cat > .env <<'EOF'
GGREMOTE_DOMAIN=remote.your-company.com
GGREMOTE_LETSENCRYPT_EMAIL=ops@your-company.com
GGREMOTE_LICENSE=eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9...
GGREMOTE_TURN_SECRET=$(openssl rand -hex 32)
EOF

# 3. 启动
docker compose up -d

# 4. 验证
curl https://remote.your-company.com/healthz
# → {"status":"ok","version":"3.4.1","peers":0,"relay_region":"internal"}

客户端切换到自托管地址

在客户端「设置 → 服务器」中填入自托管地址即可。支持同时保留公共节点作为备用通道,主节点不可达时自动回退。

bash — 通过配置文件统一切换(适合批量下发)
# Windows: %ProgramData%\ggremote\config.json
# macOS:   /Library/Application Support/ggremote/config.json
# Linux:   /etc/ggremote/config.json
{
  "server": "remote.your-company.com",
  "port": 443,
  "fallback_public": true,
  "telemetry": false
}
自托管部署的最低资源要求
规模 并发会话 建议配置 带宽
小规模 ≤ 50 2 核 4 GB 50 Mbps
中等规模 ≤ 500 4 核 8 GB 500 Mbps
大规模 > 500 8 核 16 GB + 多节点 1 Gbps

带宽说明:直连成功的会话不占用服务器带宽—— 画面在两端之间直接传输。服务器带宽主要消耗在无法直连时的中继转发上,实际占用通常远低于并发数 × 单会话码率。

身份认证

开放 API 使用 API Key 认证。可在「后台 → 开发者 → API 密钥」中创建,并按最小权限申请 scope。

请求头说明
请求头 是否必填 说明
Authorization 格式为 Bearer <api_key>
X-GGR-Org 多组织账号下指定操作的组织;缺省为默认组织
Idempotency-Key 写操作幂等键,避免重复下发命令

API 参考

接口根地址为 https://api.ggremote.com/v1(自托管时替换为你的域名)。

主要接口清单
方法 路径 说明
GET /v1/devices 查询设备列表,支持按标签、在线状态筛选
GET /v1/devices/{id} 查询单台设备详情与实时连接质量
POST /v1/devices/{id}/session 创建一次会话令牌,供客户端 SDK 发起连接
POST /v1/devices/{id}/wake 发送 Wake-on-LAN 唤醒离线设备
POST /v1/devices/{id}/revoke 吊销设备授权,立即断开并禁止重连
GET /v1/sessions 查询历史会话记录(含发起人、时长、录像 ID)
GET /v1/audit-logs 查询审计日志,支持时间范围与操作类型筛选
POST /v1/groups/{id}/members 把成员加入设备分组,赋予对应连接权限
DELETE /v1/webhooks/{id} 取消一个 Webhook 订阅

调用示例

python — 查询在线设备并发起一次会话
import requests

BASE = "https://api.ggremote.com/v1"
HEADERS = {"Authorization": "Bearer gr_live_****************"}

# 1. 找出所有生产环境的在线设备
devices = requests.get(
    f"{BASE}/devices",
    headers=HEADERS,
    params={"tags": "env=prod", "status": "online"},
    timeout=10,
).json()

for d in devices["data"]:
    print(d["id"], d["name"], d["last_seen"], d["quality"]["latency_ms"])

# 2. 为某台设备创建会话令牌(客户端用这个令牌发起连接)
session = requests.post(
    f"{BASE}/devices/dev_8f31c7/session",
    headers={**HEADERS, "Idempotency-Key": "req-20260911-001"},
    json={"mode": "control", "record": True, "ttl_seconds": 300},
    timeout=10,
).json()

print(session["data"]["token"])          # 供客户端 SDK 使用
print(session["data"]["recording_id"])   # 本次会话的录像 ID

Webhook

订阅事件后,平台会在事件发生时向你的回调地址推送 JSON。所有推送带 HMAC-SHA256 签名,务必校验。

常用 Webhook 事件
事件名 触发时机 典型用途
device.online 设备上线或离线恢复 更新 CMDB 中的设备状态
device.offline 设备掉线超过 60 秒 触发告警或自动排查工单
session.started 有人发起了远程连接 高风险设备实时通知主管
session.ended 会话结束 写入审计系统,附录像 ID
file.transferred 文件传输完成 记录数据外带路径
policy.changed 权限或策略被修改 同步到自建 SIEM
python — 校验推送签名
import hmac, hashlib

def verify(raw_body: bytes, signature: str, secret: str) -> bool:
    expected = hmac.new(secret.encode(), raw_body, hashlib.sha256).hexdigest()
    return hmac.compare_digest(expected, signature)

# Flask 示例:必须用原始 body,不能先 json.loads 再序列化
@app.post("/ggremote/webhook")
def hook():
    if not verify(request.get_data(), request.headers["X-GGR-Signature"], SECRET):
        return "", 401

    event = request.json
    if event["type"] == "session.started":
        notify_security_team(event["data"])   # 含发起人、目标设备、来源 IP
    return "", 204

重试策略:推送失败按 1s / 10s / 1min / 10min / 1h 间隔重试 5 次。 请保证回调接口幂等——同一条事件可能被投递多次。超过 5 次仍失败会触发告警并记录在后台。

错误码

所有错误遵循 HTTP 状态码 + 业务错误码 双层语义。请按业务错误码分支处理。

错误码说明
错误码 HTTP 含义 处理建议
InvalidApiKey 401 密钥无效或已被撤销 检查密钥是否正确、是否已被轮换
DeviceRevoked 403 设备授权已被吊销 需在被控端重新人工确认后才能连入
DeviceOffline 409 目标设备不在线 可先调用 /wake 唤醒,或等待其上线
ConcurrentLimit 429 并发会话数已达套餐上限 结束空闲会话,或升级套餐
ApprovalRequired 428 该设备需要审批才能连接 提示发起人走审批流程
RateLimited 429 请求频率超限 指数退避重试;或申请提高限额
InternalError 500 服务端异常 携带 request_id 提交工单
json — 错误响应
{
  "request_id": "req_3a91bd0c72",
  "error": {
    "code": "ApprovalRequired",
    "message": "设备 prod-db-01 已启用连接审批,需主管批准",
    "retryable": false,
    "details": { "approval_id": "apr_71c3f9", "policy": "high-risk-devices" }
  }
}

限额与支持

API 调用频率按套餐分层。自托管部署不限频率。

各套餐的接口调用限额
套餐 读接口 写接口 Webhook 频次
个人版 30 次 / 分钟 10 次 / 分钟 5 次 / 秒
团队版 300 次 / 分钟 100 次 / 分钟 50 次 / 秒
企业版 / 自托管 不限 不限 不限

技术支持:对接过程中遇到问题,把 request_id 和请求示例发到 dev@ggremote.com, 工程团队会在 1 个工作日内回复。企业版客户可使用专属技术对接群,并可索取安全白皮书。

准备好接进你的运维体系了?

团队版 14 天全功能试用,API 限额按团队版开放。自托管部署需企业版授权。