跳转到内容

安全与密钥

SyncTV 里有三类最重要的密钥,它们用途不同,不能混用。

配置用途是否必须稳定泄露或丢失的影响
jwt.secret签发登录 token可以轮换,但会影响登录状态泄露后攻击者可能伪造 token
security.opaque_server_setup_secretOPAQUE 密码认证必须稳定改错会导致 OPAQUE 密码记录无法验证
security.credential_encryption_key加密 Provider 凭据必须妥善保存丢失后已加密凭据可能无法读取

生产环境建议全部通过环境变量或 secret 文件注入,不要写在 Git 仓库里。

作用:签发访问 token、刷新 token 和游客 token。

要求:

  • 至少 32 个字符。
  • 高熵随机值。
  • 不要使用 change-me、项目名、域名、生日、普通单词等可猜值。

生成方式:

Terminal window
openssl rand -base64 32

配置示例:

jwt:
secret_file: "/run/secrets/jwt_secret"

环境变量:

Terminal window
SYNCTV_JWT_SECRET=...
SYNCTV_JWT_SECRET_FILE=/run/secrets/jwt_secret

轮换影响:

  • 旧 access token 会失效。
  • 旧 refresh token 也可能失效。
  • 用户需要重新登录。

如果怀疑泄露,应立即轮换。

默认值:1

作用:普通登录 token 的有效期。

建议:

  • 面向公网:1 到 2 小时。
  • 内网自用:可以略长,但不建议超过 12 小时。

默认值:30

作用:刷新 token 的有效期。用户在这个时间内可以无需重新输入密码换取新的 access token。

建议:

  • 普通自托管:30 天。
  • 更严格安全环境:7 天或更短。
  • 长期家庭使用:可以更长,但风险也更高。

默认值:4

作用:游客或匿名访问 token 的有效期。

如果你不开放游客能力,这个值影响较小。

默认值:60

作用:允许服务器和客户端之间存在少量时间误差。

如果多节点服务器时间不同步,token 可能提前过期或暂时不可用。生产环境更应该配置 NTP,而不是单纯调大这个值。

作用:加密敏感 Provider 凭据,例如媒体服务 token、API key、自定义 CA 相关 secret 等。

格式要求:

  • 必须是 64 个十六进制字符。
  • 等价于 32 字节 AES-256-GCM key。

生成方式:

Terminal window
openssl rand -hex 32

配置示例:

security:
credential_encryption_key_file: "/run/secrets/credential_encryption_key"

环境变量:

Terminal window
SYNCTV_SECURITY_CREDENTIAL_ENCRYPTION_KEY=...
SYNCTV_SECURITY_CREDENTIAL_ENCRYPTION_KEY_FILE=/run/secrets/credential_encryption_key

什么时候可以为空:

  • 只做本地临时测试。
  • 不使用需要保存敏感凭据的 Provider。

生产建议:

  • 一定配置。
  • 备份到密码管理器或 secret manager。
  • 不要随意轮换。轮换前需要考虑已加密数据迁移。

作用:OPAQUE 密码认证使用的服务端 setup secret。

OPAQUE 是一种避免服务器直接处理明文密码的密码认证协议。这个 secret 参与服务器端密码验证材料的生成,因此必须长期稳定。

要求:

  • 必填。
  • 至少 32 字符。
  • 不能是占位值。

生成方式:

Terminal window
openssl rand -base64 48

配置示例:

security:
opaque_server_setup_secret_file: "/run/secrets/opaque_server_setup_secret"

环境变量:

Terminal window
SYNCTV_SECURITY_OPAQUE_SERVER_SETUP_SECRET=...
SYNCTV_SECURITY_OPAQUE_SERVER_SETUP_SECRET_FILE=/run/secrets/opaque_server_setup_secret

非常重要:

  • 不要跟 jwt.secret 使用同一个值。
  • 不要每次容器启动随机生成新值。
  • Kubernetes/Helm 升级时必须保留原值。
  • 如果改错,已有 OPAQUE 密码记录可能无法继续登录。

这组配置控制用户账户密码强度。它不控制房间密码。

默认配置:

password_complexity:
min_length: 8
require_uppercase: true
require_lowercase: true
require_digit: true
require_special: false
max_repeated_chars: 3

密码最短长度。生产建议至少 12,但如果你有很多非技术用户,过高会增加使用成本。

是否要求至少一个大写字母。

是否要求至少一个小写字母。

是否要求至少一个数字。

是否要求特殊字符。

特殊字符能提高复杂度,但会增加移动端、电视端输入成本。如果客户端输入体验有限,可以保持 false,通过更长密码提高安全性。

限制连续重复字符数量。例如设置为 3 时,aaaa 这类连续重复会被拒绝。

设置为 0 表示关闭这个检查。

虽然它们在 server 下,但安全影响很大。

只填写你真正使用的前端域名:

server:
cors_allowed_origins:
- "https://app.example.com"

不要把随便找到的“允许所有跨域”配置复制到生产环境。

只填写你控制的反向代理 IP 或内网网段。不要填写全网。

WebAuthn/passkey 的底层配置在 WebAuthn 配置 页面解释。

用户级别的两步验证不是通过全局 YAML 配置强制开启,而是用户偏好设置。开启两步验证前,用户必须拥有至少两种本地验证方式,例如:

  • password
  • webauthn/passkey
  • email

OAuth2 登录不参与本地 2FA,但开启 2FA 的用户仍然可以使用 OAuth2 登录。