微服务设计:安全

当谈到与我们系统交互的人和事时,身份验证和授权是核心概念。在安全领域中,身份验证是确认他是谁的过程。对于一个人,通常通过用户输入的用户名和密码来验证。我们认为只有用户本人才能够知道这些信息,因此输入这些信息的人一定是他。通常来说,当我们抽象地讨论进行身份验证的人或事时,我们称之为主体。
通过授权机制,可以把主体映射到他可以进行的操作中。通常,当一个主体通过身份验证后,我们将获得关于他的信息,这些信息可以帮助我们决定其可以进行的操作。
身份验证和授权的一种常用方法是,使用某种形式的SSO(单点登录)解决方案。在企业级领域中占据统治地位的SAML和OpenID Connect,也提供了这方面的能力。
当主体试图访问一个资源(比如基于Web的接口)时,他会被定向到一个身份提供者那里进行身份验证。这个身份提供者会要求他提供用户名和密码,或使用更先进的双重身份验证。一旦身份提供者确认主体已通过身份验证,它会发消息给服务提供者,让服务提供者来决定是否允许他访问资源。
对于企业来说,通常有自己的身份提供者,它会连接到公司的目录服务。目录服务可能使用LDAP(轻量级目录访问协议)或活动目录。这些系统允许你存储主体的信息,例如他们在组织中扮演什么样的角色。
SAML是一个基于SOAP的标准,尽管有库和工具支持它,但用起来还是相当复杂。基于Google和其他公司处理SSO的方式,OpenID Connect已经成为了OAuth 2.0具体实现中的一个标准。它使用简单的REST调用,提高了其易用性。现在其最大的障碍是缺乏支持它的身份提供者。
在微服务系统中,每个服务可以自己处理如何重定向到身份提供者,并与其进行握手。显然,这意味着大量的重复工作。使用共享库可以解决这个问题,但我们必须小心地避免可能来自共享代码的耦合。
你可以使用位于服务和外部世界之间的网关作为代理,而不是让每个服务管理与身份提供者握手。基本想法是,我们可以集中处理重定向用户的行为,并且只在一个地方执行握手。
网关可以提供相当有效的粗粒度的身份认证。例如,它可以阻止任何未登录用户访问帮助台应用程序。假如我们的网关在身份验证完成时能提取出主体的属性,则可以据此做出更细致的决定。例如,我们通常将人放到某些组或分配某些角色,通过使用这些信息来了解他们能做什么。所以,对于帮助台应用程序,我们可能只允许具有某个特定的角色的主体访问。不过,超出允许(或禁止)的特定资源或端点的访问部分,它们可以留给微服务本身来处理,它会对允许哪些操作做进一步的决定。
你应该倾向于使用粗粒度的角色,围绕组织的工作方式建模。
HPPT基本身份验证,允许客户端在标准的HTTP头中发送用户名和密码。服务端可以验证这些信息,并确认客户端是否有权访问服务。这样做的好处在于,这是一种非常容易理解且得到广泛支持的协议。问题在于,通过HTTP有很高的风险,因为用户名和密码并没有以安全的方式发送。任何中间方都可以看到HTTP头的信息并读取里面的数据。因此,HTTP基本身份验证通常应该通过HTTPS进行通信。
当使用HTTPS时,客户端获得强有力的保证,它所通信的服务端就是客户端想要通信的服务端。它给予我们额外的保护,避免人们窃听客户端和服务端之间的通信,或篡改有效的负载。
SSL之上的流量不能被反向代理服务器所缓存,这是使用HTTPS的另一个缺点。这意味着,如果你需要缓存信息,就不得不在服务端或客户端内部实现。你可以在负载均衡中把HTTPS的请求转换成HTTP的请求,然后在负载均衡之后就可以使用缓存了。
确认客户端身份的另一种方法是,使用TLS(安全传输层协议),TLS是SSL在客户端证书方面的继任者。在这里,每个客户端都安装了一个X.509证书,用于客户端和服务器端之间建立通信链路。服务器可以验证客户端证书的真实性,为客户端的有效性提供强有力的保证。
使用这种方法,证书管理的工作要比只使用服务器端证书更加繁重。它不只是创建和管理数量更多的证书这么简单;相反,所有的复杂性在于证书本身,你很有可能会花费大量的时间来试图诊断服务端为什么不接受你认为的一个完全有效的客户端证书。接下来,我们要考虑在最坏的情况下,撤销和补发证书的难度。这些额外的负担意味着,当你特别关注所发数据的敏感性,或无法控制发送数据所使用的网络时,才考虑使用这种技术。
有一种安全漏洞叫作混淆代理人问题,指的是在服务间通信的上下文中,攻击者采用一些措施欺骗代理服务,让它调用其下游服务,从而做到一些他不应该能做的事情。
加密的过程依赖一个数据加密算法和一个密钥,然后使用二者对数据进行加密。那么,你的密钥存储在哪里?如果加密数据是因为担心有人窃取整个数据库,那么把密钥存储在同一个数据库中,并不会真正消除这种担心!因此,我们需要把密钥存储到其他地方。
一个解决方案是,使用单独的安全设备来加密和解密数据。另一个方案是,使用单独的密钥库,当你的服务需要密钥的时候可以访问它。密钥的生命周期管理是非常重要的操作,而这些系统可以帮你处理这个事情。
日志可以让你事后看看是否有不好的事情发生过。但是请注意,我们必须小心那些存储在日志里的信息!敏感信息需要被剔除,以确保没有泄漏重要的数据到日志里,如果泄漏的话,最终可能会成为攻击者的重要目标。
IDS(入侵检测系统)可以监控网络或主机,当发现可疑行为时报告问题。IPS(入侵预防系统),也会监控可疑行为,并进一步阻止它的发生。不同于防火墙主要是对外阻止坏事进来,IDS和IPS是在可信范围内积极寻找可疑行为。这些系统是基于启发式的(正如很多的应用防火墙),很有可能刚开始的通用规则,对于你的服务行为来说过于宽松或过于严格。
使用在告警方面相对更加积极的IDS之前,应该先使用相对被动的IDS,因为在这种情况下更容易优化规则。
对于单块系统而言,我们在通过构造网络来提供额外的保护方面能做的很有限。不过,在微服务系统中,你可以把服务放进不同的网段,以进一步控制服务间的通信。例如,AWS提供自动创建VPC(虚拟私有云)的能力,它允许主机处在不同的子网中。然后你可以通过定义对等互联规则,指定哪个VPC可以跟对方通信,甚至可以通过网关把流量路由到代理中,实际上,它提供了多个网络范围,在其中可以实施额外的安全措施。
你可能还需要流程和政策,来处理组织中的人为因素。当有人离开组织时,你如何撤销访问凭证?
作为一个好的思维锻炼,你可以考虑一个心怀不满的前雇员,如果他想的话,可能会如何损害你的系统。
posted @ 2023-07-09 11:09  wtzhang  阅读(24)  评论(0编辑  收藏  举报