Files
Octop/docker/docker-entrypoint.sh
veenyi cf9d700d61 fix(fnos): 安装向导接管管理员密码,根治 Octop123 被弱密码黑名单拒绝导致 FPK 无法启动 (issue #502)
根因:应用密码策略(src/octop/infra/users/password.py)的常见弱密码黑名单包含 octop123,
而 FnOS FPK 把初始密码写死为 Octop123,首次启动 octop init 报 "password is too common"
直接退出("Octop process exited early"),全新安装的 native / docker FPK 均无法启动。

修复内容:
- 安装向导(wizard/install,native + docker)提供两种密码方式:
  ① 自己输入密码:install_init / install_callback 按应用侧策略预校验(≥8 位、
     含字母和数字、不在常见弱密码黑名单),无效密码在安装阶段直接拦截并中文提示;
  ② 自动生成随机密码(推荐):octop_generate_password 生成 16 位强密码。
- 随机/自定义密码双通道送达:
  ① 应用「设置」窗口(wizard/config)顶部直接显示当前账号与密码(安装/改密时
     由回调渲染占位符模板),用户免翻文件;
  ② 数据目录 octop-login.txt 回落备份,永久保留、随改密同步更新。
- 启动器与容器入口三重兜底:.env 无密码时自动生成;init 因密码策略被拒时
  自动改用随机密码重试一次,并回写 .env 保持一致 —— 存量坏 .env(Octop123)
  升级后首次启动即被救活,不再依赖用户手工清理。
- 应用「设置」窗口支持改密:保持不变 / 随机生成 / 自定义(config_init 前置校验),
  本地版走官方 CLI `octop user passwd` 离线改密(停服→改密→启服防写库冲突),
  Docker 版走 `docker exec octop octop user passwd`;凭据三处同步(.env /
  octop-login.txt / 设置窗口显示)。
- 官方 CLI 管理保障:安装回调注册 octop / octop-cli 到 PATH 并做 `octop version`
  冒烟验证(结果写入安装日志)。
- docker/docker-entrypoint.sh:未设置 OCTOP_DEFAULT_PASSWORD 时自动生成随机密码,
  指定密码被策略拒绝时自动回退随机;credential.txt 增加访问地址行。
- compose / .env.example / README / user-guide 移除 Octop123 默认值与宣传文案。

本地验证:19 个 shell 脚本 bash -n 全过;7 个向导 JSON 全部合法;密码生成 300/300
通过字符集/长度/首字母/末位数字断言;octop_validate_password 与官方
validate_password_policy 对拍 19/19 一致、黑名单 14 项逐字一致;渲染链端到端模拟
(生成→校验→回落保存→设置窗口渲染→JSON 复检)通过。
2026-09-12 08:15:24 +08:00

99 lines
3.8 KiB
Bash
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env bash
# =============================================================================
# Octop 容器入口脚本
#
# 环境变量:
# HOME — 必须为 /data,使 ~/.octop 映射到数据卷
# OCTOP_DEFAULT_PASSWORD — 首次管理员密码(须 ≥8 位且含字母和数字;
# 不设置则自动生成随机密码,凭据写入
# /data/.octop/credential.txt)
# OCTOP_ADMIN_USERNAME — 首次管理员用户名(默认: admin)
# OCTOP_ADMIN_DISPLAY_NAME — 可选显示名
# OCTOP_PORT — 服务端口(默认: 8088)
#
# 密码兜底(修复 issue #502):应用侧密码策略带常见弱密码黑名单(含
# Octop123),旧版默认密码会让 octop init 报 "password is too common"
# 退出、容器反复重启。现在:未设置密码时自动生成随机强密码;指定的
# 密码被策略拒绝时也自动改用随机密码重试,保证容器一定能完成首次初始化。
# =============================================================================
set -euo pipefail
export HOME="${HOME:-/data}"
OCTOP_HOME="${HOME}/.octop"
DB_FILE="${OCTOP_HOME}/octop.db"
CREDENTIAL_FILE="${OCTOP_HOME}/credential.txt"
ADMIN_USERNAME="${OCTOP_ADMIN_USERNAME:-admin}"
ADMIN_DISPLAY_NAME="${OCTOP_ADMIN_DISPLAY_NAME:-Admin}"
PORT="${OCTOP_PORT:-8088}"
# 生成随机密码(首字符字母、末字符数字,避开易混淆字符)。
octop_random_password() {
local letters='abcdefghijkmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ'
local digits='23456789'
local all="${letters}${digits}" n=16 out="" i b
b="$(od -An -N1 -tu1 /dev/urandom 2>/dev/null | tr -d '[:space:]')"
out="${letters:$((b % ${#letters})):1}"
for ((i = 1; i < n - 1; i++)); do
b="$(od -An -N1 -tu1 /dev/urandom 2>/dev/null | tr -d '[:space:]')"
out+="${all:$((b % ${#all})):1}"
done
b="$(od -An -N1 -tu1 /dev/urandom 2>/dev/null | tr -d '[:space:]')"
out+="${digits:$((b % ${#digits})):1}"
printf '%s' "$out"
}
DEFAULT_PASSWORD="${OCTOP_DEFAULT_PASSWORD:-}"
if [ ! -f "$DB_FILE" ]; then
echo "[entrypoint] 首次启动,正在初始化 Octop..."
if [ -z "$DEFAULT_PASSWORD" ]; then
DEFAULT_PASSWORD="$(octop_random_password)"
echo "[entrypoint] 未设置 OCTOP_DEFAULT_PASSWORD,已自动生成随机密码。"
fi
if ! octop init \
--yes \
--admin-username "$ADMIN_USERNAME" \
--admin-password "$DEFAULT_PASSWORD" \
${ADMIN_DISPLAY_NAME:+--admin-display-name "$ADMIN_DISPLAY_NAME"}; then
echo "[entrypoint] 指定的初始密码未通过应用密码策略(过弱或过于常见),改用随机密码重试 ..."
DEFAULT_PASSWORD="$(octop_random_password)"
octop init \
--yes \
--admin-username "$ADMIN_USERNAME" \
--admin-password "$DEFAULT_PASSWORD" \
${ADMIN_DISPLAY_NAME:+--admin-display-name "$ADMIN_DISPLAY_NAME"}
fi
cat > "$CREDENTIAL_FILE" << EOF
Octop Login Credential
======================
URL: http://<host>:${PORT}
Username: ${ADMIN_USERNAME}
Password: ${DEFAULT_PASSWORD}
Please change this password after first login!
- Via Web: avatar menu → Change password
- Via CLI: docker exec -it <container> octop user passwd --username $ADMIN_USERNAME
This file is rewritten whenever the initial password is (re)generated here.
If you changed the password inside the Web console, that password wins.
EOF
chmod 600 "$CREDENTIAL_FILE"
echo "[entrypoint] 凭据已保存至: $CREDENTIAL_FILE"
fi
if [ $# -eq 0 ]; then
echo "[entrypoint] 正在启动 Octop,端口 $PORT..."
exec octop run --host 0.0.0.0 --port "$PORT"
fi
if [ "$1" = "octop" ]; then
echo "[entrypoint] 执行命令: $*"
exec "$@"
fi
echo "[entrypoint] 执行命令: $*"
exec "$@"