istio网格安全相关示例

144 阅读9分钟

例1:仅验证服务端证书

配置要点在于服务端,也就是要配置接收请求的服务,针对服务做pa、dr配置

注:花了1天时间,翻遍了官方文档中关于单向tls内容,文参考档中是这么配置,但实际环境中并不会生效,不知道是不是bug

1)运行demoapp
 kubectl apply -f - <<EOF 
 apiVersion: v1
 kind: Service
 metadata:
   labels:
     app: demoapp
   name: demoapp
 spec:
   ports:
   - name: http-80-80
     port: 80
     protocol: TCP
     targetPort: 80
   selector:
     app: demoapp
   type: ClusterIP
 ---
 apiVersion: apps/v1
 kind: Deployment
 metadata:
   labels:
     app: demoapp
     version: v1.0
   name: demoapp-10
 spec:
   replicas: 2
   selector:
     matchLabels:
       app: demoapp
       version: v1.0
   template:
     metadata:
       labels:
         app: demoapp
         version: v1.0
     spec:
       containers:
       - image: ikubernetes/demoapp:v1.0
         name: demoapp
         ports:
         - containerPort: 80
           name: web
           protocol: TCP
 ---
 apiVersion: apps/v1
 kind: Deployment
 metadata:
   labels:
     app: demoapp
     version: v1.1
   name: demoapp-11
 spec:
   replicas: 2
   selector:
     matchLabels:
       app: demoapp
       version: v1.1
   template:
     metadata:
       labels:
         app: demoapp
         version: v1.1
     spec:
       containers:
       - image: ikubernetes/demoapp:v1.1
         name: demoapp
         ports:
         - containerPort: 80
           name: web
           protocol: TCP
 ---
 apiVersion: networking.istio.io/v1beta1
 kind: DestinationRule
 metadata:
   name: demoapp-dr
 spec:
   host: demoapp
   subsets:
   - name: v10
     labels:
       version: v1.0
   - name: v11
     labels:
       version: v1.1
 ---
 apiVersion: networking.istio.io/v1beta1
 kind: VirtualService
 metadata:
   name: demoapp-vs
 spec:
   hosts:
   - demoapp
   http:
   - name: canary
     match:
     - uri:
         prefix: /canary
     rewrite:
       uri: /
     route:
     - destination:
         host: demoapp
         subset: v11
   - name: default
     route:
     - destination:
         host: demoapp
         subset: v10
 EOF
2)配置策略
 kubectl apply -f - <<EOF
 apiVersion: security.istio.io/v1beta1
 kind: PeerAuthentication
 metadata:
   name: demoapp
   namespace: default
 spec:
   selector:
     matchLabels:
       app: demoapp
   mtls:
     mode: PERMISSIVE
 ---
 apiVersion: networking.istio.io/v1beta1
 kind: DestinationRule
 metadata:
   name: demoapp-dr
 spec:
   host: demoapp
   trafficPolicy:
     tls:
       mode: SIMPLE
       insecureSkipVerify: true
   subsets:
   - name: v10
     labels:
       version: v1.0
   - name: v11
     labels:
       version: v1.1
 EOF

例2:实现全链路tls(tls+mtls)

入口网关实现tls,网格内使用mtls双向认证

1)部署bookinfo

清理之前的bookinfo:sh samples/bookinfo/platform/kube/cleanup.sh

 kubectl create ns bookinfo
 kubectl label ns bookinfo istio-injection=enabled
 kubectl apply -n bookinfo -f samples/bookinfo/platform/kube/bookinfo.yaml
 kubectl apply -n bookinfo -f samples/bookinfo/networking/bookinfo-gateway.yaml
 
 kubectl apply -n bookinfo -f - <<EOF
 apiVersion: networking.istio.io/v1alpha3
 kind: Gateway
 metadata:
   name: bookinfo-gateway
 spec:
   servers:
   - port:
       number: 80
       name: http
       protocol: HTTP
     hosts:
     - bookinfo.hj.com
 ---
 apiVersion: networking.istio.io/v1alpha3
 kind: VirtualService
 metadata:
   name: bookinfo
 spec:
   hosts:
   - bookinfo.hj.com
   gateways:
   - bookinfo-gateway
   http:
   - match:
     - uri:
         exact: /productpage
     - uri:
         prefix: /static
     - uri:
         exact: /login
     - uri:
         exact: /logout
     - uri:
         prefix: /api/v1/products
     route:
     - destination:
         host: productpage
         port:
           number: 9080
 EOF
 
 #强制bookinfo命名空间使用mtls
 kubectl apply -f - <<EOF
 apiVersion: security.istio.io/v1beta1
 kind: PeerAuthentication
 metadata:
   name: bookinfo
   namespace: bookinfo
 spec:
   mtls:
     mode: STRICT
 EOF
2)运行客户端pod
 kubectl run admin --image alpine -- tail -f /dev/null
 kubectl exec -it admin -- sed -i 's/dl-cdn.alpinelinux.org/mirrors.ustc.edu.cn/g' /etc/apk/repositories
3)测试
2)productpage上抓包

用于验证ingress-gw与productpage之间通信是否使用tls

 kubectl get po -n bookinfo -o wide |awk '/productpage/{print $6,$7}'
 ​
 #在对应物理机上抓包
 ifc=`route -n |awk '/10.20.135.41/{print $NF}'`
 tcpdump -X -nn port 9080 -i $ifc
3)admin上抓包

用于验证admin与ingress-gw之间通信是否使用tls

 kubectl get po -o wide |awk '/admin/{print $6,$7}'
 ifc=`route -n |awk '/10.20.135.19/{print $NF}'`
 tcpdump -X -nn port 80 -i $ifc
3)发起测试请求
 kubectl get po -n istio-system -o wide |awk '/ingress/{print $6}'
 ​
 ​
 #进入测试用的客户端pod发起请求
 kubectl exec -it admin -- sh
 curl -LIH 'host: bookinfo.hj.com' 2.2.2.17/productpage
4)结果如图

ingress-gw的集群ip是:10.20.135.24,productpage的ip是:10.20.135.41 ingress-gw与productpage之间对http做了加密,由于前面做了测试,所以没有3次握手而是直接显示了发数据 image-20231226162732136

admin-pod的ip是:10.20.135.19,ingress-gw的集群ip是:10.20.135.24 admin与ingress-gw之间使用http明文通信,可以看见http标头

image-20231226163018314

4)生成自签证书
 
 wget 'https://files-cdn.cnblogs.com/files/blogs/731344/cert.sh?t=1703330209&download=true' -O cert.sh
 ​
 #配置自定义名称后,执行脚本
 vim cert.sh
 sh cert.sh
 ​
 #把证书配置为secret,必须创建在根命名空间(istio-system),否则会找不到证书
 kubectl create secret tls hj.com.crt --key=hj.com.key --cert=hj.com.crt -n istio-system
 kubectl create secret tls hj.com.crt --key=hj.com.key --cert=hj.com.crt -n bookinfo

image-20231223193724000

image-20231226163719314

5)配置ingress-gw,配置tls
 
 kubectl apply -f - <<EOF
 apiVersion: networking.istio.io/v1beta1
 kind: Gateway
 metadata:
   name: bookinfo-gateway
   namespace: istio-system
 spec:
   selector:
     app: istio-ingressgateway
   servers:
   - port:
       number: 80
       name: http
       protocol: HTTP
     hosts:
     - "bookinfo.hj.com"
     tls:
       httpsRedirect: true
   - port:
       number: 443
       name: https
       protocol: HTTPS
     tls:
       mode: SIMPLE
       credentialName: hj.com.crt
     hosts:
     - "bookinfo.hj.com"
 EOF
6)测试
 #查看pod地址和物理机地址
 kubectl get po -o wide |awk '/admin/{print $6,$7}'
 ​
 #在对应物理机抓包
 ifc=`route -n |awk '/10.20.135.43/{print $NF}'`
 tcpdump -X -nn port 80 -i $ifc
 ​
 #发起测试请求
 kubectl exec -it admin -- curl -k -LIH 'host: bookinfo.hj.com' 2.2.2.17/productpage

admin的ip:10.20.135.43,ingress-gw的外部暴露ip:2.2.2.17 此时,admin上发起请求后,http使用tls加密image-20231226192047668

例3:配置productpage与details之间明文通信

1)添加pa策略
 kubectl apply -f - <<EOF
 apiVersion: security.istio.io/v1beta1
 kind: PeerAuthentication
 metadata:
   name: details-pa
   namespace: bookinfo
 spec:
   selector:
     matchLabels:
       app: details
   mtls:
     mode: PERMISSIVE
 EOF
2)配置dr
 kubectl apply -f - <<EOF
 apiVersion: networking.istio.io/v1alpha3
 kind: VirtualService
 metadata:
   name: details
   namespace: bookinfo
 spec:
   hosts:
   - details
   - mesh
   http:
   - route:
     - destination:
         host: details
         subset: v1
 ---
 apiVersion: networking.istio.io/v1alpha3
 kind: DestinationRule
 metadata:
   name: details
   namespace: bookinfo
 spec:
   host: details
   trafficPolicy:
     tls:
       mode: DISABLE
   subsets:
   - name: v1
     labels:
       app: details
       version: v1
   - name: v2
     labels:
       app: details
       version: v2
   workloadSelector:
     matchLabels:
       app: productpage
 EOF
3)测试
 #查看pod地址和物理机地址
 kubectl get po -n bookinfo -o wide |awk '/details/{print $6,$7}'
 ​
 #在对应物理机抓包
 ifc=`route -n |awk '/10.20.135.38/{print $NF}'`
 tcpdump -X -nn port 9080 -i $ifc
 ​
 #查看details的访问记录
 kubectl logs -f -n bookinfo details-v1-65fbc6fbcf-m9582 istio-proxy
 ​
 #发起访问
 curl -k -LIH 'host: bookinfo.hj.com' 2.2.2.17/productpage

在details的访问日志中,可以看到,请求ip中是productpage发起的 image-20231226225533505image-20231226225329747

抓包details的网卡,显示请求使用明文image-20231226225410601

例4:实现网格中服务单点登录

以bookinfo的productpage、kiali、普罗米修斯配置认证登录,默认情况下,访问这些页面是不需要输入密码的。配置单点登录有,一个账号,就可以登录访问这些页面

1)为各测试服务生成tls证书

参考例1的第三步,或者继续使用第三步的证书,此处选择继续使用

 wget 'https://files-cdn.cnblogs.com/files/blogs/731344/cert.sh?t=1703330209&download=true' -O cert.sh
 wget -O ssl.sh 'https://files.cnblogs.com/files/blogs/731344/ssl.sh?t=1703664168&download=true' && sh ssl.sh
 ​
 sh cert.sh
 ssl2 hj.com.crt ca.crt
 ​
 kubectl create secret tls hj.com.crt --key=hj.com.key --cert=hj.com.crt -n istio-system
2)部署bookinfo、kiali、普罗米修斯
bookinfo
 kubectl apply -f samples/bookinfo/platform/kube/bookinfo.yaml
 kubectl apply -f samples/bookinfo/networking/bookinfo-gateway.yaml
 
 kubectl apply -f - <<EOF
 apiVersion: networking.istio.io/v1alpha3
 kind: Gateway
 metadata:
   name: bookinfo-gateway
 spec:
   servers:
   - port:
       number: 80
       name: http
       protocol: HTTP
     hosts:
     - bookinfo.hj.com
     tls:
       httpsRedirect: true
   - port:
       number: 443
       name: https
       protocol: HTTPS
     tls:
       mode: SIMPLE
       credentialName: hj.com.crt
     hosts:
     - "bookinfo.hj.com"
 ---
 apiVersion: networking.istio.io/v1alpha3
 kind: VirtualService
 metadata:
   name: bookinfo
 spec:
   hosts:
   - bookinfo.hj.com
   gateways:
   - bookinfo-gateway
   http:
   - match:
     - uri:
         exact: /productpage
     - uri:
         prefix: /static
     - uri:
         exact: /login
     - uri:
         exact: /logout
     - uri:
         prefix: /api/v1/products
     route:
     - destination:
         host: productpage
         port:
           number: 9080
 EOF
kiali与普罗米修斯
 cd /opt/istio-1.17.0/
 kubectl apply -f samples/addons/
 
 kubectl apply -f <<EOF
 apiVersion: v1
 kind: ConfigMap
 metadata:
   name: kiali
   namespace: istio-system
   labels:
     helm.sh/chart: kiali-server-1.63.1
     app: kiali
     app.kubernetes.io/name: kiali
     app.kubernetes.io/instance: kiali
     version: "v1.63.1"
     app.kubernetes.io/version: "v1.63.1"
     app.kubernetes.io/managed-by: Helm
     app.kubernetes.io/part-of: "kiali"
 data:
   config.yaml: |
     auth:
       openid: {}
       openshift:
         client_id_prefix: kiali
       strategy: anonymous
     deployment:
       accessible_namespaces:
       - '**'
       additional_service_yaml: {}
       affinity:
         node: {}
         pod: {}
         pod_anti: {}
       configmap_annotations: {}
       custom_secrets: []
       host_aliases: []
       hpa:
         api_version: autoscaling/v2beta2
         spec: {}
       image_digest: ""
       image_name: quay.io/kiali/kiali
       image_pull_policy: Always
       image_pull_secrets: []
       image_version: v1.63
       ingress:
         additional_labels: {}
         class_name: nginx
         override_yaml:
           metadata: {}
       ingress_enabled: false
       instance_name: kiali
       logger:
         log_format: text
         log_level: info
         sampler_rate: "1"
         time_field_format: 2006-01-02T15:04:05Z07:00
       namespace: istio-system
       node_selector: {}
       pod_annotations: {}
       pod_labels:
         sidecar.istio.io/inject: "false"
       priority_class_name: ""
       replicas: 1
       resources:
         limits:
           memory: 1Gi
         requests:
           cpu: 10m
           memory: 64Mi
       secret_name: kiali
       security_context: {}
       service_annotations: {}
       service_type: ""
       tolerations: []
       version_label: v1.63.1
       view_only_mode: false
     external_services:
       custom_dashboards:
         enabled: true
       istio:
         root_namespace: istio-system
       grafana:
         in_cluster_url: http://grafana.istio-system:3000/
         health_check_url: "http://grafana.istio-system:3000/api/health"
         enabled: true
       prometheus:
         in_cluster_url: "http://prometheus.istio-system:9090"
         health_check_url: "http://prometheus.istio-system:9090/-/healthy"
       tracing:
           use_grpc: false
           in_cluster_url: "http://tracing.istio-system:80/jaeger"
     identity:
       cert_file: ""
       private_key_file: ""
     istio_namespace: istio-system
     kiali_feature_flags:
       certificates_information_indicators:
         enabled: true
         secrets:
         - cacerts
         - istio-ca-secret
       clustering:
         autodetect_secrets:
           enabled: true
           label: istio/multiCluster=true
         clusters: []
       disabled_features: []
       validations:
         ignore:
         - KIA1201
     login_token:
       signing_key: CHANGEME00000000
     server:
       metrics_enabled: true
       metrics_port: 9090
       port: 20001
       web_root: /kiali
 EOF
测试服务运行
 kubectl exec -it admin -- sh
 curl -IL productpage:9080
 curl -IL kiali.istio-system:20001
 curl -ILXGET prometheus.istio-system:9090
3)部署三方认证系统keycloak

注意事项:

  • 部署完成后,应该创建独立域
  • 独立域中创建请求客户端、用户登录账号(配置密码)等
  • 配置的https继续使用前面生成的证书
部署
 kubectl apply -f - <<EOF
 apiVersion: v1
 kind: Namespace
 metadata:
   name: keycloak
   labels:
     istio-injection: enabled
 ---
 apiVersion: v1
 kind: Service
 metadata:
   name: keycloak
   namespace: keycloak
   labels:
     app: keycloak
 spec:
   ports:
   - name: http
     port: 8080
     targetPort: 8080
   selector:
     app: keycloak
   type: LoadBalancer
 ---
 apiVersion: apps/v1
 kind: Deployment
 metadata:
   name: keycloak
   namespace: keycloak
   labels:
     app: keycloak
 spec:
   replicas: 1
   selector:
     matchLabels:
       app: keycloak
   template:
     metadata:
       labels:
         app: keycloak
     spec:
       containers:
       - name: keycloak
         image: quay.io/keycloak/keycloak:16.1.1
         env:
         - name: KEYCLOAK_USER
           value: "admin"
         - name: KEYCLOAK_PASSWORD
           value: "admin"
         - name: PROXY_ADDRESS_FORWARDING
           value: "true"
         ports:
         - name: http
           containerPort: 8080
         - name: https
           containerPort: 8443
         readinessProbe:
           httpGet:
             path: /auth/realms/master
             port: 8080
 ---
 apiVersion: networking.istio.io/v1beta1
 kind: Gateway
 metadata:
   name: keycloak-gw
   namespace: istio-system
 spec:
   servers:
   - port:
       number: 80
       name: http
       protocol: HTTP
     hosts:
     - "keycloak.hj.com"
 ---
 apiVersion: networking.istio.io/v1beta1
 kind: VirtualService
 metadata:
   name: keycloak-vs
   namespace: keycloak
 spec:
   hosts:
   - "keycloak.hj.com"
   gateways:
   - istio-system/keycloak-gw
   http:
   - route:
     - destination:
         host: keycloak
         port:
           number: 8080
 EOF
测试服务运行
 kubectl patch svc -n keycloak keycloak -p '{"spec":{"externalIPs":["2.2.2.67"]}}'
 echo 2.2.2.67 keycloak.keycloak.svc.cluster.local keycloak.hj.com bookinfo.hj.com kiali.hj.com prome.hj.com >> /etc/hosts
 curl -I keycloak.keycloak.svc.cluster.local:8080
 curl -IH 'host: keycloak.hj.com' 2.2.2.66
web界面配置

image-20231228123200868

image-20231228123247430

image-20231228123441948

image-20231228123523789

image-20231228123605713

image-20231228123638932

4)部署oauth2-proxy
部署
 kubectl apply -f - <<EOF
 apiVersion: v1
 kind: Namespace
 metadata:
   name: oauth2-proxy
   labels:
     istio-injection: enabled
 ---
 apiVersion: v1
 kind: Secret
 metadata:
   name: oauth2-proxy
   namespace: oauth2-proxy
 stringData:
   #keycloak中建的客户端id
   OAUTH2_PROXY_CLIENT_ID: ingress-gw
   #前面保存的ingress-gw客户端的secret
   OAUTH2_PROXY_CLIENT_SECRET: HAwWlzhMkqnWrUDsRzV92kik4soiWR8I
   #自定义cookie secret,生成命令: openssl rand -base64 32 | tr -- '+/' '-_'
   OAUTH2_PROXY_COOKIE_SECRET: vEBMxbw7NXfaUIJR4klhdvB678GUPxWTd7tR9hq2m8w=
 ---
 apiVersion: v1
 kind: Service
 metadata:
   name: oauth2-proxy
   namespace: oauth2-proxy
 spec:
   selector:
     app: oauth2-proxy
   ports:
   - name: http
     port: 4180
 ---
 apiVersion: apps/v1
 kind: Deployment
 metadata:
   name: oauth2-proxy
   namespace: oauth2-proxy
 spec:
   selector:
     matchLabels:
       app: oauth2-proxy
   template:
     metadata:
       labels:
         app: oauth2-proxy
     spec:
       containers:
       - name: oauth2-proxy
         image: quay.io/oauth2-proxy/oauth2-proxy:v7.2.1
         args:
         - --provider=oidc
         - --oidc-issuer-url=http://keycloak.keycloak.svc.cluster.local:8080/auth/realms/istio
         - --profile-url=http://keycloak.keycloak.svc.cluster.local:8080/auth/realms/istio/protocol/openid-connect/userinfo
         - --validate-url=http://keycloak.keycloak.svc.cluster.local:8080/auth/realms/istio/protocol/openid-connect/userinfo
         - --set-authorization-header=true
         - --http-address=0.0.0.0:4180
         - --pass-host-header=true
         - --reverse-proxy=true
         - --auth-logging=true
         - --cookie-httponly=true
         - --cookie-refresh=4m
         - --cookie-secure=false
         - --email-domain="*"
         - --pass-access-token=true
         - --pass-authorization-header=true
         - --request-logging=true
         - --set-xauthrequest=true
         - --silence-ping-logging=true
         - --skip-provider-button=true
         - --skip-auth-strip-headers=false
         - --ssl-insecure-skip-verify=true
         - --standard-logging=true
         - --upstream="static://200"
         - --whitelist-domain=".hj.com,.cluster.local"
         env:
         - name: OAUTH2_PROXY_CLIENT_ID
           valueFrom:
             secretKeyRef:
               name: oauth2-proxy
               key: OAUTH2_PROXY_CLIENT_ID
         - name: OAUTH2_PROXY_CLIENT_SECRET
           valueFrom:
             secretKeyRef:
               name: oauth2-proxy
               key: OAUTH2_PROXY_CLIENT_SECRET
         - name: OAUTH2_PROXY_COOKIE_SECRET
           valueFrom:
             secretKeyRef:
               name: oauth2-proxy
               key: OAUTH2_PROXY_COOKIE_SECRET
         resources:
           requests:
             cpu: 10m
             memory: 100Mi
         ports:
         - containerPort: 4180
           protocol: TCP
         readinessProbe:
           periodSeconds: 3
           httpGet:
             path: /ping
             port: 4180
 EOF
测试服务运行
 kubectl exec -it admin -- curl -IL oauth2-proxy.oauth2-proxy.svc.cluster.local:4180
istio全局provider新增oauth2-proxy
 istioctl apply -y -f - <<EOF
 apiVersion: install.istio.io/v1alpha1
 kind: IstioOperator
 spec:
   meshConfig:
     extensionProviders:
     - name: oauth2-proxy
       envoyExtAuthzHttp:
         service: oauth2-proxy.oauth2-proxy.svc.cluster.local
         port: 4180
         timeout: 1.5s
         includeHeadersInCheck:    #要检查的标头,用于确认用户是否完成身份认证
         - "authorization"
         - "cookie"
         headersToUpstreamOnAllow:     #身份认证检测成功时,向上游转发或添加的标头
         - "x-forwarded-access-token"
         - "authorization"
         - "path"
         - "x-auth-request-user"
         - "x-auth-request-email"
         - "x-auth-request-access-token"
         headersToDownstreamOnDeny:    #身份认证检测失败时,向下游转发或添加的标头
         - "content-type"
         - "set-cookie"
 EOF
5)入口网关配置jwt认证
 kubectl apply -f - <<EOF
 apiVersion: security.istio.io/v1beta1
 kind: RequestAuthentication
 metadata:
   name: istio-ingress-gw
   namespace: istio-system
 spec:
   selector:
     matchLabels:
       istio: ingressgateway
   jwtRules:
     #集群内访问keycloak的路径
   - issuer: "http://keycloak.keycloak.svc.cluster.local:8080/auth/realms/istio"
     jwksUri: "http://keycloak.keycloak.svc.cluster.local:8080/auth/realms/istio/protocol/openid-connect/certs"
     #audiences: ["ingress-gw","istio-ingress-gw"]
     forwardOriginalToken: true
     #集群外访问keycloak的路径
 #  - issuer: http://keycloak.hj.com:8080/auth/realms/istio
 #    jwksUri: http://keycloak.hj.com:8080/auth/realms/istio/protocol/openid-connect/certs
 ---
 apiVersion: security.istio.io/v1beta1
 kind: AuthorizationPolicy
 metadata:
   name: ext-authz-oauth2-proxy
   namespace: istio-system
 spec:
   selector:
     matchLabels:
       istio: ingressgateway
   action: CUSTOM
   provider:
     name: oauth2-proxy
   rules:
   - to:
     - operation:
         hosts:
         - "kiali.hj.com"
         - "prome.hj.com"
         - "bookinfo.hj.com"
         notPaths: ["/auth/*"]
   #- to:
   #  - operation:
   #      hosts: ["*.hj.com"]
   #      notPaths: ["/auth/*"]
 EOF
6)各服务配置https与三方认证转发
bookinfo
 kubectl apply -f - <<EOF
 apiVersion: networking.istio.io/v1alpha3
 kind: Gateway
 metadata:
   name: bookinfo-gateway
 spec:
   servers:
   - port:
       number: 80
       name: http
       protocol: HTTP
     hosts:
     - bookinfo.hj.com
     tls:
       httpsRedirect: true
   - port:
       number: 443
       name: https
       protocol: HTTPS
     tls:
       mode: SIMPLE
       credentialName: hj.com.crt
     hosts:
     - "bookinfo.hj.com"
 ---
 apiVersion: networking.istio.io/v1alpha3
 kind: VirtualService
 metadata:
   name: bookinfo
 spec:
   hosts:
   - bookinfo.hj.com
   gateways:
   - bookinfo-gateway
   http:
   - match:
     - uri:
         exact: /
     rewrite:
       uri: /productpage
     route:
     - destination:
         host: productpage
         port:
           number: 9080
   - match:
     - uri:
         exact: /productpage
     - uri:
         prefix: /static
     - uri:
         exact: /login
     - uri:
         exact: /logout
     - uri:
         prefix: /api/v1/products
     route:
     - destination:
         host: productpage
         port:
           number: 9080
   - match:
     - uri:
         prefix: /auth
     route:
     - destination:
         host: keycloak.keycloak.svc.cluster.local
         port:
           number: 8080
   - match:
     - uri:
         prefix: /oauth2
     route:
     - destination:
         host: oauth2-proxy.oauth2-proxy.svc.cluster.local
         port:
           number: 4180
 EOF
kiali
 kubectl apply -f - <<EOF
 apiVersion: networking.istio.io/v1beta1
 kind: Gateway
 metadata:
   name: kiali-gw
   namespace: istio-system
 spec:
   selector:
       istio: ingressgateway
   servers:
   - port:
       number: 80
       name: http
       protocol: HTTP
     hosts:
     - "kiali.hj.com"
     tls:
       httpsRedirect: true
   - port:
       number: 443
       name: https
       protocol: HTTPS
     tls:
       mode: SIMPLE
       credentialName: hj.com.crt
     hosts:
     - "kiali.hj.com"
 ---
 apiVersion: networking.istio.io/v1beta1
 kind: VirtualService
 metadata:
   name: kiali-vs
   namespace: istio-system
 spec:
   hosts:
   - "kiali.hj.com"
   gateways:
   - kiali-gw
   http:
   - match:
     - uri:
         prefix: /auth
     route:
     - destination:
         host: keycloak.keycloak.svc.cluster.local
         port:
           number: 8080
   - match:
     - uri:
         prefix: /oauth2
     route:
     - destination:
         host: oauth2-proxy.oauth2-proxy.svc.cluster.local
         port:
           number: 4180
   - route:
     - destination:
         host: kiali
         port:
           number: 20001
 EOF
普罗米修斯
 
 kubectl apply -f - <<EOF
 apiVersion: networking.istio.io/v1beta1
 kind: Gateway
 metadata:
   name: prome-gw
   namespace: istio-system
 spec:
   selector:
       istio: ingressgateway
   servers:
   - port:
       number: 80
       name: http
       protocol: HTTP
     hosts:
     - "prome.hj.com"
     tls:
       httpsRedirect: true
   - port:
       number: 443
       name: https
       protocol: HTTPS
     tls:
       mode: SIMPLE
       credentialName: hj.com.crt
     hosts:
     - "prome.hj.com"
 ---
 apiVersion: networking.istio.io/v1beta1
 kind: VirtualService
 metadata:
   name: prome-vs
   namespace: istio-system
 spec:
   hosts:
   - "prome.hj.com"
   gateways:
   - prome-gw
   http:
   - match:
     - uri:
         prefix: /auth
     route:
     - destination:
         host: keycloak.keycloak.svc.cluster.local
         port:
           number: 8080
   - match:
     - uri:
         prefix: /oauth2
     route:
     - destination:
         host: oauth2-proxy.oauth2-proxy.svc.cluster.local
         port:
           number: 4180
   - route:
     - destination:
         host: prometheus
         port:
           number: 9090
 EOF
7)验证登录
 #账号请求正常,可以获取token
 curl -s -d "username=sso-user&\
 password=123456&\
 grant_type=password&\
 client_id=ingress-gw&\
 client_secret=HAwWlzhMkqnWrUDsRzV92kik4soiWR8I" \
 http://keycloak.keycloak.svc.cluster.local:8080/auth/realms/istio/protocol/openid-connect/token |jq
kiali

浏览器访问:kiali.hj.com,会自动跳转到keycloak登录界面

image-20231228104028506

在keycloak登录成功后,进入kiali,同时可以在请求报文中看到登录的账号信息image-20231228104108173

bookinfo

访问:kiali.hj.com/productpage,自签证书,不识别是正常现象 image-20231228104442125

使用同一个账号,sso-user登录成功 image-20231228104913063

普罗米修斯

image-20231228105027258

image-20231228105052370

例5:jwt配合角色与组访问控制

1)keycloak配置

新建2个映射器image-20231228123948621image-20231228124109343

新建角色与组 image-20231228124219350

image-20231228124258800

用户关联刚创建的角色和组 image-20231228124448433

image-20231228124531997

创建sso-user-test账号,但不加入到刚刚的角色与组 image-20231228132120307

image-20231228130021877

2)校验token是否映射了相关角色和组信息
 curl -s -d "username=sso-user&\
 password=123456&\
 grant_type=password&\
 client_id=ingress-gw&\
 client_secret=HAwWlzhMkqnWrUDsRzV92kik4soiWR8I" \
 http://keycloak.keycloak.svc.cluster.local:8080/auth/realms/istio/protocol/openid-connect/token |jq .access_token

复制token到jwt.io中校验,有标记的2个内容才算有效,否则不能继续下去 image-20231228124820911

3)配置授权策略
 kubectl apply -f - <<EOF
 apiVersion: security.istio.io/v1beta1
 kind: AuthorizationPolicy
 metadata:
   name: bookinfo-role-group-auth
   namespace: istio-system
 spec:
   selector:
     matchLabels:
       app: istio-ingressgateway
   action: ALLOW
   rules:
   - to:
     - operation:
         hosts:
         - bookinfo.hj.com
         paths:
         - "/*"
     when:
     - key: request.auth.claims[iss]
       values:
       - "http://keycloak.keycloak.svc.cluster.local:8080/auth/realms/istio"
       - "http://keycloak.magedu.com:8080/auth/realms/istio"
     - key: request.auth.claims[roles]
       values:
       - "admin-role"
     - key: request.auth.claims[groups]
       values:
       - "/admin-group"
 EOF
4)测试访问

sso-user-test用户登录被拒绝,oauth2-proxy的回调403权限拒绝

image-20231228130301162

image-20231228130436815

将sso-user-test,加入到角色和组后,再访问就可以正常打开了 image-20231228130641189

image-20231228130703371