[zh] improve authn-policy and jwt-route (#13160)

Signed-off-by: xin.li <xin.li@daocloud.io>
This commit is contained in:
my-git9 2023-05-04 18:11:23 +08:00 committed by GitHub
parent a2ccc5bbf0
commit 0639f28050
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 54 additions and 51 deletions

View File

@ -13,7 +13,7 @@ test: yes
本任务涵盖了您在启用、配置和使用 Istio 认证策略时可能需要做的主要工作。
更多基本概念介绍请查看[认证总览](/zh/docs/concepts/security/#authentication)。
## 开始之前{#before-you-begin}
## 开始之前 {#before-you-begin}
* 理解 Istio [认证策略](/zh/docs/concepts/security/#authentication-policies)和[双向 TLS 认证](/zh/docs/concepts/security/#mutual-TLS-authentication)相关概念。
* 参照[安装步骤](/zh/docs/setup/getting-started),使用 `default`
@ -23,11 +23,11 @@ test: yes
$ istioctl install --set profile=default
{{< /text >}}
### 设置{#setup}
### 设置 {#setup}
我们将在 `foo``bar`命名空间下各自创建带有 Envoy 代理sidecar
`httpbin``sleep`服务。我们还会`legacy` 命名空间下创建不带
Envoy 代理(sidecar`httpbin``sleep` 服务。如果您希望使用相同的示例来完成这些任务,
我们将在 `foo``bar` 命名空间下各自创建带有 Envoy 代理Sidecar
`httpbin``sleep` 服务,`legacy` 命名空间下创建不带
Envoy 代理(Sidecar`httpbin``sleep` 服务。如果您希望使用相同的示例来完成这些任务,
执行如下命令:
{{< text bash >}}
@ -43,7 +43,7 @@ $ kubectl apply -f @samples/sleep/sleep.yaml@ -n legacy
{{< /text >}}
现在您可以在 `foo`、`bar` 或 `legacy` 三个命名空间下的任意 `sleep` Pod
使用 `curl``httpbin.foo`、`httpbin.bar` 或 `httpbin.legacy`
使用 `curl` `httpbin.foo`、`httpbin.bar` 或 `httpbin.legacy`
发送 HTTP 请求来验证部署结果。所有请求都应该成功返回 HTTP 200。
例如,一个检查 `sleep.bar``httpbin.foo` 可达性的指令如下:
@ -83,17 +83,17 @@ $ kubectl get destinationrules.networking.istio.io --all-namespaces -o yaml | gr
{{< /text >}}
{{< tip >}}
您可能会看到 destination rules 配置了除上面显示以外的其他 hosts
这依赖于 Istio 的版本。但是,应该没有 destination rules 配置
`foo`、`bar` 和 `legacy` 命名空间中的 hosts
您可能会看到 destination rule 配置了除上面显示以外的其他 host
这依赖于 Istio 的版本。但是,应该没有 destination rule 配置
`foo`、`bar` 和 `legacy` 命名空间中的 host
也没有配置通配符 `*`
{{< /tip >}}
## 自动双向 TLS{#auto-mutual-TLS}
## 自动双向 TLS {#auto-mutual-TLS}
默认情况下Istio 会跟踪迁移到 Istio 代理的服务器工作负载并配置客户端代理,
将双向 TLS 流量自动发送到这些工作负载,并将 plain-text 流量发送到没有
sidecar 的工作负载。
Sidecar 的工作负载。
因此,您无需做额外操作,具有代理的工作负载之间的所有流量即可启用双向 TLS。
例如检查请求 `httpbin/header` 的响应。
@ -105,14 +105,14 @@ $ kubectl exec "$(kubectl get pod -l app=sleep -n foo -o jsonpath={.items..metad
"X-Forwarded-Client-Cert": "By=spiffe://cluster.local/ns/foo/sa/httpbin;Hash=<redacted>;Subject=\"\";URI=spiffe://cluster.local/ns/foo/sa/sleep"
{{< /text >}}
当服务器没有 sidecar 时,`X-Forwarded-Client-Cert` 标头将不会存在,
当服务器没有 Sidecar 时,`X-Forwarded-Client-Cert` 标头将不会存在,
这意味着请求是 plain-text 的。
{{< text bash >}}
$ kubectl exec "$(kubectl get pod -l app=sleep -n foo -o jsonpath={.items..metadata.name})" -c sleep -n foo -- curl http://httpbin.legacy:8000/headers -s | grep X-Forwarded-Client-Cert
{{< /text >}}
## 全局以严格模式启用 Istio 双向 TLS{#globally-enabling-Istio-mutual-TLS-in-STRICT-mode}
## 全局以严格模式启用 Istio 双向 TLS {#globally-enabling-Istio-mutual-TLS-in-STRICT-mode}
当 Istio 自动将代理和工作负载之间的所有流量升级到双向 TLS 时,
工作负载仍然可以接收 plain-text 流量。为了阻止整个网格的服务以非双向 TLS 通信,
@ -158,10 +158,10 @@ command terminated with exit code 56
sleep.legacy to httpbin.legacy: 200
{{< /text >}}
您会发现除了从没有 sidecar 的服务(`sleep.legacy`)到有 sidecar
您会发现除了从没有 Sidecar 的服务(`sleep.legacy`)到有 Sidecar
的服务(`httpbin.foo` 或 `httpbin.bar`)的请求外,其他请求依然是返回成功的。
### 清除部分 1{#cleanup-part-1}
### 清除部分 1 {#cleanup-part-1}
删除在会话中添加的全局身份验证策略:
@ -169,9 +169,9 @@ sleep.legacy to httpbin.legacy: 200
$ kubectl delete peerauthentication -n istio-system default
{{< /text >}}
## 为每个命名空间或者工作负载启用双向 TLS{#enable-mutual-TLS-per-namespace-or-workload}
## 为每个命名空间或者工作负载启用双向 TLS {#enable-mutual-TLS-per-namespace-or-workload}
### 命名空间级别策略{#namespace-wide-policy}
### 命名空间级别策略 {#namespace-wide-policy}
如果要将特定命名空间内的所有工作负载更改双向 TLS请使用命名空间级别策略。
该策略的规范与整个服务网格级别规范相同,但是您可以在 `metadata` 字段指定命名空间的名称。
@ -190,8 +190,8 @@ spec:
EOF
{{< /text >}}
由于这些策略只应用于命名空间 `foo` 中的服务,您会看到只有从没有 sidecar
的客户端(`sleep.legacy`)到有 sidecar 的客户端(`httpbin.foo`)的请求会失败。
由于这些策略只应用于命名空间 `foo` 中的服务,您会看到只有从没有 Sidecar
的客户端(`sleep.legacy`)到有 Sidecar 的客户端(`httpbin.foo`)的请求会失败。
{{< text bash >}}
$ for from in "foo" "bar" "legacy"; do for to in "foo" "bar" "legacy"; do kubectl exec "$(kubectl get pod -l app=sleep -n ${from} -o jsonpath={.items..metadata.name})" -c sleep -n ${from} -- curl "http://httpbin.${to}:8000/ip" -s -o /dev/null -w "sleep.${from} to httpbin.${to}: %{http_code}\n"; done; done
@ -207,7 +207,7 @@ sleep.legacy to httpbin.bar: 200
sleep.legacy to httpbin.legacy: 200
{{< /text >}}
### 为每个工作负载启用双向 TLS{#enable-mutual-TLS-per-workload}
### 为每个工作负载启用双向 TLS {#enable-mutual-TLS-per-workload}
要为特定工作负载设置对等身份验证策略,必须配置 `selector`
字段并指定与所需工作负载匹配的标签。例如,以下对等身份验证策略和
@ -292,7 +292,7 @@ sleep.legacy to httpbin.bar: 200
sleep.legacy to httpbin.legacy: 200
{{< /text >}}
### 策略优先级{#policy-precedence}
### 策略优先级 {#policy-precedence}
为了演示特定服务策略比命名空间范围的策略优先级高,您可以像下面一样为
`httpbin.foo` 添加一个禁用双向 TLS 的策略。
@ -323,7 +323,7 @@ $ kubectl exec "$(kubectl get pod -l app=sleep -n legacy -o jsonpath={.items..me
200
{{< /text >}}
### 清除部分 2{#cleanup-part-2}
### 清除部分 2 {#cleanup-part-2}
删除之前步骤中创建的策略:
@ -332,7 +332,7 @@ $ kubectl delete peerauthentication default overwrite-example -n foo
$ kubectl delete peerauthentication httpbin -n bar
{{< /text >}}
## 终端用户认证{#end-user-authentication}
## 终端用户认证 {#end-user-authentication}
为了体验这个特性,您需要一个有效的 JWT。该 JWT 必须和您用于该示例的 JWKS 终端对应。
在这个教程中,我们使用来自 Istio 代码基础库的
@ -437,7 +437,7 @@ $ curl --header "Authorization: Bearer $TOKEN" "$INGRESS_HOST:$INGRESS_PORT/head
为了观察 JWT 验证的其它方面,使用脚本
[`gen-jwt.py`]({{< github_tree >}}/security/tools/jwt/samples/gen-jwt.py)
生成新 tokens 带上不同的发行人、受众、有效期等等进行测试。可以从 Istio 库下载此脚本:
生成新 token 带上不同的发行人、受众、有效期等等进行测试。可以从 Istio 库下载此脚本:
{{< text bash >}}
$ wget --no-verbose {{< github_file >}}/security/tools/jwt/samples/gen-jwt.py
@ -455,9 +455,9 @@ $ wget --no-verbose {{< github_file >}}/security/tools/jwt/samples/key.pem
{{< /tip >}}
JWT 认证有 60 秒的时钟偏移clock skew这意味着 JWT
令牌会比其配置 `nbf` 早 60 秒成为有效的,其配置 `exp`后 60 秒后仍然有效。
令牌会比其配置 `nbf` 早 60 秒成为有效的,其配置 `exp` 后 60 秒后仍然有效。
例如下面的命令创建一个令牌该令牌在5秒钟后过期。如您所见
例如,下面的命令创建一个令牌,该令牌在 5 秒钟后过期。如您所见,
Istio 会一直通过认证直到 65 秒后才拒绝这些令牌:
{{< text bash >}}
@ -479,7 +479,7 @@ $ for i in $(seq 1 10); do curl --header "Authorization: Bearer $TOKEN" "$INGRES
`istio-ingressgateway.istio-system.svc.cluster.local`)。
这个常用于为绑定到这个 gateway 的所有服务定义一个 JWT 策略而不是为单独的服务绑定策略。
### 提供有效令牌{#require-a-valid-token}
### 提供有效令牌 {#require-a-valid-token}
拒绝没有有效的令牌的请求,需要增加名为 `DENY` 认证策略,
可参考以下例子中的 `notRequestPrincipals:["*"]` 配置。
@ -511,10 +511,10 @@ $ curl "$INGRESS_HOST:$INGRESS_PORT/headers" -s -o /dev/null -w "%{http_code}\n"
403
{{< /text >}}
### 按路径提供有效令牌{#require-valid-tokens-per-path}
### 按路径提供有效令牌 {#require-valid-tokens-per-path}
为了按路径(路径指 host、path 或者 method)提供有效令牌我们需要在其认证策略中指定这些路径,
如下列配置中的 `/headers`。待规则生效后,对`$INGRESS_HOST:$INGRESS_PORT/headers`
为了按路径(路径指 host、path 或者 method提供有效令牌我们需要在其认证策略中指定这些路径,
如下列配置中的 `/headers`。待规则生效后,对 `$INGRESS_HOST:$INGRESS_PORT/headers`
的请求将失败,错误代码为 `403`。而到其他所有路径的请求 —— 例如:`$INGRESS_HOST:$INGRESS_PORT/ip` —— 都会成功。
{{< text bash >}}
@ -549,7 +549,7 @@ $ curl "$INGRESS_HOST:$INGRESS_PORT/ip" -s -o /dev/null -w "%{http_code}\n"
200
{{< /text >}}
### 清除部分 3{#cleanup-part-3}
### 清除部分 3 {#cleanup-part-3}
1. 删除认证策略:

View File

@ -13,13 +13,14 @@ status: Experimental
{{< boilerplate experimental >}}
本任务向您展示通过 Istio 请求身份验证策略成功完成 JWT 身份验证之后如何将 JWT 声明复制到 HTTP 头。
本任务向您展示通过 Istio 请求身份验证策略成功完成 JWT 身份验证之后如何将
JWT 声明复制到 HTTP 头。
{{< warning >}}
仅支持 string、boolean 和 integer 类型的声明。此时不支持 array 类型的声明。
{{< /warning >}}
## 开始之前{#before-you-begin}
## 开始之前 {#before-you-begin}
开始此任务之前,请做好以下准备:
@ -27,7 +28,8 @@ status: Experimental
* 使用 [Istio 安装指南](/zh/docs/setup/install/istioctl/)安装 Istio。
* 在已启用 Sidecar 注入的命名空间 `foo` 中部署 `httpbin``sleep` 工作负载。使用以下命令部署命名空间和工作负载示例:
* 在已启用 Sidecar 注入的命名空间 `foo` 中部署 `httpbin``sleep`
工作负载。使用以下命令部署命名空间和工作负载示例:
{{< text bash >}}
$ kubectl create ns foo
@ -47,10 +49,11 @@ status: Experimental
如果您未看到预期的输出,几秒后重试。缓冲和传播可能会造成延迟。
{{< /warning >}}
## 允许具有有效 JWT 和列表类型声明的请求{#allow-requests-with-valid-jwt-and-list-type-claims}
## 允许具有有效 JWT 和列表类型声明的请求 {#allow-requests-with-valid-jwt-and-list-type-claims}
1. 以下命令为 `foo` 命名空间中的 `httpbin` 工作负载创建 `jwt-example` 请求身份验证策略。
此策略接受 `testing@secure.istio.io` 签发的 JWT并将声明 `foo` 的值复制到一个 HTTP 头 `X-Jwt-Claim-Foo`
此策略接受 `testing@secure.istio.io` 签发的 JWT并将声明 `foo` 的值复制到一个 HTTP 头
`X-Jwt-Claim-Foo`
{{< text bash >}}
$ kubectl apply -f - <<EOF
@ -100,7 +103,7 @@ status: Experimental
"X-Jwt-Claim-Foo": "bar"
{{< /text >}}
## 清理{#clean-up}
## 清理 {#clean-up}
1. 移除命名空间 `foo`

View File

@ -10,20 +10,20 @@ status: Alpha
{{< boilerplate alpha >}}
本任务向您展示如何实现基于 Istio 入口网关上的 JWT 声明路由请求,来使用请求身份认证
和虚拟服务。
本任务向您展示如何实现基于 Istio 入口网关上的 JWT 声明路由请求,
来使用请求身份认证和虚拟服务。
注意:该特性只支持 Istio 入口网关,并且需要使用请求身份验证和虚拟
服务来根据 JWT 声明进行正确的验证和路由。
注意:该特性只支持 Istio 入口网关,并且需要使用请求身份验证和虚拟服务来根据
JWT 声明进行正确的验证和路由。
## 开始之前{#before-you-begin}
## 开始之前 {#before-you-begin}
* 理解 Istio [身份认证策略](/zh/docs/concepts/security/#authentication-policies)和[虚拟服务](/zh/docs/concepts/traffic-management/#virtual-services)相关概念。
* 使用 [Istio 安装指南](/zh/docs/setup/install/istioctl/)安装 Istio
* 使用 [Istio 安装指南](/zh/docs/setup/install/istioctl/)安装 Istio。
* 在 `foo` 命名空间中,部署一个 `httpbin` 工作负载
并通过 Istio 入口网关使用以下命令暴露它:
* 在 `foo` 命名空间中,部署一个 `httpbin` 工作负载,
并通过 Istio 入口网关使用以下命令暴露它:
{{< text bash >}}
$ kubectl create ns foo
@ -46,7 +46,7 @@ status: Alpha
如果您没有看到预期的输出,请在几秒钟后重试。因为缓存和传输的开销会导致延迟。
{{< /warning >}}
## 基于 JWT 声明配置入站路由{#configuring-ingress-routing-based-on-JWT-claims}
## 基于 JWT 声明配置入站路由 {#configuring-ingress-routing-based-on-JWT-claims}
Istio 入口网关支持基于经过身份验证的 JWT 的路由,
这对于基于最终用户身份的路由非常有用,并且比使用未经身份验证的 HTTP
@ -109,13 +109,13 @@ Istio 入口网关支持基于经过身份验证的 JWT 的路由,
EOF
{{< /text >}}
虚拟服务使用保留的消息头 `"@request.auth.claims.groups"` 来匹配 JWT 声明中的 `groups`
虚拟服务使用保留的消息头 `"@request.auth.claims.groups"` 来匹配 JWT 声明中的 `groups`
前缀的 `@` 表示它与来自 JWT 验证的元数据匹配,而不是与 HTTP 消息头匹配。
JWT 支持字符串类型的声明、字符串列表和嵌套声明。使用 `.` 作为嵌套声明名称的分隔符。
例如, `"@request.auth.claims.name.givenName"` 匹配嵌套声明 `name``givenName`
例如,`"@request.auth.claims.name.givenName"` 匹配嵌套声明 `name``givenName`
当前不支持使用 `.` 字符作为声明名称。
## 基于 JWT 声明验证入口路由{#validating-ingress-routing-based-on-JWT-claims}
## 基于 JWT 声明验证入口路由 {#validating-ingress-routing-based-on-JWT-claims}
1. 验证入口网关返回没有 JWT 的 HTTP 404 代码:
@ -163,9 +163,9 @@ Istio 入口网关支持基于经过身份验证的 JWT 的路由,
...
{{< /text >}}
## 清除{#cleanup}
## 清除 {#cleanup}
* 移除名称为 foo 的命名空间:
* 移除名称为 `foo` 的命名空间:
{{< text bash >}}
$ kubectl delete namespace foo