【微服务体系】6 应用安全

6 应用安全

安全作为应用重要部分,必须要考虑。本章讨论在云原生的微服务架构下的安全要求。

6.1 微服务架构安全

微服务架构动态的本质,改变了安全的方式。安全与如何定义应用或服务边界相关。如下图所示,表示单块应用和微服务应用的请求流程图。

【微服务体系】6 应用安全_第1张图片

单块应用和微服务应用两者最大的区别,单块应用的组成是固定的,而微服务的组成经常发生变化。微服务独立更新。安全边界永远不够。如何以一种有机的方式保护这种快速变化的基础设施,级每个独立的服务可以自由改变和演进,而不需要中央协调。

网络分离

在上图中,两种风格的系统中都有一个分离的子网络,使用外部的防火墙或网关保护资源是一种比较好的方法。

如上图所示,外部API连接了两个不同的微服务应用,需要定义合理的应用边界,来分割多个独立的系统,这是一种很好的方式来保护动态的系统环境。

在主机环境网络分离很自然,例如微服务应用,如上图所示,每个微服务可以看做多租户(multi-tenant)环境中的一个租户。一般不会发生这种,除非需要这样。然而,微服务架构中管理网络的最佳实践是将外部管好。

确保数据隐私

不同类型的数据需要不同层级的保护,这些保护会影响数据的访问、传输、存储。

当需要处理数据时,可以考虑以下内容:
1.不要传输原始文本的密码
2.保护私钥
3.使用知名的加密技术,而非自定义
4.使用加盐的hash来存储密码,https://crackstation.net/hashing-security.htm
5.敏感的数据应该尽早被加密,尽可能晚的解密。如果敏感数据需要在服务之间流转,保持加密形式,除非需要需要用到这个数据。这可以避免意外泄露。

backing service
连接后端服务,作为网络中添加的资源,需要被保护起来。在很多云环境中,后端服务由云平台提供,依赖于多租户(multi-tenancy)和API keys,或访问令牌(access tokens)提供数据隔离。理解后端的这些特性至关重要,特别是它如何存储数据,确保满足监管要求(HIPAA, PCI等)。

Log data

日志数据需要权衡哪些用来进行问题诊断,哪些必须保护起来,出于监管和隐私原因。当输出日志时,充分利用日志的等级来控制数据如何输出。对于用户提供的数据,需要考虑这些数据是否原本属于日志内容。例如,我们是否需要将这个属性的值写入日志中,或我们是否真的关系它是否为null。

自动化

尽可能的让微服务自动化,包含一般的运维。可重复的自动进程应该应用于跨分片环境下申请安全策略、证书、管理SSL证书以及钥匙,避免人为错误。

信用证、证书、钥匙应该存储到一个地方,以供自动化使用,可以考虑以下建议:
1.不要将证书存在应用中
2.不要将证书存储在公共仓库中
3.只存储加密的数据

6.2 标识和信任

在高度分布的、动态的环境下,例如微服务架构,在建立稳定统一模式的标识上花费很大功夫。我们必须建立和维护用户的标识,而不会调用中心服务,从而引入额外的延迟或内容。

在这个环境中建立和维护可信不是那么容易,假设私有网络是安全的这种方式本身就是不安全的。端到端的SSL可以加密传输的字节,但是它不能只考自己构建一个可信的环境,它key管理方。

本节讨论认证与授权,以及标识传播,用于建立和维护可信任的服务间通信。

认证与授权

微服务环境中需要认证和授权,在单块应用中,拥有细粒度的角色、角色与中心用户仓库相关联。微服务独立生命周期的重要性,像这种角色和用户的依赖是反面模式(anti-pattern)。开发独立的微服务受中心资源更新的约束。

专注的、中心化的服务或API网关创建认证(authentication,建立用户标识信息)是很常见的做法。这个中心的服务可以将用户认证信息代理给第三方。

当使用授权(auhorization,建立用户的权限,访问受保护资源权限的权限),在微服务环境中,保持组或角色的定义粗粒度是很常见的做法,跨服务切片。允许独立服务维护自己的控制粒度。将服务确保独立为基本原则。根据应用整体需求,权衡哪些在公共授权服务中定义,哪些在特定的服务中实现。

授权委托 OAuth2.0

OAuth 提供一个开源的框架,用于授权第三方应用访问。虽然框架定义了授权的交互模式,但是没有定义程序接口。具体参考:https://tools.ietf.org/html/rfc6749

OpenID Connect(OIDC)提供了一个基于OAuth2.0的表示层,委托认证至第三方。它定义了一个基于REST的互操作机制,建立在OAuth之上。具体可参考:https://openid.net/connect/

JWT (Json web tokens)

标识传递是微服务架构中另一个具有挑战性的问题,当用户(human或 服务)已经认证后,表示需要以一种可信的方式传递到另一个服务。频繁的调用认证中心来校验表示是非常低效的,特别是通过中心网关路由的服务与服务之间的通信,会产生延迟。

JWT 可以携带用户的信息,可以完成以下任务:
1.知道用户的请求由用户初始化
2.知道请求的表示由谁产生
3.知道这个请求不是由前一个请求恶意重复的

JWT有契约的和URL友好的。从名称中也可以猜出,JWT包含一种JSON结构的数据。这个结构包含标准的申明属性,例如提交者、目标,过期时间。清晰的映射其他安全机制。JWT也提供自定义的空间,允许添加额外信息。

当我们构建应用的同时,我们很可能被告诫,JWT因为显示性而无效。对于安全和隐私原因,登录时将准确的错误信息告诉前端是一种不好的主意。这样做可能泄露具体的实现或用户细节。JWT.IO 提供很多有用的web工具,帮助开发JWT应用,具体参考:https://jwt.io

处理时间

JWT有一个优点是确定性地运行标识传递。当JWT过期,会触发校验JWT中的标识,从而产生新的JWT。JWT有三个字段与时间相关,都是可选的。一般来说,包括以下字段:
1.JWT创建时间(iat),在当前时间之前表示有效
2.“no process before”(nbf),在当前时间之前表示有效
3.过期时间(exp),在当前时间之后表示,jwt有效

这些时间都是以UNIX时间戳表示。

Signed JWT

签名JWT能在服务之间够建立信任,一个接收者可以校验签名者的表示,以及JWT的内容是否被更改过。

JWT可以使用共享的秘钥进行签名,或者秘钥对(public/private, SSL 证书)。

基于Hash的消息认证编码

使用基于Hash的消息认证码(HMAC,Hash-based Messaging Authentication Code)进行认证比HTTP basic优雅。当使用HMAC,请求信息被哈希编码并签名,用于创建一个署名,然后,包含在发送的请求中。当请求被接收,这个请求属性将被反哈希,用于确保数值是匹配的。这中方式可以认证用户,校验内容在传输中没有被修改。这种哈希标签可以疲惫重复的攻击。

HMAC校验能在API网关中使用。例如,网关认证用户,然后无论服务缓存响应信息、生成JWT或者其他自定义的头。使用JWT的好处是运行下游的服务一致地使用JWT来识别用户,将原来认证方法进行解耦独立。

HMAC不是完整的标准,API提供(网关或独立的服务)方经常需要提供不同的请求参数来生成签名。

建议使用HMAC共享库,因为HMAC需要在API消费者和提供方进行计算。

API Keys 和共享秘钥

一个API key可以代表不同的含义,但一般用来识别原始请求。识别原始的请求在API管理中非常重要,比如 限流或跟踪。API Keys通常与账户的证书分开,根据需要创建或销毁。

一个API Key可以是一串字符,但是不像密码,这个字符串是随机生成的,超过40个字符长度。然而,优势字符直接在请求中使用,作为bearer token 或查询参数。使用API key可以让共享秘钥的签名的JWT更安全,或者数字方法(HMAC)。

如果服务创建API key,确保API key是以高度加密和正确存储的安全方式生成的。确保这些key能随时吊销。如果应用有分离的部分,那么为每个部分应该使用不同的API key。这样便于更细粒度的用户使用追踪,减少某个危险key造成的影响。

也可以使用非对称秘钥(例如 SSL),但是需要维护一个公钥基础设施(public key infrastructure,PKI)。虽然这样更安全,但是可以加大人力劳动,并且也很难管理,如果第三方也是API消费者。

考虑到12要素,秘钥应该依据配置注入,当微服务内部通讯时。这个secret不应该硬编码到应用中,因为这样会造成危险。

你可能感兴趣的:(软件系统架构与开发环境,分布式系统)