谷歌应用引擎:隐藏 Rails 密钥的最佳实践?

Posted

技术标签:

【中文标题】谷歌应用引擎:隐藏 Rails 密钥的最佳实践?【英文标题】:Google app engine: Best practice for hiding Rails secret keys? 【发布时间】:2017-04-19 11:56:28 【问题描述】:

我正在将我的 Rails 应用程序部署到 GAE,其代码存储在 github 中。

显然,我需要隐藏我的密钥和数据库密码。

在 Heroku 中,我可以使用 Heroku GUI 将它们设置在环境变量中非常容易和很好,因此它不会出现在任何源代码或数据库中。

GAE 呢? 我无法在 app.yaml 中设置它们,因为:

    .gitignore 不是一个选项:即使我通过 .gitignore 隐藏 app.yaml 文件或替代 json 文件,我也必须将其保存在本地计算机中。这意味着只有我可以部署,我必须自己做备份。这太可怕了。 有人说我可以在数据库中存储秘密值。但我也想隐藏数据库密码。

有什么想法吗?

【问题讨论】:

我用 GPG 加密.env 文件中的环境变量,并使用dotgpg 来管理它们。您可以加密您的 app.yaml 文件并将其存储在存储库中。 @p4sh4 感谢您的评论。这个想法很棒,但你有没有用 CI 工具(比如 Circle CI)尝试过你的想法? 是的,特别是 CircleCI - 但我将测试和部署所需的环境变量添加到 CircleCI 本身,因为可以以安全的方式这样做,而且我不解密 @ 987654324@ 文件在那里。 【参考方案1】:

存储此信息的最安全方法是使用project metadata。在 Flexible/ManagedVM 环境中,您可以通过 simple http request 访问元数据。

来自谷歌博客文章:

借助 Compute Engine、Container Engine 和 托管虚拟机,您可以使用一个神奇的 URL 来 CURL 来获取元数据。

ManagedVM 是现在称为“AppEngine 灵活环境”的旧名称。由于您说您在 App Engine 上使用 Ruby,因此您必须使用灵活/托管虚拟机。因此,您应该能够使用这些“神奇的 URL”。

因此,要在 Ruby 中获取名为 mysecret 的应用程序机密,您可以这样做:

Net::HTTP.get(
    URI.parse('http://metadata.google.internal/computeMetadata/v1/project/attributes/mysecret'))

(对于@joshlf)以下是如何在 Python 中访问 AppEngine 标准环境中的 project 元数据:

# Note that the code will not work on dev_appserver, 
# you will need to switch to some other mechanism 
# for configuration in that environment
# Specifically the project_id will resolve to something
# compute engine API will treat as invalid

from google.appengine.api import app_identity
from googleapiclient import discovery
from oauth2client.client import GoogleCredentials

compute = discovery.build(
    'compute', 'v1', credentials=GoogleCredentials.get_application_default())

def get_project_metadata(metadata_key):
    project_id = app_identity.get_application_id()
    project = compute.projects().get(project=project_id).execute()
    for entry in project['commonInstanceMetadata']['items']:
        if entry['key'] == metadata_key:
            return entry['value']
    return None

get_project_metadata('my_key')

【讨论】:

谢谢。项目元数据不是与 GCE 一起使用,而不是 GAE 吗?还是您在谈论 Cloud Datastore? 感谢更新。我将尝试元数据并添加我对它的感受。 是的,我可以使用元数据。谢谢。但是与 Heroku(我们可以很容易地定义环境变量)和 AWS(您可以在服务器中设置它们)相比,我仍然觉得这种方式有点痛苦...... 您知道如何从 Google App Engine 访问元数据吗?我想出了如何从 Google Cloud Shell 控制台访问实例元数据,而不是项目范围的元数据。 @joshlf 我用一些可以在标准环境中工作的代码更新了我的答案。你没有说你使用的是什么语言,所以我假设是 Python。如果您经常访问元数据,您可能希望缓存结果。【参考方案2】:

我在answer to a similar question 中解决了这个问题。本质上,您可以在app.yaml 旁边创建一个credentials.yaml 文件并将其导入app.yaml。这将允许您将凭据指定为 ENV 变量,同时保留忽略 git 中文件的能力。 includes: 标签允许您在 app.yaml 中导入一组文件。

例如app.yaml:

runtime: go
api_version: go1

env_variables:
  FIST_VAR: myFirstVar

includes:
- credentials.yaml

credentials.yaml:

env_variables:
  SECOND_VAR: mySecondVar
  API_KEY: key-123

【讨论】:

以上是关于谷歌应用引擎:隐藏 Rails 密钥的最佳实践?的主要内容,如果未能解决你的问题,请参考以下文章

开源大数据 OLAP 引擎最佳实践

架构最佳实践:Rails 和移动/Web 应用程序

开源大数据 OLAP 引擎最佳实践

使用 Capistrano 将 Rails 应用程序部署到多个服务器 - 最佳实践

分析/优化谷歌应用引擎应用程序的最佳方法是啥?

在 Rails 中引入类似触发器的功能的最佳实践