5

迈向istio-7 tls

 2 years ago
source link: https://tangxusc.github.io/2019/04/%E8%BF%88%E5%90%91istio-7-tls/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

迈向istio-7 tls

April 1, 2019

in istio

我们已经完成了我们服务的路由,并且也已经有了镜像流量了,那么接下来我们要做什么呢?

安全-所有应用都离不开的话题,在微服务中也一样会存在安全问题,特别是在一个企业的微服务系统中,各服务对外的接口安全都做的很好,但是服务间的安全等问题很多企业都做的不够好.这里我给大家一个例子:

企业x有一个混合云集群,node节点分别位于 某云服务器提供商和本地机房这两个地方,并且部署了两个服务,其中存在不少敏感信息,我们用一个表单来说明这样的情况:

某云 本地
服务A local-node1
服务B cloud-node2

这个时候,我们发现,服务A调用服务B实际上是一次跨云之旅,但是这个跨云之旅中途会出现以下几个安全问题:

  • 中途被劫道(劫持)
  • 到目标服务的可能是间谍(请求被修改,替换)

那么,我们如何应对这样的情况呢?

在istio的安全章节中 我找到了一个应对此问题的答案,各位请跟我来,我指给各位看istio-安全

好了,大幕拉开,表演开始.

%E6%9C%8D%E5%8A%A1%E5%9B%BE.png

target配置

#记得开启自动注入
#kubectl label namespace test istio-injection=enabled
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
 name: target
 namespace: test
 labels:
   app: target
   version: v1
spec:
 template:
    metadata:
     labels:
       app: target
       version: v1
    spec:
     containers:
     - name: target
       image: service-proxy:go-1
       ports:
       - containerPort: 8090
         name: http
         protocol: TCP
---
kind: Service
apiVersion: v1
metadata:
  name: target
  namespace: test
spec:
  selector:
    app: target
  ports:
    - port: 80
      name: http #一定注意命名
      protocol: TCP
      targetPort: 8090

在k8s中部署服务

$ kubectl create ns test
$ kubectl label namespace test istio-injection=enabled
$ kubectl apply -f k8s.yaml -n test
$ curl 服务地址/index -v
#返回 index

这是一个很平常的服务,我们将对此服务流量进行tls加密,来防止被劫道和间谍行为.

路由及tls配置

apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: target
  namespace: test
spec:
  selector:
    istio: ingressgateway
  servers:
  - port:
      number: 80
      name: http
      protocol: HTTP
    hosts:
    - "*"
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: target
  namespace: test
spec:
  hosts:
  - "*"
  gateways:
  - target
  http:
  - match:
    - uri:
        prefix: /target/
    rewrite:
      uri: "/"
    route:
    - destination:
       host: target
       subset: v1
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: target
  namespace: test
spec:
  host: target
  subsets:
  - name: v1
    labels:
      app: target
      version: v1
  trafficPolicy:
    tls:
      mode: ISTIO_MUTUAL
---
apiVersion: "authentication.istio.io/v1alpha1"
kind: "Policy"
metadata:
  name: "default"
  namespace: "test"
spec:
  peers:
  - mtls: {}
#---
#apiVersion: "authentication.istio.io/v1alpha1"
#kind: "MeshPolicy"
#metadata:
#  name: "default"
#spec:
#  peers:
#  - mtls: {}

在istio中部署此配置

$ kubectl apply -f istio.yaml -n test
#现在我们通过gateway访问target 这个服务
$ curl 网关地址/target/index
#返回index
#那我们再使用`服务地址`来访问呢
$ curl 服务地址/index
curl: (56) Recv failure: 连接被对方重设

可以看到,现在我们访问istio,居然是连接被对方重设,不再是以前的直接返回结果了;

那么发生了什么呢?

tls

我们可以将target这个服务视作 service A

我们使用kubectl apply -f istio.yaml的时候,其实配置是将这些crd(第三方资源)存储到了kubernetes中,pilot,citadel监听到这些文件的创建后,pilot下发tls配置,citadel生成相应的证书下发到具体的sidecar中.

整个通信过程就很简单了,我们使用http流量到达 ingress gateway 再转发到 Service A对应的proxy,此时proxy会根据下发的配置来对此请求进行证书的校验,不通过的 就直接拒绝这个连接,通过的再转发到Service A进行请求处理.

Policy/MeshPolicy

那么看过配置文件的就会问了,那这个Policy 和 MeshPolicy有什么区别呢,或者说最佳实践是什么呢?

Policy:只作用于该规则namespace的策略,也就是说,这个策略只能在一个namespace中生效

MeshPolicy:显然 这个是针对所有namespace的,但是这个MeshPolicy的name只能是default,并且没有target属性

ingress-Gateway tls

那么我们设置Ingress-gateway的tls呢?

apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: my-gateway
spec:
  selector:
    app: ingressgateway
  servers:
  - port:
      number: 80
      name: http
      protocol: HTTP
    hosts:
    - "*"
    tls:
      httpsRedirect: true # 用 301 重定向指令响应 http 协议的请求。
  - port:
      number: 443
      name: https
      protocol: HTTPS
    hosts:
    - "*"
    tls:
      mode: SIMPLE # 在这一端口开放 https 服务
      serverCertificate: /etc/certs/servercert.pem
      privateKey: /etc/certs/privatekey.pem

请一定注意,ingress-gateway是对外的服务,那么此处要求的证书一定是对外的,并且经过正确签名的证书才不会出错.

  • MeshPolicy/Policy 在name为default时,都不能设置target属性
  • 使用服务间的tls时,在消费端(DestinationRule)需要配置对请求进行tls加密
  • 在服务端(Service)需要配置Policy来指定服务端对流量进行进行校验
$ kubectl delete namespace/test

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK