无论是微服务还是单体应用,往往都会用到很多配置信息。在众多的配置信息中,有一类非常敏感,例如数据库账号密码、API Key、Service Account等。由于其特殊性,这些配置信息一旦泄露出去就很可能会使得应用遭到黑客攻击,例如数据库账号密码泄露可能导致“拖库”,甚至数据丢失。
在实际开发过程中,有几种常见的敏感配置信息管理方式,其优缺点各不相同,让我们依次来看看。
3种常见方式
方式一:存储于独立的源代码仓库
将敏感配置信息硬编码到源代码中是一种古老的做法,由于其安全性难以得到保证,并且管理维护难度大,因此早已被开发团队摒弃。
取而代之的是将敏感配置信息存储在配置文件中,并且将其单独放置于另外一个源代码仓库,在CI构建或者部署过程中,由CI从对应的源代码仓库中获取配置信息,然后将其打入应用包。
这种方式最大的好处在于团队可以方便的对源代码仓库添加访问控制,但是缺点也是比较明显的:敏感配置信息并没有被加密存储,而且会被CI服务器缓存下来。
方式二:通过系统环境变量动态设置
这是一种另辟蹊径的做法,即把敏感配置信息设置到系统环境变量里,而不是存储在配置文件中。
这背后的逻辑是,既然敏感配置信息明文存储不够安全,就算加密存储也存在被破解的可能,那么就干脆不存储了。
此种方式看上去非常巧妙但也隐含着一些问题。系统环境变量不可能凭空出现,必然需要有一个“主体”去设置它,而这个所谓的“主体”不外乎是人、CI或者脚本。
通过人来设置环境变量十分低效且易出错,而如果通过CI或者脚本来自动进行设置,看似提高了效率但敏感配置信息也就缓存在了CI中,或者作为脚本文件的一部分存储在了源代码仓库中。方式一中遇到的问题再次出现。
方式三:在运行时从配置中心动态获取
随着微服务、容器化变得越来越流行,而配置中心几乎已经成为了这一领域里的标准配置。
这种方式下,所有的配置信息(无论其敏感与否)都统一存储在配置中心,应用在启动或者运行过程中通过HTTP从配置中心动态获取配置。由于所有的配置信息都集中在一起,并且由应用以自助的方式获取,因此非常便于维护管理。
最为关键的是,采用这种方式既可以方便的实现敏感配置信息加密存储,又具备完善的权限控制能力,而且还能提供详细的日志记录。
目前有不少工具或者框架可供开发团队选择,以搭建出这样的配置中心,常见的例如Hashicorp Vault ,Spring Cloud Config。如果是Cloud Native应用,还可以使用云平台提供的安全配置管理服务,例如微软Azure的Key Vault。
然而配置中心的方式并非完美,依然有值得注意的地方。由于大量应用依赖于这个配置中心,因此单点失败的概率相比于其他几种方式会有所提高。此外,敏感配置信息会在网络上传输,因此传输过程的安全性也需要考虑在内,建议对其启用HTTPS。再者,配置中心也是众多微服务中的一个,考虑到它的特殊性,团队十分有必要对其添加适当的网络访问控制,例如仅允许从企业内部进行访问。
6个原则
各个团队所面临的实际情况很可能千差万别,并且本文所述的几种方式可能并非涵盖了所有的敏感配置信息管理方式。无论你的团队采用的是哪种方式,在使用过程中都可以参考下面这些原则,以保证敏感配置信息的安全性:
- 适度隔离:将敏感配置信息同源代码、普通配置信息隔离存储。
- 访问控制:通过白名单等方式,限制敏感配置信息的访问权限。
- 加密存储:将敏感配置信息加密后存储,仅在使用前临时解密,以进一步防止信息泄露。
- 安全传输:企业内网环境并非100%可信,通过HTTPS等加密手段以保证敏感配置信息的传输安全。
- 日志记录:详细记录下针对配置信息的操作,以便于事后追查或者合规审查。
- 差别配置:不同的环境(例如生产环境,UAT环境,Dev环境等)使用不同的Credential,以避免“把鸡蛋放到一个篮子里”。
总结
应用往往需要用到配置信息,其中一些由于其特殊性因此相比于其他配置信息而言更加敏感,它们需要被很好的保护起来以避免应用遭受黑客攻击。
不同的敏感配置信息管理方式有着各自的特点。将敏感配置信息单独存储于源代码仓库中的方式常见于单体应用架构,与此同时配置中心在微服务架构下更为常见,而使用环境变量这种方式的团队也不在少数。
没有绝对的好,也没有绝对的坏。团队采用哪种方式不是最重要的,关键在于是否遵循了一些基本的原则以保证敏感配置信息的安全性。