local_settings.py 反模式的原因之一是将 SECRET_KEY、AWS 密钥等值放入设置文件有问题:
- 秘密通常应该是这样的:秘密!将它们保留在版本控制中意味着拥有存储库访问权限的每个人都可以访问它们。
我的问题是如何将所有密钥保密?
将您的local_settings.py
数据存储在使用 GPG 加密的文件中 - 最好严格按照key=value
您解析并分配给 dict 的行(另一种有吸引力的方法是将其作为可执行的 python,但配置文件中的可执行代码让我颤抖)。
有一个 python gpg 模块,所以这不是问题。从您的钥匙圈中获取您的钥匙,并使用 GPG 钥匙圈管理工具,这样您就不必一直输入您的钥匙串密码。确保您直接从加密文件中读取数据,而不仅仅是创建您读取的解密临时文件。这是失败的秘诀。
这只是一个大纲,您必须自己构建它。
这样,秘密数据仅保留在进程内存空间中,而不是文件或环境变量中。
我使用 Windows 7 和 Powershell 做我的 Django 项目,所以对我来说设置环境变量略有不同。设置完成后,我只是在settings.py
文件中执行了以下操作:
import os
SECRET_KEY = os.environ["SOME_SECRET_KEY"]
要使用 PowerShell 在 Windows 中设置环境变量,请按照以下链接中的说明进行操作:
理想情况下,local_settings.py
不应为生产/部署的服务器签入。您可以将备份副本保存在其他地方,但不能保存在源代码管理中。
local_settings.py
为了方便,可以用开发配置签入,以便每个开发人员都需要更改它。
这能解决你的问题吗?
最初的问题是关于如何在环境变量中保密。这在《 Django 的两勺》一书中进行了广泛的讨论。下面是他们所说的摘要,然后是关于使用这种技术的警告。
从 1.11 版的第 48 页(第 5.3 节)开始:
Django(和 Python)支持的每个操作系统都提供了创建环境变量的简单功能。
以下是使用环境变量作为密钥的好处:
- 对设置保密可以让您毫不犹豫地将每个设置文件存储在版本控制中。你所有的 Python 代码真的应该存储在版本控制中,包括你的设置。
- 不是每个开发人员都维护自己的复制粘贴版本的 local_settings.py.example 用于开发,而是每个人都共享相同的版本控制 settings/local.py 。
- 系统管理员可以快速部署项目,而无需修改包含 Python 代码的文件。
- 大多数平台即服务建议使用环境变量进行配置,并具有用于设置和管理它们的内置功能。
在下一页,本书继续:
在开始设置环境变量之前,您应该具备以下条件:
- 一种管理您要存储的秘密信息的方法。
- 很好地理解 bash 设置如何在服务器上工作,或者愿意让您的项目由平台即服务托管。
他们描述了如何在本地和生产环境中设置环境变量(以 Heroku 为例——您需要检查您是否使用不同的主机,这只是一种可能性):
如何在本地设置环境变量
export SOME_SECRET_KEY=1c3-cr3am-15-yummy如何在生产中设置环境变量
heroku config:set SOME_SECRET_KEY=1c3-cr3am-15-yummy
最后,在第 52 页,他们给出了如何访问密钥的说明。例如,您可以将下面的前两行放在设置文件中,以替换默认放置在那里的原始密钥字符串:
>>> import os >>> os.environ['SOME_SECRET_KEY'] '1c3-cr3am-15-yummy'
此代码片段只是从操作系统获取 SOME_SECRET_KEY 环境变量的值,并将其保存到名为 SOME_SECRET_KEY 的 Python 变量中。
遵循这种模式意味着所有代码都可以保留在版本控制中,并且所有机密都保持安全。
请注意,这在某些情况下不起作用,例如,如果您使用的是 Apache 服务器。要处理这种模式不起作用的情况,您应该查看他们书中的第 5.4 节(“当您无法使用环境变量时”)。在这种情况下,他们建议使用秘密文件。
截至 2017 年底,这种在环境变量中存储机密的技术是两勺和十二因素应用程序设计模式中推荐的最佳实践。在 Django 文档中也推荐它。但是,存在一些安全风险:如果某些开发人员或某些代码可以访问您的系统,他们将可以访问您的环境变量,并且可能会无意(或有意)将它们公开。Michael Reinsch 在这里提出了这一点:http:
//movingfast.io/articles/environment-variables-considered-harmful/
我写了一个 getcreds() 函数,它从文件中获取密钥。我将文件保存在 www-data 可以访问的位置,因此无论我在 settings.py 中需要凭据的任何地方,我都只需调用 getcreds() 并将文件名作为参数传递。它返回文件中所有行的列表,宾果游戏我有隐藏的秘密。这是代码...
from __future__ import unicode_literals, absolute_import
import os
def getcreds(fname, project, credsroot='/var/www/creds', credsdir=None):
""" return a list of userid and password and perhaps other data """
if credsdir is None:
credsdir = os.path.join(credsroot, project)
creds = list()
fname = os.path.join(credsdir, fname).replace("\\", "/")
with open(fname, 'r') as f:
for line in f:
# remove leading/trailing whitespace and append to list
creds.append(line.strip())
assert creds, "The list of credentials is empty"
return creds
这是一种与 Heroku 上的部署兼容的方法:
创建一个名为 gitignored 的文件.env
,其中包含:
export DJANGO_SECRET_KEY = 'replace-this-with-the-secret-key'
然后编辑settings.py
以删除实际SECRET_KEY
并添加它:
SECRET_KEY = os.environ['DJANGO_SECRET_KEY']
然后当你想在本地运行开发服务器时,使用:
source .env
python manage.py runserver
当您最终部署到 Heroku 时,转到您的应用程序设置选项卡并将 DJANGO_SECRET_KEY 添加到 Config Vars。
您可能需要使用 os.environ。得到(“SOME_SECRET_KEY”)