11 KiB
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 添加以下配置:
# 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终止:
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 |
操作步骤(反向代理方案)
- 在服务器A的Nginx配置中添加上述
bbb.xxx.com的代理配置。 - 将您的SSL证书上传至服务器A,并配置正确路径。
- 在服务器B上配置HTTP服务(如上述简化配置)。
- 确保服务器A的防火墙允许443端口入站,且服务器A能访问服务器B的80端口。
- 重载两台服务器的Nginx配置。
核心优势
- 无需等待DNS生效:修改立即生效。
- 统一SSL管理:所有子域名的证书可在服务器A集中管理。
- 灵活路由:未来可轻松更改后端服务器,用户无感知。
这个方案非常适合需要集中管理或频繁变更后端服务的场景。
gateway in openclaw.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配置为:
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连接。
这是最新的配置:
"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 升级配置:
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:
"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 配置后重载
# 在中转服务器上执行
sudo nginx -t # 测试配置
sudo nginx -s reload # 重载(不中断连接)
2) 重启 OpenClaw Gateway
# 在 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 在手机上?从桌面运行 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