Istio 授权策略不适用于子网关

Jam*_*ott 6 kubernetes istio

我正在努力实现的目标:阻止所有到服务的流量,包含在与服务相同的命名空间内处理它的代码。

为什么:这是将特定服务“锁定”到特定 IP/CIDR 的第一步

我有一个名为的主要入口 GW istio-ingressgateway,它适用于服务。

$ kubectl describe gw istio-ingressgateway -n istio-system
Name:         istio-ingressgateway
Namespace:    istio-system
Labels:       operator.istio.io/component=IngressGateways
              operator.istio.io/managed=Reconcile
              operator.istio.io/version=1.5.5
              release=istio
Annotations:  API Version:  networking.istio.io/v1beta1
Kind:         Gateway
Metadata:
  Creation Timestamp:  2020-08-28T15:45:10Z
  Generation:          1
  Resource Version:    95438963
  Self Link:           /apis/networking.istio.io/v1beta1/namespaces/istio-system/gateways/istio-ingressgateway
  UID:                 ae5dd2d0-44a3-4c2b-a7ba-4b29c26fa0b9
Spec:
  Selector:
    App:    istio-ingressgateway
    Istio:  ingressgateway
  Servers:
    Hosts:
      *
    Port:
      Name:      http
      Number:    80
      Protocol:  HTTP
Events:          <none>
Run Code Online (Sandbox Code Playgroud)

我还有另一个“主要”GW,K8s 入口 GW 来支持 TLS(我想我会包括这个,尽可能明确)

k describe gw istio-autogenerated-k8s-ingress -n istio-system
Name:         istio-autogenerated-k8s-ingress
Namespace:    istio-system
Labels:       app=istio-ingressgateway
              istio=ingressgateway
              operator.istio.io/component=IngressGateways
              operator.istio.io/managed=Reconcile
              operator.istio.io/version=1.5.5
              release=istio
Annotations:  API Version:  networking.istio.io/v1beta1
Kind:         Gateway
Metadata:
  Creation Timestamp:  2020-08-28T15:45:56Z
  Generation:          2
  Resource Version:    95439499
  Self Link:           /apis/networking.istio.io/v1beta1/namespaces/istio-system/gateways/istio-autogenerated-k8s-ingress
  UID:                 edd46c17-9975-4089-95ff-a2414d40954a
Spec:
  Selector:
    Istio:  ingressgateway
  Servers:
    Hosts:
      *
    Port:
      Name:      http
      Number:    80
      Protocol:  HTTP
    Hosts:
      *
    Port:
      Name:      https-default
      Number:    443
      Protocol:  HTTPS
    Tls:
      Credential Name:     ingress-cert
      Mode:                SIMPLE
      Private Key:         sds
      Server Certificate:  sds
Events:                    <none>
Run Code Online (Sandbox Code Playgroud)

我希望能够在命名空间中创建另一个 GW,x并将授权策略附加到该 GW。如果我在istio-system命名空间中创建授权策略,那么它会返回,RBAC: access denied这很好 - 但这适用于使用主 GW 的所有服务。

apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: block-all
  namespace: istio-system
spec:
  selector:
    matchLabels:
      app: istio-ingressgateway
  action: DENY
  rules:
    - from:
        - source:
            ipBlocks: ["0.0.0.0/0"]
Run Code Online (Sandbox Code Playgroud)

我目前拥有的不起作用。任何指针将不胜感激。以下都是x应用时在namespace下创建的kubectl apply -f files.yaml -n x

apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  annotations:
      app: x-ingress
  name: x-gw
  labels:
    app: x-ingress
spec:
  selector:
    istio: ingressgateway
  servers:
    - hosts:
        - x.y.com
      port:
        name: http
        number: 80
        protocol: HTTP
      tls:
        httpsRedirect: true
    - hosts:
        - x.y.com
      port:
        name: https
        number: 443
        protocol: HTTPS
      tls:
        mode: SIMPLE
        privateKey: sds
        serverCertificate: sds
        credentialName: ingress-cert
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: x
  labels:
    app: x
spec:
  hosts:
    - x.y.com
  gateways:
    - x-gw
  http:
    - route:
        - destination:
            host: x
---
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: x-ingress-policy
spec:
  selector:
    matchLabels:
      app: x-ingress
  action: DENY
  rules:
    - from:
        - source:
            ipBlocks: ["0.0.0.0/0"]
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: x
  labels:
    app: x
spec:
  hosts:
    - x.y.com
  gateways:
    - x-gw
  http:
    - route:
        - destination:
            host: x

Run Code Online (Sandbox Code Playgroud)

以上应该阻止所有到 GW 的流量,因为它匹配 CIDR 范围 0.0.0.0/0

我完全误解了 GW/AuthorizationPolicies 的概念,或者我错过了什么?

编辑 我最终创建了另一个具有 IP 限制块的 GW,因为 AWS 上的经典负载均衡器不支持 IP 转发。

apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
metadata:
  namespace: istio-system
  name: istiocontrolplane
spec:
  profile: demo
  components:
    ingressGateways:
      - name: istio-ingressgateway
        enabled: true
      - name: admin-ingressgateway
        enabled: true
        label:
          istio: admin-ingressgateway
        k8s:
          serviceAnnotations:
            service.beta.kubernetes.io/aws-load-balancer-type: "nlb"
---
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: deny-all-admin
  namespace: istio-system
spec:
  selector:
    matchLabels:
      istio: admin-ingressgateway
  action: ALLOW
  rules:
    - from:
        - source:
            ipBlocks: ["176.252.114.59/32"]
Run Code Online (Sandbox Code Playgroud)
kubectl patch svc istio-ingressgateway -n istio-system -p '{"spec":{"externalTrafficPolicy":"Local"}}'
Run Code Online (Sandbox Code Playgroud)

然后,我在我想要锁定的工作负载中使用了该网关。

jt9*_*t97 8

据我所知你应该使用AuthorizationPolicy通过三种方式

\n
    \n
  • 在入口网关上
  • \n
  • 在命名空间上
  • \n
  • 关于特定服务
  • \n
\n

我试图让它在带有注释的特定网关上工作,就像你所做的那样,但我无法让它为我工作。

\n

例如

\n

以下授权策略拒绝对命名空间 x 中工作负载的所有请求。

\n
apiVersion: security.istio.io/v1beta1\nkind: AuthorizationPolicy\nmetadata:\n name: deny-all\n namespace: x\nspec:\n  {}\n
Run Code Online (Sandbox Code Playgroud)\n

以下授权策略拒绝入口网关上的所有请求。

\n
apiVersion: security.istio.io/v1beta1\nkind: AuthorizationPolicy\nmetadata:\n  name: deny-all\n  namespace: istio-system\nspec:\n  selector:\n    matchLabels:\n      app: istio-ingressgateway\n
Run Code Online (Sandbox Code Playgroud)\n

以下授权策略拒绝httpbin上的所有请求上的所有请求。

\n
apiVersion: security.istio.io/v1beta1\nkind: AuthorizationPolicy\nmetadata:\n  name: deny-service-x\n  namespace: x\nspec:\n  selector:\n    matchLabels:\n      app: httpbin\n
Run Code Online (Sandbox Code Playgroud)\n
\n

假设您拒绝 x 命名空间上的所有请求,只允许对 httpbin 服务的 get 请求。

\n

然后您将使用此 AuthorizationPolicy 拒绝所有请求

\n
apiVersion: security.istio.io/v1beta1\nkind: AuthorizationPolicy\nmetadata:\n  name: deny-all\n  namespace: x\nspec:\n  {}\n
Run Code Online (Sandbox Code Playgroud)\n

并且这个AuthorizationPolicy只允许get请求。

\n
apiVersion: "security.istio.io/v1beta1"\nkind: "AuthorizationPolicy"\nmetadata:\n  name: "x-viewer"\n  namespace: x\nspec:\n  selector:\n    matchLabels:\n      app: httpbin\n  rules:\n  - to:\n    - operation:\n        methods: ["GET"]\n
Run Code Online (Sandbox Code Playgroud)\n
\n

还有一个主要问题,那就是 ipBlocks。有相关的github 问题

\n

正如@incfly 此处提到的

\n
\n

我猜它\xe2\x80\x99s在非入口pod中停止工作的原因是因为sourceIP属性那时将不是真正的客户端IP。

\n

根据https://github.com/istio/istio/issues/22341 7,(尚未完成)这旨在提供更好的支持,而无需将 k8s externalTrafficPolicy 设置为本地,并且还支持 CIDR 范围。

\n
\n
\n

我已经尝试过istio 文档中的这个示例来使其工作,但它对我不起作用,即使我更改了externalTrafficPolicy. 然后使用envoyfilter解决方法

\n

@hleal18在这里提供的答案

\n
\n

使用 EnvoyFilters 成功运行的示例,特别是在 httbin 上应用了 remote_ip 条件。

\n

分享清单以供参考。

\n
\n
apiVersion: networking.istio.io/v1alpha3\nkind: EnvoyFilter\nmetadata:\n  name: httpbin\n  namespace: foo\nspec:\n  workloadSelector:\n    labels:\n      app: httpbin\n  configPatches:\n    - applyTo: HTTP_FILTER\n      match:\n        context: SIDECAR_INBOUND\n        listener:\n          filterChain:\n            filter:\n              name: "envoy.http_connection_manager"\n              subFilter:\n                name: "envoy.router"\n      patch:\n        operation: INSERT_BEFORE\n        value:\n          name: envoy.filters.http.rbac \n          config:\n            rules:\n              action: ALLOW\n              policies:\n                "ip-premissions":\n                  permissions:\n                    - any: true\n                  principals:\n                    - remote_ip:\n                        address_prefix: xxx.xxx.xx.xx\n                        prefix_len: 32\n
Run Code Online (Sandbox Code Playgroud)\n
\n

我已经在我的测试集群上尝试了上述特使过滤器,据我所知它正在工作。

\n

看看我所做的以下步骤。

\n

1.我已经更改了externalTrafficPolicy

\n
kubectl patch svc istio-ingressgateway -n istio-system -p \'{"spec":{"externalTrafficPolicy":"Local"}}\'\n
Run Code Online (Sandbox Code Playgroud)\n

2.我创建了启用 istio-injection 的命名空间 x 并在此处部署了 httpbin。

\n
kubectl create namespace x\nkubectl label namespace x istio-injection=enabled\nkubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.7/samples/httpbin/httpbin.yaml -n x\nkubectl apply -f https://github.com/istio/istio/blob/master/samples/httpbin/httpbin-gateway.yaml -n x\n
Run Code Online (Sandbox Code Playgroud)\n

3.我创建了envoyfilter

\n
apiVersion: networking.istio.io/v1alpha3\nkind: EnvoyFilter\nmetadata:\n  name: httpbin\n  namespace: x\nspec:\n  workloadSelector:\n    labels:\n      app: httpbin\n  configPatches:\n    - applyTo: HTTP_FILTER\n      match:\n        context: SIDECAR_INBOUND\n        listener:\n          filterChain:\n            filter:\n              name: "envoy.http_connection_manager"\n              subFilter:\n                name: "envoy.router"\n      patch:\n        operation: INSERT_BEFORE\n        value:\n          name: envoy.filters.http.rbac\n          config:\n            rules:\n              action: ALLOW\n              policies:\n                "ip-premissions":\n                  permissions:\n                    - any: true\n                  principals:\n                    - remote_ip:\n                        address_prefix: xx.xx.xx.xx\n                        prefix_len: 32\n
Run Code Online (Sandbox Code Playgroud)\n

地址前缀CLIENT_IP,我用过一些命令来获取它。

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

4.我已经用curl和我的浏览器对其进行了测试。

\n
curl "$INGRESS_HOST":"$INGRESS_PORT"/headers -s -o /dev/null -w "%{http_code}\\n"\n200\n
Run Code Online (Sandbox Code Playgroud)\n

在此输入图像描述

\n
\n

如果您还有其他问题,请告诉我,我也许可以提供帮助。

\n