【问题标题】:Secure Kiali (in Istio) by source ip address通过源 IP 地址保护 Kiali(在 Istio 中)
【发布时间】:2021-12-21 09:05:00
【问题描述】:

我在 Istio 1.10.2 中使用 this 应用了 kiali。现在我正在尝试通过过滤源 IP 地址来保护它。我尝试使用授权策略,但没有奏效。 it should deny any request that is not in the ALLOW policy

授权策略:

apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: kiali-ingress-policy-allow
  namespace: istio-system
spec:
  selector:
    matchLabels:
      app: kiali
  action: ALLOW
  rules:
  - from:
    - source:
        remoteIpBlocks: ["10.43.212.247/32","10.43.212.242/32"]

虚拟服务:

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: kiali
  namespace: istio-system
spec:
  hosts:
  - "kiali.myinternaldomain.local"
  gateways:
  - istio-system/my-internal-gateway
  http:
  - match:
    - uri:
        prefix: /
    route:
    - destination:
        host: kiali
        port:
          number: 20001

使用默认配置文件和这些额外参数安装 ISTIO:

apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
spec:
  meshConfig:
    accessLogFile: /dev/stdout
  components:
    ingressGateways:
      - name: istio-ingressgateway
        enabled: true
        k8s:
          overlays:
          - apiVersion: apps/v1
            kind: Deployment
            name: istio-ingressgateway
            patches:
            - path: kind
              value: DaemonSet
            - path: spec.strategy
            - path: spec.updateStrategy
              value:
                rollingUpdate:
                  maxUnavailable: 50%
                type: RollingUpdate
    egressGateways:
      - name: istio-egressgateway
        enabled: true
        k8s:
          hpaSpec:
            minReplicas: 2
    pilot:
      k8s:
        hpaSpec:
          minReplicas: 2
  values:
    gateways:
      istio-ingressgateway:
        autoscaleEnabled: false
        env:
          ISTIO_META_HTTP10: '1'
    pilot:
      env:
        PILOT_HTTP10: '1'

【问题讨论】:

  • 您是如何设置集群的——一些裸机解决方案或云提供商?您使用的是哪个 Kubernetes 版本?
  • 裸机。 Kubernetes 1.20.6
  • 你用的是哪个installation configuration profile?您的集群中是否已经应用了任何AuthorizationPolicy?您是如何在裸机解决方案上设置 LoadBalancer 的?你能分享来自 Istio ingress gateway pod 的日志吗(使用kubectl get pods -n istio-system 命令获取 pod 名称,然后使用kubectl logs istio-ingressgateway-{random} -n istio-system)?
  • 为什么使用remoteIpBlocks,而不是IpBlocks?您是否检查了进入集群的源 IP 地址?请求来自哪里 - 在集群外部还是来自其他 pod?你能设置 TCPdump 来观察传入的 IP 地址吗?您能否使用以下命令获取 kiali pod 的名称并检查日志:istioctl proxy-config log "$pod" -n istio-system --level rbac:debug
  • 另外请回答之前的问题。

标签: kubernetes istio


【解决方案1】:

我设法在 GCP VMs 上的 Istio 1.10.2 中设置工作 ALLOW 策略,集群是使用带有 Calico CNI 插件的 kubeadm 设置的。我使用了这个文档 - Ingress Gateway

注意:我将istio-ingressgateway 服务类型更改为NodePort 服务而不是LoadBalancer,但这在这种情况下并不重要。


我的网络设计如下:

  • 第一个虚拟机 - Kubernetes 节点 - 10.xxx.0.2 地址
  • 第二个虚拟机 - 10.xxx.0.3 地址
  • 第三个虚拟机 - 10.xxx.0.4 地址 - 此地址将在 ALLOW 策略中

我部署了以下 NGINX 服务和部署...

apiVersion: v1
kind: Service
metadata:
  name: nginx-svc
  labels:
    app: nginx
spec:
  ports:
  - name: http
    port: 80
    targetPort: 80
  selector:
    app: nginx
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deply
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
        version: v1
    spec:
      containers:
      - image: nginx
        imagePullPolicy: IfNotPresent
        name: nginx
        ports:
        - containerPort: 80

...以及以下网关和虚拟服务定义:

apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: gateway
spec:
  selector:
    istio: ingressgateway
  servers:
  - port:
      number: 80
      name: http
      protocol: HTTP
    hosts:
    - "*"
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: nginx-vs
spec:
  hosts:
  - "my-test.com"
  gateways:
  - gateway
  http:
  - route:
    - destination:
        host: nginx-svc 
        port:
          number: 80

查看虚拟服务定义中的nginx-svc服务名称(你应该使用你要配置的那个)。

我可以从网络中的每个虚拟机运行以下命令:

user@vm-istio:~$ curl 10.xxx.0.2:31756 -H "Host: my-test.com"
<!DOCTYPE html>
...
<title>Welcome to nginx!</title>

所以它工作正常。

enabled RBAC debugging for the ingress gateway pod...

kubectl get pods -n istio-system -o name -l istio=ingressgateway | sed 's|pod/||' | while read -r pod; do istioctl proxy-config log "$pod" -n istio-system --level rbac:debug; done

...我将externalTrafficPolicy 设置为Local 在服务中istio-ingressgateway 设置为preserve an IP address from the original client

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

在 istio 入口网关控制器的日志中,我可以看到请求即将到来并且它们正在继续:

kubectl logs istio-ingressgateway-5d57955454-9mz4b -n istio-system -f
...
[2021-11-24T13:39:47.220Z] "GET / HTTP/1.1" 200 - via_upstream - "-" 0 615 1 0 "10.xxx.0.3" "curl/7.64.0" "69953f69-8a46-9e2a-a5a7-36861bae4a77" "my-test.com" "192.168.98.74:80" outbound|80||nginx-svc.default.svc.cluster.local 192.168.98.72:60168 192.168.98.72:8080 10.xxx.0.3:55160 - -
[2021-11-24T13:39:48.980Z] "GET / HTTP/1.1" 200 - via_upstream - "-" 0 615 1 0 "10.xxx.0.4" "curl/7.64.0" "89284e11-42f9-9e84-b256-d3ea37311e92" "my-test.com" "192.168.98.74:80" outbound|80||nginx-svc.default.svc.cluster.local 192.168.98.72:60192 192.168.98.72:8080 10.xxx.0.4:35800 - -

现在,我将应用基于 IP 的允许列表以仅允许第二个 VM 地址托管 my-test.com

apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: ingress-policy
  namespace: istio-system
spec:
  selector:
    matchLabels:
      app: istio-ingressgateway
  action: ALLOW
  rules:
  - from:
    - source:
        ipBlocks: ["10.xxx.0.4"]
    to:
    - operation:
        hosts:
        - "my-test.com" 

在地址为 10.xxx.0.4 的 VM 上 curl 像以前一样工作,但在地址为 10.xxx.0.3 的 VM 上,我们可以注意到以下内容:

user@vm-istio:~$ curl 10.xxx.0.2:31756 -H "Host: my-test.com"
RBAC: access denied

所以它按预期工作。

在 istio 入口网关控制器的日志中,我们可以注意到请求被拒绝(查找与 RBAC 相关的日志):

kubectl logs istio-ingressgateway-5d57955454-9mz4b -n istio-system -f
2021-11-24T14:05:11.382613Z     debug   envoy rbac      checking request: requestedServerName: , sourceIP: 10.xxx.0.3:55194, directRemoteIP: 10.xxx.0.3:55194, remoteIP: 10.xxx.0.3:55194,localAddress: 192.168.98.72:8080, ssl: none, headers: ':authority', 'my-test.com'
':path', '/'
':method', 'GET'
':scheme', 'http'
'user-agent', 'curl/7.64.0'
'accept', '*/*'
'x-forwarded-for', '10.xxx.0.3'
'x-forwarded-proto', 'http'
'x-envoy-internal', 'true'
'x-request-id', '63c0f55c-5545-92a0-80fc-aa2a5a63bf04'
'x-envoy-decorator-operation', 'nginx-svc.default.svc.cluster.local:80/*'
'x-envoy-peer-metadata', '...'
'x-envoy-peer-metadata-id', 'router~192.168.98.72~istio-ingressgateway-5d57955454-9mz4b.istio-system~istio-system.svc.cluster.local'
, dynamicMetadata: 
2021-11-24T14:05:11.382662Z     debug   envoy rbac      enforced denied, matched policy none
[2021-11-24T14:05:11.382Z] "GET / HTTP/1.1" 403 - rbac_access_denied_matched_policy[none] - "-" 0 19 0 - "10.xxx.0.3" "curl/7.64.0" "63c0f55c-5545-92a0-80fc-aa2a5a63bf04" "my-test.com" "-" outbound|80||nginx-svc.default.svc.cluster.local - 192.168.98.72:8080 10.xxx.0.3:55194 - -

尤其是这部分:

[2021-11-24T14:05:11.382Z] "GET / HTTP/1.1" 403 - rbac_access_denied_matched_policy[none]

这清楚地表明我们的政策正在发挥作用。

允许我们请求的日志示例:

2021-11-25T10:58:34.717495Z     debug   envoy rbac      enforced allowed, matched policy ns[istio-system]-policy[ingress-policy]-rule[0]
[2021-11-25T10:58:34.717Z] "GET / HTTP/1.1" 200 - via_upstream - "-" 0 615 25 23 "10.xxx.0.4" "curl/7.64.0" "889e3326-093c-94b1-b856-777c06cbe2b7" "my-test.com" "192.168.98.75:80" outbound|80||nginx-svc.default.svc.cluster.local 192.168.98.72:46190 192.168.98.72:8080 10.xxx.0.4:37148 - -

什么是重要的:

  • 确保在 pod istio-ingressgateway-{..} 的日志中可以注意到其他 VM 的源 IP 地址,以便策略可以允许/阻止
  • 我的建议是在服务网格边缘设置 AuthorizationPolicy 用于外部流量 - 这是 istio 入口网关,这就是为什么我的 AuthorizationPolicy 使用“选择器”匹配标签 app: ingress-istio-ingressgateway(不是 kiali )
  • use a proper type of IPs - ipBlocks vs remoteIpBlocks。根据您的设置,它应该是ipBlocks

何时使用ipBlocks vs. remoteIpBlocks如果您使用 X-Forwarded-For HTTP 标头或代理协议来确定原始客户端 IP 地址,那么您应该使用remoteIpBlocks 在您的 AuthorizationPolicy 中。如果您使用的是externalTrafficPolicy: Local,那么您应该在您的AuthorizationPolicy 中使用ipBlocks

【讨论】:

  • 非常感谢您的解决方案。正如您所说,关键修改是将选择器更改为 istio-ingressgateway 。我将把我的最终 YAML 作为解决方案放在这里。
【解决方案2】:

正如@mikolaj-s 所述,解决方案是将选择器更改为 istio-ingressgateway。我试图使用选择器 kiali,因为这是我在其他命名空间中用于其他工作负载的方式。即使应用标签配置完美:

> kubectl get services -l app=kiali -A
NAMESPACE      NAME    TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)              AGE
istio-system   kiali   ClusterIP   10.97.200.171   <none>        20001/TCP,9090/TCP   13d
> kubectl get pods -l app=kiali -A    
NAMESPACE      NAME                     READY   STATUS    RESTARTS   AGE
istio-system   kiali-6fbbc6d8c9-rctjh   1/1     Running   0          47h

我还更改了逻辑以使用操作“DENY”、来源“notIpBlocks”并指定主机名。

有效的最终授权策略是:

apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: kiali-ingress-policy-allow
  namespace: istio-system
spec:
  action: DENY
  rules:
    - from:
        - source:
            notIpBlocks: ["10.43.212.247/32","10.43.212.242/32"]
      to:
        - operation:
            hosts:
              - kiali.myinternaldomain.local
  selector:
    matchLabels:
      app: istio-ingressgateway

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-03-10
    • 2020-07-25
    • 2023-03-05
    • 2016-11-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-09
    相关资源
    最近更新 更多