alibaba / higress

Cloud Native API Gateway | 云原生API网关

Home Page:https://higress.io

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

使用gateway api , 支持mtls

alexzzh opened this issue · comments

Why do you need it?

项目中需要使用gateway api,同时网关需要完成和客户端之间的tls卸载以及验证客户端证书(mtls)

How could it be?

what we want

使用 gateway api时,可以为不同的监听端口指定验证客户端的证书,形如:

apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: higress-gateway
  namespace: higress-system
spec:
  gatewayClassName: higress-gateway
  listeners:
  - name: 业务1
    port: 4006
    protocol: HTTPS
    allowedRoutes:
      namespaces:
        from: All
    tls:
      certificateRefs:
      - kind: Secret
        name: 站点证书1
  ca:   ===》 需求
     ca证书链1
  - name: 业务2
    port: 4005
    protocol: HTTPS
    allowedRoutes:
      namespaces:
        from: All
    tls:
      certificateRefs:
      - kind: Secret
        name: 站点证书2
  ca: ===》 需求
     ca证书链2
     
 对应 envoy 配置
 resources:
  - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.Secret"
    validation_context:
      trusted_ca:
        ca证书链2

想要尝试下,请帮忙分配下,感谢 @johnlanni

@hanxiantao 好的,钉钉上联系一下我吧,交流一下实现细节,这块功能需要在 https://github.com/alibaba/higress/tree/feat/istio-1.19.0 这个分支上做

@hanxiantao 好的,钉钉上联系一下我吧,交流一下实现细节,这块功能需要在 https://github.com/alibaba/higress/tree/feat/istio-1.19.0 这个分支上做

作为提issue的同学,我也想参与讨论

@alexzzh 我们在controller SIG里一起讨论吧

@johnlanni @hanxiantao

同步下最新信息: 看源码发现mtls目前应该已经满足,that's fine!
可以通过以下配置实现,这要求系统中wildcard-foobar-com 这个secret除了证书和私钥,还存在cacert这个key或者系统中存在wildcard-foobar-com-cacert这个secret且内容为ca证书,实测都有效。

kind: GatewayClass
metadata:
  name: higress-gateways
spec:
  controllerName: "higress.io/gateway-controller"
---
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: higress-gateway
  namespace: higress-system
spec:
  gatewayClassName: higress
  listeners:
  - name: fazheng
    port: 4006
    protocol: HTTPS
    allowedRoutes:
      namespaces:
        from: All
    tls:
      options:
        gateway.higress.io/tls-terminate-mode: "MUTUAL"
      certificateRefs:
      - kind: Secret
        name: wildcard-foobar-com
alex@alexdeMacBook-Pro gateway-api % kubectl describe secret wildcard-foobar-com -n higress-system 
Name:         wildcard-foobar-com
Namespace:    higress-system
Labels:       <none>
Annotations:  <none>

Type:  Opaque

Data
====
tls.crt:  1635 bytes
tls.key:  1704 bytes
alex@alexdeMacBook-Pro gateway-api % kubectl describe secret wildcard-foobar-com-cacert -n higress-system 
Name:         wildcard-foobar-com-cacert
Namespace:    higress-system
Labels:       <none>
Annotations:  <none>

Type:  Opaque

Data
====
ca.crt:  1830 bytes
  • 效果如下
    164111713423453_ pic

另外,我们这边整理了目前我们项目在ssl层相关配置,目前gateway api有部分尚未满足,再此列出来以作进一步讨论:
以下是目前客户现场真实配置(目前我们使用的是filesystem xDS来完成配置同步和加载),按照序号列出待支持点

 transport_socket:
      name: envoy.transport_sockets.tls
      typed_config:
        "@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext
        require_client_certificate: true
        session_timeout: 7200s
        common_tls_context:
          alpn_protocols: ["http/1.1"] ==》 序号1
          tls_params:
             tls_minimum_protocol_version: TLSv1_1 ==》 序号2
             tls_maximum_protocol_version: TLSv1_2 ==》 序号2
             enable_gmtls: true ==》 序号4
             cipher_suites: [ECDHE-SM4-SM3, ECC-SM4-SM3] ==》 序号3
          tls_certificate_sds_secret_configs:
            name: sds-double
            sds_config:
              path: /config/sds-double.yaml
          validation_context_sds_secret_config:
            name: sds-validation
            sds_config:
              path: /config/sds-validation.yaml

==》config/sds-double.yaml
resources:
  - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.Secret"
    name: sds-double
    tls_certificate:
      certificate_chain:
        inline_string: |
          -----BEGIN CERTIFICATE-----
          -----END CERTIFICATE-----
      private_key:
        inline_string: |
          -----BEGIN EC PRIVATE KEY-----
          Proc-Type: 4,ENCRYPTED
          DEK-Info: CN-GM-SM4-CBC,B221A3FEE3C307B93B545F536246A8A4
          -----END EC PRIVATE KEY-----
      gmtls_sign_certificate_chain: ==》 序号5
        inline_string: |
          -----BEGIN CERTIFICATE-----
          -----END CERTIFICATE-----
      gmtls_sign_private_key:
        inline_string: |
          -----BEGIN EC PRIVATE KEY-----
          Proc-Type: 4,ENCRYPTED
          DEK-Info: CN-GM-SM4-CBC,B221A3FEE3C307B93B545F536246A8A4
          -----END EC PRIVATE KEY-----
      gmtls_enc_certificate_chain:
        inline_string: |
          -----BEGIN CERTIFICATE-----
          -----END CERTIFICATE-----
      gmtls_enc_private_key:
        inline_string: |
          -----BEGIN EC PRIVATE KEY-----
          Proc-Type: 4,ENCRYPTED
          DEK-Info: CN-GM-SM4-CBC,09C7A2229D847AC1A140505DDB9E0EAB
         
          -----END EC PRIVATE KEY-----
      password: ==》 序号6
        inline_string: "\0"

==》 /config/sds-validation.yaml
resources:
  - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.Secret"
    name: sds-validation
    validation_context:
      allow_expired_certificate: true ==》 序号7
      trusted_ca:
        inline_string: |
          -----BEGIN CERTIFICATE-----
          -----END CERTIFICATE-----

针对这些点将来的可行方案如下,各位可以提出不同意见以作改进:
序号1: 设置alpn_protocols,强制不使用http2 - 目前1.19中的 disableAlpnH2 还不能生效,之后会rebase过来
序号2: 支持设置 protocol_version - 因为是通用需求,我这边提交了PR 使其支持
序号3: 支持设置 cipher_suites - 同序号2
序号4:支持设置定制指令,如 enable_gmtls - 因为不是通用需求,且需要修改control-plane字段,后续可以单独做patch,不合入主分支
序号5: 支持配置签名加密证书 - 同 序号4
序号6: 支持配置加密的证书私钥的解密私钥 - 因为私钥不应该用户可见,所以这个可以考虑在pilot buildTLS时根据全局开关来设置,因为不是通用需求,后续可以单独做patch,不合入主分支
序号7: 支持配置不校验客户端证书有效期 ,避免ca服务器和服务端时间不同步导致ca刚签发的客户端证书在服务端无法校验通过, 这个还是比较有用的 - 可以考虑在pilot buildTLS时根据全局开关来设置,可能是通用需求。