0

注意

其根本原因与Istio 相同:启用 JWT RequestAuthentication 时运行状况检查/sidecar 失败,但经过进一步诊断,我已将其改写为简单(试图获得帮助)

问题

我正在尝试在 Istio 网格中配置 RequestAuthentication(和 AuthorizationPolicy)。我的 JWK 令牌由内部 OAUTH 服务器(基于 CloudFoundry)提供,该服务器可正常用于其他服务。当我配置 uri 以获取签名密钥并链接到内部 pod 时,我的问题就出现了。此时,Istio 并未解析内部 pod 的名称。我很困惑,因为微服务能够连接到我所有的内部 pod(mongodb、mysql、rabbitmq),包括 uaa。为什么 RequestAuthentication 不能做同样的事情?

UAA 服务配置(注意:我还在为外部访问创建一个虚拟服务,这工作正常)

apiVersion: apps/v1
kind: Deployment
metadata:
  name: uaa
spec:
  replicas: 1
  selector:
    matchLabels:
      app: uaa
  template:
    metadata:
      labels:
        app: uaa
    spec:
      containers:
      - name: uaa
        image: example/uaa
        imagePullPolicy: Never
        env:
        - name: LOGGING_LEVEL_ROOT
          value: DEBUG
        ports:
        - containerPort: 8090
        resources:
          limits:
            memory: 350Mi
---
apiVersion: v1
kind: Service
metadata:
  name: uaa
spec:
  selector:
    app: uaa
  ports:
    - port: 8090
      name: http
---
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: vs-auth
spec:
  hosts:
  - "kubernetes.example.com"
  gateways:
  - gw-ingress
  http:
  - match:
    - uri:
        prefix: /oauth
    rewrite:
      uri: "/uaa/oauth"
    route:
    - destination:
        port:
          number: 8090
        host: uaa
  - match:
    - uri:
        prefix: /uaa
    rewrite:
      uri: "/uaa"
    route:
    - destination:
        port:
          number: 8090
        host: uaa        

RequestAuthentication:注意参数 jwksUri,寻找uaa主机名。

apiVersion: "security.istio.io/v1beta1"
kind: "RequestAuthentication"
metadata:
  name: "ra-product-composite"
spec:
  selector:
    matchLabels:
      app: "product-composite"
  jwtRules:
  - issuer: "http://uaa:8090/uaa/oauth/token"
    jwksUri: "http://uaa:8090/uaa/token_keys"
    forwardOriginalToken: true
---
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: "ap-product-composite"
spec:
  selector:
    matchLabels:
      app: "product-composite"
  action: ALLOW
  rules:
  - to:
    - operation: 
        methods: ["GET","POST","DELETE","HEAD","PUT"]
        paths: ["*"]

错误日志(在 istiod pod 中)

2021-03-17T09:56:18.833731Z     error   Failed to fetch jwt public key from "http://uaa:8090/uaa/token_keys": Get "http://uaa:8090/uaa/token_keys": dial tcp: lookup uaa on 10.96.0.10:53: no such host
2021-03-17T09:56:18.838233Z     info    ads     LDS: PUSH for node:product-composite-5cbf8498c7-nhxtj.chp18 resources:29 size:134.8kB
2021-03-17T09:56:18.856277Z     warn    ads     ADS:LDS: ACK ERROR sidecar~10.1.4.2~product-composite-5cbf8498c7-nhxtj.chp18~chp18.svc.cluster.local-8 Internal:Error adding/updating listener(s) virtualInbound: Provider 'origins-0' in jwt_authn config has invalid local jwks: Jwks RSA [n] or [e] field is missing or has a parse error

解决方法

目前,我已将 OAUTH 服务器声明为外部服务器,并重定向了请求,但这完全是低效的。

apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
  name: se-auth
spec:
  hosts:
  - "host.docker.internal"
  ports:
  - number: 8090
    name: http
    protocol: HTTP
  resolution: DNS
  location: MESH_EXTERNAL
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: vs-auth
spec:
  hosts:
  - "kubernetes.example.com"
  gateways:
  - gw-ingress
  http:
  - match:
    - uri:
        prefix: /oauth
    rewrite:
      uri: "/uaa/oauth"
    route:
    - destination:
        port:
          number: 8090
        host: "host.docker.internal"
  - match:
    - uri:
        prefix: /uaa
    rewrite:
      uri: "/uaa"
    route:
    - destination:
        port:
          number: 8090
        host: "host.docker.internal"        
---
apiVersion: "security.istio.io/v1beta1"
kind: "RequestAuthentication"
metadata:
  name: "ra-product-composite"
spec:
  selector:
    matchLabels:
      app: "product-composite"
  jwtRules:
  - issuer: "http://uaa:8090/uaa/oauth/token"
    jwksUri: "http://host.docker.internal:8090/uaa/token_keys"
    forwardOriginalToken: true

解决方法 2:

我已经解决了在主机名中使用 FQDN(完全限定名)的方法。但这并不能解决我的问题,因为将配置文件链接到命名空间(我使用多个命名空间,我只需要一个配置文件)无论如何,我当前的行是:

    jwksUri: "http://uaa.mynamespace.svc.cluster.local:8090/uaa/token_keys"

我完全确定这是一个愚蠢的配置参数,但我找不到它!提前致谢

4

2 回答 2

1

jwksUri: "http://uaa:8090/uaa/token_keys"在 istiod 中不起作用,因为http://uaa将被解释为http://uaa.istio-system.svc.cluster.local. 这就是为什么您的解决方法正在解决问题的原因。

我不明白为什么您的解决方法 2 不是一个足够的解决方案。假设您的 uaa 服务在 namespace 中运行auth。如果你配置jwksUriwith uaa.auth.svc.cluster.local,每个 kubernetes pod 都可以调用它,不管它的命名空间是什么。

于 2021-03-17T13:04:55.723 回答
0

我有一个非常相似的问题,这是由所有 pod的PeerAuthentication设置引起的。mtls.mode = STRICT这导致istiodpod 无法检索密钥(因为istiod它在 上执行 HTTP GET 时似乎不使用 MTLS jwksUri)。

解决方案是在托管的 Pod 上设置一个PeerAuthenticationwith (在我的例子中是 dex)。mtls.mode = PERMISSIVEjwksUri

一些示例 YAML:

apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
  name: default-mtls
  namespace: my-namespace
spec:
  mtls:
    ## the empty `selector` applies STRICT to all Pods in `my-namespace`
    mode: STRICT
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
  name: dex-mtls
  namespace: my-namespace
spec:
  selector:
    matchLabels:
      my_label: dex
  mtls:
    ## the dex pods must allow incoming non-MTLS traffic because istiod reads the JWKS keys from:
    ## http://dex.my-namespace.svc.cluster.local:5556/dex/keys
    mode: PERMISSIVE

于 2021-09-29T05:48:24.603 回答