服务器/数据库配置文件(包括密码)是否应存储在源代码管理中?

时间:2010-11-22 07:22:51

标签: svn git version-control passwords config

我希望听到一些最佳做法......

假设一个Web应用程序与几个不同的生产服务器(数据库等)交互......包含数据库密码的配置文件是否应该存储在源代码管理中(例如,git,svn)?

如果没有,跟踪应用程序需要访问的服务器数据库(或其他相关)密码的最佳方法是什么?

编辑增加了奖励,鼓励更多讨论,并听取更多人认为最佳做法。

12 个答案:

答案 0 :(得分:27)

答案 1 :(得分:18)

暂且不说密码永远不应存储在纯文本中任何地方(除了某人的头盖骨或只有首席执行官,首席财务官和首席信息官可以访问的锁定保险库(并且一次需要所有三个密钥) )),您应该将所有内容存储到构建产品所需的源代码管理中。

这不仅意味着你的来源,甚至包括构建机器,编译器选项,编译器本身等的规范。

如果我们能找到检查物理硬件的方法,我们也会这样做: - )

构建过程本身可以复制的任何内容,或者运行而不是构建软件(例如密码)的任何内容通常都不属于源代码管理,但有些商店会这样做他们的可执行文件,生成的文档等等,这样他们就可以快速获得特定的发布版本。

答案 2 :(得分:11)

密码不应存储在源代码管理中。完全没有。永远。见How to keep secrets secret

密码,服务器名称等是服务器管理员执行的部署配置的一部分。必须记录此程序并将记录的程序置于控制之下。

或者,部署配置可以由sysadmin运行以执行配置的脚本执行,并且在脚本执行期间,它将要求sysadmin提供所需的信息。同样,此脚本必须保留在版本控制中。

除服务器配置之外的所有其他内容必须在源代码管理中。

在源代码管理中存储服务器配置通常是一个坏主意,因为它妨碍了部署并可能导致小型灾难(例如,当某人没有意识到他们从源代码控制部署的测试版本正在与实时服务进行通信时)

始终将这些配置文件保留在webroot之外。

可信连接可能是一个选项,允许已知的IP地址通过配置该服务来连接服务..

答案 3 :(得分:7)

一般来说,我同意paxdiablo:把所有可能的东西置于源代码控制之下。这包括具有数据库凭据的生产配置文件。

考虑一下服务器崩溃的情况,备份结果是糟糕的,你需要备份服务器。我认为您和您的客户(或老板)肯定会同意,在源代码管理中部署网站所需的一切都是一大优势。

如果要使用持续集成(另一种最佳实践)从源构建易于部署的软件包,则必须将配置文件置于源代码管理之下。

还要考虑在大多数情况下,具有源代码控制访问权限的开发人员无法直接访问生产数据库服务器。生产密码对他们来说毫无用处。

如果错误的人获得了对您的来源的访问权限,他们仍然需要访问生产服务器才能破坏密码。因此,如果您的生产环境得到适当保护,源代码管理中密码的安全风险将非常有限。

答案 4 :(得分:3)

我认为这个问题更多的是关于信息所有权,信任和组织。您应该问问自己,您认为您的组织中有哪些部分可以保护您的系统密码不被泄露和滥用?

我一直在组织中,由负责业务的人员保管。在其他人中,他们已被委派给运营团队,该团队也拥有围绕创建和使用等的流程。

最重要的是,您的组织中明确定义了应该有权访问系统密码的人员。之后,您可以决定使用适当的技术解决方案来保护密码。

答案 5 :(得分:1)

没有。应直接在服务器上配置生产密码。您应该为部署团队/人员创建部署说明,以在部署期间更改正确的属性文件。

答案 6 :(得分:1)

在我的用于PHP的Subversion存储库中,包含密码的配置文件以config.php.sample形式签入,并提示必须提供的内容以及依赖脚本需要config.php出现在同一位置。

存储库配置为忽略该目录的config.php,以避免“意外”添加或签入。

答案 7 :(得分:1)

示例配置文件,当然,我会将它们置于版本控制之下。但通常不会使用服务器地址或密码等真实世界访问数据。更像是

# program.conf
#
# mysql option for $myprog.
#
#SERVER_ADDR=127.0.0.1
#SERVER_USER=mysql
#SERVER_PASSWD=abcdef

答案 8 :(得分:1)

源代码中的密码问题:

  • 从一个部署到另一个部署很难变化(我不想在生产中修改源代码)
  • 在进行开发时意外破坏生产数据库的可能性增加
  • 安全问题(在大多数商店中,代码/开发人员没有理由知道prod密码)
  • 更改密码需要重新部署

我发现最好的工作是检查配置,使用混合使用默认值和占位符来部署特定数据。我们的应用程序总是寻找允许覆盖任何变量的系统配置。这允许生产机器具有适合其部署的配置。

注意:当我作为管理员运行时,我总是将代码与代码分开管理(有充分理由)。

答案 9 :(得分:0)

我总是会排除包含密码或其他访问详细信息(如数据库)的重要配置文件,这纯粹是最佳做法。此外,在源和版本控制之上通常提供多个用户,并且并非所有用户都使用相同的数据库详细信息,甚至使用相同的服务器配置(域等),为此,配置文件应保持排除在外整个。

答案 10 :(得分:0)

如果没有正确的构建过程,我正在使用此策略(对于PHP应用程序):

  1. 制作文件夹/etc/companyname
  2. 在其中,放置两个文件:

    <?php // env.php
    return 'prod'; 
    
    <?php // appname-prod.php
    return array(
      'db' => array( /* credentials */ ),
      /* other host-specific conf data */
    ); 
    
  3. 使两个文件只能由PHP进程读取

  4. 现在你的应用程序的配置文件将是:

    <?php // config.php
    $env = (require "/etc/companyname/env.php");
    $creds = (require "/etc/companyname/appname-{$env}.php");
    

    有了这个,环境定义了使用的凭据,您可以在预先配置的环境之间移动代码(并使用$env控制某些选项)。当然,这可以通过服务器环境变量来完成,但是a)设置起来更简单,并且b)不会将凭证暴露给服务器上的每个脚本(不会出现在像{{1这样的杂散调试垃圾中) }})。

    为了更容易在PHP之外阅读,您可以制作凭证文件JSON或其他东西,只是忍受微小的性能损失(APC不会缓存它们)。

答案 11 :(得分:0)

我更喜欢在主设置文件旁边添加 local_settings 文件。不应将此 local_settings 添加到存储库,但我会将 sample.local_setting 添加到存储库以显示此文件的结构。

在运行时,如果存在local_settings,则其值将覆盖主设置文件的值。

例如在python中:

<强> settings.py:

log='error.log'
db=lambda:None
db.host='localhost'
db.user=''
db.password=''

try:
    import local_settings
except ImportError:
    pass

<强> local_settings.py:

from settings import *

db.user='abcd'
db.password='1234'