浅谈秘钥管理

在过去的两年时间里,出现了很多秘钥管理的解决方案,有各自的优势和应用场景。有一些应用例如Docker,实现了一些类似的秘钥管理功能。

然而,进一步思考我们能发现,各种各样的不同用户的应用场景和使用需求下其实可以抽象出一个相同的深刻的体系结构范式。转换到这种思维模式,我来谈谈几点扩展的思考。


什么是秘钥管理?

秘钥管理,从字面的意义上来看就是集中管理敏感信息,这些敏感信息通常能用来获取敏感数据,例如包含用户信息的数据库的用户名/密码。在过去,此类敏感信息通常是管理员手动放到服务器上去的。在配置管理流行起来后,这些敏感信息就放在了 Chef, Puppet 或者是 CFEengine等配置管理系统里。如今,一些服务云例如 AWS 等等有严格的访问控制策略(IAM),可以被例如 EC2 实例的源继承,可以去数据库(例如Dynamo)或者是 S3 bucket 访问敏感信息。这种方式在云上被很好的支持,但并不轻便。一种更轻便的秘钥管理方法是利用数据库或者是web服务提供敏感信息的访问,他们同时被SSL/TLS或其他类型的秘钥保护起来。但不可回避的问题是,你怎么获取这些秘密信息?答案便又回到了问题开始的地方,例如管理员手动将一个具有访问秘密信息权限的一个秘密放到系统或者配置管理系统里... 这样一来我们便进入了一个死循环。
那么首先,我们先退回几步,问问我们自己以下几个问题:

为什么我们需要秘钥管理?

以下几点,使得秘钥管理的需求越来越强烈。
  1. 我们现在运行的服务器更多了(例如VMs, Instance, Containers, 等等),但生存时间可能更短,有的可能只存在几分钟。这意味着手动将秘钥放置到机器上不太实用了,有些情况甚至无法完成这样的操作。那么我就需要将秘钥放到Image或者配置管理中去,我们先假设后者更容易实现(对Docker containers来说前者更容易)。
  2. 我们越来越喜欢将我们的应用,脚本,工具,配置管理等等共享出来,我们甚至会将它们放在GitHub上完全开源。有的时候我们需要频繁的从个人开发笔记本,多个云,服务器等等之前迁移代码,我们很难凭一己之力保证这些秘钥的可靠性,因此唯一的方案就是使代码和秘钥分离。
  3. 我们应当时常的轮换秘钥,一旦发生秘钥泄露的情况,我们应当有能力及时的更新秘钥。然而秘钥更新对我们来说是一个大问题:SSL/TLS证书有效期一般都有三年以上,更新起来很麻烦;对于秘钥来说,如果你想要更换数据库连接的密码,需要花费很长时间将更新的密码同步到所有的客户端上,这导致的结果就是大家只能尽量的避免秘钥更换,只有在不得已需要更换时(例如发生泄漏)才会更换,而通常这时已经晚了,而且你会觉得更换起来尤其困难,因为你很少执行这样的操作。
  4. 秘钥通常最后都是归属到人管理的,人们对于秘钥丢失导致无法获取资源的担忧常常超过对秘钥泄露的担忧,因此大家会习惯性的备份秘钥,备份的环境有可能就是不安全的,未授权的。那么最好的解决办法就是,首先通过一个秘钥获取一台笔记本或者工作站的权限,在这里你可以获得你所需的所有秘钥,也就是秘钥需要被集中的管理起来。
  5. 承接第四点,我们还需要对我们的秘钥访问进行审计。在很多环境下,当一个公司的高级管理员离职后,所有他之前知晓的秘钥都应该被更换。然而,通常又无法确认他具体知晓哪些秘钥,那么理论上应当修改所有的秘钥。这样我们就回到了第三点的场景。总的来说就是,我们没有一种可靠的方法确认秘钥正在被谁拥有和使用。
  6. 秘钥生成很难标准化。即使有这样一个标准,也很难保证让所有人都遵守。秘钥是有特殊字符的20个字节吗?秘钥长度是2048bits吗? 你只能尽力去创建一个策略,让所有人都遵守,然后祈祷没有人忘记或者撒谎。
  7. ……
还会有更多的需求场景,但我们先讨论到这里。
下一个我们要问自己的问题是:

我们期待秘钥管理提供哪些功能?

我能想到的有一下几点:
  1. 秘钥管理需要人机交互都友好;
  2. 理想状态下,我们所有的秘钥都存储在一个小的可控的空间里,并可以在这里集中进行秘钥轮换和更新;
  3. 我们需要确保秘钥按照指定的标准生成;
  4. 秘钥获取情况需要被审计,以此可以定位秘钥泄露的情况;
  5. 秘钥管理需要同配置管理协同工作但又不成为配管的一部分,这样配置不需要进行严格的访问控制,秘钥又能在配置管理干涉不到的条件下管理。
  6. 最重要的是,秘钥管理系统需要百分之百可以信任,坚不可摧。我们的其他系统可能会有缺陷,但一旦我们的秘钥管理系统沦陷,其他所有系统的大门将被攻破,后果不堪设想。
  7. ……
任何秘钥管理系统都会考虑到的重要的问题是,什么系统能够访问秘钥管理系统?拥有什么权限?我们希望可以遵循最小访问原则,通过一定的策略限制访问权限。但即便如此,同一个系统的不同组件它存在的安全风险也是不一样的。例如一台接受外部用户请求的web服务器的安全风险就比底层的数据库服务器高很多,而这台数据库服务器又比LDAP服务器更危险,因为web服务拥有访问数据库的权限,但web服务并不知道LDAP服务器的存在。但如果web 服务器的操作系统授权可以连接LDAP的话,LDAP这台服务器又比其他访问不到的服务器更危险。这样一来,会牵扯出一系列的服务器。

什么是安全?

我们常说:“没有绝对的安全”,安全都是相对而言的,也就是说:“如果一个黑客想要攻击进你的服务器的话,他一定有办法。”这句话的成立是在给定无限的时间和无限的资源这个前提下的。在这个前提下,任何的安全防护都可以越过,甚至可以通过贿赂一个员工,利用社会工程学攻击一个职员等方式。
认识到这点对于真正理解什么是安全来说非常重要。我们在此所说的“安全”是指一系列需要大量时间资源和意志才能攻破的防护措施。就好比你的给你的家安装了一道质量上好的防盗门去保护你家里的安全,不是为了去阻止攻击者绕过这个门破窗而入。你可能会给家里的窗户都装上防盗窗,但不是为了保证攻击者不会用断线钳剪断钢筋,掏个洞进入你家。尽管如此,我们还是会采取这些防护措施,去阻止那些不会采取如此极端措施的攻击者。如果真的有人想要实施抢劫,他可以剪断防盗窗,或者打破窗户,拿枪对着你,将你的家洗劫一空后离去。但是,极少会有如此胆大妄为的攻击者。在互联网上,很多用户都是匿名的,这在一定程度上增加了人们的胆量,但原则还是一样的。
我们重新回到秘钥管理的话题上来,我想说的是这里没有绝对安全的访问秘钥的方式,它们都有无法防护的“如果”的前提。因此,我们需要对我们的系统进行风险评估,来决定出哪种防护方案能提高时间,资源,毅力等攻击成本,从而达到阻止攻击者入侵的目的。防火墙能够减小暴露在外的攻击面,限制了攻击者可利用的攻击资源;一条“任何未经授权的访问都将被起诉!”的警示语,并不会真正阻挡什么,但会削弱攻击者实施攻击的意愿;而一个多层级的秘钥管理系统增加了攻击时间,它可能并不会阻止攻击,但却可以拖慢攻击时间,给人们发现检测到攻击并处理它争取到更多的时间。
这也是为什么我讨厌听到人们说:“不存在安全这回事。”这种说法是毫无意义的。我们除了需要建立一些列安全防护措施外,还有一项重要的工作就是攻击检测,防护措施帮助我们阻止大部分的攻击者入侵,我们还需要尽可能及时的发现一小部分成功的入侵,并准备好应急处理方案。
当我们要从一个服务器上访问秘钥时,我们会遇到这个场景的特殊的问题:

鸡和蛋的问题

秘钥管理中,一直困扰着我们的一个问题就是,不管你用一个web服务或者是数据库等等去中心化管理你的秘钥,你仍然始终需要自己保管一个秘钥去获取你秘钥管理中心访问秘钥的权限。就这好比鸡和蛋的关系,不管是先有蛋还是先有鸡,都会有一个源头。更可怕的,恰恰这个未被秘钥管理管理起来的秘钥却是最危险又最重要的秘钥,因为它有获得其他所有秘钥的权限。
目前很多秘钥管理似乎都没能解决这个问题。当你需要给多个服务器各分发一对TLS证书和秘钥或一对对称秘钥时,你怎样将它们分发到各个服务器上?最后你会发现,你回到了最开始我们讨论秘钥管理的一系列问题上。最好的方案是回退到使用例如AWS IAM策略下发,这也就意味着没有用云服务的应用就没有办法了。如此循环往复,似乎没有尽头……
令人激动的是,现在终于出现了一个终极解决方案:

Vault changes the game!

我们的需求是,一个集中化存储秘钥和对秘钥访问进行审计的方案。实际上,许多数据库就能做到这些功能,我们甚至可以设定数据库的访问控制策略,去控制什么账户能够访问什么秘钥。这没有什么新鲜的,但我们剩下的问题呢?
首先,Vault 相较于数据库的第一大优势的它不仅出处秘钥还能生成秘钥。这解决我们的一系列问题,例如可以确保不会有人见过这个秘钥,因此也确保任何人都不会有这个秘钥的备份。另外,秘钥轮换起来也更简单,我们可以直接在vault里创建,存储和分享秘钥。
第二点,Vault提供了多种访问秘钥的方式,即有人类友好也有机器友好的方式。人们可以继续使用他们熟悉的系统例如LDAP,Github access tokens, 用户名密码等等方式进行认证,在最近的更新中还集成了DUO,支持了多因素认证。
最重要的是,Vault提供了一些新颖且实用的机器访问方案。如果是Token或者TLS的话,又将我们带回了鸡和蛋这个问题上。我们可以使用各种不同的认证方式,最终可以解决我们的问题。我将在我的下一篇博客中做详细介绍,希望你也能从中找适合你的解决方案。

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值