跳转至

安全说明

安全架构概览

flowchart LR
    Client["客户端请求"] --> CORS["CORS 中间件<br/>来源校验"]
    CORS --> JWT["JWT 中间件<br/>令牌验证(白名单跳过)"]
    JWT --> Router["路由处理器"]
    Router --> Access["设备访问控制<br/>can_access() 权限检查"]
    Access --> Proxy["设备转发<br/>WebSocket 加密传输"]

身份认证

JWT 令牌

使用 PyJWT + HS256 对用户身份进行签名。

  • 密钥通过 CLOUD_JWT_SECRET 配置,生产环境要求至少 32 字符
  • 令牌有效期默认 72 小时,可通过 CLOUD_JWT_EXPIRE_HOURS 调整
  • 客户端通过 Authorization: Bearer <token> 头部传递令牌

用户管理

用户通过 CLOUD_AUTH_USERS 环境变量以 JSON 格式配置:

{
  "admin": {
    "password": "strong-password",
    "role": "admin",
    "display_name": "系统管理员"
  },
  "operator": {
    "password": "operator-password",
    "role": "user",
    "display_name": "操作员"
  }
}

设备认证

设备通过预设的共享 Token 认证:

  1. 建立 WebSocket 连接,携带 X-Device-ID 头部
  2. 发送 register 帧,包含 token 字段
  3. 服务端与 CLOUD_DEVICE_TOKEN 比对,匹配后标记设备为已注册
  4. 未通过认证的设备无法接收代理请求

设备绑定与权限隔离

  • 非管理员用户只能访问绑定的设备
  • 管理员(role == "admin")可访问所有设备
  • 绑定关系持久化在 device_bindings.json 文件中

生产配置校验

config.validate_production_config()CLOUD_ENV=production 时执行:

检查项 失败条件
JWT 密钥强度 使用默认值或长度 < 32 字符
设备 Token 使用默认值或以 replace-with- 开头
管理员密码 使用默认值或以 replace-with- 开头

全部通过后服务启动;否则抛出 RuntimeError 拒绝启动。

CORS 策略

config.CORS_ORIGINS 明确定义允许的跨域来源。生产环境中不应包含通配符或不可信来源。

固件安全

下位机固件采用 ECDSA P-256 + SHA-256 签名链保护:

  • 固件在受控构建环境签名(私钥不进入 API 服务器)
  • 上传后服务端验证镜像头结构、摘要和 CRC
  • 版本发布和激活全程记录审计日志

通信安全

层次 协议 安全措施
客户端 → Nginx HTTPS TLS 1.3,由 Nginx 终止
Nginx → Cloud API HTTP 内网通信,127.0.0.1
设备 → Cloud API WSS WebSocket over TLS
设备请求代理 JSON/WS 设备 Token 认证

威胁模型

威胁 缓解措施
未授权 API 访问 JWT 中间件 + 路由白名单
设备仿冒 共享 Token + 设备 ID
跨域攻击 严格 CORS 白名单
JWT 伪造 HS256 签名 + 生产密钥强度校验
固件篡改 ECDSA 签名 + SHA-256 摘要校验
配置泄露 环境变量 + .gitignore 排除 .env

密钥管理建议

  1. 生成强随机密钥
# PowerShell 生成 64 字符随机 Token
$rand = -join ((65..90) + (97..122) + (48..57) | Get-Random -Count 64 | ForEach-Object {[char]$_})
Write-Output $rand
  1. 存储在环境变量或密钥管理服务(KMS/HashiCorp Vault)中,不要提交到代码仓库

  2. 定期轮换密钥,同时维护旧密钥的短时窗口以平滑过渡

  3. 固件签名私钥使用硬件安全模块(HSM)或受控构建机管理