Rails 5.2 凭据 + 资产预编译



我有一个持续集成,它采用rails应用程序并将其打包为docker映像。

作为此打包过程的步骤之一,我想进行资产预编译。

我在 Rails 5.1 上这样做。我不得不提供一些虚拟SECRET_KEY_BASE才能让它通过。

SECRET_KEY_BASE=1 RAILS_ENV=production rails assets:precompile

我现在正在迁移到 Rails 5.2,并希望开始使用凭据。我正在尝试以下命令:

RAILS_ENV=production rails assets:precompile

如果我不RAILS_MASTER_KEY,那么它会显示一个错误:

缺少用于解密文件的加密密钥。向您的团队询问您的 主密钥并将其写入/home/config/master.key 或将其放入 环境['RAILS_MASTER_KEY']。

如果我提供虚拟(不正确(RAILS_MASTER_KEY,它会抱怨它无法解码凭据。

我不想给CI一个真正的RAILS_MASTER_KEY

结果,问题是。如何在没有它的情况下编译资产或有什么解决方法?

我也没有看到解决方案。另一种方法是继续设置 config/environment/production.rb 以包含以下行:

config.require_master_key = false

并继续使用您的SECRET_KEY_BASE=1 rails assets:precompile

我还没有找到更好的方法。至少这种方式似乎比维护假主密钥要好。

我的解决方案(Rails 6+(是为每个环境(测试,开发,生产(提供单独的凭据文件。

运行测试时,我通过向我的 CIRAILS_MASTER_KEY=xxx提供test环境的解密密钥。 要使用RAILS_ENV=production预编译资产,我只需将我的测试凭据 YML 文件复制到生产凭据之上。 然后,资产步骤可以仅使用test环境密钥解密凭据。

echo "Using 'test' environment credentials for precompiling"
cp ./config/credentials/test.yml.enc ./config/credentials/production.yml.enc
echo "Compiling assets"
RAILS_ENV=production bundle exec rake assets:precompile

我创建了一个假的credentials.yml.enc和与之关联的RAILS_MASTER_KEY,我在预编译资产时使用它们。

我们可以通过使用 docker 机密将master.key传递给 CI 容器,轻松解决 Docker 1.13 及更高版本中的问题(假设您的 CI 也在 Docker 容器中运行(。请注意,这仅适用于 docker swarm,但单个 docker 容器也可以充当 docker swarm 节点。要将单个节点(例如,在本地开发系统上(更改为 swarm 节点,请使用init命令并按照说明进行操作:

docker swarm init

https://docs.docker.com/engine/reference/commandline/swarm_init/

然后在 CI 容器的docker-compose.yml中将master.key声明为 docker secret,并将其定位到容器中的正确位置:

version: '3.4'
services:
my_service:
...  
secrets:
- source: master_key
target: /my_root/config/master.key
uid: '1000'
gid: '1000'
mode: 0440
...  
security_opt:
- no-new-privileges
...  
secrets:
master_key:
file: config/master.key

https://docs.docker.com/compose/compose-file/

如您所见,我们还可以为容器中的master.key分配专用访问权限,并保护它免受权限提升。有关 docker 群的进一步解释,请访问:

https://docs.docker.com/engine/swarm/secrets/#how-docker-manages-secrets

为什么这应该是解决问题的首选解决方案?您的秘密master.key不再存储在 CI Docker 容器中,而是安全地保存在 Docker Swarm 基础设施的加密 Raft 日志中,您不必使用伪造的密钥进行任何杂技扭曲。

顺便说一句,我使用这种方法来保护我在公共 Docker 容器中特定于领域的专业知识:使用target参数,每个 docker 密钥可以携带最大 500 kb 的通用字符串或二进制内容,尤其是包含敏感知识的代码片段。

最新更新