[Istio] 锁好家门 🚪: 全面阻止与允许外部流量 (ALLOW_ANY vs REGISTRY_ONLY)

大家好!今天,我将深入探讨在引入Istio时,安全方面首先需要考虑的“Egress(出站)流量控制”。

如果Kubernetes Pod中偷偷潜入的恶意代码将数据传输到外部黑客服务器,会发生什么?😱 光是想象就令人毛骨悚然。Istio只需进行非常简单的配置更改,就可以从源头上阻止这种“数据泄露”的尝试。

让我们一起了解默认设置(ALLOW_ANY)和安全设置(REGISTRY_ONLY)之间的区别,以及实际的配置方法!🚀


1. Istio的默认行为:“门是敞开的?” 🔓

如果安装了Istio的Pod向外部互联网(例如:google.com, api.slack.com)发送请求,会发生什么?

如果没有进行特殊设置,默认情况下通信是成功的。

  • 设置值: outboundTrafficPolicy.mode = ALLOW_ANY
  • 行为: 边车代理(Envoy)在收到发往未知目的地(服务注册表中没有的地址)的请求时,会“直接通过(Passthrough)”。
  • 优点: 开发时很方便。可以随意调用外部API。
  • 缺点: 安全性脆弱。无法阻止被入侵的Pod与外部C&C服务器(攻击者服务器)通信。

2. 强化安全:“只允许去注册过的地方!” 🛡️

在安全性至关重要的生产环境(Production)中,应采用白名单(Whitelist)方式。也就是说,声明“除了我允许的地方,哪里都不能去!”

  • 设置值: outboundTrafficPolicy.mode = REGISTRY_ONLY
  • 行为: 边车代理会检查请求目的地。如果目的地在Istio的内部服务注册表(Service Registry)中注册,则允许发送;否则,毫不留情地阻止。
  • 优点: 防止数据泄露,提供强大的出站安全。
  • 缺点: 每次需要外部通信时,都必须手动注册ServiceEntry,这会带来不便。

3. 实践:应用安全策略 👨‍💻

我们将直接使用istioctl来更改整个集群的出站策略。

Step 1: 检查当前状态 (ALLOW_ANY)

目前是默认设置状态。让我们尝试从测试Pod(tester)连接到外部服务httpbin.org。

kubectl exec tester -- 
    curl -sS -o /dev/null -D - http://httpbin.org/status/200 | 
    grep "HTTP/"

# 结果: HTTP/1.1 200 OK (成功!)

外部通信没有任何限制,运行良好。

Step 2: 更改策略 (切换到REGISTRY_ONLY) 🔥

现在,使用istioctl install命令更改全局设置。修改meshConfig以阻止未知流量。

istioctl install --set profile=demo 
    -y --manifests=/root/istio-${ISTIO_VERSION}/manifests 
    --set meshConfig.outboundTrafficPolicy.mode=REGISTRY_ONLY
  • –set meshConfig.outboundTrafficPolicy.mode=REGISTRY_ONLY: 这个选项是关键!

Step 3: 验证阻止 🚫

等待几秒钟,直到设置生效,然后再次尝试相同的连接。

Bash

kubectl exec tester -- 
    curl -sS -o /dev/null -D - http://httpbin.org/status/200 | 
    grep "HTTP/"

结果:

curl: (56) Recv failure: Connection reset by peer
command terminated with exit code 56

看到了吗?不是200 OK,而是出现了Connection reset by peer错误。这并不是网络断开,而是Istio边车代理强制中断了连接(TCP Reset),因为它说:“嘿,你正试图访问一个未注册的地方?不行!”


4. 那么,现在如何进行外部通信呢? 🤔

“如果Naver和Google都无法访问,我们的服务该怎么办?”

别担心!在REGISTRY_ONLY模式下,我们可以通过一个名为ServiceEntry的资源,告诉Istio我们需要的外部目的地是“值得信任的地方”。

apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
  name: external-httpbin
spec:
  hosts:
  - httpbin.org  # 注册允许的外部域名
  ports:
  - number: 80
    name: http
    protocol: HTTP

这样注册后,httpbin.org就变成了“已知站点”,可以再次访问。这正是零信任安全的真正开始!


🏁 总结

是为了方便而使用ALLOW_ANY,还是为了安全而使用REGISTRY_ONLY并承担管理成本?

答案取决于您的环境,但请记住,安全事故不期而至。即使有点麻烦,使用REGISTRY_ONLY和ServiceEntry的组合是构建安全集群的捷径。🛣️

今天的实践辛苦了!下次我将带来更多关于ServiceEntry处理方法的详细内容。再见!👋



Comments

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注