☰
内网服务器 OpenClaw 部署 + WebUI 内网直连 + 本地模型接入 全流程教程
2026/10/10 14:14:00 网站建设 项目流程

摘要:本文面向内网 Ubuntu 服务器,完整讲解 OpenClaw 的重装部署、本地模型接入与 WebUI 内网直连全流程。内容包括:备份旧配置、停止服务并重装、手写models.providers配置接入本地模型代理(freellmapi/auto)、以 systemd 用户服务启动 Gateway,以及通过 Gateway 原生 TLS 自签证书实现局域网内其他电脑直接访问 Control UI。文章重点剖析了两个最容易踩的坑——自定义 Provider 的input/cost字段格式校验失败,以及新设备访问 Control UI 时的配对审批流程,并给出常见问题排查对照表,帮助读者少走弯路、一步到位完成部署。

1. 方案背景与架构

目标

  • 服务器上已安装过 OpenClaw,需重装到干净状态。
  • 接入本地模型代理(本文示例为freellmapi,监听127.0.0.1:31415,提供 OpenAI 兼容的/v1接口,内含 206 个模型,其中auto为自动路由模型)。
  • 局域网内其他电脑(Windows 等)能通过内网 IP 直接访问WebUI(Control UI),无需 SSH 隧道。

架构图

flowchart TD A[浏览器: https://192.168.1.107:18789] -- HTTPS TLS 自签证书 --> B[OpenClaw Gateway 端口 18789 TLS 终止] B -- http://127.0.0.1:31415/v1 OpenAI 兼容 --> C[本地模型代理 freellmapi] C -- 上游模型服务 --> D[模型推理]

关键结论(先看,少走弯路)

  1. OpenClaw 的 Control UI只允许在“安全上下文”(HTTPS 或 localhost)下工作。直接用http://内网IP:18789访问会报control ui requires device identity (use HTTPS or localhost secure context),且 token 认证无法替代该限制。必须开 HTTPS。
  2. OpenClaw Gateway原生支持 TLS 终止(gateway.tls),不需要额外装 nginx。
  3. 新设备首次访问 Control UI 会进入设备配对流程,需要在服务器端批准(openclaw devices approve),否则提示pairing required: device is not approved yet。
  4. 自定义模型 Provider 的models[].input/models[].cost字段格式要求严格,格式不对会导致配置校验失败(详见第 5 节)。

2. 前置准备

2.1 服务器环境

# 查看系统版本 cat /etc/os-release uname -a 确认 Node / npm(本文使用 nvm 安装的 Node v24.19.0) node -v npm -v 查看 openclaw 是否已全局安装及版本 which openclaw openclaw --version

2.2 确认本地模型代理

# 确认本地模型代理监听 ss -tlnp | grep 31415 查看可用模型(确认有 auto / claude-sonnet-4-5 等) curl -s http://127.0.0.1:31415/v1/models -H "Authorization: Bearer <your-api-key>" | head -c 2000

3. 备份旧配置

重装前务必备份~/.openclaw目录,避免丢失原有 gateway token、设备、workspace 等:

cp -r ~/.openclaw ~/.openclaw.bak.$(date +%Y%m%d) du -sh ~/.openclaw.bak.$(date +%Y%m%d)

备份后用cat ~/.openclaw/openclaw.json记录原有关键配置(gateway token、端口等),作为重装后对比基线。

4. 停止服务并重装 OpenClaw

4.1 查看现有 gateway 服务

OpenClaw 安装为 systemd用户服务时,服务名为openclaw-gateway.service:

export XDG_RUNTIME_DIR=/run/user/$(id -u) systemctl --user list-unit-files | grep -i openclaw systemctl --user status openclaw-gateway | head -8 确认是否开机自启(Linger) loginctl show-user $USER | grep Linger

4.2 停止服务并卸载旧版本

export XDG_RUNTIME_DIR=/run/user/$(id -u) systemctl --user stop openclaw-gateway systemctl --user is-active openclaw-gateway # 应输出 inactive 清理可能残留的前台进程 pkill -f "openclaw" 2>/dev/null 卸载旧全局包(需加载 nvm 环境) source ~/.nvm/nvm.sh npm uninstall -g openclaw

4.3 安装最新版

source ~/.nvm/nvm.sh npm install -g openclaw@latest openclaw --version # 确认版本

若 npm 提示allow-scripts未执行 install 脚本,可执行一次npm install -g --allow-scripts=openclaw,@google/genai,protobufjs,tree-sitter-bash。

5. 配置本地模型 Provider(接入 auto)

5.1 为什么不走交互式 onboard

openclaw onboard交互式向导在 SSH 会话中容易卡住。推荐直接手写models.providers配置,一步到位。

5.2 配置 JSON 模板

在~/.openclaw/openclaw.json中加入:

{ "models": { "providers": { "freellmapi": { "baseUrl": "http://127.0.0.1:31415/v1", "apiKey": "<your-api-key>", "api": "openai-completions", "models": [ { "id": "auto", "name": "Auto (router picks the best available model)", "reasoning": false, "contextWindow": 1048576, "contextTokens": 1048576, "maxTokens": 32768 } ] } } }, "agents": { "defaults": { "model": { "primary": "freellmapi/auto" } } } }

字段说明

字段说明
baseUrl本地模型代理的 OpenAI 兼容地址,末尾要带/v1
apiKey本地代理的 API key
api固定openai-completions;仅当后端支持/v1/responses时才用openai-responses
models[].id在代理里真实存在的模型 ID(如auto)
contextWindow/contextTokens/maxTokens上下文与输出上限,按代理实际能力填写

5.3 校验与踩坑

用官方 CLI 校验配置:

source ~/.nvm/nvm.sh openclaw config validate # 期望输出: Config valid: ~/.openclaw/openclaw.json

坑 1:input/cost字段格式
若在models[]里写了"input": 0.0或"cost": 0.0,会报models.providers.xxx.models.0.input: Invalid input导致整个配置失效。
解法:直接删掉这两个字段,不要给简单数值。

坑 2:不能用config set分步拼 Provider
openclaw config set models.providers.xxx.baseUrl ...会做增量校验,因缺少models字段而报custom model providers must declare models。自定义 Provider 必须一次性完整写入 JSON。
(可以先用 base64 传输脚本改 JSON,再用config validate校验。)

6. 配置并启动 Gateway(systemd 用户服务)

6.1 安装/重建系统服务

export XDG_RUNTIME_DIR=/run/user/$(id -u) source ~/.nvm/nvm.sh openclaw gateway install --force # 生成/覆盖 systemd 用户服务 systemctl --user daemon-reload systemctl --user enable --now openclaw-gateway

6.2 确认启动

systemctl --user status openclaw-gateway | head -12 # Active: active (running) # Main PID: ... 查看日志,确认模型已加载 journalctl --user -u openclaw-gateway --no-pager -n 20 | grep -iE "agent model|listening|ready" 期望看到: agent model: freellmapi/auto (thinking=off, fast=off)

6.3 验证模型端到端

curl -s -X POST http://127.0.0.1:31415/v1/chat/completions \ -H "Content-Type: application/json" \ -H "Authorization: Bearer <your-api-key>" \ -d '{"model":"auto","messages":[{"role":"user","content":"hi"}],"max_tokens":16}'

能看到返回(含_routed_via表示 auto 实际路由到的上游模型)即链路 OK。

7. 内网 WebUI 访问:HTTPS 直连方案

7.1 背景:为什么不能 http:// 内网 IP 直连

Control UI 需要安全上下文才能生成设备身份。局域网明文 HTTP(http://192.168.1.107:18789)会被浏览器判定为非安全上下文,报错:

control ui requires device identity (use HTTPS or localhost secure context)

token 认证不能替代设备身份,gateway.controlUi.allowInsecureAuth=true也只在 localhost 下放宽。

7.2 方案对比

方案优点缺点
SSH 隧道(ssh -L 18789:127.0.0.1:18789)零改动隧道进程易断、需保活、非“直接访问”
Gateway 原生 TLS(本文方案)内网 IP 直连、无额外组件需自签证书(浏览器信任一次即可)
Tailscale Serve公网可访问、证书自动需装 Tailscale 并登录

推荐 Gateway 原生 TLS,最贴合“内网 IP 直接访问”诉求。

7.3 生成自签名证书(含 IP SAN)

证书必须包含服务器的内网 IP 的 SAN,否则浏览器会报“证书名称不匹配”。

mkdir -p ~/.openclaw/certs && cd ~/.openclaw/certs openssl req -x509 -newkey rsa:2048 \ -keyout server.key -out server.crt \ -days 3650 -nodes \ -subj "/CN=192.168.1.107" \ -addext "subjectAltName=IP:192.168.1.107,DNS:localhost,DNS:<your-hostname>" chmod 600 server.key 验证 SAN openssl x509 -in server.crt -noout -ext subjectAltName 期望: IP Address:192.168.1.107, DNS:localhost, DNS:<hostname>

7.4 配置 Gateway TLS

source ~/.nvm/nvm.sh openclaw config set gateway.tls.enabled true openclaw config set gateway.tls.certPath /home/<user>/.openclaw/certs/server.crt openclaw config set gateway.tls.keyPath /home/<user>/.openclaw/certs/server.key openclaw config set gateway.controlUi.allowedOrigins '["https://192.168.1.107:18789","http://localhost:18789","http://127.0.0.1:18789"]' openclaw config validate

说明:gateway.tls支持enabled / certPath / keyPath / caPath / autoGenerate。生产建议用正式证书;内网自签即可。
allowedOrigins需要把实际访问来源的https://IP:端口加进去,否则浏览器 CORS/Origin 校验会拦。

7.5 重启并验证

export XDG_RUNTIME_DIR=/run/user/$(id -u) systemctl --user restart openclaw-gateway sleep 8 systemctl --user is-active openclaw-gateway 服务器本地验证(-k 忽略证书校验) curl -sk -o /dev/null -w "%{http_code}\n" https://127.0.0.1:18789/ # 200 curl -sk -o /dev/null -w "%{http_code}\n" https://192.168.1.107:18789/ # 200 明文 http 此时应失效(000),说明已被 TLS 取代

7.6 本机(Windows)导入证书,消除浏览器警告

把server.crt拷到本机后:

# 导入到当前用户受信任根(无需管理员) Import-Certificate -FilePath C:\path\to\server.crt -CertStoreLocation Cert:\CurrentUser\Root

之后浏览器访问https://192.168.1.107:18789不再有证书警告。

8. 设备配对审批(最容易踩的坑)

8.1 现象

HTTPS 通了、token 填对了,仍然进不去,页面/日志提示:

pairing required: device is not approved yet (requestId: xxxx) phase=auth_validated

含义:token 已验证通过,但当前浏览器设备尚未获得配对批准。Control UI 的流程是:

flowchart LR A[新设备 HTTPS 首次连接] -- 生成配对请求 new pairing --> B[服务器端批准] B -- 设备进入已配对表 --> C[之后免审批连接]

8.2 查看待批准设备

source ~/.nvm/nvm.sh openclaw devices list

输出分为Pending(待批准)与Paired(已配对):

Pending (1) │ Request: 70e5fe9e-218d-4550-8016-eccc19da97e8 │ Device : cea971d9... │ IP : 192.168.1.108 │ Status : new pairing

8.3 批准设备

openclaw devices approve 70e5fe9e-218d-4550-8016-eccc19da97e8 # 输出: Approved cea971d9... (70e5fe9e-...)

再openclaw devices list,该设备应进入Paired列表。

8.4 重要注意点

配对请求有有效期。若批准前请求已过期(No pending device request matches ...),需要让浏览器重新打开/刷新Control UI 页面生成新请求,再在有效期内尽快批准。
相关命令:openclaw devices approve|reject|list|remove|revoke|clear。

9. 验证与日常使用

  1. 浏览器打开https://192.168.1.107:18789。
  2. 输入 gateway token(来自openclaw.json的gateway.auth.token)登录。
  3. 进入 Control UI 后,可在 WebChat 中发消息,验证freellmapi/auto正常推理。

日常状态检查

openclaw gateway status openclaw doctor openclaw models list --provider freellmapi systemctl --user status openclaw-gateway

10. 常见问题排查

现象原因解决
control ui requires device identity用明文 HTTP 访问非 localhost改走 HTTPS(本文第 7 节)
pairing required: device is not approved yet新设备未批准openclaw devices list+approve(第 8 节)
models.0.input: Invalid inputinput/cost字段格式错误删除这两个字段后重新config validate
custom model providers must declare models用config set分步写 Provider一次性完整写入 JSON
No pending device request matches配对请求已过期浏览器刷新页面重新生成,再尽快批准
HTTP 000 / 连不上gateway 未启动或绑定错误systemctl --user status+journalctl --user -u openclaw-gateway看日志
浏览器证书警告未信任自签证书将 server.crt 导入本机受信任根(第 7.6 节)
SSH 隧道方案易断隧道进程被清理改用本文 HTTPS 直连方案

附:最终 openclaw.json 关键片段(供对照)

{ "gateway": { "mode": "local", "auth": { "mode": "token", "token": "<your-token>" }, "port": 18789, "bind": "lan", "controlUi": { "allowInsecureAuth": true, "allowedOrigins": [ "https://192.168.1.107:18789", "http://localhost:18789", "http://127.0.0.1:18789" ]}, "tls": { "enabled": true, "certPath": "/home/<user>/.openclaw/certs/server.crt", "keyPath": "/home/<user>/.openclaw/certs/server.key" } }, "models": { "providers": { "freellmapi": { /* 见第 5 节 */ } } }, "agents": { "defaults": { "model": { "primary": "freellmapi/auto" } } } }

(内容由AI生成,仅供参考)

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询