安全 - 启用每服务双向认证

优质
小牛编辑
133浏览
2023-12-01

在安装指南中,我们展示了如何启用边车之间的双向TLS认证。 这些设置将应用于网格中的所有边车。

在本教程中,您将学习:

  • 注解Kubernetes服务以禁用(或启用)一个选定服务的双向TLS身份验证。
  • 修改Istio网格配置以解除控制服务的相互TLS身份验证。

在开始前

  • 了解Isio双向TLS认证的概念。

  • 熟悉验证Istio双向TLS认证。

  • 参考安装指南中的说明,通过双向TLS认证安装Istio。

  • 使用Istio边车启动httpbin Demo。 同样为了验证目的,启动两个休眠的实例:一个有边车,一个没有(在不同的命名空间)。 以下是帮助您启动这些服务的命令:

  1. kubectl apply -f <(istioctl kube-inject -f samples/httpbin/httpbin.yaml)
  2. kubectl apply -f <(istioctl kube-inject -f samples/sleep/sleep.yaml)
  3. kubectl create ns legacy && kubectl apply -f samples/sleep/sleep.yaml -n legacy

在这个初始设置中,我们期望默认命名空间中的休眠实例可以与httpbin服务进行通信,但是传统命名空间中的休眠实例不能,因为它没有边车来使能mTLS。

  1. kubectl exec $(kubectl get pod -l app=sleep -o jsonpath={.items..metadata.name}) -c sleep -- curl http://httpbin.default:8000/ip -s
  1. {
  2. "origin": "127.0.0.1"
  3. }
  1. kubectl exec $(kubectl get pod -l app=sleep -o jsonpath={.items..metadata.name} -n legacy) -n legacy -- curl http://httpbin.default:8000/ip -s
  1. command terminated with exit code 56

禁用“httpbin”服务的相互TLS身份验证

如果我们希望在不更改网格验证设置下禁用httpbin(在端口8000上)的mTLS,我们可以通过将此注释添加到httpbin服务定义来实现。

  1. annotations:
  2. auth.istio.io/8000: NONE

要进行快速验证,运行kubectl edit svc httpbin并添加上面的注解(或者编辑原始的httpbin.yaml文件并重新应用它)。 应用更改之后,由于mTLS已被删除sleep.legacy的请求现在应该是成功的。

注意:
注解可以用于相反的方向,例如:对单个服务启用mTLS,只需使用注解值MUTUAL_TLS而非NONE。 人们可以使用此选项在选定的服务上启用mTLS,而不是在整个网格中启用它。

注解也可以用于没有边车的(服务端)服务,以指示Istio在对该服务进行调用时不为客户端应用mTLS。 事实上如果一个系统有一些服务不由Istio管理(即没有边车),这是一个推荐的解决方案,以解决与这些服务的通信问题。

禁用控制服务的相互TLS身份验证

由于不能在Istio 0.3中注解控制服务,例如:API服务器。所以在网格配置中引入mtls_excluded_services来指定不应使用mTLS的服务列表。 如果你的应用程序需要与任何控制服务通信,则应在其中列出其完全限定域名(FQDN)。

作为Demo的一部分,我们将展示该字段的影响。

默认情况下(0.3或更高版本),该列表包含kubernetes.default.svc.cluster.local(这是通用设置中的API服务器服务的名称)。 你可以通过运行以下命令来验证:

  1. kubectl get configmap -n istio-system istio -o yaml | grep mtlsExcludedServices
  1. mtlsExcludedServices: ["kubernetes.default.svc.cluster.local"]

然后预计请求kubernetes.default服务应该是可能的:

  1. kubectl exec $(kubectl get pod -l app=sleep -o jsonpath={.items..metadata.name}) -c sleep -- curl https://kubernetes.default:443/api/ -k -s
  1. {
  2. "kind": "APIVersions",
  3. "versions": [
  4. "v1"
  5. ],
  6. "serverAddressByClientCIDRs": [
  7. {
  8. "clientCIDR": "0.0.0.0/0",
  9. "serverAddress": "104.199.122.14"
  10. }
  11. ]
  12. }

现在运行kubectl edit configmap istio -n istio-system并清除mtlsExcludedServices,在完成后重新启动pilot:

  1. kubectl get pod $(kubectl get pod -l istio=pilot -n istio-system -o jsonpath={.items..metadata.name}) -n istio-system -o yaml | kubectl replace --force -f -

上面相同的测试请求现在失败了(失败码为35),这是由于休眠的边车再次开启了mTLS:

  1. kubectl exec $(kubectl get pod -l app=sleep -o jsonpath={.items..metadata.name}) -c sleep -- curl https://kubernetes.default:443/api/ -k -s
  1. command terminated with exit code 35