【Istio安全】网格边缘-Egress继续网格边缘的实践ingress-gateway, 分为HTTPHTTPS-不终止TLSHTTPS-种子TLS三种场景。

准备工作

有了Egress的实践,这里不使用httpbin做内部服务,而是用egress-gateway的成果, www.aliyun.comhbchen.com的两个外部服务进行测试。

$ kubectl apply -f - <<EOF
apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
  name: entry-x
spec:
  hosts:
  - www.aliyun.com
  - hbchen.com
  ports:
  - number: 80
    name: http
    protocol: HTTP
  resolution: NONE
EOF

$ kubectl apply -f - <<EOF
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: originate-tls-for-aliyun
spec:
  host: www.aliyun.com
  trafficPolicy:
    loadBalancer:
      simple: ROUND_ROBIN
  subsets:
    - name: originate-tls
      trafficPolicy:
        loadBalancer:
          simple: ROUND_ROBIN
        portLevelSettings:
        - port:
            number: 443
          tls:
            mode: SIMPLE
EOF

环境变量

export INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="http2")].nodePort}')
export SECURE_INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="https")].nodePort}')

export INGRESS_HOST=$(minikube ip)

接下来进入正文

都只需要定义两个.yaml配置:

  • Gateway:ingress-example-gateway
  • VirtualService:ingress-example-svc

Http Gateway

ServiceEntry

官方文档控制 Ingress 流量

kubectl apply -f - <<EOF
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: ingress-example-gateway
spec:
  selector:
    istio: ingressgateway
  servers:
  - port:
      number: 80
      name: http
      protocol: http
    hosts:
    - "hbchen.com"
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: ingress-example-svc
spec:
  hosts:
  - "hbchen.com"
  gateways:
  - ingress-example-gateway
  http:
  - match:
    - port: 80
    route:
    - destination:
        host: hbchen.com
        port:
          number: 80
EOF

访问测试

curl -I -v -HHost:hbchen.com http://$INGRESS_HOST:$INGRESS_PORT

Https Gateway-不终止TLS

ServiceEntry

官方文档没有 TLS 的 Ingress gateway

不终止TLS即透传https请求到网格内服务,这里我们使用一个外部服务来模拟一个支持https的服务

kubectl apply -f - <<EOF
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: ingress-example-gateway
spec:
  selector:
    istio: ingressgateway
  servers:
  - port:
      number: 80
      name: http
      protocol: http
    hosts:
    - "www.aliyun.com"
  - port:
      number: 443
      name: https
      protocol: HTTPS
    tls:
      mode: PASSTHROUGH
    hosts:
    - "www.aliyun.com"
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: ingress-example-svc
spec:
  hosts:
  - "www.aliyun.com"
  gateways:
  - ingress-example-gateway
  http:
  - match:
    - port: 80
    route:
    - destination:
        host: www.aliyun.com
        subset: originate-tls
        port:
          number: 443
  tls:
  - match:
    - port: 443
      sni_hosts:
      - www.aliyun.com
    route:
    - destination:
        host: www.aliyun.com
        port:
          number: 443
EOF

访问测试

curl -I -v -HHost:www.aliyun.com http://$INGRESS_HOST:$INGRESS_PORT
curl -I -v --resolve www.aliyun.com:$SECURE_INGRESS_PORT:$INGRESS_HOST https://www.aliyun.com:$SECURE_INGRESS_PORT

Https Gateway-终止TLS

ServiceEntry

官方文档使用 SDS 为 Gateway 提供 HTTPS 加密支持

终止TLS即由ingress-gateway提供https服务,更符合ingress-gateway作为网格统一入口的需求

启用SDS

SDS默认是关闭的,所以首先需要开启ingress-gatewaySDS

$ cd istio/path 

# 生成.yaml
$ helm template install/kubernetes/helm/istio/ --name istio \
--namespace istio-system -x charts/gateways/templates/deployment.yaml \
--set gateways.istio-egressgateway.enabled=false \
--set gateways.istio-ingressgateway.sds.enabled=true > \
$HOME/istio-ingressgateway.yaml

# 重新部署
$ kubectl apply -f $HOME/istio-ingressgateway.yaml

生成证书

$ git clone https://github.com/nicholasjackson/mtls-go-example

$ cd mtls-go-example
$ ./generate.sh hbchen.com 123456

$ mkdir ./../hbchen.com && mv 1_root 2_intermediate 3_application 4_client ./../hbchen.com
$ cd ..

创建Secret

$ kubectl create -n istio-system secret generic hbchen-credential \
--from-file=key=hbchen.com/3_application/private/hbchen.com.key.pem \
--from-file=cert=hbchen.com/3_application/certs/hbchen.com.cert.pem
kubectl apply -f - <<EOF
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: ingress-example-gateway
spec:
  selector:
    istio: ingressgateway
  servers:
  - port:
      number: 443
      name: https
      protocol: HTTPS
    tls:
      mode: SIMPLE
      credentialName: "hbchen-credential" # NOTE: 和 Secret 名称一致
    hosts:
    - "hbchen.com"
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: ingress-example-svc
spec:
  hosts:
  - "hbchen.com"
  gateways:
  - ingress-example-gateway
  http:
  - match:
    - port: 443
    route:
    - destination:
        host: hbchen.com
        port:
          number: 80
EOF

访问测试

curl -I -v -HHost:hbchen.com \
--resolve hbchen.com:$SECURE_INGRESS_PORT:$INGRESS_HOST \
--cacert hbchen.com/2_intermediate/certs/ca-chain.cert.pem \
https://hbchen.com:$SECURE_INGRESS_PORT

TODO

JWT

Authn