Istio 安全管理

主要涉及

制作环境

chap5初始化环境

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# 初始化环境
kubectl get svc
#svc1
#vm2-svc
kubectl delete svc svc1
kubectl expose --name=svc1 pod pod1 --port=80
kubectl expose --name=svc2 pod pod2 --port=80

mkdir chap5 && cd chap5
cp ../chap4/mygw1.yaml ../chap4/vs.yaml ../chap4/vs2.yaml ./

cat mygw1.yaml
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: mygw
spec:
selector:
istio: ingressgateway # use istio default controller
servers:
- port:
number: 80
name: http-1
protocol: HTTP
hosts:
- "*.yuan.cc"

cat vs.yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: myvs
spec:
hosts:
- "aa.yuan.cc"
gateways:
- mygw
http:
- route:
- destination:
host: svc1
# 创建 vs
kubectl apply -f vs.yaml

mv vs2.yaml vs3.yaml
cat vs3.yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: myvs3
spec:
hosts:
- "vm.yuan.cc"
gateways:
- mygw
http:
- route:
- destination:
host: vm2-svc
# 创建 vs3
kubectl apply -f vs3.yaml

cp vs.yaml vs2.yaml
cat vs2.yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: myvs2
spec:
hosts:
- "bb.yuan.cc"
gateways:
- mygw
http:
- route:
- destination:
host: svc2
# 创建 vs2
kubectl apply -f vs2.yaml

客户端服务器修改hosts

1
2
3
4
5
6
7
8
9
vim /etc/hosts
192.168.26.230 aa.yuan.cc aa
192.168.26.230 bb.yuan.cc bb
192.168.26.230 vm.yuan.cc vm

# 测试连通
curl aa.yuan.cc #111
curl bb.yuan.cc #222
curl vm.yuan.cc #hello vm vm

为了安全性,我们更建议使用 https 访问

https —- http + TLS (传输层加密) 在 SSL 被放弃使用后转向 TLS

  • 有效的提升安全性
  • 有效提升网站权重(百度/谷歌)
  • 有效解决流量劫持

启用 TLS 网关

对于istio 来说,所有需要的密钥都需要放入特定的目录中

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
# 生成密钥对(自签发)
mkdir -p /etc/istio/ingressgateway-certs/
# 有效期为 365天,rsa算法,私钥为.key ,公钥为.crt(公钥就是证书)
openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/istio/ingressgateway-certs/mykey.key -out /etc/istio/ingressgateway-certs/mycrt.crt -subj "/CN=mytest/O=my-test"
# 注意:一定要放在/etc/istio/ingressgateway-certs/里

# 创建tls类型的secret
kubectl create secret tls istio-ingressgateway-certs --key /etc/istio/ingressgateway-certs/mykey.key --cert /etc/istio/ingressgateway- certs/mycrt.crt -n istio-system
# 注意:密钥名必须是 istio-ingressgateway-certs

# 创建 secret 的目录,是让isgressgateway知道有这个证书和私钥

cp mygw1.yaml mygw1-tls.yaml
vim mygw1-tls.yaml

apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: mygw
spec:
selector:
istio: ingressgateway # use istio default controller
servers:
#- port:
# number: 80
# name: http-1
# protocol: HTTP
# hosts:
# - "*.yuan.cc"
- port:
number: 443
name: https
protocol: HTTPS
hosts:
- "aa.yuan.cc"
tls:
mode: SIMPLE #简单的单项认证(客户端单项的认证服务器端)
serverCertificate: /etc/istio/ingressgateway-certs/mycrt.crt
privateKey: /etc/istio/ingressgateway-certs/mykey.key

# 客户端访问测试
curl -kv https://aa.yuan.cc
#curl: (35) OpenSSL SSL_connect: SSL_ERROR_SYSCALL in connection to aa.yuan.cc:443

#查看istio-ingressgateway日志
kubectl get pods -n istio-system
kubectl logs istio-ingressgateway-8f747d485-g3h35 -n istio-system
#/etc/istio/ingressgateway-certs/mycrt.crt: no such file or directory

kubectl get depoly istio-ingressgateway -o yaml -n istio-system

kubectl get secrets -n istio-system

#进入容器查看
kubectl exec -it istio-ingressgateway-8f747d485-g3h35 -n istio-system -- bash
ls /etc/istio/ingressgateway-certs
# tls.crt tls.key

# 修改 mygw1-tls.yaml
vim mygw1-tls.yaml
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: mygw
spec:
selector:
istio: ingressgateway # use istio default controller
servers:
#- port:
# number: 80
# name: http-1
# protocol: HTTP
# hosts:
# - "*.yuan.cc"
- port:
number: 443
name: https
protocol: HTTPS
hosts:
- "aa.yuan.cc"
tls:
mode: SIMPLE
#serverCertificate: /etc/istio/ingressgateway-certs/mycrt.crt
#privateKey: /etc/istio/ingressgateway-certs/mykey.key
serverCertificate: /etc/istio/ingressgateway-certs/tls.crt
privateKey: /etc/istio/ingressgateway-certs/tls.key
# 重载 mygw1-tls.yaml
kubectl apply -f mygw1-tls.yaml
#客户端测试
curl -kv https://aa.yuan.cc # 访问通过,但是访问http是访问不通的,如果需要访问需要放行80端口,如果需要跳转需要加上 tls:httpsRedirect:
--------------------------------------------
# http 跳转 https
# 修改 mygw1-tls.yaml
vim mygw1-tls.yaml
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: mygw
spec:
selector:
istio: ingressgateway # use istio default controller
servers:
- port:
number: 80 #放行 80 端口
name: http-1
protocol: HTTP
hosts:
- "aa.yuan.cc" #当然此处的hosts和下面的hosts也可以使用通配符,但是一般不同的三级域名会有自己的证书,不太建议这么做,比如写成 "*.yuan.cc"
tls:
httpsRedirect: true #跳转 https
- port:
number: 443
name: https
protocol: HTTPS
hosts:
- "aa.yuan.cc"
tls:
mode: SIMPLE
#serverCertificate: /etc/istio/ingressgateway-certs/mycrt.crt
#privateKey: /etc/istio/ingressgateway-certs/mykey.key
serverCertificate: /etc/istio/ingressgateway-certs/tls.crt
privateKey: /etc/istio/ingressgateway-certs/tls.key

基于虚拟主机做 TLS

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
kubectl get secrets -n istio-system
kubectl delete secrts istio-ingressgateway-certs -n istio-system

# 生成证书
ls /etc/istio/ingressgateway-certs
openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/istio/ingressgateway- certs/mykey22.key -out /etc/istio/ingressgateway-certs/mycrt22.crt -subj "/CN=mytest22/O=my-test22"

# 生成是generic类型的证书,不是tls证书
kubectl create secret generic istio-ingressgateway-certs \
--from-file=/etc/istio/ingressgateway-certs/mycrt.crt \
--from-file=/etc/istio/ingressgateway-certs/mykey.key \
--from-file /etc/istio/ingressgateway-certs/mycrt22.crt \
--from-file /etc/istio/ingressgateway-certs/mykey22.key -n istio-system

# 做 TLS 类型的证书的话,他只支持给一个站点提供服务
#编辑 mygw1-tls.yaml
vim mygw1-tls.yaml
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: mygw
spec:
selector:
istio: ingressgateway # use istio default controller
servers:
- port:
number: 80
name: http-1
protocol: HTTP
hosts:
- "aa.yuan.cc"
tls:
httpsRedirect: true #跳转 https
- port:
number: 443
name: https-2
protocol: HTTPS
hosts:
- "aa.yuan.cc"
tls:
mode: SIMPLE
serverCertificate: /etc/istio/ingressgateway-certs/mycrt.crt
privateKey: /etc/istio/ingressgateway-certs/mykey.key
- port:
number: 443
name: https
protocol: HTTPS
hosts:
- "bb.yuan.cc"
tls:
mode: SIMPLE
serverCertificate: /etc/istio/ingressgateway-certs/mycrt22.crt
privateKey: /etc/istio/ingressgateway-certs/mykey22.key

# 重载 mygw-tls
kubectl apply -f mygw-tls.yaml

# 客户端测试
curl -kv https://aa.yuan.cc #可以访问
curl -kv https://bb.yuan.cc #可以访问

# 查看 gateway 证书验证
kubectl get pods -n istio-system
kubectl exec -it istio-ingressgateway-8f568d595-8cvl8 -n istio-system -- bash
ls /etc/istio/ingressgateway-certs/
# mycrt.crt mycrt22.crt mykey.key mykey22.key

cert-manager 概念及使用

使用 cert-manager 来管理证书

通过 let encrypt 去帮助我们申请证书 (免费,但只有90天有效期,需要续期)

帮助文档:

https://letsencrypt.org/zh-cn/docs/

https://letsencrypt.org/zh-cn/how-it-works/

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
mkdir cert-m && cd cert-m
#创建 cert-manager
wget https://github.com/cert-manager/cert-manager/releases/download/v0.16.0/cert-manager.yaml
kubectl apply -f cert-manager.yaml #如果拉不到镜像,可以对对应的镜像 save 再 load 回来
kubectl get crd | grep cert

# 查看官网手册
cert-manager.io/docs/configuration/acme/dns01

# 修改DNS
# --- 登入阿里云,对域名的 DNS 服务器改为 dara.ns.cloudflare.com 和 rob.ns.cloudflare.com

# 登入 cloudflare,使用 cloudflare DNS
https://dash.cloudflare.com/
1、添加站点
2、选择 0 美元免费版
# 生成token , 添加API令牌
dash.cloudflare.com/profile/api-tokens
#创建自定义令牌 参考 cert-manager.io/docs/configuration/acme/dns01/cloudflare
创建完令牌后会给出一段令牌,需要及时保存

#创建 Secret, 编辑 mydnssecret
vim mydnssecret.yaml
apiVersion: v1
kind: Secret
metadata:
name: cloudflare-api-token-secret
type: Opaque
stringData:
api-token: <API Token> #将令牌复制到此处

#创建 secret
kubectl get ns
kubectl apply -f mydnssecret.yaml -n cert-manager

#创建 clusterissuer
kubectl get clusterissuer
# No resources found
vim ciss.yaml
apiVersion: cert-manager.io/v1alpha2
kind: ClusterIssuer
metadata:
name: letsencrypt-dns01 #用dns来审核,会比http审核的方式会方便一下
spec:
acme:
privateKeySecretRef:
name: letsencrypt-dns01
server: https://acme-v02.api.letsencrypt.org/directory #通过此站点访问
solvers:
- dns01:
cloudflare:
email: my-cloudflare-acc@example.com
apiTokenSecretRef:
key: api-token #此处value即为secret的stringData所对应的api-token,名字保持一致
name: cloudflare-api-token-secret #和secret的name保持一致

#启动
kubectl apply -f ciss.yaml
kubectl get clusterissuer
#letsencrypt-dns01 True

# 开始申请证书
kubectl get certificate
# www-ck8s-com True www-ck8s-com-tls
kubectl get secrets www-ck8s-com-tls -o yaml #可以看到证书的相关信息
kubectl get secrets www-ck8s-com-tls -o jsonpath='{.data.tls\.crt}' | base64 -d > mycertx.crt
kubectl get secrets www-ck8s-com-tls -o jsonpath='{.data.tls\.key}' | base64 -d > mycertx.key
cp mycertx.crt mycertx.key /etc/istio/ingressgateway-certs/

# 删除原来的 tls 证书
kubectl delete secrets istio-ingressgateway-certs -n istio-system

# 生成证书
kubectl create secret generic istio-ingressgateway-certs --from-file=/etc/istio/ingressgateway-certs/mycertx.crt --from-file=/etc/istio/ingressgateway-certs/mykeyx.key -n istio-system

vim vs.yaml
spec:
hosts:
- "www.ck8s.com"

vim mygw1-tls.yaml
servers:
- port:
number: 80
name: http-1
protocol: HTTP
hosts:
- "www.ck8s.com"
tls:
httpsRedirect: true #跳转 https
- port:
number: 443
name: https-2
protocol: HTTPS
hosts:
- "www.ck8s.com"
tls:
mode: SIMPLE
serverCertificate: /etc/istio/ingressgateway-certs/mycertx.crt
privateKey: /etc/istio/ingressgateway-certs/mykeyx.key

kubectl apply -f vs.yaml
kubectl apply -f mygw1-tls.yaml

# 内网测试机 本机修改 hosts 文件 192.168.26.230 www.ck8s.com www
浏览器访问 www.ck8s.com ,显示https 并且没有显示警告不安全

# 将 vs hosts 恢复为之前的

创建自定义令牌

令牌创建成功

mTLS认证 PeerAuthentication

mTLS (mutual TLS,双向TLS): 让客户端和服务器端通信的时候都必须进行TLS认证

默认情况下,在网格内部 默认启用了mTLS 了。

PERMISSIVE:工作负载接受双向 TLS 和纯文本流量。

当没有 Sidecar 的工作负载无法使用双向 TLS 时,此模式适合用在迁移过程。

通过使用 sidecar 注入迁移工作负载后,应该将模式切换为 STRICT。

STRICT:工作负载仅接受双向 TLS 通信。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
### 测试没有添加 mTLS 
# 编辑 vs yaml
vim vs.yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: myvs
spec:
hosts:
- "aa.yuan.cc"
- "svc1" #添加
gateways:
- mygw
http:
- route:
- destination:
host: svc1

# 重载 vs yaml
kubectl apply -f vs.yaml

kubectl get pods -n default # 没有被注入的pod
#podx 1/1 Running
kubectl exec -it podx -n default -- bash
curl svc1.ns1 #返回111,代表网格之外现在也可以被访问
111
--------------------------------------------------------
### 测试添加 mTLS,如果没有在网格里的 pod 是不能访问的
vim mtls1.yaml
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
name: default
spec:
mtls:
mode: STRICT #仅接受双向 TLS 通信

# 创建 mtls
kubectl get PeerAuthentication
# No resources found in ns1 namespace
kubectl apply -f mtls1.yaml

#网格外 pod 测试
kubectl exec -it podx -n default -- bash
curl svc1.ns1 #访问不通的
# curl: (56) Recv failure: COnnection reset by peer

# istio 对 podx 进行注入,加入网格内在进行测试
kubectl delete pod podx -n default
istioctl kube-inject -f podx.yaml | kubectl apply -f - -n default
kubectl get pods -n default
#podx 2/2 Running
kubectl exec -it podx -n default -- bash
curl svc1.ns1 #访问的通了,返回111
# 111

单pod设置mTLS

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
#把网格内的 podx 去除
kubectl delete pod podx -n default
kubectl apply -f podx.yaml -n default
kubectl exec -it podx -n default -- bash
curl svc1.ns1
#curl: (56) Recv failure: Connection reset by peer

#创建namespace ns2,给 ns2 添加 istio 标签
kubectl create ns ns2
kubectl get ns --show-labels
#ns1 istio-injection=enabled.kubernetes.io/metadata.name=ns1
#ns2 kubernetes.io/metadata.name=ns2
kubectl label ns ns2 istio-injection=enabled

# 创建 ns2 内的 podx,svc2 ,让 default 中的 podx 访问测试
kubectl apply -f podx.yaml -n ns2
kubectl get pods -n ns2
#podx 2/2 Running
kubectl expose --name=svc2 pod podx --port=80 -n ns2

#default podx进行测试
kubectl exec -it podx -n default -- bash
curl svc2.ns2 #返回 nginx 页面,访问连通

#清理下环境
kubectl delete pod podx -n ns2
kubectl delete svc svc2 -n ns2

------------------------------------------------------------
# 修改 mtls,针对单 pod 设置 mTLS
vim mtls1.yaml
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
name: default
spec:
selector:
matchLabels:
run: pod1 #只应用与 pod1 上,与 pod1 通信时必须通过 mTLS
mtls:
mode: STRICT #仅接受双向 TLS 通信

# 修改 mtls,针对单 pod 设置 mTLS,放行某端口,对某端口可以不建立 mTLS
vim mtls1.yaml
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
name: default
spec:
selector:
matchLabels:
run: pod1 #只应用与 pod1 上,与 pod1 通信时必须建立 mTLS
mtls:
mode: STRICT #或者此处可以改为PERMISSIVE
portLevelMtls:
80:
mode: DISABLE # 和端口80通信可以不需要 mTLS

授权管理AuthorizationPolicy

设置的是允许哪些客户端允许过来访问

拒绝优先级 > 允许优先级

基于命名空间做授权

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
#清理环境,先把相关的 tls 先删掉
kubectl delete -f mtls1.yaml
#---有点卡,把vm2相关的先关掉
kubectl delete svc vm2-svc
kubectl delete -f ../chap4/mygw.yaml
kubectl delete -f ../chap4/xx/

#客户端测试, default 中的 podx
kubectl exec -it podx -n default -- bash
curl aa.yuan.cc
111
curl bb.yuan.cc
222


kubectl get AuthorizationPolicy
#No resources found in ns1 namespace
mkdir chap5/ap && cd chap5/ap

#编辑全局拒绝策略
vim rule-default-deny-all.yaml
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: ns1-deny-all
spec:
{}
#这种在spec下直接写一个{} 默认是拒绝的意思,且优先级最低

# 启用AuthorizationPolic,podx测试
kubectl apply -f rule-default-deny-all.yaml
curl svc1.ns1
#RBAC: access denied

#设置某个客户端可以访问
vim rule-allow-ns.yaml
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: allow-ns
namespace: ns1
spec:
selector:
matchLabels:
run: pod1
action: ALLOW #允许规则,如果没有匹配下面的规则,是不允许其他客户端来访问的
rules:
- from:
- source:
namespaces:
- "ns2" #只允许ns2命名空间的可以来访问
#- "default"

#启动允许策略,再创建个 ns2 的 podx 进行测试
kubectl apply -f rule-allow-ns.yaml
kubectl apply -f podx.yaml -n ns2
kubectl exec -it podx -n ns2 -- bash
curl svc1 #可以访问
#111

## 注意:
#命名空间测试的话,客户端pod要注入 istio 才能生效,from和to 可以一起用。当前命名 要通过 svc1.ns1 这种访问才能生效。

基于 IP 的限制

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# 编辑放行规则
vim rule-allow-ns.yaml

apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: allow-ns
namespace: ns1
spec:
selector:
matchLabels:
run: pod1
action: ALLOW #允许规则,如果没有匹配下面的规则,是不允许其他客户端来访问的
rules:
- from:
#- source:
#notnamespace #除了此命名空间,都可以访问
#namespaces:
#- "ns2" #只允许ns2命名空间的可以来访问
- source:
ipBlocks:
#- "0.0.0.0/0" #允许所有客户端访问
#- "10.244.0.0/16"
- "192.168.26.9/24" #允许此网段的服务器访问
#- source:
#remoteIpBlocks: #这里remoteIpBlocks设置的是拒绝的意思,凡是匹配了这个地址,都是拒绝的
#- "192.168.26.23"
#- source:
#principals: ["cluster.local/ns/ns1/sa/default"] #指定ns2里,以default跑的pod,且同样的sa才可以访问

# 重载 放行规则
kubectl apply -f rule-allow-ns.yaml

when 的使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
- to:
- operation:
methods: ["GET"]
hosts:
- svc1.ns1
paths:
- /demo1/*
- when:
- key: request.headers[test]
values:
- "test"
# when和from这些是或的关系
# pod 测试
curl svc1.ns1
#RBAC: access denied
curl svc1.ns1 --header "test:test"
#111

JWT 认证

JWT全称: Json Web Token

本质就是类似用户名和密码,客户端访问的时候,必须要提供这些token信息,不然访问不了。

这个token有固定的格式,采用JWK/JWKs格式的。

JWK: Json Web Key

JWKs :JWK set

生成TOKEN

https://jwt.io/

生成 token

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
yum install boost-python36.x86_64 python3-pip.noarch -y
pip3 install ipython pip

#国内源
mkdir -p .pip
vim .pip/pip.conf
[global]
index-url = http://pypi.douban.com/simple
[install]
trusted-host=pypi.douban.com

pip3 install --upgrade pip
pip3 install jwt
pip3 install ipython jwcrypto

mkdir token && cd token
openssl genrsa -out key.pem 2048
openssl rsa -in key.pem -pubout -out pub.pem

写一个脚本– 用于实现生成 jwt token

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
vim aa.py

#!/usr/bin/python3
#-*- coding: UTF-8 -*-
from jwcrypto.jwk import JWK
from pathlib import Path

private_key = Path("key.pem").read_bytes()
jwk = JWK.from_pem(private_key)

# 导出公钥 RSA Public Key
public_key = jwk.public().export_to_pem()
print(public_key)

print("="*30)

# 导出 JWK
jwk_bytes = jwk.public().export()
print(jwk_bytes)

python3 aa.py

显示生成kid

登入 https://jwt.io/,加密类型选择 RS256,添加自己的信息,得到 Encode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# 创建 RequestAuthentication
vim ra.yaml

apiVersion: "security.istio.io/v1beta1"
kind: "RequestAuthentication"
metadata:
name: "myra"
spec:
selector:
matchLabels:
run: pod1 #应用于pod1
jwtRules:
- issuer: "testing@secure.istio.io" #与jwt生成信息对应
jwks: |
{ "keys":
[
{
"e":"AQAB",
"kid":"DHFbpoIUqrY8t2zpA2qXfCmr5VO5ZEr4RzHU_-envvQ",
"kty":"RSA",
"n":"xAE7eB6qugXyCAG3yhh7pkDkT65pHymX- P7KfIupjf59vsdo91bSP9C8H07pSAGQO1MV_xFj9VswgsCg4R6otmg5PV2He95lZdHtOcU5DXIg_pbhLdKXbi66GlVeK6ABZOUW3 WYtnNHD-91gVuoeJT_DwtGGcp4ignkgXfkiEm4sw-4sfb4qdt5oLbyVpmW6x9cfa7vs2WTfURiCrBoUqgBo_- 4WTiULmmHSGZHOjzwa8WtrtOQGsAFjIbno85jp6MnGGGZPYZbDAa_b3y5u- YpW7ypZrvD8BgtKVjgtQgZhLAGezMt0ua3DRrWnKqTZ0BJ_EyxOGuHJrLsn00fnMQ"
}
]
}

# 启用 ra
kubectl apply -f ra.yaml

# 参数分析
{
"alg": "RS256", # 算法「可选参数」
"kty": "RSA", # 密钥类型
"use": "sig", # 被用于签名「可选参数」
"kid": "xxx", # key 的唯一 id
"n": "xxx", #n 是公钥的指数
"e": "AQAB" #是公钥的模数(modulus)
}

# 测试
kubectl apply -f default-deny-all.yaml #默认拒绝所有
vim allow-only2.yaml #只允许特定的可以访问
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: require-jwt
spec:
selector:
matchLabels:
run: pod1
action: ALLOW
rules:
- from:
- source:
requestPrincipals: ["testing@secure.istio.io/testing@secure.istio.io"] #含有被此签名的才可以被访问

kubectl apply -f allow-only2.yaml
#进入pod2 进行测试
curl -I -H "Authorization: Bearer $TOKEN" svc1.ns1 #使用正确的token才可以访问
#111
curl -I -H "Authorization: Bearer invalidToken" svc1.ns1 #随便写了个假的,返回401
# Jwt is not in the form of Header.Payload.Signature with two dots and 3 sectionsroot@pod2