Istio: RequestAuthentication jwksUri не разрешает имена внутренних служб

Уведомление

Основная причина этого та же, что и Istio: проверка работоспособности / сопроводительный файл не работают, когда я включаю JWT RequestAuthentication, но после дальнейшей диагностики я изменил формулировку на просто (пытаюсь получить помощь)

Проблема

Я пытаюсь настроить RequestAuthentication (и AuthorizationPolicy) в сетке Istio. Мои токены JWK предоставляются внутренним сервером OAUTH (на основе CloudFoundry), который отлично работает с другими службами. Моя проблема возникает, когда я настраиваю uri для получения ключа подписи, связанного с внутренним модулем. В настоящий момент Istio не разрешает имя внутреннего модуля . Я запутался, потому что микросервисы могут подключаться ко всем моим внутренним модулям (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)

      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:

Я нашел обходное решение, используя полное доменное имя (полное имя) в имени хоста. Но это не решает мою проблему, потому что связывает файл конфигурации с пространством имен (я использую несколько пространств имен, и мне нужен только один файл конфигурации). В любом случае моя текущая строка:

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

Я полностью уверен, что это глупый параметр конфигурации, но я не могу его найти! заранее спасибо

2 ответа

jwksUri: "http://uaa:8090/uaa/token_keys" не будет работать с istiod, потому что http://uaa будет интерпретироваться как http://uaa.istio-system.svc.cluster.local. Вот почему ваш обходной путь решает проблему.

Я не понимаю, почему ваш обходной путь 2 не является достаточным решением. Допустим, ваша служба uaa работает в пространстве имен auth. Если вы настроите jwksUri с uaa.auth.svc.cluster.local, каждый модуль kubernetes может вызывать его, независимо от его пространства имен.

У меня была очень похожая проблема, вызванная тем, что mtls.mode = STRICTдля всех капсул. Это привело к тому, что модуль не смог получить ключи (как istiod похоже, не использует MTLS, когда выполняет HTTP GET на).

Решение заключалось в том, чтобы установить PeerAuthentication с участием mtls.mode = PERMISSIVE на модуле, на котором размещен jwksUri (который в моем случае был dex).

Некоторый пример 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

Другие вопросы по тегам