diff --git a/content_zh/docs/tasks/traffic-management/egress-tls-origination/index.md b/content_zh/docs/tasks/traffic-management/egress-tls-origination/index.md new file mode 100644 index 0000000000..9f171f991e --- /dev/null +++ b/content_zh/docs/tasks/traffic-management/egress-tls-origination/index.md @@ -0,0 +1,194 @@ +--- +title: 出口流量的 TLS +description: 此任务描述 Istio 如何配置出口流量的 TLS +weight: 42 +--- + +> 注意:此任务使用新的 [v1alpha3 流量管理 API](/blog/2018/v1alpha3-routing/)。旧的 API 已被弃用,将在下一个 Istio 版本中删除。如果您需要使用旧版本,请按照[此处](https://archive.istio.io/v0.7/docs/tasks/traffic-management/)的文档操作。 + +[控制出口流量](/docs/tasks/traffic-management/egress/)任务演示了如何从网格内部的应用程序访问 Kubernetes 集群外部的 HTTP 和 HTTPS 服务, 如该主题中所述,默认情况下,启用了 Istio 的应用程序无法访问群集外的 URL, 要启用外部访问,必须定义外部服务的[`ServiceEntry`](/docs/reference/config/istio.networking.v1alpha3/#ServiceEntry),或者[直接访问外部服务](/docs/tasks/traffic-management/egress/#calling-external-services-directly)。 + +此任务描述 Istio 如何配置出口流量的 TLS。 + +## 用例 + +考虑一个对外部站点执行 HTTP 调用的遗留应用程序, 假设运行应用程序的组织收到一个新要求,该要求规定必须加密所有外部流量, 使用 Istio,只需通过配置就可以实现这样的要求,而无需更改应用程序的代码。 + +在此任务中,如果原始流量为 HTTP,则将 Istio 配置为打开与外部服务的 HTTPS 连接, 应用程序将像以前一样发送未加密的 HTTP 请求,Istio 将加密应用程序的请求。 + +## 前提条件 + +* 按照[安装指南](/docs/setup/)中的说明设置 Istio 。 + +* 启动 [sleep]({{< github_tree >}}/samples/sleep) 示例,它将作为外部调用的测试源。 + + 如果您已启用[自动注入 sidecar](/docs/setup/kubernetes/sidecar-injection/#automatic-sidecar-injection), 请按如下命令部署 `sleep` 应用程序: + + {{< text bash >}} + $ kubectl apply -f @samples/sleep/sleep.yaml@ + {{< /text >}} + + 否则,您必须在部署 `sleep` 应用程序之前手动注入 sidecar: + + {{< text bash >}} + $ kubectl apply -f <(istioctl kube-inject -f @samples/sleep/sleep.yaml@) + {{< /text >}} + + 请注意,任何可以 `exec` 和 `curl` 的 pod 都可以执行以下步骤。 + +* 创建一个 shell 变量来保存源 pod 的名称,以便将请求发送到外部服务, 如果您使用 [sleep]({{< github_tree >}}/samples/sleep) 示例,请按如下命令运行: + + {{< text bash >}} + $ export SOURCE_POD=$(kubectl get pod -l app=sleep -o jsonpath={.items..metadata.name}) + {{< /text >}} + +## 配置 HTTP 和 HTTPS 外部服务 + +首先,与[控制出口流量](/docs/tasks/traffic-management/egress/)任务相同的方式配置对 _cnn.com_ 的访问。 +请注意,在 `hosts` 中定义中使用 `*` 通配符:`*.cnn.com` , 使用通配符可以访问 _www.cnn.com_ 以及 _edition.cnn.com_ 。 + +1. 创建一个 `ServiceEntry` 以允许访问外部 HTTP 和 HTTPS 服务: + + {{< text bash >}} + $ cat <}} + +1. 向外部 HTTP 服务发出请求: + + {{< text bash >}} + $ kubectl exec -it $SOURCE_POD -c sleep -- curl -sL -o /dev/null -D - http://edition.cnn.com/politics + HTTP/1.1 301 Moved Permanently + ... + location: https://edition.cnn.com/politics + ... + + HTTP/1.1 200 OK + Content-Type: text/html; charset=utf-8 + ... + Content-Length: 151654 + ... + {{< /text >}} + + 输出应该与上面的类似(一些细节用省略号代替)。 + +注意 _curl_ 的 `-L` 标志,它指示 _curl_ 遵循重定向, 在这种情况下, +服务器返回一个重定向响应([301 Moved Permanently](https://tools.ietf.org/html/rfc2616#section-10.3.2))到 `http://edition.cnn.com/politics` 的 HTTP 请求, 重定向响应指示客户端通过 HTTPS 向 `https://edition.cnn.com/politics` 发送附加请求, 对于第二个请求,服务器返回所请求的内容和 _200 OK_ 状态代码。 + +而对于 _curl_ 命令,这种重定向是透明的,这里有两个问题, 第一个问题是冗余的第一个请求,它使获取 `http://edition.cnn.com/politics` 内容的延迟加倍, 第二个问题是 URL 的路径,在这种情况下是 _politics_ ,以明文形式发送, 如果有攻击者嗅探您的应用程序与 _cnn.com_ 之间的通信,则攻击者会知道您的应用程序获取的 _cnn.com_ 的哪些特定主题和文章, 出于隐私原因,您可能希望阻止攻击者披露此类信息。 + +在下一节中,您将配置 Istio 以执行 TLS 以解决这两个问题, 在继续下一部分之前清理配置: + +{{< text bash >}} +$ istioctl delete serviceentry cnn +{{< /text >}} + +## 出口流量的 TLS + +1. 定义一个 `ServiceEntry` 以允许流量到 _edition.cnn.com_ ,一个 `VirtualService` 来执行请求端口重写,一个 `DestinationRule` 用于 TLS 发起。 + + 与上一节中的 `ServiceEntry` 不同,这里使用 HTTP 作为端口 433 上的协议,因为客户端将发送 HTTP 请求,而 Istio 将为它们执行 TLS 发起, 此外,在此示例中,必须将分辨率设置为 DNS 才能正确配置 Envoy。 + + 最后,请注意 `VirtualService` 使用特定的主机 _edition.cnn.com_ (没有通配符),因为 Envoy 代理需要确切地知道使用 HTTPS 访问哪个主机: + + {{< text bash >}} + $ cat <}} + +1. 发送 HTTP 请求到 `http://edition.cnn.com/politics` ,如上一节所述: + + {{< text bash >}} + $ kubectl exec -it $SOURCE_POD -c sleep -- curl -sL -o /dev/null -D - http://edition.cnn.com/politics + HTTP/1.1 200 OK + Content-Type: text/html; charset=utf-8 + ... + Content-Length: 151654 + ... + {{< /text >}} + + 这次你收到 _200 OK_ , Istio 为 _curl_ 执行了 TLS 发起,因此原始 HTTP 请求作为 HTTPS 转发到 _cnn.com_ , _cnn.com_ 服务器直接返回内容,无需重定向, 您消除了客户端和服务器之间的双重往返,并且请求使网格加密,而没有透露应用程序获取 _cnn.com_ 的 _politics_ 部分这一事实。 + + 请注意,您使用的命令与上一节中的命令相同, 对于以编程方式访问外部服务的应用程序,代码不会更改, 因此,您可以通过配置 Istio 来获得 TLS 的好处,而无需更改代码行。 + +## 其他安全因素 + +请注意,应用程序 `pid` 与本地主机上的 `sidecar` 之间的流量仍未加密, 这意味着如果攻击者能够穿透应用程序的节点,他们仍然可以在节点的本地网络上看到未加密的通信, 在某些环境中,可能存在严格的安全要求,即必须加密所有流量,即使在节点的本地网络上也是如此, 如果有这么严格的要求,应用程序应该只使用 HTTPS(TLS),此任务中描述的 TLS 是不够的。 + +另请注意,即使对于应用程序发起的 HTTPS ,攻击者也可以通过检查[服务器名称指示(SNI)](https://en.wikipedia.org/wiki/Server_Name_Indication)来了解对 _cnn.com_ 的请求, ), 在 TLS 握手期间,未加密地发送 _SNI_ 字段, 使用 HTTPS 可防止攻击者了解特定主题和文章,但这并不能阻止攻击者了解 _cnn.com_ 被访问。 + +## 清理 + +1. 删除您创建的 Istio 配置项: + + {{< text bash >}} + $ istioctl delete serviceentry cnn + $ istioctl delete virtualservice rewrite-port-for-edition-cnn-com + $ istioctl delete destinationrule originate-tls-for-edition-cnn-com + {{< /text >}} + +1. 关闭 [sleep]({{< github_tree >}}/samples/sleep) 服务: + + {{< text bash >}} + $ kubectl delete -f @samples/sleep/sleep.yaml@ + {{< /text >}}