将网站的秘密值作为环境变量有什么好处?

Aid*_*tis 25 website configuration web-server environment-variables

https://12factor.net/config 上的 devops 指南建议将网站机密(数据库密码、api 密钥等)放入环境变量中。与使用从版本控制中忽略的文本文件(JSON、XML、YAML、INI 或类似文件)相比,它有什么优势?

我发现复制带有机密的配置文件比处理 .bash_profile 和网络服务器配置中的环境变量要容易得多。我错过了什么吗?

Aus*_*arn 21

作者列出了他们的推理,尽管它有点脱节。他们的主要论点是很容易意外签入配置文件,并且配置文件具有不同的格式,并且可能分散在系统中(对于安全相关的配置(如身份验证令牌和凭据),所有这三个参数充其量只是平庸的参数)。

根据我自己的经验,您基本上有以下三个选项,以及相关的优点和缺点:

将数据存储在配置文件中。

在采用这种方法时,理想情况下,您应该将它们与存储库本身隔离,并确保它们位于应用程序存储其内容的区域之外。

好处:

  • 非常容易隔离和控制访问,尤其是当您使用 SELinux 或 AppArmor 之类的东西来提高整体系统安全性时。
  • 对于非技术用户而言,通常易于更改(这对于已发布的软件来说是一个优势,但对于特定于您的组织的软件则不一定)。
  • 易于跨大型服务器组进行管理。有各种用于配置部署的工具。
  • 相当容易验证正在使用的确切配置是什么。
  • 对于编写良好的应用程序,您通常可以通过更新配置文件然后向应用程序发送特定信号(通常是 SIGHUP)来更改配置而不会中断服务。

缺点:

  • 需要进行适当的规划以确保数据安全。
  • 您可能需要学习不同的格式(尽管现在只需要担心少数格式,而且它们通常具有相似的语法)。
  • 确切的存储位置可能在应用程序中进行了硬编码,这使得部署可能会出现问题。
  • 配置文件的解析可能有问题。

将数据存储在环境变量中。

通常这是通过从启动脚本中获取环境变量和值的列表来完成的,但在某些情况下,它可能只是在程序名称之前在命令行上声明它们。

好处:

  • 与解析配置文件相比,从环境变量中提取一个值在几乎任何编程语言中都是微不足道的。
  • 您不必担心意外发布配置。
  • 您通过默默无闻获得了一定程度的安全性,因为这种做法并不常见,而且大多数入侵您的应用程序的人不会立即考虑查看环境变量。
  • 访问可以由应用程序本身控制(当它产生子进程时,它可以轻松地清理环境以删除敏感信息)。

缺点

  • 在大多数 UNIX 系统上,访问进程的环境变量相当容易。一些系统提供了缓解这种情况的方法(例如,Linux 上的hidepid挂载选项/proc),但默认情况下它们并未启用,并且无法防止来自拥有该进程的用户的攻击。
  • 如果您正确处理了上述安全问题,那么查看正在使用的确切设置是非常重要的。
  • 你必须信任应用程序在它产生子进程时清理环境,否则它会泄漏信息。
  • 如果不完全重新启动应用程序,您将无法轻松更改配置。

使用命令行参数传递数据。

说真的,不惜一切代价避免这种情况,它不安全,而且维护起来很麻烦。

好处:

  • 在大多数语言中,比环境变量更容易解析。
  • 子进程不会自动继承数据。
  • 提供一种在开发应用程序时快速测试特定配置的简单方法。

缺点:

  • 就像环境变量一样,在大多数系统上很容易读取另一个进程的命令行。
  • 更新配置极其繁琐。
  • 对配置的长度设置硬限制(有时低至 1024 个字符)。

  • *在大多数 UNIX 系统上,您几乎可以读取任何进程环境变量,而无需任何重要权限。* -- 您能扩展一下吗?/proc/####/environ 文件只能由所有者读取,因此您需要是 root 用户或拥有 sudo。 (7认同)
  • 我同意@rrauenza 提出的观点。答案非常好,但我想澄清一下*您可以在不需要任何重要特权的情况下读取几乎任何进程环境变量*。关于“*您实际上只需要 CAP_SYS_ADMIN 功能(root 隐式具有)*...”好吧,如果恶意代理具有 root 权限,则进一步讨论是多余的,而 CAP_SYS_ADMIN 也可能是 root 权限(参见 http:/ /man7.org/linux/man-pages/man7/capabilities.7.html、*CAP_SYS_ADMIN* 和 *内核开发人员注意事项*) (3认同)

And*_*man 13

Web 服务器的每个子进程都会继承环境变量。这是连接到服务器的每个会话,以及由它们生成的每个程序。秘密将自动透露给所有这些过程。

如果您将机密保存在文本文件中,则它们必须可由服务器进程读取,因此每个子进程也可能读取。但至少程序必须去寻找它们;它们不会自动提供。您还可以让一些子进程在不同的帐户下运行,并使机密只能由这些帐户读取。例如,suEXEC在 Apache 中执行此操作。