rdp-manager 服务端自部署指南

面向想用 rdp-manager 管理自己机器的用户:在自己的服务器上跑起管理服务端,

让你的所有 Windows 机器通过它互相连接。全程约 30 分钟(其中大部分在等证书签发)。

0. 你需要什么

要求说明
一台 Linux 服务器任意发行版,Docker + Docker Compose1C1G 即可(管理面很轻)
一个域名已解析到该服务器frps.example.com
一张 TLS 证书免费证书即可(Let's Encrypt / 腾讯云 / 阿里云)用于管理端 HTTPS
frp 数据面(可选但推荐)frps ≥ 0.61,一台可达的服务器RDP 流量的中继;与本文的管理面可以同机

架构速览(与被控端/控制端的关系):

Windows 机器 A(控制台 + Agent) ──HTTPS──> 管理服务端(本文部署) <──HTTPS── Windows 机器 B(控制台 + Agent)
        │                                                            │
        └──────────── stcp 加密隧道(经 frps 中继,RDP 流量) ────────────┘

管理面只走 API(登录/机器列表/出票),RDP 流量全部经 frps 的 stcp 隧道端到端加密,
管理服务器看不到 RDP 明文。

1. 准备 frps 数据面(已有可跳过)

如果你还没有 frps,最简配置(frps.toml):

bindAddr = "0.0.0.0"
bindPort = 7000
auth.token = "<一个足够随机的长字符串>"

启动(docker):

docker run -d --name frps --restart unless-stopped \
  --network host \
  -v /path/to/frps.toml:/etc/frp/frps.toml \
  fatedier/frps:0.61.1

开放防火墙/安全组的 7000 端口(stcp 模式不占用其他公网端口)。

2. 部署管理服务端

2.1 获取服务端

从发布页下载对应平台的二进制,或从源码构建:

# 源码构建(Linux amd64)
git clone https://gitee.com/birdman1992/rdp-manager.git
cd rdp-manager
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -trimpath -ldflags "-s -w" \
  -o rdp-manager-server ./cmd/server

2.2 目录布局与配置

在工作目录(如 /opt/rdp-manager)准备:

/opt/rdp-manager/
├── rdp-manager-server          # 二进制
├── docker-compose.yml          # 见下
├── Dockerfile                  # 见下
├── .env                        # 密钥与 frps 信息(权限 600)
└── data/                       # SQLite 数据(自动创建)

Dockerfile(运行时镜像,二进制 COPY 即可):

FROM alpine:3.20
RUN adduser -D -u 10001 app
COPY rdp-manager-server /usr/local/bin/rdp-manager-server
USER app
VOLUME /data
ENV RDP_LISTEN=:8080 RDP_DB=/data/rdp-manager.db
EXPOSE 8080
ENTRYPOINT ["rdp-manager-server", "serve"]

docker-compose.yml:

services:
  rdp-manager-server:
    build: .
    container_name: rdp-manager-server
    restart: unless-stopped
    ports:
      - "127.0.0.1:8081:8080"     # 只暴露给本机 nginx,不直接对公网
    env_file: .env
    volumes:
      - ./data:/data
      - ./public/downloads:/downloads    # 可选:发布页下载目录
    healthcheck:
      test: ["CMD", "wget", "-qO-", "http://127.0.0.1:8080/healthz"]
      interval: 30s
      timeout: 5s
      retries: 3

注:data/ 目录需可被容器内 uid 10001 写入:sudo chown -R 10001:10001 data

.env(两个密钥用 rdp-manager-server keygen 各生成一份):

RDP_LISTEN=:8080
RDP_DB=/data/rdp-manager.db
RDP_JWT_SECRET=<64位十六进制,server keygen 生成>
RDP_MASTER_KEY=<64位十六进制,server keygen 生成>
RDP_FRPS_ADDR=frps.example.com     # 下发给两端做 stcp 中继的公网地址
RDP_FRPS_PORT=7000
RDP_FRPS_TOKEN=<frps 的 auth.token,与 1. 中一致>
RDP_DOWNLOADS_DIR=/downloads       # 可选:挂载发布包后启用下载端点

2.3 起容器并建号

cd /opt/rdp-manager
docker compose up -d --build
curl -s http://127.0.0.1:8081/healthz          # 应返回 {"ok":true}

# 建第一个账号(幂等;重复执行即重置口令)
docker exec rdp-manager-server rdp-manager-server \
  seed -user <你的用户名> -pass <你的口令>

3. HTTPS 接入(nginx 反代)

管理端必须走 HTTPS(登录口令与令牌会明文过公网)。以独立子域 rdp.example.com 为例:

# /etc/nginx/conf.d/rdp.conf
limit_req_zone $binary_remote_addr zone=rdp_login:10m rate=10r/m;

server {
    listen 443 ssl;
    http2 on;
    server_name rdp.example.com;

    ssl_certificate     /etc/nginx/certs/rdp.example.com.pem;
    ssl_certificate_key /etc/nginx/certs/rdp.example.com.key;

    location /api/auth/ {
        limit_req zone=rdp_login burst=5 nodelay;   # 登录端点限流
        proxy_pass http://127.0.0.1:8081;
        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;
    }

    location / {
        proxy_pass http://127.0.0.1:8081;
        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;
    }
}

DNS 加一条 A 记录 rdp.example.com → 服务器 IP,签一张免费证书(各云厂商流程约 10 分钟),
nginx -t 通过后 reload。

证书有有效期(免费证书一般 90 天/1 年),记台账到期前续签。

若你的 nginx 跑在 docker 容器里:注意单文件挂载的 inode 脱钩问题

(宿主机编辑后容器看不到),改配置建议用目录挂载或 docker cp 进容器。

4. 客户端接入

在每台 Windows 机器上:

  • https://rdp.example.com/ 下载发布包,解压到任意目录
  • 双击 console.exe,服务端地址填 https://rdp.example.com,用 2.3 建的账号登录
  • 点「允许控制本机(绑定)」——机器出现在列表,即可被其他机器一键连接
  • 无人值守常驻:管理员 PowerShell 运行包内 install.ps1 -ServerUrl https://rdp.example.com

    5. 部署验证

    服务器上:

    curl -s https://rdp.example.com/healthz     # {"ok":true}
    curl -s -o /dev/null -w '%{http_code}' https://rdp.example.com/    # 200(产品页)

    客户端全链路(在任一 Windows 机器上,仓库 scripts/e2e-remote.ps1):

    .\scripts\e2e-remote.ps1 -ServerUrl https://rdp.example.com `
      -User <账号> -Pass <口令>
    # 10 步全绿:登录→绑定→frps 注册→出票兑换→visitor→RDP X.224 协商往返→清理

    6. 运维速查

    场景命令/位置
    看日志docker logs rdp-manager-server
    重置某人密码docker exec rdp-manager-server rdp-manager-server seed -user <名> -pass <新口令>
    升级服务端替换二进制 → docker compose up -d --build(数据在 ./data,升级不丢)
    备份备份 data/rdp-manager.db(SQLite 单文件)+ .env(密钥丢了 secretKey 无法解密)
    机器离线判定心跳超 90 秒;Agent 30s 一次,偶发离线通常是网络抖动
    发布新客户端上传 zip 到 public/downloads/,更新产品页版本号

    7. 安全检查清单

  • ☐ RDP_JWT_SECRET / RDP_MASTER_KEY 足够随机(64 位十六进制),.env 权限 600
  • ☐ 8081 只绑 127.0.0.1,公网仅 443(nginx)可达
  • ☐ 登录端点已限流(上面 nginx 配置已含)
  • ☐ frps token 足够长且未在任何公开位置出现
  • ☐ 证书续期已记台账
  • ☐ 定期备份 data 库与 .env
  • 祝部署顺利。遇到问题:先看 docker logs,再看客户端 Agent 日志
    (%ProgramData%\rdp-manager\agent-console.log)。