在服务器环境变量中存储关键密码是否安全?


23

我有一簇服务器,每个服务器都有配置文件,这些文件当前包含用于敏感的关键任务系统(消息队列,数据存储和其他服务)的纯文本密码。

某些人将关键密码从配置文件中移到运行服务器进程的用户帐户的环境变量中。通过这种方式,可以将配置文件提交给版本控制,并且系统管理员只需要在设置服务器系统时创建适当的环境变量。自然,对运行这些服务的帐户的访问非常受限制。

这真的是避免在纯文本配置文件中输入密码的最佳方法,还是有更好的方法?


3
好吧,请记住,如果确实将其存储为变量,则无论是在静态还是在用户查询时,它都是纯文本格式。这意味着,如果您失去对服务器层的一点控制,您就已经为攻击者提供了密码。我可能会使用加密,然后根据需要解密密码信息。
Frank Thomas

好主意,弗兰克。如果要使用加密,您将使用哪种系统?是基于RSA / SSH密钥,密钥链工具还是其他工具?我们目前使用Linux> 2.6系统,例如CentOS和Amazon。
Steve HHH 2014年

Answers:


11

如果您使用的是Linux系统,请查看/ proc / * / environ,并确定环境变量是否是存储敏感信息的好地方。/ proc / self是当前进程:

$ tr '\0' '\n' < /proc/self/environ
USER=me
LOGNAME=me
HOME=/home/me
PATH=/usr/bin:/bin:/usr/sbin:/sbin
MAIL=/var/mail/me
SHELL=/usr/bin/sh
SSH_CLIENT=1.2.3.4 58195 22
SSH_CONNECTION=1.2.3.4 58195 7.8.9.0 22
SSH_TTY=/dev/pts/1
TERM=xterm

没关系,设置环境变量的事情可能是在某个地方读取文件。

要记住的是,使用密码意味着密码可用于程序。如果用户每次在程序需要时都没有输入此密码,则只能根据程序的访问权限来访问该密码。您可以在本地对密码进行加密,并使用密钥对程序进行解密,但是这样做的目的是使密码不致于意外泄露。与该程序具有相同访问权限的用户可以执行该程序可以执行的相同操作,包括读取加密密钥。

正确的方法是让应用程序作为受限帐户运行,并将密码存储在受文件系统级权限保护的文件中。希望您可以“包含”文件或类似文件,以将密码保留在版本控制系统之外(假设VCS没有安全控制)。为了防止意外泄露,请根据需要隐藏密码-base64对其进行编码,并使用pgp进行加密,无论服务器程序选项集中有何意义。如果您正在编写程序来执行此操作,则最好的办法是仅在需要时提示用户输入密码,然后在使用后立即从内存中清除该密码。



3
是的,运行程序的用户拥有的模式0600的文件可以由可以访问程序环境的同一个人访问。但是,正如我提到的那样,环境可能是通过读取文件来配置的,因此将数据复制到环境中只会增加数据可用位置的数量。默认情况下,环境被复制到子进程。而且由于错误或故意的设计决策,许多程序都可以通过外部方式查询环境变量(请考虑phpinfo())。如果以任何一种方式涉及文件,为什么要增加攻击面?
dannysauer 2015年

1
您提供的tr命令对我不起作用-这确实cat /proc/self/environ | tr '\0' '\n'
起作用

我在电话里,所以很难说...应该是零;您输入字母“ o”了吗?
dannysauer 2016年

8

最终,如果您需要读取写入任何数据,最终将使用密码来保护某些内容(或者,如果您对物理硬件智能卡和PIN 确实很偏执),则不会无论您拥有多少层加密。

这归结为系统安全性与便利性的基本问题。您可以通过添加很多层的安全控制措施来添加“纵深防御”,恶意行为者必须破坏这些安全控制层才能获取“商品”,但是当合法行为者想要读取或更改某些数据时,他们必须经历一堆篮球。替代方法是文本文件中的纯文本密码。

如果我真的想保护关键任务系统中的某些信息,该怎么办:

  1. 使用完整磁盘加密,以便对整个永久性存储的内容进行加密。

  2. 限制对计算机的物理访问。使用安全的锁定机制锁定机器的机箱,并控制对按键的物理访问。雇用肌肉(武装警卫)担任看门人。

  3. 在设备的操作系统中实施细粒度的强制访问控制(MAC)。您可以从GNU / Linux上的SELinux之类的东西开始,并将其设置为Enforcing,然后根据生产软件的确切需求定制策略,从而为这些帐户提供(仅)对所需文件的所需权限。

  4. 如果您要使用系统专用密码和配置文件的版本控制,那么您确实要避免将纯文本密码错误地提交给版本控制的可能的错误,因为这样可能很难将泄露的密码从服务器中删除。 VCS的缓存。环境变量是几种可行的选择之一。另一个是程序启动时的密码提示,但是随后重新启动计算机并恢复操作状态是手动操作,不能自动完成,因此又有安全性与便利性。

  5. 确保您有网络专家来照顾防火墙权限,以最大程度地减少您遭受网络攻击的风险。审核(与渗透测试以及白盒测试相关的代码)与外部系统(尤其是公共Internet)接口的任何软件。“接口”不仅包括直接的网络连接,而且还包括读取或写入“不可信”数据(其字节来自安全服务器的RAM /磁盘/ CPU外部的数据)。

这不是一个完整的列表,但是特别是第4点可能与您相关,尽管如果您至少没有执行第1步到第3步,那么考虑第4点和第5点不会对您有很大帮助,因为您的系统在相当基本的级别上并不安全。


我会跳过#1。如果系统正在运行,则文件系统已安装且未加密。如果未运行,则您的物理访问控制应该足够。如果需要重新启动,则您需要有人在每次引导时提供解密密钥(这很烦人),或者您需要让计算机提供该密钥-在这种情况下,通常只要拥有硬盘访问权限的任何人都可以使用凭据。由于这种权衡成本,大多数“服务器”计算机通常不使用磁盘加密。:)
dannysauer 2014年

“这归结为系统安全性与便捷性的基本问题”(引自我的回答),它同样适用于您的评论。您不能同时最大化安全性便利性。
allquixotic 2014年

1
如果某些RAM的一部分撞到磁盘(交换),或者如果它撞到ssd扇区(稍后变得“坏”并从操作系统移开但仍保留那块ram),则#1很重要。即使磁盘当前处于解锁状态,该数据块最终也会在盘片上打乱。
akira

3

在环境变量中传递密码与让程序从文件中读取密码一样安全。只有以同一用户身份运行的进程才能读取进程的环境,并且无论如何都允许这些进程读取相同的文件。

请注意,这与在命令行上输入密码不同。命令行参数对于在同一台计算机上运行的所有进程(除非采取加强措施)都是可读的,而不仅仅是以同一用户身份运行的进程。

如果通过环境传递变量,请注意该程序是否启动其他程序。这些其他程序将继承其父级的环境。因此,如果您担心其他程序可能会意外泄漏其环境的内容,请不要执行此操作。

您的方案中的缺陷是“设置服务器系统时创建适当的环境变量”。环境变量是流程的动态属性。设置系统时不能创建它,如果设置的意思是在重启后仍然存在,则不能创建它。您的意思大概是管理员安排了某个用户登录时在环境中显示此变量。这是通过配置文件(通常是~/.pam_environment~/.profile从中读取文件~/.profile)完成的。因此,实际上,此解决方案不会将密码移出配置文件。

进行设置以使密码位于用户的登录时环境中不是一个好主意。这意味着以该用户身份运行的每个进程都将拥有秘密,因此很容易在任何地方泄漏。

除了受版本控制的配置文件和常规部署机制之外,还应该在文件中放置一个密码。如果方便的话,可以将密码放在环境中,但是应该对尽可能小的程序集进行设置。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.