Isito 入门(九):安全认证
本教程已加入 Istio 系列:https://istio.whuanle.cn
7,认证
本章的内容主要是讲解服务间通讯的安全和集群外部访问内部服务的 jwt token 验证。
Istio 提供两种类型的认证,一种是服务间认证 Peer Authentication,一种是客户端请求认证 Request Authentication。
Peer Authentication
Peer authentication 用于服务到服务的认证,在零信任网络中,Envoy 给服务之间的通讯加密,只有服务双方才能看到请求内容和响应结果。
在 Istio 中,默认情况下,服务之间的通信不会被加密或进行身份验证。比如说, A 服务通过 http 请求 B 服务,流量经过 Envoy A 时,Envoy A 直接将流量发送到 Envoy B 中,流量不会进行加密处理,也就是明文请求。
Istio 的 Peer Authentication 主要解决以下问题:
- 保护服务到服务的通信。
- 提供密钥管理系统,通讯加密需要使用证书,而证书会过期,所以需要一个管理系统自动颁发证书、替换证书等。
- 为每个服务提供强大的身份标识,以实现跨群集和云的互操作性。
Request Authentication
Request authentication 用于外部请求的用户认证, Istio 使用 JWT(JSON Web Token) 来验证客户端的请求,并使用自定义认证实现或任何 OpenID Connect 的Request authentication 认证实现来简化的开发人员体验。
支持以下认证类型:
- ORY Hydra
- Keycloak
- Auth0
- Firebase Auth
- Google Auth
Peer Authentication
Istio 的 PeerAuthentication 是一种安全策略,用于对服务网格内的工作负载之间的通信进行双向 TLS(mTLS)验证。
通过 PeerAuthentication 在 Envoy 间启用 mTLS,以确保工作负载之间的通信在传输过程中是加密和安全的。
PeerAuthentication 可以配置为整个集群或只在命名空间中起作用,但是只能有一个网格范围的 Peer 认证策略,每个命名空间也只能有一个命名空间范围的 Peer 认证策略。
PeerAuthentication 的定义
下面是一个简单的 PeerAuthentication 示例:
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
name: my-peer-authentication
namespace: my-namespace
spec:
selector:
matchLabels:
app: my-app
mtls:
mode: STRICT
selector
: 标签选择器,用于选择应用 PeerAuthentication 策略的工作负载。例如:
selector:
matchLabels:
app: my-app
如果省略选择器,PeerAuthentication 策略将应用于命名空间中的所有工作负载。
mtls: 定义双向 TLS 的模式,有三种模式。
STRICT
: 强制执行 mTLS,要求客户端和服务器使用 TLS 进行通信。这需要客户端和服务器具有有效的证书。PERMISSIVE
: 允许客户端使用TLS或纯文本进行通信。这对于逐步迁移到 mTLS 的场景非常有用。DISABLE
: 禁用 mTLS,不要求客户端和服务器使用 TLS 进行通信。
只能有一个网格范围的 Peer 认证策略,每个命名空间也只能有一个命名空间范围的 Peer 认证策略。当同一网格或命名空间配置多个网格范围或命名空间范围的 Peer 认证策略时,Istio 会忽略较新的策略。当多个特定于工作负载的 Peer 认证策略匹配时,Istio 将选择最旧的策略。
实验
我们继续服用前面使用的 bookinfo 微服务,给 bookinfo 命名空间启用 mTLS。
kubectl apply -f - <<EOF
apiVersion: "security.istio.io/v1beta1"
kind: "PeerAuthentication"
metadata:
name: "bookinfo-policy"
namespace: "bookinfo"
spec:
mtls:
mode: STRICT
EOF
然后再次请求 productpage 服务,可以使用以下命令制作大量的模拟请求。
for i in `seq 1 1000`; do curl -s -o /dev/null http://192.168.3.150:30666/productpage; done
然后在 kiali 面板中的 Display 选项中下拉选择 Security。
RequestAuthencation
Istio 的 RequestAuthentication 是一种安全策略,用于验证和授权客户端访问Istio服务网格中的服务。
RequestAuthencation 需要搭配一个 AuthorizationPolicy来 使用。RequestAuthentication 和 AuthorizationPolicy 这两个策略用于验证和授权客户端访问服务网格中的服务。
RequestAuthentication 负责验证客户端提供的 JWT,而 AuthorizationPolicy 负责基于角色的访问控制(RBAC),允许定义细粒度的权限以限制对特定服务、方法和路径的访问。
RequestAuthencation 的定义
下面是一个完整的 RequestAuthentication 示例:
apiVersion: security.istio.io/v1beta1
kind: RequestAuthentication
metadata:
name: my-request-authentication
namespace: my-namespace
spec:
jwtRules:
- issuer: "https://accounts.google.com"
audiences:
- "my-audience-1"
- "my-audience-2"
jwksUri: "https://www.googleapis.com/oauth2/v3/certs"
jwtHeaders:
- "x-jwt-assertion"
- "x-jwt-assertion-original"
jwtParams:
- "access_token"
forward: true
如果只针对命名空间中的部分应用,可以使用:
selector:
matchLabels:
app: my-app
在 RequestAuthentication 中,jwtRules 是一个配置项,用于定义如何验证和处理 JWT。
一个典型的 jwtRules 配置可能包括以下几个部分:
issuer
: 发行者,表示JWT的发行方,例如:https://accounts.google.com
。这个字段用于验证JWT的iss(发行者)声明。audiences
: 受众列表,表示接受JWT的一组实体。这个字段用于验证JWT的aud(受众)声明。例如:["my-audience-1", "my-audience-2"]
。jwksUri
: JSON Web Key Set(JWKS)的URL,用于获取JWT签名公钥。Istio会从这个URL下载公钥,用于验证JWT的签名。例如:https://www.googleapis.com/oauth2/v3/certs
。jwtHeaders
: 一个字符串数组,表示可以从HTTP请求头中获取JWT的头名称。默认情况下,Istio会从"Authorization"头中获取令牌。例如:["x-jwt-assertion", "x-jwt-assertion-original"]
。jwtParams
: 一个字符串数组,表示可以从HTTP请求参数中获取JWT的参数名称。例如:["access_token"]
。forward
: 一个布尔值,表示是否将JWT转发给上游服务。默认值为false
,表示JWT令牌不会转发给上游服务。如果设置为true
,则Istio会将令牌添加到请求头中,并转发给上游服务。
通过正确配置 jwtRules,Istio 可以对请求中的 JWT 进行验证,确保客户端访问服务网格中的服务时具有适当的授权。
AuthorizationPolicy 的定义
Istio 的 AuthorizationPolicy 是一种安全策略,用于控制在Istio服务网格中谁可以访问哪些服务。它提供了基于角色的访问控制(RBAC),允许定义细粒度的权限,以限制对特定服务、方法和路径的访问。AuthorizationPolicy 使用 Istio 的 Envoy 代理拦截并检查传入的请求,以确保它们满足定义的访问策略。
AuthorizationPolicy 的示例如下:
apiVersion: security.istio.io/v1
kind: AuthorizationPolicy
metadata:
name: httpbin-policy
namespace: bookinfo
spec:
selector:
matchLabels:
app: httpbin
action: ALLOW
rules:
- to:
- operation:
paths: ["/delay/*"]
AuthorizationPolicy 的主要属性包括:
action
: 定义在规则匹配时要执行的操作。它可以是ALLOW
(允许访问),DENY
(拒绝访问)或CUSTOM
(自定义操作,与自定义扩展插件一起使用)。rules
: 定义一组访问策略规则。每个规则可以包括以下属性:from
: 包含一个或多个源规范,用于定义允许访问的来源。可以包括principals
(发起请求的主体,例如用户或服务帐户)和namespaces
(发起请求的命名空间)。to
: 包含一个或多个目标规范,用于定义允许访问的操作。可以包括methods
(允许的HTTP方法,例如GET或POST)和paths
(允许访问的路径,可以是精确路径或通配符路径)。when
: 包含一组条件,用于定义规则生效的附加约束。例如,您可以使用key
和values
定义请求头匹配。
实验
RequestAuthentication 的作用对象是 Kubernetes Service,主要有两种形式,一种是绑定 ingressgateway。
apiVersion: security.istio.io/v1beta1
kind: RequestAuthentication
metadata:
name: ingress-jwt
namespace: bookinnfo
spec:
selector:
matchLabels:
istio: ingressgateway
jwtRules:
- issuer: "testing@secure.istio.io"
jwksUri: "https://raw.githubusercontent.com/istio/istio/release-1.17/security/tools/jwt/samples/jwks.json"
一种是绑定 Pod。
apiVersion: security.istio.io/v1beta1
kind: RequestAuthentication
metadata:
name: frontend
namespace: default
spec:
selector:
matchLabels:
app: frontend
jwtRules:
- issuer: "testing@secure.istio.io"
jwksUri: "https://raw.githubusercontent.com/istio/istio/release-1.5/security/tools/jwt/samples/jwks.json"
考虑到一般不会在 istio-ingressgateway 这个入口网关上操作,所以下面我们使用第二种形式做实验。
提供 jwksjson
首先是这个 YAML 文件中的 jwksUri
,里面包含了一个 jwksjson 地址,里面包含了用于验证 token 是否有效的公钥。
在 C# 中,可以这样生成一个 jwksjson。
using System;
using System.IO;
using System.Security.Cryptography;
using Microsoft.IdentityModel.Tokens;
using Newtonsoft.Json;
namespace JWKSGenerator
{
class Program
{
static void Main(string[] args)
{
using var rsa = RSA.Create(2048);
var jwk = new RsaSecurityKey(rsa);
jwk.KeyId = Guid.NewGuid().ToString();
var jsonWebKey = JsonWebKeyConverter.ConvertFromRSASecurityKey(jwk);
var jwkJson = JsonConvert.SerializeObject(jsonWebKey);
var jwksJson = "{\"keys\": [" + jwkJson + "]}";
Console.WriteLine(jwksJson);
}
}
}
创建 RequestAuthentication
考虑到官网示例中给出的 jwks.json 需要FQ才能访问,我们可以直接将 jwks.json 放在 YAML 文件中。
apiVersion: security.istio.io/v1beta1
kind: RequestAuthentication
metadata:
name: httpbin-jwt
namespace: bookinfo
spec:
selector:
matchLabels:
app: httpbin
jwtRules:
- issuer: "testing@secure.istio.io"
forwardOriginalToken: true
jwks: |
{
"keys": [
{
"e": "AQAB",
"kid": "DHFbpoIUqrY8t2zpA2qXfCmr5VO5ZEr4RzHU_-envvQ",
"kty": "RSA",
"n": "xAE7eB6qugXyCAG3yhh7pkDkT65pHymX-P7KfIupjf59vsdo91bSP9C8H07pSAGQO1MV_xFj9VswgsCg4R6otmg5PV2He95lZdHtOcU5DXIg_pbhLdKXbi66GlVeK6ABZOUW3WYtnNHD-91gVuoeJT_DwtGGcp4ignkgXfkiEm4sw-4sfb4qdt5oLbyVpmW6x9cfa7vs2WTfURiCrBoUqgBo_-4WTiULmmHSGZHOjzwa8WtrtOQGsAFjIbno85jp6MnGGGZPYZbDAa_b3y5u-YpW7ypZrvD8BgtKVjgtQgZhLAGezMt0ua3DRrWnKqTZ0BJ_EyxOGuHJrLsn00fnMQ"
}
]
}
或者继续使用官方的 jwksUri。
apiVersion: security.istio.io/v1beta1
kind: RequestAuthentication
metadata:
name: httpbin-jwt
namespace: bookinfo
spec:
selector:
matchLabels:
app: httpbin
jwtRules:
- issuer: "testing@secure.istio.io"
forwardOriginalToken: true
jwksUri: "https://raw.githubusercontent.com/istio/istio/release-1.5/security/tools/jwt/samples/jwks.json"
然后部署一个 AuthorizationPolicy,对 /delay/*
地址进行全放通,那么其它地址都需要进行验证才能放行。
apiVersion: security.istio.io/v1
kind: AuthorizationPolicy
metadata:
name: httpbin-policy
namespace: bookinfo
spec:
selector:
matchLabels:
app: httpbin
action: ALLOW
rules:
- to:
- operation:
paths: ["/delay/*"]
执行命令之后,你可以使用以下命令查看是否正常:
kubectl logs -n istio-system -l app=istiod
然后查看策略规则对象:
kubectl get requestauthentication -n bookinfo
kubectl get authorizationpolicy -n bookinfo
最后通过 istio-ingressgateway 的节点端口来访问 /status
和 /delay
,会发现 /status
在没有 token 的情况下返回 403,而 /delay
可以正常访问。
如果我们需要验证,当 token 中的 issuer 为 example-issuer 才能访问时,可以使用:
apiVersion: security.istio.io/v1
kind: AuthorizationPolicy
metadata:
name: httpbin-policy
namespace: bookinfo
spec:
selector:
matchLabels:
app: httpbin
action: ALLOW
rules:
- to:
- operation:
paths: ["/delay/*"]
when:
- key: request.auth.claims[iss]
values: ["example-issuer"]
AuthorizationPolicy 的规则有很多,可以通过这些规则限制不同服务的访问策略。
请参考官方文档:https://istio.io/latest/zh/docs/concepts/security/#authorization-policies
所以 istio 这里一般做验证 jwt 是否有效,或者做路由地址的策略访问,但是如果有数十个上百个路由,使用 istio 配置就会好麻烦。但是依然不是我们想要的,因为在 istio 中配置不同应用访问权限和检验 token 比较繁琐,而且业务系统大多数情况下需要给用户单独配置各种 API 的访问权限。
Isito 入门(九):安全认证的更多相关文章
- 网络编程懒人入门(九):通俗讲解,有了IP地址,为何还要用MAC地址?
1.前言 标题虽然是为了解释有了 IP 地址,为什么还要用 MAC 地址,但是本文的重点在于理解为什么要有 IP 这样的东西.本文对读者的定位是知道 MAC 地址是什么,IP 地址是什么. (本文同步 ...
- C#基础入门 九
C#基础入门 九 集合 对于很多应用程序,需要创建和管理相关对象组,有两种方式可以将对象分组,一是创建对象数组,如 object[] obj=new object[3]{1,2.33,"st ...
- cesium编程入门(九)实体 Entity
cesium编程入门(九)实体 Entity 在cesium编程入门(五)绘制形状提到过添加实体的方法,这一节聊一聊实体相关的一些内容: 先来看 Entity 的各个属性 id 唯一标志,如果没设置, ...
- LOJ数列分块入门九题(上)
一转眼,已经有整整一年没有在博客园写博客了.去洛谷写了几篇(How time flys. 最近突然想起其实我不太擅长分块算法,又想起去年暑假有位同学同我提起过LOJ的数列分块九题,说来惭愧,打了这么久 ...
- Django学习之九: auth 认证组件
目录 Django auth 认证组件 配置使用auth组件及其中间件 request.user 可以直接在template模版中使用 auth组件常用api 获取认证model类 认证检测装饰器@l ...
- requests库入门04-http基本认证
因为后续样例中GitHub都需要提供认证,所以先写关于基本认证的 http的请求中,有一些请求是需要通过授权认证之后才会响应,授权认证就是检查用户名和密码的过程.http有一个基本认证方式,在认证的过 ...
- 数列分块入门九题(三):LOJ6283~6285
Preface 最后一题我一直觉得用莫队是最好的. 数列分块入门 7--区间乘法,区间加法,单点询问 还是很简单的吧,比起数列分块入门 7就多了个区间乘. 类似于线段树,由于乘法的优先级高于加法,因此 ...
- 数列分块入门九题(二):LOJ6280~6282
Preface 个人感觉这中间的三题是最水的没有之一 数列分块入门 4--区间加法,区间求和 这个也是很多数据结构完爆的题目线段树入门题,但是练分块我们就要写吗 修改还是与之前类似,只不过我们要维护每 ...
- 数列分块入门九题(一):LOJ6277~6279
Preface 分块,一个神奇的暴力算法.可以把很多\(O(n^2)\)的数据结构题的暴力优化到常数极小的\(O(n\sqrt n)\).当一些毒瘤题无法用线段树,主席树,平衡树,树状数组...... ...
- 微服务Kong(九)——认证参考
客户端访问上游API服务,通常由Kong的认证插件及其配置参数来控制. 通用认证 一般情况下,上游API服务都需要客户端有身份认证,且不允许错误的认证或无认证的请求通过.认证插件可以实现这一需求.这些 ...
随机推荐
- springboot下使用rabbitMQ之开发配置方式(一)
springboot下使用rabbitMQ之开发配置方式(一) 距离上次发布博客已经小一年了,这次...嗯,没错,我又回来啦... 本次结合着B站某MQ视频以及最近在MQ上的实践聊一聊个人在使用rab ...
- oracle用户密码刷新
1.查询用户信息 col username for a25 col account_status for a18 col profile for a20 select username,account ...
- windows配置supervisor实现nginx自启
前言 有些老项目的nginx部署在windows server上,而且服务器比较老旧,经常异常重启.鉴于个人并不熟悉windows server,因此配置supervisor自启nginx,实现win ...
- Android13冻结进程分析:如何提高设备性能和用户体验
Android13冻结进程分析:如何提高设备性能和用户体验 本文介绍了Android13中的冻结进程功能,它是一种重要的资源管理策略,可以提高系统性能和稳定性,同时最大限度地节省设备的资源和电池消耗. ...
- 从零玩转系列之微信支付实战PC端项目构建+页面基础搭建 | 技术创作特训营第一期
一.前言 欢迎来到本期的博客!在这篇文章中,我们将带您深入了解前端开发领域中的一个热门话题: 如何使用 Vue 3 和 Vite 构建前端项目.随着现代 Web 应用程序的需求不断演进, 选择适当的工 ...
- Go开始:Go基本元素介绍
本文深入探讨了Go编程语言中的核心概念,包括标识符.关键字.具名函数.具名值.定义类型.类型别名.包和模块管理,以及代码块和断行.这些元素是构成Go程序的基础,也是编写高质量代码的关键. 关注Tech ...
- 地表最帅缓存Caffeine
简介 缓存是程序员们绕不开的话题,像是常用的本地缓存Guava,分布式缓存Redis等,是提供高性能服务的基础.今天敬姐带大家一起认识一个更高效的本地缓存--Caffeine. Caffeine Ca ...
- 斜率优化DP 学习笔记
斜率优化 DP 适用情况 适用于求解最优解(最大.最小)问题. 上凸壳与下凸壳 求解步骤 对于任意状态转义方程,设 \(A_i\),\(B_i\),使状态转移方程转化为 \(f_i = \min(f_ ...
- Solution -「CF 1073G」Yet Another LCP Problem
Description Link. 给定字符串,正整数集合 \(A,B\),满足 \(\forall u\in A,v\in B,1\le u,v\le n\). 求 \(\sum_{i\in A}\ ...
- 本计划在 .NET 8 中推出的 WASI 推迟到 .NET 9
本计划在 .NET 8 中推出的 WASI 已推迟到 .NET 9,请参阅 Github 上的 WASI 跟踪问题. 在.NET 8 Preview 4 开始支持生成与 WASI 兼容的 .wasm ...