【问题标题】:How to whitelist egress traffic with a NetworkPolicy that doesn't prevent Apache Ignite from starting up?如何使用不阻止 Apache Ignite 启动的 NetworkPolicy 将出口流量列入白名单?
【发布时间】:2021-11-16 16:37:59
【问题描述】:

我有一些或多或少复杂的微服务架构,其中 Apache Ignite 用作无状态数据库/缓存。 Ignite Pod 是其Namespace 中唯一的Pod,并且架构必须通过安全审核,如果我不对egress 流量应用最严格的NetworkPolicy,它将无法通过.它必须限制 Ignite 本身不需要的所有可能的流量。

起初,我想:很好,Ignite 不会向其他 Pods 推送任何流量(Namespace 中没有其他 pod),所以这很容易做到限制所有 @987654329 @Namespace 中的流量,其中 Ignite 是唯一的 Pod ...

好吧,实际上效果并不好:
任何 egress 规则,即使我允许流量到 Ignite 文档中提到的所有端口,也会导致启动失败并显示 IgniteSpiException,上面写着 无法检索 Ignite pod IP 地址,@ 987654334@.

问题似乎出在TcpDiscoveryKubernetsIpFinder,尤其是getRegisteredAddresses(...) 方法,它显然在Namespace 内部进行了一些出口流量,以注册Ignite 节点的IP 地址。发现端口 47500 当然是允许的,但这并不会改变情况。 Ignite 与来自其他Namespaces 的其他Pods 的功能在没有应用egress 规则的情况下工作,这意味着(对我而言)关于ClusterRoleClusterRoleBindingService 的配置在Namespace 和 Ignite 本身的 xml 配置等似乎是正确的。甚至限制来自其他命名空间的流量的 ingress 规则也按预期工作,完全允许所需的流量。

这些是我应用的政策:

[工作中,仅阻止不需要的流量]

## Denies all Ingress traffic to all Pods in the Namespace
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: deny-all-ingress-in-cache-ns
  namespace: cache-ns
spec:
  # selecting nothing here will deny all traffic between pods in the namespace
  podSelector:
    matchLabels: {}
  # traffic routes to be considered, here: incoming exclusively
  policyTypes:
    - Ingress
## Allows necessary ingress traffic
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: netpol-cache-ns
  namespace: cache-ns
# defines the pod(s) that this policy is targeting
spec:
  policyTypes:
    - Ingress
  podSelector:
    matchLabels:
      app: ignite
  # <----incoming traffic----
  ingress:
    - from:
      - namespaceSelector:
          matchLabels:
            zone: somewhere-else
        podSelector:
          matchExpressions:
            - key: app
              operator: In
              values: [some-pod, another-pod]  # dummy names, these Pods don't matter at all
      ports:
        - port: 11211   # JDBC
          protocol: TCP
        - port: 47100   # SPI communication
          protocol: TCP
        - port: 47500   # SPI discovery (CRITICAL, most likely...)
          protocol: TCP
        - port: 10800   # SQL
          protocol: TCP
# ----outgoing traffic---->
# NONE AT ALL

应用这两个,一切正常,但安全审计会说类似
egress 的限制在哪里?如果这个节点因为使用这些路由的 Pod 之前被黑客入侵而通过允许的路由被黑客入侵怎么办?然后它可能会调用 C&C 服务器!不允许这种配置,强化你的架构!

[阻止所需/必要的流量]

一般拒绝所有流量...

## Denies all traffic to all Pods in the Namespace
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: deny-all-traffic-in-cache-ns
  namespace: cache-ns
spec:
  # selecting nothing here will deny all traffic between pods in the namespace
  podSelector:
    matchLabels: {}
  # traffic routes to be considered, here: incoming exclusively
  policyTypes:
    - Ingress
    - Egress   # <------ THIS IS THE DIFFERENCE TO THE WORKING ONE ABOVE

...然后允许特定路线

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: netpol-cache-ns-egress
  namespace: cache-ns
# defines the pod(s) that this policy is targeting
spec:
  policyTypes:
    - Egress
  podSelector:
    matchLabels:
      app: ignite
  ----outgoing traffic---->
  egress:
    # [NOT SUFFICIENT]
    # allow egress to this namespace at specific ports
    - to:
      - namespaceSelector:
          matchLabels:
            zone: cache-zone
      ports:
        - protocol: TCP
          port: 10800
        - protocol: TCP
          port: 47100   # SPI communication
        - protocol: TCP
          port: 47500
    # [NOT SUFFICIENT]
    # allow dns resolution in general (no namespace or pod restriction)
    - ports:
      - protocol: TCP
        port: 53
      - protocol: UDP
        port: 53
    # [NOT SUFFICIENT]
    # allow egress to the kube-system (label is present!)
    - to:
      - namespaceSelector:
          matchLabels:
            zone: kube-system
    # [NOT SUFFICIENT]
    # allow egress in this namespace and for the ignite pod
    - to:
      - namespaceSelector:
          matchLabels:
            zone: cache-zone
        podSelector:
          matchLabels:
            app: ignite
    # [NOT SUFFICIENT]
    # allow traffic to the IP address of the ignite pod
    - to:
      - ipBlock:
          cidr: 172.21.70.49/32  # won't work well since those addresses are dynamic
      ports:
        - port: 11211   # JDBC
          protocol: TCP
        - port: 47100   # SPI communication
          protocol: TCP
        - port: 47500   # SPI discovery (CRITICAL, most likely...)
          protocol: TCP
        - port: 49112   # JMX
          protocol: TCP
        - port: 10800   # SQL
          protocol: TCP
        - port: 8080    # REST
          protocol: TCP
        - port: 10900   # thin clients
          protocol: TCP

使用的 Apache Ignite 版本是 2.10.0

现在给所有读者的问题是:

如何将Egress 限制在Namespace 内的绝对最小值,以便Ignite 启动并正常工作?将Egress 拒绝到集群外部就足够了吗?

如果您需要更多 yamls 来获得有根据的猜测或提示,请随时在评论中提出请求。

更新:

从 ignite pod 内部执行 nslookup -debug kubernetes.default.svc.cluster.local 而不显示任何限制 egress 的策略

BusyBox v1.29.3 (2019-01-24 07:45:07 UTC) multi-call binary.

Usage: nslookup HOST [DNS_SERVER]

Query DNS about HOST

一旦应用(任何)NetworkPolicyEgress 限制为特定端口、pod 和命名空间,Ignite pod 就会拒绝启动并且查找不再到达 kubernetes.default.svc.cluster.local

Egress 到 DNS 被允许(UDP 53 到 k8s-app:kube-dns)⇒ 仍然无法进行 ip 查找

另一个更新

启用记录器的调试模式后,我可以找到一些有趣的消息:

  1. 关于(唯一)节点有 2 个 IP 地址的消息(不知道这是否会导致问题,但我什至不知道如何只给节点一个 IP 地址):
2021-09-30 13:39:46,081 DEBUG [org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi] - <This node 6f1c5f37-b1a6-4b05-a407-07aad6a9c725 has 2 TCP addresses. Note that TcpDiscoverySpi.failureDetectionTimeout works per address sequentially. Setting of several addresses can prolong detection of current node failure.>

此消息显示有限制出口和没有,所以它可能不是这个特定问题的原因,仍然以某种方式困扰着我。

  1. 一条消息表明已注册丢失的 IP 地址(没有出口限制,每个出口都允许):
2021-09-30 13:40:46,982 DEBUG [org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi] - <Registered missing addresses in IP finder: [/127.0.0.1:47500]>

这里我想知道 localhost / 127.0.0.1 IP 地址,为什么在没有出口限制的情况下可以访问但在应用出口限制时无法访问?

【问题讨论】:

    标签: security kubernetes microservices ignite kubernetes-networkpolicy


    【解决方案1】:

    Ignite 无法将 kubernetes.default.svc.cluster.local 解析为 IP。

    【讨论】:

    • 感谢您的建议,我会尽快尝试!
    • 不幸的是,这并没有改变这种情况。此注释是否必须具有 default 值,或者我是否必须根据我的环境提供不同的标签?
    • 更新:在这里应用正确的命名空间名称并没有改变任何东西,但是集群必须更新到 1.21,这导致现在需要一些等待时间......可能之后它会工作,我会在这里持续更新。
    • 这个想法是允许出口到命名空间default 中的kubernetes 服务。您需要启用 1.21 版集群 NamespaceDefaultLabelName 功能门,以便此策略可以开箱即用。否则,您将需要手动标记 default 命名空间,以便 matchLabels 可以工作。
    • 嗨@WytrzymałyWiktor 还没有,谢谢你的提问。我已经设置了一个测试命名空间,我可以在其中拒绝所有出口,并为 pod 启用到 53/UPD 上的 kube-system 的单个路由。该 pod 可以达到 dns 分辨率。只要有时间,我也会尝试为 ignite pod 配置该配置。之后我将用结果更新这篇文章。我之前可能错过了这个特殊的NetworkPolicy...
    猜你喜欢
    • 2018-11-21
    • 2021-04-07
    • 1970-01-01
    • 2021-08-04
    • 2015-01-04
    • 2021-12-21
    • 2021-05-31
    • 1970-01-01
    • 2020-02-01
    相关资源
    最近更新 更多