单服务器生产部署:从架构到故障恢复 · 5/10

生产环境密钥怎么放:.env、文件权限、轮换与泄露处理

区分普通配置和敏感密钥,梳理 .env、systemd EnvironmentFile、容器 secrets 的使用边界,并建立权限、备份、轮换和疑似泄露后的处理顺序。

环境变量是一种传递方式,不是安全等级

把密码从代码移到 .env 是进步,但不代表它自动安全。文件可能进入 Git、备份、镜像构建上下文、进程环境或调试日志。先把信息分三类:公开配置、内部但不敏感的配置、泄露后必须立即轮换的秘密。只有第三类需要按密钥管理。 典型秘密包括数据库密码、会话签名密钥、第三方 API token、SMTP 密码和私钥。域名、日志级别、公开站点 URL 通常不是秘密,不必把所有配置都藏起来增加排错困难。

建一份不包含值的密钥清单

清单记录名称、用途、使用服务、负责人、来源、创建时间、轮换周期和撤销方式,不记录真实值。这样能回答某个 API token 泄露后会影响哪些进程,也能发现早已不用却仍有效的凭证。 为开发、测试和生产使用不同凭证。不要把个人账户生成的长期密钥当成服务器永久资产;能使用服务账号和最小权限就不要使用全权管理员密钥。

文件位置和权限要有明确规则

systemd 可用 /etc/myapp/myapp.env,通过 EnvironmentFile 读取;文件由 root 管理,应用组只读。Compose 的 env_file 同样应放在部署目录之外或严格限制权限,并加入 .gitignore 与构建忽略。

bash
sudo install -d -m 750 -o root -g myapp /etc/myapp
sudo install -m 640 -o root -g myapp /private/path/myapp.env /etc/myapp/myapp.env
sudo -u myapp test -r /etc/myapp/myapp.env

不要在共享聊天、命令历史和截图中直接粘贴值。编辑时使用权限受控的方式;完成后检查 shell history 和临时文件。备份如果包含密钥,备份本身也要加密并限制访问。

容器环境需要额外检查

不要在 Dockerfile 用 ARG 或 ENV 烘焙生产秘密,它们可能留在镜像层和构建记录。Compose 环境变量适合一般配置;对高敏感内容,考虑文件挂载或平台提供的 secrets 机制,让应用从受限文件读取。无论哪种方式,容器内拥有相应权限的进程仍可能读取,最小权限和进程隔离不能省。 执行 docker compose config 时可能展开变量,输出不要上传公开日志。健康检查和错误处理也不能把完整连接串回显。

轮换要设计成两把钥匙短暂共存

直接替换数据库密码或签名密钥,可能让旧进程立刻断开或所有用户退出。能双密钥验证的系统先加入新密钥、部署并验证,再撤销旧密钥;不能双持时安排窗口,先备份、更新服务端、逐个重启消费者,最后验证旧密钥已失效。 会话签名密钥轮换可能使现有登录失效,要提前接受这个影响。数据库用户可以创建新账号并切换连接,确认无旧连接后再删除旧账号。轮换完成要更新清单日期,而不是只改文件。

怀疑泄露时先撤销,不先追究是谁

处理顺序是:限制影响范围、撤销或轮换、检查异常使用、修复泄露路径、再复盘。仅从 Git 历史删除字符串不够,因为旧提交和克隆仍可能保存;真实密钥必须视为已经暴露。 保留时间线:何时发现、哪些服务使用、何时撤销、日志是否出现异常。审计时避免把秘密再次复制到报告。对公开仓库、CI 日志和镜像仓库都要检查。

完成标准

仓库和镜像不含生产秘密,服务以最小权限读取受控文件,开发与生产凭证分开,日志不回显值,每个秘密都有负责人和撤销方式,并完成过至少一次轮换演练。下一篇进入最能检验架构是否真实可恢复的环节:数据库备份与恢复演练

参考来源

  1. Best practices for working with environment variables in Docker ComposeDocker Docs
  2. systemd.execsystemd
我正在使用 · 推广推荐

需要时再考虑的两项实用服务

这不是自动排名,也不是每个人都需要购买。我只列出自己正在使用的入口,并把适用场景和限制说清楚。

推广说明:链接包含我的推荐信息。你通过链接注册或开通后,我可能获得平台奖励;不会因此向你额外收费。价格、活动、地区与服务条款请以下单页为准。 查看完整商业披露