实现一个微服务很难。部署一个微服务应用程序复杂性也很高。保护微服务的安全就更难更复杂。从哪里开始呢?脑海中首先出现的一些词是身份验证和授权、防火墙、授信、会话、令牌。我们需要保护应用程序的安全,也需要保护容器的安全。
保护微服务
实现一个微服务很难。部署一个微服务应用程序复杂性也很高。保护微服务的安全就更难更复杂。从哪里开始呢?脑海中首先出现的一些词是身份验证和授权、防火墙、授信、会话、令牌。我们需要保护应用程序的安全,也需要保护容器的安全。
保护应用程序
一种方法是构建一个单点登录(SSO)网关,像普通的网关一样,它位于应用程序的前端,但需要考虑到其与SSO服务器的握手,并执行URL重定向操作。可以用http报文头传送授权和认证信息给服务。但是除非使用https,否则这样做是不安全的。但是我们知道https有证书,维护多个微服务的证书可能会成为问题,尤其是需要补发或撤销这些证书的时候,复杂性将进一步增加,我们尽量避免这种情况。
另一种方法是用HMAC(基于哈希的消息代码)。这个请求的主体带有哈希私钥,结果是随着请求发送的。然后,服务器通过使用其私钥和请求主体的副本重新创建哈希,并将其与接收到的哈希进行比较。如果一切都匹配,那就意味着消息没有被篡改,请求可以通过。这种模式由JWT(Json Web Tokens)实现。但是,事实上网络侦听器仍然可以看到数据。
Twitter,Google等使用API密钥。使用API密钥,服务可以识别谁在调用,并可以对其设置限制。密钥是成对的(公钥和私钥),它们必须集中管理。
假定一切都准备就绪了,但是还是有一个问题,如何确保用户无法访问其他用户的数据呢?那就需要做更多的限制,可以通过限定用户只能访问他自己的数据来保护我们的服务,但是将导致在许多地方产生大量的样板代码。不幸的是,没有更好的办法。微服务意味着复杂性和一些重复预期会被减少。
还是没有解决嗅探器(sniffer,也叫数据抓包软件)的问题。怎样才能确保sniffer看不到数据呢。答案是加密。先加密,然后根据需要进行解密。这就是微服务复杂系统的另一个组件:密钥服务。
有很多库可以用,最好的选择是使用成熟的库,如OAuth或SAML。
服务可以有状态参数。为网关中初始化的所有服务保持一个全局会话,并将其传播到所有其它服务。会话可以从像KeyCloak这样的中央认证和授权服务器(SSO)获得。
我们更希望服务没有状态参数。这意味着需要将状态从服务器转移到客户端。Json的 Web令牌(JWT)非常符合这种需求。这是一种在双方之间转移声明的安全方式。基本上它的一个json作为Json Web签名(JWS)的主体或Json Web加密(JWE)的明文传递。声明可以进行数字签名,并包含发行者,用户的身份,到期时间,还可以包含自定义属性。
举一个例子,流程看起来如下图:
客户端应用程序将与 UAA (用户认证和授权)服务器进行交互。它为包含一个JWT令牌的重定向URL交换其证书。令牌将提交到 网关 ,在UAA服务器进行验证。如果一切正常,它会将该JWT令牌转发到所请求的服务,将会解码它并授予其对所请求资源的访问权限。
保护容器
现在已经知道如何保护应用程序了,是时候关注容器的安全了。Docker是一个广泛使用的容器。可以做些什么来保护它们呢?
答案是深度防御。这意味着需要防火墙;这意味着需要小心记录在日志中的信息(被攻击后,日志有助于快速恢复系统);这意味着需要监视集群的可疑行为(入侵检测系统和入侵防御系统);这意味着需要将服务分开并将它们放在不同的位置(虚拟私有云),并创建一组规则,确保它们仍然能够相互通信;这意味着保持操作系统更新(特别是安全更新)。
Aaron Grattafiori在Docker Con 2016年的演讲中谈到三个原则:
最小权限 原则,这意味着不以root身份运行应用程序
最小意外 原则
最小访问 原则,这意味着每个模块只能访问与其相关的数据
假设已经遵循了上述三原则,想到的下一个问题是:使用的Docker图像安全吗?怎么知道它们没有包含恶意代码呢?幸运的是,在Docker 1.8中引入了 Docker Content Trust ,与此同时,Docker图像的发布者在将其推送到注册表之前进行了验证。
保护Docker安全的一个有用的工具是 Calico 。每个Docker网络都有Calico配置文件,必须设置规则和策略以控制流量。
网友评论