Istio authorization policy not applying on child gateway

后端 未结 1 1964
自闭症患者
自闭症患者 2021-01-03 04:33

What I am trying to achieve: block all traffic to a service, containing the code to handle this within the same namespace as the service.

Why

相关标签:
1条回答
  • 2021-01-03 04:52

    As far as I know you should rather use AuthorizationPolicy in 3 ways

    • on ingress gateway
    • on namespace
    • on specific service

    I have tried to make it work on a specific gateway with annotations like you did, but I couldn't make it work for me.

    e.g.

    the following authorization policy denies all requests to workloads in namespace x.

    apiVersion: security.istio.io/v1beta1
    kind: AuthorizationPolicy
    metadata:
     name: deny-all
     namespace: x
    spec:
      {}
    

    the following authorization policy denies all requests on ingress gateway.

    apiVersion: security.istio.io/v1beta1
    kind: AuthorizationPolicy
    metadata:
      name: deny-all
      namespace: istio-system
    spec:
      selector:
        matchLabels:
          app: istio-ingressgateway
    

    the following authorization policy denies all requests on httpbin in x namespace.

    apiVersion: security.istio.io/v1beta1
    kind: AuthorizationPolicy
    metadata:
      name: deny-service-x
      namespace: x
    spec:
      selector:
        matchLabels:
          app: httpbin
    

    Let's say you deny all requests on x namespace and allow only get requests for httpbin service.

    Then you would use this AuthorizationPolicy to deny all requests

    apiVersion: security.istio.io/v1beta1
    kind: AuthorizationPolicy
    metadata:
      name: deny-all
      namespace: x
    spec:
      {}
    

    And this AuthorizationPolicy to allow only get requests.

    apiVersion: "security.istio.io/v1beta1"
    kind: "AuthorizationPolicy"
    metadata:
      name: "x-viewer"
      namespace: x
    spec:
      selector:
        matchLabels:
          app: httpbin
      rules:
      - to:
        - operation:
            methods: ["GET"]
    

    And there is the main issue ,which is ipBlocks. There is related github issue about that.

    As mentioned here by @incfly

    I guess the reason why it’s stop working when in non ingress pod is because the sourceIP attribute will not be the real client IP then.

    According to https://github.com/istio/istio/issues/22341 7, (not done yet) this aims at providing better support without setting k8s externalTrafficPolicy to local, and supports CIDR range as well.


    I have tried this example from istio documentation to make it work, but it wasn't working for me, even if I changed externalTrafficPolicy. Then a workaround with envoyfilter came from above istio discuss thread.

    Answer provided by @hleal18 here.

    Got and example working successfully using EnvoyFilters, specifically with remote_ip condition applied on httbin.

    Sharing the manifest for reference.

    apiVersion: networking.istio.io/v1alpha3
    kind: EnvoyFilter
    metadata:
      name: httpbin
      namespace: foo
    spec:
      workloadSelector:
        labels:
          app: httpbin
      configPatches:
        - applyTo: HTTP_FILTER
          match:
            context: SIDECAR_INBOUND
            listener:
              filterChain:
                filter:
                  name: "envoy.http_connection_manager"
                  subFilter:
                    name: "envoy.router"
          patch:
            operation: INSERT_BEFORE
            value:
              name: envoy.filters.http.rbac 
              config:
                rules:
                  action: ALLOW
                  policies:
                    "ip-premissions":
                      permissions:
                        - any: true
                      principals:
                        - remote_ip:
                            address_prefix: xxx.xxx.xx.xx
                            prefix_len: 32
    

    I have tried above envoy filter on my test cluster and as far as I can see it's working.

    Take a look at below steps I made.

    1.I have changed the externalTrafficPolicy with

    kubectl patch svc istio-ingressgateway -n istio-system -p '{"spec":{"externalTrafficPolicy":"Local"}}'
    

    2.I have created namespace x with istio-injection enabled and deployed httpbin here.

    kubectl create namespace x
    kubectl label namespace x istio-injection=enabled
    kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.7/samples/httpbin/httpbin.yaml -n x
    kubectl apply -f https://github.com/istio/istio/blob/master/samples/httpbin/httpbin-gateway.yaml -n x
    

    3.I have created envoyfilter

    apiVersion: networking.istio.io/v1alpha3
    kind: EnvoyFilter
    metadata:
      name: httpbin
      namespace: x
    spec:
      workloadSelector:
        labels:
          app: httpbin
      configPatches:
        - applyTo: HTTP_FILTER
          match:
            context: SIDECAR_INBOUND
            listener:
              filterChain:
                filter:
                  name: "envoy.http_connection_manager"
                  subFilter:
                    name: "envoy.router"
          patch:
            operation: INSERT_BEFORE
            value:
              name: envoy.filters.http.rbac
              config:
                rules:
                  action: ALLOW
                  policies:
                    "ip-premissions":
                      permissions:
                        - any: true
                      principals:
                        - remote_ip:
                            address_prefix: xx.xx.xx.xx
                            prefix_len: 32
    

    address_prefix is the CLIENT_IP, there are commands I have used to get it.

    export INGRESS_HOST=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
    export INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="http2")].port}')
    curl "$INGRESS_HOST":"$INGRESS_PORT"/headers -s -o /dev/null -w "%{http_code}\n"
    CLIENT_IP=$(curl "$INGRESS_HOST":"$INGRESS_PORT"/ip -s | grep "origin" | cut -d'"' -f 4) && echo "$CLIENT_IP"
    

    4.I have test it with curl and my browser.

    curl "$INGRESS_HOST":"$INGRESS_PORT"/headers -s -o /dev/null -w "%{http_code}\n"
    200
    


    Let me know if you have any more questions, I might be able to help.

    0 讨论(0)
提交回复
热议问题