启动速查¶
按使用场景分类的命令速查表。每条命令都可以直接 copy-paste 用——把
X / Y 换成你自己的账号密码即可。
约定
X= 登录账号(手机号 / 牛牛号 / moomoo ID / 邮箱)Y= 密码明文Z= 短信验证码(首次登录时服务端发到手机)
1. 账号平台速选¶
富途有两个独立账号体系:牛牛(auth.futunn.com)和 moomoo
(auth.moomoo.com)。两边都支持数字 ID / 手机号 / 邮箱三种格式
作为 --login-account。同一手机号 / 邮箱可以分别在两边注册独立账号
(不同密码)——用 --platform 显式选平台避免登到错账号。
# 牛牛账号(默认,CN / HK 归属)—— 数字 ID / 手机号 / 邮箱 任选一种
./futu-opend --login-account 12345678 --login-pwd Y
./futu-opend --login-account '+86-13900000000' --login-pwd Y
./futu-opend --login-account 'user@example.com' --login-pwd Y
# moomoo 账号(US / SG / AU / JP / CA 归属)—— 同样三种格式,加 --platform moomoo
./futu-opend --login-account 87654321 --login-pwd Y --platform moomoo
./futu-opend --login-account '+1-4155551234' --login-pwd Y --platform moomoo
./futu-opend --login-account 'user@example.com' --login-pwd Y --platform moomoo
手机号格式必须带区号 + 破折号
手机号请严格使用 +<区号>-<号码> 格式,如 +86-13900000000 /
+1-4155551234,否则将导致识别失败。
2. 首次部署(推荐流程)¶
强烈推荐分两步:先前台 setup 一次完成 SMS,再启动生产实例。这样 systemd / Docker 场景不会在启动时卡 SMS。
# 第一步:前台跑一次 setup(会交互要求输入短信验证码)
./futu-opend --setup-only \
--login-account X --login-pwd Y --platform moomoo
# 第二步:正常启动(自动用缓存凭据跳过 SMS)
./futu-opend --login-account X --login-pwd Y --platform moomoo \
--rest-port 22222 --grpc-port 33333
--setup-only 完成认证后立即退出,不启动任何 server。凭据会写到
~/.futu-opend-rs/credentials-<hash>.json,30 天内不再要 SMS。
3. 生产环境(无人值守)¶
systemd¶
/etc/systemd/system/futu-opend.service:
[Unit]
Description=FutuOpenD Rust Gateway
After=network-online.target
[Service]
Type=simple
User=futu
Environment=FUTU_ACCOUNT=...
Environment=FUTU_PWD=...
ExecStart=/usr/local/bin/futu-opend \
--login-account ${FUTU_ACCOUNT} --login-pwd ${FUTU_PWD} \
--platform moomoo \
--rest-port 22222 --grpc-port 33333 \
--rest-keys-file /etc/futu-opend/keys.json \
--grpc-keys-file /etc/futu-opend/keys.json \
--audit-log /var/log/futu-opend/audit.jsonl
Restart=on-failure
RestartSec=10
[Install]
WantedBy=multi-user.target
部署步骤:
# 1. 前台跑一次 setup 写 credentials(用 futu 用户身份)
sudo -u futu /usr/local/bin/futu-opend --setup-only \
--login-account X --login-pwd Y --platform moomoo
# 2. 启动 systemd 服务
sudo systemctl enable --now futu-opend
Docker¶
docker run -d --name futu-opend --restart unless-stopped \
-p 11111:11111 -p 22222:22222 -p 33333:33333 \
-v ~/.futu-opend-rs:/root/.futu-opend-rs \
-v /etc/futu-opend/keys.json:/etc/futu-opend/keys.json:ro \
ghcr.io/futuleaf/futu-opend-rs:rs-v1.4.17 \
--login-account X --login-pwd Y --platform moomoo \
--rest-port 22222 --grpc-port 33333 \
--rest-keys-file /etc/futu-opend/keys.json \
--grpc-keys-file /etc/futu-opend/keys.json
凭据目录挂载
-v ~/.futu-opend-rs:/root/.futu-opend-rs 至关重要 —— 容器重建后
device_id 和 credentials 需要持久化,否则每次重启都要重新 SMS 验证。
4. 多实例并行(牛牛 + moomoo 同时跑)¶
常见场景:一个账号在牛牛、一个在 moomoo,想同时连两个后端。端口必须错开,
否则 futucli 默认连 127.0.0.1:11111 会指向错的实例。
# 实例 A:牛牛账号(默认端口)
./futu-opend --login-account 12345678 --login-pwd Y1 \
--rest-port 22222 --grpc-port 33333 &
# 实例 B:moomoo 账号(端口 +1)
./futu-opend --login-account '+86-13900000000' --login-pwd Y2 --platform moomoo \
--port 11112 --rest-port 22223 --grpc-port 33334 &
v1.4.16 起启动时会检测端口占用,冲突会打 WARN 日志提醒你。
客户端访问:
5. 调试与开发¶
# 详细日志(看协议帧 + HTTP 请求响应)
./futu-opend --login-account X --login-pwd Y --log-level trace
# 只看鉴权流程(POST raw response / salt / tgtgt 关键行)
./futu-opend --login-account X --login-pwd Y --log-level debug 2>&1 \
| grep -E "POST.*raw|salt|tgtgt|error_code"
# JSON 结构化日志(给 logging pipeline / Loki / ELK)
./futu-opend --login-account X --login-pwd Y --json-log
# 单独写审计日志(只记 auth / 交易事件,常规日志不变)
./futu-opend --login-account X --login-pwd Y \
--audit-log /var/log/futu-opend/audit.jsonl
6. 故障恢复¶
device_id 被锁(ret_type=15 或 ret_type=21)¶
# 方法 A:清空文件 + 重新 setup(推荐,最彻底)
./futu-opend --reset-device --setup-only \
--login-account X --login-pwd Y --platform moomoo
# 方法 B:换一个特定 device_id(不触发新 SMS 的情况,比如迁移机器时)
./futu-opend --device-id abcdef0123456789 \
--login-account X --login-pwd Y
# 方法 C:手动清所有状态(怀疑所有缓存都坏了)
rm -rf ~/.futu-opend-rs/
v1.4.17 起,SMS 验证码输错(error_code=21)自动轮换 device_id 重试 2 次,
一般不用手动处理。
密码对了但 error_code=2 账号密码不匹配¶
几乎一定是平台选错了(moomoo 账号发到 futunn 了,或反之):
连接卡住(Connection timed out)¶
v1.4.10 加了 10s 超时,v1.4.11 按地区选 IP 池,v1.4.12 并发 3 IP 竞速。 新版一般不会卡。如仍挂:
# 看具体卡在哪
./futu-opend --login-account X --login-pwd Y --log-level debug
# 如果是海外账号但所在区域 IP 全不通(ISP 屏蔽),只能走 VPN
客户端侧常见症状¶
| 症状 | 原因 | 处理 |
|---|---|---|
connect refused :11111 |
网关根本没起来 / 被别的进程占端口 | 看 futu-opend 控制台日志;v1.4.16+ 启动时会 WARN 端口占用 |
account/password mismatch |
登录凭证错 | 改 --login-account / --login-pwd,或加 --platform moomoo 选对平台 |
device not authorized |
新设备需短信验证 | 前台跑一次 --setup-only 输入验证码 |
no subscription |
先 subscribe 再 quote | 先 POST /api/subscribe 再 POST /api/quote |
gRPC UNAUTHENTICATED |
没带 Bearer Token 或 key 错 | 看下一节配 --grpc-keys-file |
7. 登录密码安全存储(v1.4.18+)¶
避免明文密码出现在 ps aux / ~/.bash_history / 配置文件 backup 里。
opend 按 7 层优先级查密码,推荐用 OS keychain:
# 一次性存到 keychain(macOS Keychain / Linux Secret Service / Windows Credential Manager)
futucli set-login-pwd --account 12345678
# 交互式输入密码,不回显不进 history
# 之后启动 opend 不带 --login-pwd,自动从 keychain 读
./futu-opend --login-account 12345678 --platform moomoo --rest-port 22222
7 层优先级(高到低)¶
| 优先级 | 方式 | 适用场景 | 安全 |
|---|---|---|---|
| 1 | --login-pwd-file <path> |
Docker secrets / systemd LoadCredential | ⭐⭐⭐⭐⭐ |
| 2 | --login-pwd <plain> |
老脚本兼容(会打 WARN) | ⭐ 暴露在 argv |
| 3 | --login-pwd-md5 <hex> |
同上,md5 等同明文 | ⭐ 暴露在 argv |
| 4 | FUTU_PWD env var |
CI / cron / bash export | ⭐⭐⭐ 无 argv 泄露 |
| 5 | OS keychain | 长期本地 / 服务器(推荐默认) | ⭐⭐⭐⭐ |
| 6 | 交互式 prompt(stdin 是 tty) | 本地开发随手跑 | ⭐⭐⭐⭐ 不回显不进 history |
| 7 | 以上都没有 | 报错退出 | — |
部署场景选择指南¶
# A. 本地长期使用(最推荐)
futucli set-login-pwd --account 12345678 # 一次性
./futu-opend --login-account 12345678 ... # 每次启动自动读 keychain
# B. Docker(用 secret 挂载到文件)
docker run -v pwd-file:/run/secrets/futu-pwd:ro \
ghcr.io/futuleaf/futu-opend-rs \
--login-account X --login-pwd-file /run/secrets/futu-pwd ...
# C. systemd(LoadCredential 从 EncryptedDir / TPM 读)
# /etc/systemd/system/futu-opend.service
[Service]
LoadCredential=login-pwd:/etc/futu/pwd
ExecStart=/usr/local/bin/futu-opend \
--login-account X \
--login-pwd-file ${CREDENTIALS_DIRECTORY}/login-pwd ...
# D. CI / cron(FUTU_PWD env)
FUTU_PWD='...' ./futu-opend --login-account X ...
# E. 本地随手跑(啥都不配,会弹 prompt)
./futu-opend --login-account 12345678 ...
# → "Login password for account 12345678: "
清除密码¶
8. REST / gRPC / 核心 WebSocket 鉴权¶
生产环境强烈建议加 Bearer Token 鉴权,否则 /api/* 端口对所有客户端
开放。
# 1. 生成 API key(限定 scope + 过期时间)
futucli gen-key \
--keys-file ~/.futu-opend-rs/keys.json \
--scopes quote,trade:read \
--expires 30d
# 2. 启动 opend 带 keys-file
./futu-opend --login-account X --login-pwd Y \
--rest-keys-file ~/.futu-opend-rs/keys.json \
--grpc-keys-file ~/.futu-opend-rs/keys.json \
--ws-keys-file ~/.futu-opend-rs/keys.json \
--rest-port 22222 --grpc-port 33333 --websocket-port 44444
# 3. 客户端带 Bearer token 访问
curl -H "Authorization: Bearer <key_plaintext>" \
http://localhost:22222/api/qot/get_global_state
详细的 scope 表和 key 管理见 API Key 授权配置。
9. 网络受限场景(进阶)¶
走 HTTPS 代理(调试 / 抓包)¶
# --auth-server 显式指定时,不会被 attribution 自动切换覆盖(v1.4.15+)
./futu-opend --login-account X --login-pwd Y \
--auth-server http://127.0.0.1:19998
用自写的 HTTP 代理(比如 mitmproxy)可以抓到完整的 /authority/salt、
POST /authority/ 请求体,用于调试账号识别问题。
海外账号 IP 不通¶
富途的海外 IP 偶尔被 ISP 屏蔽。现象:所有 HK/US 地区的 IP 全 connect timeout(10s 后失败),gateway 进 offline mode。
# 先确认是不是网络问题
for ip in 101.32.217.163 43.135.111.64; do
nc -vz $ip 9595 # 或 `timeout 5 bash -c "</dev/tcp/$ip/9595"`
done
- 全 FAIL,CN IP 能通 → ISP 屏蔽了海外段 → 走 VPN
- 全 FAIL,443 能通但 9595 不通 → 防火墙挡 9595 → IT 开端口
- 部分通 → 等 v1.4.12 的并发竞速自动选通的 IP
10. 凭据文件位置¶
v1.4.17 起所有持久化文件统一在 ~/.futu-opend-rs/:
~/.futu-opend-rs/
├── device-<hash>.dat # 16-hex device_id(每 account 一份)
├── credentials-<hash>.json # device_sig + tgtgt + rand_key + uid
└── keys.json # (可选)API key 文件
<hash> = md5(normalized_account)[..16],所以 +86-13900000000 和
13900000000 共享同一份文件(归一化会把区号拆出去)。
什么时候删这些文件:
| 情况 | 删哪个 |
|---|---|
| device_id 被服务端锁定 | device-<hash>.dat + credentials-<hash>.json(或用 --reset-device) |
| 换了密码 | credentials-<hash>.json 保留,让重新 SMS 验证 |
| 切换平台(futunn ↔ moomoo) | 无需删,两个平台有独立缓存 |
| 彻底清理 | rm -rf ~/.futu-opend-rs/ |
索引¶
- 第一次跑起来:快速开始
- 深入主题:API Key 授权配置 / MCP 接入 LLM / 部署到生产
- 完整 CLI 参数表:CLI 参数
- 遇到新问题:Contact 反馈