New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Zero trust security mechanism in mesh #14002
Open
namelessssssssssss
wants to merge
62
commits into
apache:3.3-dev-xds
Choose a base branch
from
namelessssssssssss:3.3-dev-xds-security
base: 3.3-dev-xds
Could not load branches
Branch not found: {{ refName }}
Could not load tags
Nothing to show
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Zero trust security mechanism in mesh #14002
namelessssssssssss
wants to merge
62
commits into
apache:3.3-dev-xds
from
namelessssssssssss:3.3-dev-xds-security
Conversation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
namelessssssssssss
changed the title
xDS security init commit
Zero trust security mechanism in mesh
Apr 5, 2024
…-dev-xds-security # Conflicts: # dubbo-xds/src/main/java/org/apache/dubbo/xds/directory/XdsDirectory.java # dubbo-xds/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.xds.security.authz.RuleProvider
Quality Gate passedIssues Measures |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
What is the purpose of the change
This is a draft commit of xDS security support. Mainly including:
Proposal (Chinese)
背景
目标:为Dubbo提供一套零信任安全实现,包含数据面和可选的控制面。
实现概览
概述
mesh下的零信任安全体系,关注于两个维度的安全性
在实践中,鉴权和验证通常在L4(传输层)和L7(应用层)进行,代表协议为TCP协议与HTTP协议。
1、传输层下的验证模型
传输层通常通过TLS/SSL加密实现验证。对端通过证书表示自身身份,被调用方通过查找信任存储库、验证信任链来确定证书是否可信。相比常见的单向TLS(一方提供证书,另一方验证证书),mutual(双向)TLS要求通信双方均提供证书并进行验证。
证书由集群内的证书签发服务签发。通常由服务发起一个包含了新生成证书的CSR请求,证书签发服务为证书签名,并确保它可以被信任链中的根证书或某个中间证书验证
信任存储由集群内的证书管理服务提供,可能与证书签发服务相同。服务通过它获取信任存储,通常是根证书和其签发的部分中间证书的集合。
当对端提供证书的签名可以被信任存储中的任一证书的公钥验证,则认为对端证书可信。
1.1 Istio的mTLS验证模型
1、istio下服务部署时,其istio agent(和envoy一样在服务pod部署)会首先生成一个证书,并向istiod:15012/IstioCertificateService 发送一条包含证书的CSR请求,为证书签名。
2、此处服务需要通过其pod下的k8s(第一方)或 istio(第三方)ServiceAccount JWT Token 向 istiod 表明身份,以建立最初的信任关系。
3、签名完成后,istio agent 作为SDS服务端,以SDS协议将证书提供给envoy,enovy 再通过该证书向 istiod:15012/AdsService 安全端口建立连接,并进行Xds协议的后续调用。
4、在与控制面的Ads服务建立安全连接后,后续服务间通过envoy进行通信时均使用该证书建立mTLS连接。
5、证书的轮换由agent周期性发送CSR请求实现。服务的证书不会在其严格到期时再轮换,而是在其快到期时就尝试签名新证书。IstioCertificateService会将最新的信任链作为CSR请求响应返回,服务则可以使用该信任链更新信任存储。
1.2 X.509 SPIFFE Identity
SPIFFE是 Secure Production Identity Framework for Everyone(适用于所有人的安全生产身份框架)的缩写。它以一串spiffe://开头的URL为服务提供身份,通常以X.509证书或JWT中附加字段的形式出现。这些spiffe的载体称为SVID。
spiffe://<trust-domain>/<namespace>/<service-account>
满足spiffe标准的X.509证书示例 (X.509 SVID):
Istio签发的证书符合SPIFFE标准。Istio agent在生成证书时,会根据pod的环境变量创建一个SPIFFE URL并将其写入待签名的X.509证书, 并携带k8s SA Token或其它身份证明验证自身身份。
Istiod收到CSR请求时,会通过Token和注册条目校验代理为证书写入的SPIFFE信息是否合规。
通过满足SPIFFE标准的X.509证书,上游服务就可以确定下游服务的具体信息(位于哪个信任域、服务名称及工作负载),这些信息可用于后续的访问权限验证流程。
1.2.1 SPIRE
SPIRE是SPIFFE的运行时环境,它是CNCF提供的一个SPIFFE实现。Istio提供了自己的SPIRE实现(Istio CA/Citadel/Istiod +Istio pilot),并支持和CNCF的实现进行集成。
SPIRE主要由Server 和 代理组成。Server 作为中心化的服务,为客户端(服务实例)提供证书签发、管理服务,而代理则负责生成证书、管理证书并请求Server为证书签名、续签,为Node内工作负载提供有效证书。
![image-20240411120322335](/Users/nameles/Library/Application Support/typora-user-images/image-20240411120322335.png)
1.2.2 注册条目
注册条目描述了哪些工作负载可以和哪些SPIFFE身份关联起来,为工作负载关联身份提供了准入条件。这些条目存储在SPIRE Server上,由SPIRE Server管理。
注册条目由选择器、SPIFFE ID、联邦关系等字段组成。
1.3 istio的mTLS配置
istio的mTLS配置由 PeerAuthentication 定义,用于配置是否启用mTLS及对应策略
该策略包含三种类型
STRICT:严格模式,经由该服务的流量必须由mTLS加密,否则会被拒绝。这要求对端服务必须支持TLS且可以提供有效证书,一般同为istio mesh下且部署有sidecar的应用。
PERMISSIVE:宽容模式,服务接受通过mTLS或普通TCP连接的流量。此配置适用于集群中同时存在非istio服务的迁移环境。
NONE/不设置:关闭模式,服务不主动配置证书和密钥,也不会主动建立mTLS连接。适用于少数高性能、不能承受TLS带来的额外开销的场景。
mTLS策略有两种解析方式:
从CDS协议的Endpoint配置中显式获取TLS配置
从LDS协议隐式获取,通过解析 virtualInbound 监听器链中的协议配置实现:若 TransportProtocol仅包含TLS,则认为使用STRICT模式;若同时包含其它协议,则认为使用PERMISSIVE模式;若不包含TLS协议则认为不启用。
2、应用层下的验证模型
应用层下的验证一般指上游服务对对端服务身份进行验证,确保其包含的身份证明不被伪造、身份信息可信。
身份证明通常由JWT携带,并通过HTTP Header传递,通常包含在 Authorizaiton / Cookie 头部中,但也可以是用户的某个自定义Header、表单中的某个字段,并不强制。
根据服务调用者的不同,其JWT来源也可能不同,主要可分为:网格内服务通信时的服务账户JWT与网格外消费者提供的JWT。不管是哪种来源的JWT,payload及签名都必须包含可被上游服务识别,且符合当前配置鉴权及验证策略的标识。
2.1 网格内服务身份证明
在istio mesh内部,istio默认使用k8s ServiceAccount JWT作为服务的身份证明。
认证服务需要具备根据服务信息的JWT的签发能力,并支持其自动更新。对于默认的K8s SA Token,约定存储于服务pod下的
/var/run/secrets/kubernetes.io/token
, 并由k8s负责其自动更新及轮换。相比证书,Token的过期时间更短,通常为几个小时。2.2 网格外消费者身份证明
非网格或istio体系外的请求者也可以使用其它外部认证服务,如OAuth2、OIDC、或某些云服务提供商的认证服务。Istio也支持与这些服务进行集成,使用其他来源的JWT而非Sa JWT。
2.3 身份证明的验证
istio内,用户通过配置 RequestAuthentication 和 AuthorizationPolicy 来指定服务如何验证对端JWT并进行鉴权。其中,RequestAuthentication更注重于验证JWT的有效性,而AuthorizationPolicy则注重于对有效JWT进行更细粒度的RBAC鉴权。
![image-20240411202502036](/Users/nameles/Library/Application Support/typora-user-images/image-20240411202502036.png)
RequestAuthentication示例:
JWT的有效性主要由其是否能被JWKS验证决定。
JWKS(JSON Web Key Set)是一组JWK集合,每个JWT包含了用于验证JWT签名的公钥信息。当一个JWT的签名可以被某个JWK的公钥验证时,认为它是可信的。
在RequestAuthentication中指定的jwksUri是一个外部的JWKS服务地址。除了配置一个独立的JWKS服务,它也可以配置为静态的JWK串。
Istio 将 RequestAuthentication 中的 JWKS 、issuer等验证属性由LDS协议下发到envoy sidecar。LDS中,它会被转换为
envoy.filters.http.jwt_authn
过滤器配置。http_authn过滤器会在下游请求入站时提取JWT,并按照定义的策略进行验证。jwt_authn过滤器配置示例:
这个过滤器使用了静态JWKS。
3、应用层下的鉴权模型
istio下,基于角色的权限控制(RBAC)由AuthorizationPolicy定义。用户通过配置AuthorizationPolicy来为服务进行细粒度的权限控制,包括端口、请求PATH、方法、Header等属性。
![image-20240411204459268](/Users/nameles/Library/Application Support/typora-user-images/image-20240411204459268.png)
AuthorizaitonPolicy示例:
RBAC过滤器本身不和JWT绑定,它可以仅通过一些通用的连接属性进行权限校验。但对端服务的JWT可以为校验提供更多的元数据,以支持基于更多属性的权限控制。
在Envoy中,jwt_authn过滤器在校验JWT同时也会将各种声明提取到校验上下文(HTTP header等)中,RBAC过滤器后续可以从上下文中获取这些属性用于校验。
实现
传输层验证实现
如前文所述,mesh下传输层安全性主要由mTLS提供,包括
1、证书签名前服务身份证明的获取。身份证明来源多样(k8s SA token、外部OAUTH服务,等),格式统一为 JWT。
2、通过服务运行环境生成证书、使用CSR请求为证书签名并缓存证书
3、从信任存储源拉取信任存储(证书链)
4、LDS 监听Listener配置,按port获取对端安全策略(PERMISSIVE、STRICT、NONE)
5、连接建立时提供证书,并要求对端提供证书,使用信任存储验证
Istio + mTLS保证了:
接口及实现:
ServiceIdentitySource 服务身份源,提供JWT形式的服务身份证明
默认实现 KubeServiceJwtIdentitySource 使用本地k8s服务账户Token
CertSource 证书源,提供有效的X.509证书并负责维护
TrustSource 信任源,提供信任证书链(信任存储)并负责维护
CertSource和TrustSource的默认实现 IstioCitadelCertificateSigner,通过本地服务身份生成证书并请求Istio签名,并缓存CSR请求返回的信任链作为信任存储。
LdsListener LDS资源监听器
传输层鉴权下 TlsModeListener 负责解析Listener中各入站port的协议配置(是否支持TLS/SSL),将配置写入TlsModeRepo。
MeshCredentialProvider
现有CertProvider接口的实现,从CertSource和TrustSource获取证书及信任存储,并通过TlsModeRepo判断对端的安全策略。作为客户端时,其要求服务端提供证书;作为服务端时,其要求客户端提供证书。
应用层验证&鉴权实现
应用层验证、鉴权操作集中在Provider链路:
1、请求入站时从请求中解析出消费者请求凭据,包括所有可用于进行访问控制的字段:
其中应用层协议字段协议相关,提供 CredentialFactory 从请求中解析协议相关字段
2、验证、鉴权规则的获取,包括:
若对端是具有SPIFFE身份的服务(TLS中已提供证书),则凭据的验证是可选的,支持不提供JWT/不对JWT的签名进行校验。
首先,根据当前连接的上下文信息(URL、Invocaition、请求凭据)
1、RequestAuthorizer(实现RoleBasedAuthorizer)先获取适用于当前请求的规则源(RuleSource)
2、使用对应的规则工厂(RuleFactory)生成规则树
3、通过 CredentialFactory 获取请求凭据,创建 AuthorizationRequestContext,并使用规则树评估请求,包括所有AND规则和OR规则。
为对端生成怎样的规则树由RuleFactory判断。生成的规则树可能包含两颗子树:验证树和鉴权树,分别使用请求凭据中的不同字段进行校验;也可能仅包含两颗树中的一个,取决于为对端使用怎样的验证策略。
规则树
规则树定义了规则属性之间的关系。如:
无论是Isitio的AuthorizationPolicy,又或是envoy的RBAC filter配置,都可以使用规则树表示完整的规则结构。
目前提供两套构建规则树的实现:
1、以KubeApiClient拉取AuthorizationPolicy配置,以Map构建规则树
2、以LDS监听器获取RBAC、authn过滤器配置,以HTTP filter构建规则树