TLS Origination for Egress Traffic(0.8)

Control Egress Traffic task 演示了在服务网格内的应用如何访问外部(k8s集群外)的HTTP和HTTPS服务。快速提醒:默认情况下,启用Istio的应用不能访问集群外部的URL。为了启用这种访问,必须定义 ServiceEntry ,或者必须经过配置 direct access to external services (直接访问外部服务)。
这个task描述了如何针对Istio服务网格内的应用配置Istio来暴露外部TCP服务。

Use case

考虑执行对外部站点的HTTP调用的遗留应用。假设运行该应用程序的组织接收到一个新的要求,它声明所有的外部流量都必须加密。借助Istio,只需通过配置即可实现此要求,而无需更改应用程序的代码。

在这个task,我们展示如何配置Istio来开启与原始流量为HTTP的外部服务进行HTTPS连接。应用程序将像以前一样发送未加密的HTTP请求,Istio将加密应用程序的请求。

Before you begin

  • 安装Istio
  • 启动 sleep 示例应用,作为外部调用的测试源。

如果你开启了自动注入sidecar,执行

kubectl apply -f samples/sleep/sleep.yaml

samples/sleep/sleep.yaml

否则,你不得不在部署sleep 应用前手动注入sidecar:

kubectl apply -f <(istioctl kube-inject -f samples/sleep/sleep.yaml)

注意: 任何你能 curl 和exec 的pod都可以。

  • 创建一个shell变量来保存将请求发送到外部服务的源pod的名称。如果我们使用sleep例子,我们运行:
export SOURCE_POD=$(kubectl get pod -l app=sleep -o jsonpath={.items..metadata.name})

Configuring HTTP and HTTPS external services

首先,我们用 Control Egress Traffic task中的相同方式配置访问 cnn.com 。注意我们在hosts 定义中使用了通配符**.cnn.com. 使用通配符可以让我们访问 www.cnn.com ,同样也可以访问edition.cnn.com.

1.为允许访问外部HTTP和HTTPS服务创建一个ServiceEntry

cat <<EOF | istioctl create -f -
apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
  name: cnn
spec:
  hosts:
  - "*.cnn.com"
  ports:
  - number: 80
    name: http-port
    protocol: HTTP
  - number: 443
    name: https-port
    protocol: HTTPS
EOF

2.向外部HTTP服务发送一个请求:

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
...

输出应该和上面类似(不重要的细节被省略号代替):

注意 curl-L 标识。它让curl 可以重定向。这种情况下,服务器对一个发送到http://edition.cnn.com/politics 的HTTP请求有一个重定向响应(301 Moved Permanently)。重定向响应命令客户端发送一个额外的请求,这次是到 https://edition.cnn.com/politics 的HTTPS请求。第二次请求,服务端响应请求内容,并返回 200 OK 状态码。

对于curl 使用者来说,这个重定向是透明的,这里就有两个问题。第一个问题是第一个请求多余,这会使获取 http://edition.cnn.com/politics的内容的延迟加倍。第二个问题是,在这种情况下,URL的路径以明文的形式发送。如果有攻击者嗅探我们的应用程序和 cnn.com 之间的通信,攻击者就会知道我们的应用程序获取了哪些具体主题和 cnn.com 的文章。由于隐私原因,我们可能希望阻止攻击者披露这些信息。

下一节,我们将配置Istio 为执行 TLS 创建来解决上述两个问题。让我们在进行下一节前清除我们的配置:

istioctl delete serviceentry cnn

TLS origination for Egress traffic

1.定义一个ServiceEntry 允许访问 edition.cnn.com, 一个VirtualService 执行请求端口覆写,一个DestinationRule 用于TLS创建。
不同于上一节的ServiceEntry ,这里我们在433端口使用HTTP 协议,因为客户端将发起HTTP 请求,而Istio 将为它们执行TLS 创建。此外,在这种情况下,必须将解析度设置为DNS 才能正确配置Envoy 。
最后,注意VirtualService 使用一个特别的 host edition.cnn.com  (没有通配符),因为 Envoy 代理需要正确的知道使用HTTPS到达哪个host:

cat <<EOF | istioctl create -f -
apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
  name: cnn
spec:
  hosts:
  - edition.cnn.com
  ports:
  - number: 80
    name: http-port
    protocol: HTTP
  - number: 443
    name: http-port-for-tls-origination
    protocol: HTTP
  resolution: DNS
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: rewrite-port-for-edition-cnn-com
spec:
  hosts:
  - edition.cnn.com
  http:
  - match:
      - port: 80
    route:
    - destination:
        host: edition.cnn.com
        port:
          number: 443
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: originate-tls-for-edition-cnn-com
spec:
  host: edition.cnn.com
  trafficPolicy:
    loadBalancer:
      simple: ROUND_ROBIN
    portLevelSettings:
    - port:
        number: 443
      tls:
        mode: SIMPLE # initiates HTTPS when accessing edition.cnn.com
EOF

2.像上一节,向http://edition.cnn.com/politics发送一个HTTP 请求。

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
...

这次我们受到第一次也是唯一的回应,200 OK 。Istio为curl 执行了TLS创建,因此原始HTTP请求以HTTPS的形式被转发到cnn.com。cnn.com的服务器直接返回内容,无需重定向。我们避免了在客户端和服务器之间的双向往返,并且请求保留了网格的加密,而没有透露我们的应用获取了cnn.compolitics 部分。

注意,我们在上一节使用了相同的命令。对于以编程方式访问外部服务的应用,代码不会更改。通过配置Istio,我们可以获得TLS创建的好处,无需修改代码,透明地为应用程序提供服务。

Additional security considerations

注意,应用pod和本地主机上的sidecar代理之间的流量仍未加密。这意味着如果攻击者能够穿透我们应用程序的节点,他们仍然能够看到节点本地网络上的未加密通信。在某些环境中,可能存在一个严格的安全要求,即所有通信都必须加密,即使在节点的本地网络上也是如此。有了这样一个严格的要求,应用应该只使用HTTPS(TLS),这个task所描述的TLS创建是不够的。

还请注意,即使对于由应用发起的HTTPS,攻击者也可以通过检查服务器名称指示—— Server Name Indication (SNI)知道正在发送对 cnn.com 的请求。SNI字段在TLS握手期间未加密发送。使用HTTPS可以防止攻击者知道特定的主题和文章,但是并不能防止攻击者知道 cnn.com 被访问。

Cleanup

1.移除我们之前创建的Istio配置记录:

istioctl delete serviceentry cnn
istioctl delete virtualservice rewrite-port-for-edition-cnn-com
istioctl delete destinationrule originate-tls-for-edition-cnn-com

2.关闭sleep服务:

kubectl delete -f samples/sleep/sleep.yaml

猜你喜欢

转载自blog.csdn.net/ybt_c_index/article/details/80737664
TLS