395 lines
11 KiB
Markdown
395 lines
11 KiB
Markdown
# 1
|
||
|
||
我有一个域名xxx.com,配置了DNS 的a记录 * 指向ip1,ip1所在服务器A配置了 Nginx,用来解析子域名。
|
||
现在我有个新的服务器B 其ip 为 ip2,我现在想配置其中一个子域名指向这个服务器,以便通过子域名访问,而且我有SSL证书,想配置http或者https 访问 bbb.xxx.com 时都指向这个服务器B的 ip2。
|
||
这个nginx配置怎么写?
|
||
|
||
# HTTP 服务器块 - 强制重定向到 HTTPS
|
||
server {
|
||
listen 80;
|
||
listen [::]:80;
|
||
server_name bbb.xxx.com;
|
||
|
||
# 将所有 HTTP 请求重定向到 HTTPS
|
||
return 301 https://$server_name$request_uri;
|
||
}
|
||
|
||
# HTTPS 服务器块
|
||
server {
|
||
listen 443 ssl http2;
|
||
listen [::]:443 ssl http2;
|
||
server_name bbb.xxx.com;
|
||
|
||
# SSL 证书配置 (请替换为您的实际路径)
|
||
ssl_certificate /path/to/your/fullchain.pem; # 例如: /etc/ssl/xxx.com/fullchain.pem
|
||
ssl_certificate_key /path/to/your/privkey.pem; # 例如: /etc/ssl/xxx.com/privkey.pem
|
||
|
||
# 启用 SSL 会话复用以提高性能
|
||
ssl_session_cache shared:SSL:10m;
|
||
ssl_session_timeout 10m;
|
||
|
||
# 网站根目录配置 (请根据您的实际情况修改)
|
||
root /var/www/bbb.xxx.com;
|
||
index index.html index.htm;
|
||
|
||
# 日志配置
|
||
access_log /var/log/nginx/bbb.xxx.com.access.log;
|
||
error_log /var/log/nginx/bbb.xxx.com.error.log;
|
||
|
||
# 基本安全头
|
||
add_header X-Frame-Options SAMEORIGIN;
|
||
add_header X-Content-Type-Options nosniff;
|
||
add_header X-XSS-Protection "1; mode=block";
|
||
|
||
# 主 location 块
|
||
location / {
|
||
try_files $uri $uri/ =404;
|
||
}
|
||
|
||
# 禁止访问隐藏文件
|
||
location ~ /\. {
|
||
deny all;
|
||
}
|
||
}
|
||
|
||
---
|
||
|
||
这个意思还是通过DNS解析,而不是通过服务器A的Nginx解析,对吧?
|
||
能不能通过服务器A的Nginx解析来做到类似效果呢?
|
||
|
||
您理解得完全正确。之前的方案是通过DNS直接将 `bbb.xxx.com` 解析到服务器B的IP2。
|
||
|
||
**当然可以通过服务器A的Nginx作为反向代理来实现,无需修改DNS记录。** 这样所有流量会先到达服务器A,再由A转发到服务器B。
|
||
|
||
### 服务器A的Nginx配置(反向代理方案)
|
||
|
||
在服务器A上为 `bbb.xxx.com` 添加以下配置:
|
||
|
||
```nginx
|
||
# HTTP 服务器块 - 重定向到 HTTPS
|
||
server {
|
||
listen 80;
|
||
server_name bbb.xxx.com;
|
||
return 301 https://$server_name$request_uri;
|
||
}
|
||
|
||
# HTTPS 服务器块 - 核心代理配置
|
||
server {
|
||
listen 443 ssl http2;
|
||
server_name bbb.xxx.com;
|
||
|
||
# SSL 证书配置 (证书需放置在服务器A上)
|
||
ssl_certificate /path/to/your/certificate.pem;
|
||
ssl_certificate_key /path/to/your/private.key;
|
||
|
||
# 将请求代理转发到服务器B (IP2)
|
||
location / {
|
||
proxy_pass http://ip2:80; # 假设服务器B在80端口监听
|
||
# 或 proxy_pass https://ip2:443; # 如果服务器B也配置了HTTPS
|
||
|
||
# 以下为关键代理头设置,确保正确传递信息
|
||
proxy_set_header Host $host;
|
||
proxy_set_header X-Real-IP $remote_addr;
|
||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||
proxy_set_header X-Forwarded-Proto $scheme;
|
||
proxy_set_header X-Forwarded-Host $server_name;
|
||
|
||
# 可选:优化设置
|
||
proxy_buffering off;
|
||
proxy_http_version 1.1;
|
||
proxy_set_header Connection "";
|
||
}
|
||
}
|
||
```
|
||
|
||
### 服务器B的Nginx配置(简化版)
|
||
|
||
服务器B只需基本的HTTP服务,因为SSL已在服务器A终止:
|
||
```nginx
|
||
server {
|
||
listen 80;
|
||
server_name bbb.xxx.com;
|
||
root /var/www/bbb.xxx.com;
|
||
index index.html;
|
||
|
||
# 因为经过代理,可从头部获取真实用户IP
|
||
set_real_ip_from ip1; # ip1是服务器A的IP
|
||
real_ip_header X-Forwarded-For;
|
||
real_ip_recursive on;
|
||
}
|
||
```
|
||
|
||
### 两种方案对比
|
||
|
||
| 特性 | **DNS直接解析** | **Nginx反向代理** |
|
||
| :--- | :--- | :--- |
|
||
| **实现方式** | DNS记录指向IP2 | 流量经服务器A转发 |
|
||
| **DNS修改** | 需要 | **不需要**,利用现有通配符记录 |
|
||
| **SSL证书位置** | 服务器B | **服务器A** |
|
||
| **性能** | 直接访问,延迟低 | 多一跳转发,略有延迟 |
|
||
| **维护点** | 分散(两台服务器) | **集中**(主要维护服务器A) |
|
||
| **适用场景** | 子域名完全独立 | 需统一入口、集中管理SSL |
|
||
|
||
### 操作步骤(反向代理方案)
|
||
1. 在**服务器A**的Nginx配置中添加上述`bbb.xxx.com`的代理配置。
|
||
2. 将您的SSL证书上传至服务器A,并配置正确路径。
|
||
3. 在**服务器B**上配置HTTP服务(如上述简化配置)。
|
||
4. 确保服务器A的防火墙允许443端口入站,且服务器A能访问服务器B的80端口。
|
||
5. 重载两台服务器的Nginx配置。
|
||
|
||
### 核心优势
|
||
- **无需等待DNS生效**:修改立即生效。
|
||
- **统一SSL管理**:所有子域名的证书可在服务器A集中管理。
|
||
- **灵活路由**:未来可轻松更改后端服务器,用户无感知。
|
||
|
||
这个方案非常适合需要集中管理或频繁变更后端服务的场景。
|
||
|
||
---
|
||
|
||
## gateway in openclaw.json
|
||
|
||
```json
|
||
"gateway": {
|
||
"port": 18789,
|
||
"mode": "local",
|
||
"bind": "lan",
|
||
"controlUi": {
|
||
"allowedOrigins": [
|
||
"http://82.156.219.55:18789"
|
||
],
|
||
"dangerouslyAllowHostHeaderOriginFallback": true,
|
||
"allowInsecureAuth": false,
|
||
"dangerouslyDisableDeviceAuth": false
|
||
},
|
||
"auth": {
|
||
"mode": "token",
|
||
"token": "5eb77a151f15431db1cf9a8be66843edb0f5924e0534adf5"
|
||
},
|
||
"tailscale": {
|
||
"mode": "off",
|
||
"resetOnExit": false
|
||
}
|
||
},
|
||
```
|
||
|
||
## 域名及中转
|
||
|
||
当前中转为从其他服务器跳转,其他服务器的Nginx配置为:
|
||
|
||
```conf
|
||
server {
|
||
listen 80;
|
||
server_name openclaw.wantsong.life;
|
||
return 301 https://$server_name$request_uri;
|
||
}
|
||
|
||
server {
|
||
listen 443 ssl;
|
||
server_name openclaw.wantsong.life;
|
||
charset utf-8;
|
||
ssl_certificate /etc/nginx/ssl/_.wantsong.life.pem;
|
||
ssl_certificate_key /etc/nginx/ssl/_.wantsong.life.key;
|
||
|
||
ssl_session_timeout 5m;
|
||
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
|
||
ssl_prefer_server_ciphers on;
|
||
ssl_session_cache shared:SSL:1m;
|
||
ssl_ciphers AWSGCM:ALL:!DH:!EXPORT:!RC4:+HIGH:!MEDIUM:!LOW:!aNULL:!eNULL;
|
||
|
||
location / {
|
||
proxy_pass http://82.156.219.55:18789; # 假设服务器B在80端口监听
|
||
# 或 proxy_pass https://ip2:443; # 如果服务器B也配置了HTTPS
|
||
|
||
# 以下为关键代理头设置,确保正确传递信息
|
||
proxy_set_header Host $host;
|
||
proxy_set_header X-Real-IP $remote_addr;
|
||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||
proxy_set_header X-Forwarded-Proto $scheme;
|
||
proxy_set_header X-Forwarded-Host $server_name;
|
||
|
||
# 可选:优化设置
|
||
proxy_buffering off;
|
||
proxy_http_version 1.1;
|
||
proxy_set_header Connection "";
|
||
|
||
}
|
||
}
|
||
```
|
||
|
||
现在访问`https://openclaw.wantsong.life`可以打开页面。但是Token不起作用。
|
||
|
||
## 我的问题
|
||
|
||
能否直接访问`https://openclaw.wantsong.life`,不需要SSH连接,直接输入Token连接。
|
||
|
||
|
||
这是最新的配置:
|
||
|
||
```json
|
||
"gateway": {
|
||
"port": 18789,
|
||
"mode": "local",
|
||
"bind": "lan",
|
||
"controlUi": {
|
||
"allowedOrigins": [
|
||
"https://openclaw.wantsong.life",
|
||
"http://82.156.219.55:18789"
|
||
],
|
||
"dangerouslyAllowHostHeaderOriginFallback": false,
|
||
"allowInsecureAuth": false,
|
||
"dangerouslyDisableDeviceAuth": false
|
||
},
|
||
"auth": {
|
||
"mode": "token",
|
||
"token": "5eb77a151f15431db1cf9a8be66843edb0f5924e0534adf5"
|
||
},
|
||
"tailscale": {
|
||
"mode": "off",
|
||
"resetOnExit": false
|
||
}
|
||
},
|
||
```
|
||
|
||
现在的问题是,我用ssh后,本地访问localhost能访问,能连接;
|
||
但是访问https,页面能打开,但是输入token连接时报错:disconnected (1006): no reason
|
||
这个问题是什么?
|
||
|
||
|
||
这是典型的 **WebSocket 连接失败** 问题。错误码 `1006` 表示 WebSocket 异常关闭,通常是因为 **Nginx 反向代理没有正确配置 WebSocket 升级**。
|
||
|
||
OpenClaw 的 Control UI 使用 WebSocket 进行实时通信,Nginx 必须传递 `Upgrade` 头。
|
||
|
||
---
|
||
|
||
## 修复 Nginx 配置
|
||
|
||
在你的 Nginx `location /` 块中,**添加 WebSocket 升级配置**:
|
||
|
||
```nginx
|
||
location / {
|
||
proxy_pass http://82.156.219.55:18789;
|
||
|
||
# 关键代理头
|
||
proxy_set_header Host $host;
|
||
proxy_set_header X-Real-IP $remote_addr;
|
||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||
proxy_set_header X-Forwarded-Proto $scheme;
|
||
proxy_set_header X-Forwarded-Host $server_name;
|
||
|
||
# ========== WebSocket 升级(必须添加)==========
|
||
proxy_set_header Upgrade $http_upgrade;
|
||
proxy_set_header Connection "upgrade";
|
||
# =============================================
|
||
|
||
# 可选:优化设置
|
||
proxy_buffering off;
|
||
proxy_http_version 1.1;
|
||
proxy_cache_bypass $http_upgrade;
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 同时简化 `openclaw.json`
|
||
|
||
既然你只用 HTTPS 域名访问,可以清理掉 HTTP 的 Origin:
|
||
|
||
```json
|
||
"gateway": {
|
||
"port": 18789,
|
||
"mode": "local",
|
||
"bind": "lan",
|
||
"controlUi": {
|
||
"allowedOrigins": [
|
||
"https://openclaw.wantsong.life"
|
||
],
|
||
"dangerouslyAllowHostHeaderOriginFallback": false,
|
||
"allowInsecureAuth": false,
|
||
"dangerouslyDisableDeviceAuth": false
|
||
},
|
||
"auth": {
|
||
"mode": "token",
|
||
"token": "5eb77a151f15431db1cf9a8be66843edb0f5924e0534adf5"
|
||
},
|
||
"tailscale": {
|
||
"mode": "off",
|
||
"resetOnExit": false
|
||
}
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 操作步骤
|
||
|
||
### 1) 更新 Nginx 配置后重载
|
||
```bash
|
||
# 在中转服务器上执行
|
||
sudo nginx -t # 测试配置
|
||
sudo nginx -s reload # 重载(不中断连接)
|
||
```
|
||
|
||
### 2) 重启 OpenClaw Gateway
|
||
```bash
|
||
# 在 OpenClaw 服务器上执行
|
||
openclaw gateway restart
|
||
```
|
||
|
||
### 3) 清除浏览器缓存后重试
|
||
- 按 `Ctrl+Shift+R` 强制刷新
|
||
- 或打开开发者工具 → Network → 勾选 "Disable cache"
|
||
|
||
---
|
||
|
||
## 验证 WebSocket 是否工作
|
||
|
||
打开浏览器开发者工具 → Network → WS,然后连接:
|
||
|
||
**成功时:**
|
||
- 看到 `upgrade` 请求
|
||
- Status: `101 Switching Protocols`
|
||
- Connection 保持 open
|
||
|
||
**失败时(当前情况):**
|
||
- Status: `400` 或 `502` 或直接关闭
|
||
- 显示 `disconnected (1006)`
|
||
|
||
---
|
||
|
||
## 为什么 SSH 隧道能工作?
|
||
|
||
SSH 隧道是 **TCP 直连**,不经过 Nginx,所以 WebSocket 升级头不需要处理:
|
||
```
|
||
浏览器 → SSH 隧道 → OpenClaw Gateway (直连)
|
||
```
|
||
|
||
而域名访问是:
|
||
```
|
||
浏览器 → Nginx (需要 Upgrade 头) → OpenClaw Gateway
|
||
```
|
||
|
||
---
|
||
|
||
加上 `Upgrade` 和 `Connection` 头后应该就能正常连接了。如果还有问题,把浏览器 Console 和 Network 面板的报错贴出来。
|
||
|
||
|
||
---
|
||
|
||
|
||
现在有新的报错了:
|
||
|
||
pairing required
|
||
此设备需要网关主机的配对批准。
|
||
openclaw devices list
|
||
openclaw devices approve <requestId>
|
||
在手机上?从桌面运行 openclaw dashboard --no-open 复制完整 URL(包括 #token=...)。
|
||
Docs: Device pairing
|
||
|
||
我运行了 `openclaw dashboard --no-open`,得到的还是127的访问方式:
|
||
|
||
Dashboard URL: http://127.0.0.1:18789/#token=5eb77a151f15431db1cf9a8be66843edb0f5924e0534adf5
|
||
|
||
那么通过Https,我需要把我的地址放到openclaw devices list 里面么?
|
||
|
||
http://openclaw.wantsong.cn/#token=5eb77a151f15431db1cf9a8be66843edb0f5924e0534adf5
|