Plombery 生产部署指南:从 CORS、密钥管理到路径穿越防护的 8 个安全最佳实践
【免费下载链接】plomberyPython task scheduler with a user-friendly web UI项目地址: https://gitcode.com/gh_mirrors/pl/plombery
Plombery 是一款带用户友好 Web UI 的 Python 任务调度器(Python task scheduler)。当你要把 Plombery 从本地开发搬到生产环境时,默认的宽松配置(CORS 全放行、弱会话密钥、明文密钥)会成为安全隐患。本文将带你完成 Plombery 生产部署的 8 个安全加固步骤:限制 CORS 来源、启用 OAuth 登录、更换会话密钥、用环境变量管理密钥、路径穿越防护、生产数据库配置、前端 URL 设置与同源反向代理部署,帮助新手用最少改动获得一个安全可靠的 Plombery 任务调度平台。
部署前先了解:Plombery 的配置从哪里读?
Plombery 支持三种配置来源(详见 docs/configuration/index.md):
- 环境变量(
.env文件,适合放密钥) - YAML 配置文件
plombery.config.yaml(适合提交到版本库) - 两者结合——官方推荐的方式:YAML 里用
$变量名占位,运行时由环境变量注入
所有配置项的完整定义在 src/plombery/config/model.py 中,与生产部署最相关的有:allowed_origins、data_path、database_url、frontend_url和auth。系统级参数说明见 docs/configuration/system.md。
最佳实践 1:如何收紧 CORS 允许来源(allowed_origins)
为什么重要:Plombery 默认allowed_origins为*,即允许任何网站向你的 API 发跨域请求。生产环境必须显式指定来源。
- 在配置中将
allowed_origins改为你的实际域名列表,例如只允许https://pipelines.example.com。 - 注意来源不能带路径,甚至不能带结尾的
/——框架会自动把 URL 规范化为scheme://host[:port]形式,逻辑见 src/plombery/api/middlewares.py 中的setup_cors。 - 该配置项开启了
allow_credentials=True(携带 Cookie 认证),所以绝不能再用*,否则浏览器会直接拒绝带凭证的跨域请求。
最佳实践 2:最快启用方法——开启 OAuth 登录认证
Plombery 内置基于 OAuth 的认证系统(基于 Authlib),生产部署强烈建议开启,否则任何人都能触发你的流水线。
- Google、Microsoft 等主流提供商开箱即用,配置示例见 docs/configuration/auth/google.md:在
plombery.config.yaml的auth块中填写provider、client_id、client_secret(用$变量引用密钥)。 - 在提供商后台注册应用时,回调地址填
/api/auth/redirect:
- 认证开启后,所有 API 路由都会经过会话检查:未登录请求收到 401,实现逻辑在 src/plombery/api/authentication.py。
- 支持任意兼容 OpenID 的提供商,通用配置参考 docs/configuration/auth/generic-oauth.md。
最佳实践 3:立即更换会话 secret_key
认证开启后,Plombery 使用SessionMiddleware加密会话 Cookie,密钥来自auth.secret_key。它的默认值是弱字符串(源码中可见SecretStr("not-very-secret-string")的兜底值),攻击者可伪造会话 Cookie。
✅操作:生成一个 32 位以上随机字符串(如openssl rand -hex 32),通过环境变量写入配置,每次部署都更换。
最佳实践 4:密钥管理——绝不明文提交 client_secret
这是密钥管理(secret management)的核心:
- YAML 配置里只写
$GOOGLE_CLIENT_SECRET这样的占位符;加载器 src/plombery/config/yaml_loader.py 会在运行时把$VAR解析为环境变量值。 - 真实密钥放在
.env文件或宿主机环境变量里,并且.env必须加入.gitignore,永远不要提交到 git。 - 代码层面的双保险:
client_id/client_secret字段在 src/plombery/config/model.py 中声明为SecretStr,日志和 repr 中不会泄露明文。
最佳实践 5:路径穿越防护——保护 run 数据目录
Plombery 会把每次流水线运行的日志和任务输出存到磁盘(见下图的运行日志界面):
危险场景:攻击者构造 run id 为../../.env之类的参数,试图读取数据目录外的敏感文件。Plombery 在 src/plombery/orchestrator/data_storage.py 中内置了_check_is_valid_path:所有拼接出的路径必须落在data_path/.data内,否则抛出InvalidDataPath异常拒绝访问。
✅部署操作:
- 显式设置
data_path为独立的绝对路径(默认是当前工作目录),把运行数据与代码、.env物理隔离; - 用非 root 用户运行,并确认该用户没有读取
.env所在目录的权限。
最佳实践 6:把数据库换成生产级配置
默认database_url是sqlite:///./plombery.db,文件就在项目目录里。生产环境:
- 迁移到 PostgreSQL 等网络数据库,或至少把 SQLite 文件放在
data_path指定的受控目录并做定期备份; - 数据库连接串中的密码同样走环境变量,不写入 YAML;
- 若使用 Turso(libsql)云数据库,额外配置
database_auth_token。
最佳实践 7:正确设置 frontend_url
frontend_url有两个安全作用:认证回调成功后会RedirectResponse跳转到该地址,且用于区分前后端部署。
- 前后端同源部署时保持默认即可;
- 前端独立域名时,将其设为真实前端 URL,并配合实践 1 把该 URL 加入
allowed_origins; - 避免留空或指向内网地址,防止回调被劫持到非预期站点。
最佳实践 8:反向代理 + 同源部署,收口 WebSocket
Plombery 的实时日志推送通过 WebSocket 挂载在/ws端点(见 src/plombery/websocket.py),同时/路径挂载了前端静态文件。生产部署建议:
- 用 Nginx 等反向代理统一入口:同一个域名下同时转发
/(前端)、/api/*和/ws,从根本上避免跨域问题,也便于只开 443 端口; - WebSocket 需要升级 HTTP 头(
Upgrade/Connection),Nginx 中不要遗漏proxy_set_header Upgrade配置; - 强制 HTTPS,并设置会话 Cookie 的
Secure与HttpOnly属性。
上线前检查清单
| # | 检查项 | 对应配置 |
|---|---|---|
| 1 | CORS 已收紧到真实域名 | allowed_origins |
| 2 | OAuth 登录已启用 | auth |
| 3 | 会话密钥为强随机值 | auth.secret_key |
| 4 | 密钥走环境变量,.env未入库 | .env+ YAML 占位符 |
| 5 | data_path独立且权限最小化 | data_path |
| 6 | 数据库已迁移/备份 | database_url |
| 7 | 前端 URL 指向生产域名 | frontend_url |
| 8 | 反向代理 HTTPS + WebSocket 升级 | Nginx 配置 |
完成以上 8 步,你的 Plombery 实例就具备了生产级的访问控制与数据隔离。Plombery 的核心依然是"极简代码跑流水线",安全加固只是多了一个配置文件和环境变量的事——这正是它为团队数据流水线提供可靠 Web UI 的基础。
【免费下载链接】plomberyPython task scheduler with a user-friendly web UI项目地址: https://gitcode.com/gh_mirrors/pl/plombery
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考