关于服务端配置泄露思考
背景介绍
对于前后端同构的项目来说,一套代码有可能运行在两个不同的环境中,所以对于这些代码来说,兼容性,安全性的考虑要比其他代码复杂的多。
例如某些代码如果依赖浏览器 api,例如 window,document 等,如果不做兼容处理则会报错。
例如某些依赖第三方模块的代码,如果没有配置到 dependencies 中,那服务端在执行时会报错导致程序无法正常运行。
还有一种情况,就是某些敏感的配置信息,例如私钥,redis 信息等,这些敏感信息应该只存在于服务器上。
思考
以上三种情况,最常见的是前两种,但这两种情况也比较容易发现和解决,往往测试环境就能测试出来,只要开发人员修复即可。
但第三种情况并不会影响服务正常运行,但对服务的安全性造成了巨大的隐患。但这种情况又极难发现,有没有办法从架构层面解决这个问题,从而避免人为失误呢?
配置隔离方案就能很好地解决这一问题。
关于配置隔离
配置是非常敏感的数据,造成上述问题的根本原因是因为开发人员随意添加修改配置,不计后果地引入到业务中导致的,所以要从根本上解决这个问题,需要从架构上,让业务开发的人员尽可能避免接触到这些配置。
最简单的方法就是“代码隔离”,就是将配置代码从业务的代码仓库中迁移出来,单独管理。
能够想到的最简单的方式就是利用 git 的 submodules,从而避免业务人员随意修改配置信息。
这一步相当于将配置权限回收了,但要解决配置随意引用的问题,要从构建流程着手优化。
在做服务端配置隔离时,大家大体上有两个思路,一个是基于构建时引入配置,另一个是运行时引入配置。
我们的配置系统是 consul 提供的服务,若是启动时获取配置,如果配置中心出现问题,很可能会影响服务的稳定性。故采用构建时引入配置,这样配置就持久化在容器镜像中,即使配置中心挂了服务也能正常启动。
但我个人认为还是基于运行时引用更加合适一些,其中还有一些安全性的考虑。
基于运行时引入配置,对于后端业务来说,在程序启动前没有人能知道具体的配置信息是什么,进一步保证了数据安全,并且配置信息全程存放在内存中,并没有落地,也不存在泄露的情况。
对于前端程序来说,所有的配置都通过 html 进行下发。业务人员无法通过引用文件的形式引入配置(构建会报错)。通过 html 进行下发,即使发生错误也能快速发现并修复,并不会长久储存在静态文件当中,也不会被 CDN 进行缓存,安全性大大提升。