1. 简介
mTLS (mutual TLS,双向TLS): 让客户端和服务器端通信的时候都必须进行TLS认证
默认情况下,在网格内部默认启用了mTLS了。
2. 启用tls网关
2.1 创建私钥
1
| 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"
|
2.2 创建secret
1
| kubectl create secret generic istio-ingressgateway-certs --from-file /etc/istio/ingressgateway-certs/mykey.key --from-file /etc/istio/ingressgateway-certs/mycrt.crt -n istio-system
|
2.3 创建gateway
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
| apiVersion: networking.istio.io/v1alpha3 kind: Gateway metadata: name: mygw spec: selector: istio: ingressgateway servers: - port: number: 80 name: http protocol: HTTP hosts: - "aa.rhce.cc" - "bb.rhce.cc" - "demoapp.rhce.cc" tls: httpsRedirect: true - port: number: 443 name: https protocol: HTTPS hosts: - "aa.rhce.cc" tls: mode: SIMPLE serverCertificate: /etc/istio/ingressgateway-certs/mycrt.crt privateKey: /etc/istio/ingressgateway-certs/mykey.key
|
3. PeerAuthentication
用于设置别人在和网格里的pod进行通信的时候,是否要求mTLS
3.1 默认策略
1 2 3 4 5 6 7 8
| apiVersion: security.istio.io/v1beta1 kind: PeerAuthentication metadata: name: default spec: mtls: mode: STRICT
|
PERMISSIVE:工作负载接受双向TLS和纯文本流量,当没有Sidecar的工作负载无法使用双向TLS时,此模式适合用在迁移过程。
通过使用sidecar注入迁移工作负载后,应该将模式切换为STRICT。
STRICT:工作负载仅接受双向TLS通信。
3.2 选择性策略
1 2 3 4 5 6 7 8 9 10 11 12 13
| apiVersion: security.istio.io/v1beta1 kind: PeerAuthentication metadata: name: default spec: selector: matchLabels: run: pod1 mtls: mode: STRICT portLevelMtls: 80: mode: DISABLE
|
4. 授权管理AuthorizationPolicy
设置的是允许哪些客户端允许过来访问,功能类似k8s networkpolicy
拒绝优先级 > 允许优先
4.1 默认拒绝
1 2 3 4 5 6
| apiVersion: security.istio.io/v1beta1 kind: AuthorizationPolicy metadata: name: default-deny-all spec: {}
|
这里就拒绝掉了所有的,虽然这里没有指定是允许还是拒绝,但是是拒绝的意思。
默认是拒绝的意思,且优先级最低
4.2 允许访问pod1
1 2 3 4 5 6 7 8 9 10 11 12
| apiVersion: security.istio.io/v1beta1 kind: AuthorizationPolicy metadata: name: allow-pod1 namespace: ns1 spec: selector: matchLabels: run: pod1 action: ALLOW rules: - {}
|
一旦设置了允许,那么没有允许的也会被拒绝。这种写了action: DENY,然后在rules里写了{},则是拒绝所有的,这种优先级最高,其他的allow都不会在生效
4.3 基于名称空间过滤
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| apiVersion: security.istio.io/v1beta1 kind: AuthorizationPolicy metadata: name: allow-pod1 namespace: ns1 spec: selector: matchLabels: run: pod2 action: ALLOW rules: - from: - source: namespaces: - ns2
|
4.4 基于sa过滤
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| apiVersion: security.istio.io/v1beta1 kind: AuthorizationPolicy metadata: name: allow-pod1 namespace: ns1 spec: selector: matchLabels: run: pod2 action: ALLOW rules: - from: - source: principals: ["cluster.local/ns/ns1/sa/default"]
|
4.5 基于IP地址过滤
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| apiVersion: security.istio.io/v1beta1 kind: AuthorizationPolicy metadata: name: allow-pod1 namespace: ns1 spec: selector: matchLabels: run: pod2 action: ALLOW rules: - from: - source: ipBlocks: - "0.0.0.0/0"
|
ipBlocks: 允许的IP通信
notIpBlocks: 拒绝的ip
4.6 基于头部信息过滤
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| apiVersion: security.istio.io/v1beta1 kind: AuthorizationPolicy metadata: name: allow-pod1 namespace: ns1 spec: selector: matchLabels: run: pod2 action: ALLOW rules: - from: - source: remoteIpBlocks: - "192.168.26.23"
|
remoteIpBlocks: 允许的IP通信
notRemoteIpBlocks: 拒绝的ip
只有指定了X-Forwarded-For头部信息才可以访问
4.7 限制请求方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| apiVersion: security.istio.io/v1beta1 kind: AuthorizationPolicy metadata: name: allow-pod1 namespace: ns1 spec: selector: matchLabels: run: pod2 action: ALLOW rules: - to: - operation: methods: ["GET"] hosts: - "svc2" paths: - /demo1/*
|
4.8 when语句
when和from这些是或的关系
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| apiVersion: security.istio.io/v1beta1 kind: AuthorizationPolicy metadata: name: allow-pod1 namespace: ns1 spec: selector: matchLabels: run: pod2 action: ALLOW rules: - when: - key: request.headers[test] values: - "test"
|
4.9 JWT过滤
JWT全称: Json Web Token
本质就是类似用户名和密码,客户端访问的时候,必须要提供这些token信息,不然访问不了。
这个token有固定的格式,采用JWK/JWKs格式的。
JWK: Json Web Key
JWKs :JWK set
4.9.1 生成token
生成公钥和私钥
1 2
| openssl genrsa -out key.pem 2048 openssl rsa -in key.pem -pubout -out pub.pem
|
生成JWKs信息
1 2 3 4
| yum install boost-python36.x86_64 python3-pip.noarch pip3 install --upgrade pip pip3 install jwt pip3 install ipython jwcr
|
脚本
1 2 3 4 5 6 7 8 9 10 11 12 13 14
|
from jwcrypto.jwk import JWK from pathlib import Path private_key = Path("key.pem ").read_bytes() jwk = JWK.from_pem(private_key)
public_key = jwk.public().export_to_pem() print(public_key) print("="*30)
jwk_bytes = jwk.public().export() print(jwk_bytes)
|
或在线生成 https://8gwifi.org/jwkconvertfunctions.jsp
4.9.2 创建ra
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| apiVersion: "security.istio.io/v1beta1" kind: "RequestAuthentication" metadata: name: "productpage" spec: selector: matchLabels: run: pod1 jwtRules: - issuer: "testing@secure.istio.io" jwks: | { "keys": [ { "e":"AQAB", "kid":"85d3c3fe-5c86-4482-a165-9b66dc3773c3", "kty":"RSA", "n":"ucu4hlGJFdEw4rLW1hmVCa_sHcAyKrHnBxtFYGUVVLvUBAGZ1pgU2YOmtTDoN5rrew_4-511U1q4IYmWKiwNjt-4-JLR7auTH8L_GIcpUh8LO77i8btsbExV7hduHc1ewiOI8fgTUQ4sADiLb-_hnZTYaAJTpNOVZKcyIakNo7rNTXFzaArKVp88GMZMIq6f9R2f-Sd-Hh70aMzwUFAA3bpWxRQYdYrQschKnBceVLNKXtXjQA0MZnb-dq6sjiVmkp0a20GBs8-ib-mIZROkM8Mno9mu4DXZVu0GLJRUwU_puwMZ6hQqB8ucsS0l2xMJtc_2uL05f-Vd5V9JLAdzJw" } ] }
|
4.9.3 创建AuthorizationPolicy
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| apiVersion: security.istio.io/v1beta1 kind: AuthorizationPolicy metadata: name: allow-pod1 namespace: ns1 spec: selector: matchLabels: run: pod2 action: ALLOW rules: - from: - source: requestPrincipals: ["testing@secure.istio.io/testing@secure.istio.io"]
|