【发布时间】: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 规则的情况下工作,这意味着(对我而言)关于ClusterRole、ClusterRoleBinding、Service 的配置在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
一旦应用(任何)NetworkPolicy 将 Egress 限制为特定端口、pod 和命名空间,Ignite pod 就会拒绝启动并且查找不再到达 kubernetes.default.svc.cluster.local。
Egress 到 DNS 被允许(UDP 53 到 k8s-app:kube-dns)⇒ 仍然无法进行 ip 查找
另一个更新
启用记录器的调试模式后,我可以找到一些有趣的消息:
- 关于(唯一)节点有 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.>
此消息显示有限制出口和没有,所以它可能不是这个特定问题的原因,仍然以某种方式困扰着我。
- 一条消息表明已注册丢失的 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