Python 如何在版本控制系统中安全地保存密钥和密码?

Python 如何在版本控制系统中安全地保存密钥和密码?,python,django,git,version-control,Python,Django,Git,Version Control,我在版本控制系统中保留重要的设置,如开发和生产服务器的主机名和端口。但我知道在VCS存储库中保守秘密(如私钥和数据库密码)是不好的做法 但是,和其他设置一样,密码似乎应该进行版本控制。那么,什么是保持密码版本控制的正确方法呢 我想这将包括在他们自己的“机密设置”文件中保存机密,并对该文件进行加密和版本控制。但是什么技术呢?如何正确地做到这一点?有没有更好的办法完全解决这个问题 我一般都会问这个问题,但在我的特定实例中,我希望使用git和github为Django/Python站点存储密钥和密码

我在版本控制系统中保留重要的设置,如开发和生产服务器的主机名和端口。但我知道在VCS存储库中保守秘密(如私钥和数据库密码)是不好的做法

但是,和其他设置一样,密码似乎应该进行版本控制。那么,什么是保持密码版本控制的正确方法呢

我想这将包括在他们自己的“机密设置”文件中保存机密,并对该文件进行加密和版本控制。但是什么技术呢?如何正确地做到这一点?有没有更好的办法完全解决这个问题


我一般都会问这个问题,但在我的特定实例中,我希望使用git和github为Django/Python站点存储密钥和密码

此外,理想的解决方案是在我使用git进行推/拉操作时做一些神奇的事情——例如,如果加密的密码文件发生更改,则会运行一个脚本,请求密码并将其解密到位



编辑:为了清楚起见,我想问一下在哪里存储生产机密。

一个选项是将绑定项目的凭据放入加密容器(TrueCrypt或Keepass)并推送它

更新为我以下评论的答案:


有趣的问题顺便说一句。我刚刚发现:这对于自动加密来说非常有希望,我建议使用配置文件,而不要对其进行版本设置

但是,您可以修改文件的版本示例


我认为共享开发设置没有任何问题。根据定义,它应该不包含有价值的数据。

通常,我将密码作为配置文件分开。让他们远离

/yourapp
    main.py
    default.cfg.dist
当我运行
main.py
时,将复制的真实密码放入
default.cfg


当你使用git或hg时。您可以忽略
*.cfg
文件来生成
.gitignore
.hgignore

我认为最干净的方法是使用环境变量。例如,您不必处理.dist文件,生产环境中的项目状态将与本地计算机的状态相同


如果你感兴趣的话,我建议你阅读配置一章,其他的也一样

编辑:我假设您希望跟踪您以前的密码版本,例如,防止密码重复使用的脚本等。

我认为GnuPG是最好的方法——它已经在一个与git相关的项目(git附件)中被用于加密存储在云服务上的存储库内容。GnuPG(gnu pgp)提供了非常强大的基于密钥的加密

  • 您在本地机器上保留了一把钥匙
  • 将“mypassword”添加到被忽略的文件
  • 在预提交钩子上,您将mypassword文件加密到git跟踪的mypassword.gpg文件中,并将其添加到提交
  • 在合并后挂钩上,您只需将mypassword.gpg解密为mypassword
  • 现在,如果您的“mypassword”文件没有更改,那么加密它将使用相同的密文,并且不会添加到索引中(没有冗余)。对mypassword稍加修改就会导致密文和mypassword.gpg完全不同,临时区域中的mypassword.gpg与存储库中的mypassword.gpg差异很大,因此将添加到提交中。即使攻击者获得了您的gpg密钥,他仍然需要强制执行密码。如果攻击者使用密文访问远程存储库,他可以比较一组密文,但它们的数量不足以给他带来任何不可忽视的优势

    稍后,您可以使用.gittributes为密码的quit git diff提供动态解密

    此外,您还可以为不同类型的密码等使用单独的密钥

    我一般地问这个问题,但在我的具体情况下,我想 使用git存储Django/Python站点的密钥和密码 和github

    不,只是不要,即使这是你的私人回购协议,你也不打算分享,不要

    您应该创建一个local_settings.py,将其放在VCS ignore上,然后在您的settings.py中执行以下操作

    from local_settings import DATABASES, SECRET_KEY
    DATABASES = DATABASES
    
    SECRET_KEY = SECRET_KEY
    

    如果您的机密设置有这么多功能,我很想说您做错了什么

    请使用GPG等加密密码文件。在本地计算机和服务器上添加密钥。解密文件并将其放在repo文件夹之外

    我使用位于我的homefolder中的passwords.conf。每次部署时,此文件都会更新

    Heroku推送设置和密钥:

    处理此类配置变量的传统方法是将它们放在某种类型的属性文件的源代码下。这是一个容易出错的过程,对于开源应用程序来说尤其复杂,因为这些应用程序通常必须使用特定于应用程序的配置来维护单独的(和私有的)分支

    一个更好的解决方案是使用环境变量,并将键保留在代码之外。在传统主机上或在本地工作时,可以在bashrc中设置环境变量。在Heroku上,使用配置变量

    通过Foreman和
    .env
    文件,Heroku提供了一个令人羡慕的工具链,用于导出、导入和同步环境变量


    就我个人而言,我认为将密钥与代码一起保存是错误的。它从根本上与源代码管理不一致,因为密钥是针对代码外部的服务的。一个好处是开发人员可以克隆HEAD并运行应用程序,而无需任何设置。但是,假设开发人员签出了代码的历史修订版。他们的副本将包括去年的数据库密码,因此应用程序将无法访问今天的数据库


    使用上面的Heroku方法,开发人员可以签出去年的应用程序,用今天的密钥配置它,并在今天的数据库上成功运行它

    您想要加密您的敏感设置文件,同时仍在ve中维护该文件,这是完全正确的
    clean_filter_openssl 
    smudge_filter_openssl 
    diff_filter_openssl 
    
    #!/bin/bash
    
    SALT_FIXED=<your-salt> # 24 or less hex characters
    PASS_FIXED=<your-passphrase>
    
    openssl enc -base64 -aes-256-ecb -S $SALT_FIXED -k $PASS_FIXED
    
    * filter=openssl diff=openssl
    [merge]
        renormalize = true
    
    [filter "openssl"]
        smudge = ~/.gitencrypt/smudge_filter_openssl
        clean = ~/.gitencrypt/clean_filter_openssl
    [diff "openssl"]
        textconv = ~/.gitencrypt/diff_filter_openssl
    
    import os
    
    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "project.local")
    
    # This application object is used by the development server
    # as well as any WSGI server configured to use this file.
    from django.core.wsgi import get_wsgi_application
    application = get_wsgi_application()
    
    *.secret.* filter=git-crypt diff=git-crypt