github.com/projectcontour/contour@v1.28.2/site/content/docs/main/config/tls-termination.md (about)

     1  # TLS Termination
     2  
     3  HTTPProxy follows a similar pattern to Ingress for configuring TLS credentials.
     4  
     5  You can secure a HTTPProxy by specifying a Secret that contains TLS private key and certificate information.
     6  If multiple HTTPProxies utilize the same Secret, the certificate must include the necessary Subject Authority Name (SAN) for each fqdn.
     7  
     8  Contour (via Envoy) requires that clients send the Server Name Indication (SNI) TLS extension so that requests can be routed to the correct virtual host.
     9  Virtual hosts are strongly bound to SNI names.
    10  This means that the Host header in HTTP requests must match the SNI name that was sent at the start of the TLS session.
    11  
    12  Contour also follows a "secure first" approach.
    13  When TLS is enabled for a virtual host, any request to the insecure port is redirected to the secure interface with a 301 redirect.
    14  Specific routes can be configured to override this behavior and handle insecure requests by enabling the `spec.routes.permitInsecure` parameter on a Route.
    15  
    16  The TLS secret must:
    17  - be a Secret of type `kubernetes.io/tls`. This means that it must contain keys named `tls.crt` and `tls.key` that contain the certificate and private key to use for TLS, in PEM format.
    18  
    19  The TLS secret may also:
    20  - add any chain CA certificates required for validation into the `tls.crt` PEM bundle. If this is the case, the serving certificate must be the first certificate in the bundle and the intermediate CA certificates must be appended in issuing order.
    21  
    22  ```yaml
    23  # ingress-tls.secret.yaml
    24  apiVersion: v1
    25  data:
    26    tls.crt: base64 encoded cert
    27    tls.key: base64 encoded key
    28  kind: Secret
    29  metadata:
    30    name: testsecret
    31    namespace: default
    32  type: kubernetes.io/tls
    33  ```
    34  
    35  The HTTPProxy can be configured to use this secret using `tls.secretName` property:
    36  
    37  ```yaml
    38  # httpproxy-tls.yaml
    39  apiVersion: projectcontour.io/v1
    40  kind: HTTPProxy
    41  metadata:
    42    name: tls-example
    43    namespace: default
    44  spec:
    45    virtualhost:
    46      fqdn: foo2.bar.com
    47      tls:
    48        secretName: testsecret
    49    routes:
    50      - services:
    51          - name: s1
    52            port: 80
    53  ```
    54  
    55  If the `tls.secretName` property contains a slash, eg. `somenamespace/somesecret` then, subject to TLS Certificate Delegation, the TLS certificate will be read from `somesecret` in `somenamespace`.
    56  See TLS Certificate Delegation below for more information.
    57  
    58  The TLS **Minimum Protocol Version** a virtual host should negotiate can be specified by setting the `spec.virtualhost.tls.minimumProtocolVersion`:
    59  
    60  - 1.3
    61  - 1.2  (Default)
    62  
    63  ## Fallback Certificate
    64  
    65  Contour provides virtual host based routing, so that any TLS request is routed to the appropriate service based on both the server name requested by the TLS client and the HOST header in the HTTP request.
    66  
    67  Since the HOST Header is encrypted during TLS handshake, it can’t be used for virtual host based routing unless the client sends HTTPS requests specifying hostname using the TLS server name, or the request is first decrypted using a default TLS certificate.
    68  
    69  Some legacy TLS clients do not send the server name, so Envoy does not know how to select the right certificate. A fallback certificate is needed for these clients.
    70  
    71  _**Note:**
    72  The minimum TLS protocol version for any fallback request is defined by the `minimum TLS protocol version` set in the Contour configuration file.
    73  Enabling the fallback certificate is not compatible with TLS client authentication._
    74  
    75  ### Fallback Certificate Configuration
    76  
    77  First define the `namespace/name` in the [Contour configuration file][1] of a Kubernetes secret which will be used as the fallback certificate.
    78  Any HTTPProxy which enables fallback certificate delegation must have the fallback certificate delegated to the namespace in which the HTTPProxy object resides.
    79  
    80  To do that, configure `TLSCertificateDelegation` to delegate the fallback certificate to specific or all namespaces (e.g. `*`) which should be allowed to enable the fallback certificate.
    81  Finally, for each root HTTPProxy, set the `Spec.TLS.enableFallbackCertificate` parameter to allow that HTTPProxy to opt-in to the fallback certificate routing.
    82  
    83  ```yaml
    84  apiVersion: projectcontour.io/v1
    85  kind: HTTPProxy
    86  metadata:
    87    name: fallback-tls-example
    88    namespace: defaultub
    89  spec:
    90    virtualhost:
    91      fqdn: fallback.bar.com
    92      tls:
    93        secretName: testsecret
    94        enableFallbackCertificate: true
    95    routes:
    96      - services:
    97          - name: s1
    98            port: 80
    99  ---
   100  apiVersion: projectcontour.io/v1
   101  kind: TLSCertificateDelegation
   102  metadata:
   103    name: fallback-delegation
   104    namespace: www-admin
   105  spec:
   106    delegations:
   107      - secretName: fallback-secret-name
   108        targetNamespaces:
   109        - "*"
   110  ```
   111  
   112  ## Permitting Insecure Requests
   113  
   114  A HTTPProxy can be configured to permit insecure requests to specific Routes.
   115  In this example, any request to `foo2.bar.com/blog` will not receive a 301 redirect to HTTPS, but the `/` route will:
   116  
   117  ```yaml
   118  apiVersion: projectcontour.io/v1
   119  kind: HTTPProxy
   120  metadata:
   121    name: tls-example-insecure
   122    namespace: default
   123  spec:
   124    virtualhost:
   125      fqdn: foo2.bar.com
   126      tls:
   127        secretName: testsecret
   128    routes:
   129      - services:
   130          - name: s1
   131            port: 80
   132      - conditions:
   133        - prefix: /blog
   134        permitInsecure: true
   135        services:
   136          - name: s2
   137            port: 80
   138  ```
   139  
   140  ## Client Certificate Validation
   141  
   142  It is possible to protect the backend service from unauthorized external clients by requiring the client to present a valid TLS certificate.
   143  Envoy will validate the client certificate by verifying that it is not expired and that a chain of trust can be established to the configured trusted root CA certificate.
   144  Only those requests with a valid client certificate will be accepted and forwarded to the backend service.
   145  
   146  ```yaml
   147  apiVersion: projectcontour.io/v1
   148  kind: HTTPProxy
   149  metadata:
   150    name: with-client-auth
   151  spec:
   152    virtualhost:
   153      fqdn: www.example.com
   154      tls:
   155        secretName: secret
   156        clientValidation:
   157          caSecret: client-root-ca
   158    routes:
   159      - services:
   160          - name: s1
   161            port: 80
   162  ```
   163  
   164  The preceding example enables validation by setting the optional `clientValidation` attribute.
   165  Its mandatory attribute `caSecret` contains a name of an existing Kubernetes Secret that must be of type "Opaque" and have only a data key named `ca.crt`.
   166  The data value of the key `ca.crt` must be a PEM-encoded certificate bundle and it must contain all the trusted CA certificates that are to be used for validating the client certificate.
   167  If the Opaque Secret also contains one of either `tls.crt` or `tls.key` keys, it will be ignored.
   168  
   169  By default, client certificates are required but some applications might support different authentication schemes. In that case you can set the `optionalClientCertificate` field to `true`. A client certificate will be requested, but the connection is allowed to continue if the client does not provide one. If a client certificate is sent, it will be verified according to the other properties, which includes disabling validations if `skipClientCertValidation` is set.
   170  
   171  ```yaml
   172  apiVersion: projectcontour.io/v1
   173  kind: HTTPProxy
   174  metadata:
   175    name: with-optional-client-auth
   176  spec:
   177    virtualhost:
   178      fqdn: www.example.com
   179      tls:
   180        secretName: secret
   181        clientValidation:
   182          caSecret: client-root-ca
   183          optionalClientCertificate: true
   184    routes:
   185      - services:
   186          - name: s1
   187            port: 80
   188  ```
   189  
   190  When using external authorization, it may be desirable to use an external authorization server to validate client certificates on requests, rather than the Envoy proxy.
   191  
   192  ```yaml
   193  apiVersion: projectcontour.io/v1
   194  kind: HTTPProxy
   195  metadata:
   196    name: with-client-auth-and-ext-authz
   197  spec:
   198    virtualhost:
   199      fqdn: www.example.com
   200      authorization:
   201        # external authorization server configuration
   202      tls:
   203        secretName: secret
   204        clientValidation:
   205          caSecret: client-root-ca
   206          skipClientCertValidation: true
   207    routes:
   208      - services:
   209          - name: s1
   210            port: 80
   211  ```
   212  
   213  In the above example, setting the `skipClientCertValidation` field to `true` will configure Envoy to require client certificates on requests and pass them along to a configured authorization server.
   214  Failed validation of client certificates by Envoy will be ignored and the `fail_verify_error` [Listener statistic][2] incremented.
   215  If the `caSecret` field is omitted, Envoy will request but not require client certificates to be present on requests.
   216  
   217  Optionally, you can enable certificate revocation check by providing one or more Certificate Revocation Lists (CRLs).
   218  Attribute `crlSecret` contains a name of an existing Kubernetes Secret that must be of type "Opaque" and have a data key named `crl.pem`.
   219  The data value of the key `crl.pem` must be one or more PEM-encoded CRLs concatenated together.
   220  Large CRL lists are not supported since individual Secrets are limited to 1MiB in size.
   221  
   222  ```yaml
   223  apiVersion: projectcontour.io/v1
   224  kind: HTTPProxy
   225  metadata:
   226    name: with-client-auth-and-crl-check
   227  spec:
   228    virtualhost:
   229      fqdn: www.example.com
   230      tls:
   231        secretName: secret
   232        clientValidation:
   233          caSecret: client-root-ca
   234          crlSecret: client-crl
   235    routes:
   236      - services:
   237          - name: s1
   238            port: 80
   239  ```
   240  
   241  CRLs must be available from all relevant CAs, including intermediate CAs.
   242  Otherwise clients will be denied access, since the revocation status cannot be checked for the full certificate chain.
   243  This behavior can be controlled by `crlOnlyVerifyLeafCert` field.
   244  If the option is set to `true`, only the certificate at the end of the certificate chain will be subject to validation by CRL.
   245  
   246  ```yaml
   247  apiVersion: projectcontour.io/v1
   248  kind: HTTPProxy
   249  metadata:
   250    name: with-client-auth-and-crl-check-only-leaf
   251  spec:
   252    virtualhost:
   253      fqdn: www.example.com
   254      tls:
   255        secretName: secret
   256        clientValidation:
   257          caSecret: client-root-ca
   258          crlSecret: client-crl
   259          crlOnlyVerifyLeafCert: true
   260    routes:
   261      - services:
   262          - name: s1
   263            port: 80
   264  ```
   265  
   266  ## Client Certificate Details Forwarding
   267  
   268  HTTPProxy supports passing certificate data through the `x-forwarded-client-cert` header to let applications use details from client certificates (e.g. Subject, SAN...). Since the certificate (or the certificate chain) could exceed the web server header size limit, you have the ability to select what specific part of the certificate to expose in the header through the `forwardClientCertificate` field. Read more about the supported values in the [Envoy documentation](https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_conn_man/headers#x-forwarded-client-cert).
   269  
   270  ```yaml
   271  apiVersion: projectcontour.io/v1
   272  kind: HTTPProxy
   273  metadata:
   274    name: with-client-auth
   275  spec:
   276    virtualhost:
   277      fqdn: www.example.com
   278      tls:
   279        secretName: secret
   280        clientValidation:
   281          caSecret: client-root-ca
   282          forwardClientCertificate:
   283            subject: true
   284            cert: true
   285            chain: true
   286            dns: true
   287            uri: true
   288    routes:
   289      - services:
   290          - name: s1
   291            port: 80
   292  ```
   293  
   294  ## TLS Session Proxying
   295  
   296  HTTPProxy supports proxying of TLS encapsulated TCP sessions.
   297  
   298  _Note_: The TCP session must be encrypted with TLS.
   299  This is necessary so that Envoy can use SNI to route the incoming request to the correct service.
   300  
   301  If `spec.virtualhost.tls.secretName` is present then that secret will be used to decrypt the TCP traffic at the edge.
   302  
   303  ```yaml
   304  # httpproxy-tls-termination.yaml
   305  apiVersion: projectcontour.io/v1
   306  kind: HTTPProxy
   307  metadata:
   308    name: example
   309    namespace: default
   310  spec:
   311    virtualhost:
   312      fqdn: tcp.example.com
   313      tls:
   314        secretName: secret
   315    tcpproxy:
   316      services:
   317      - name: tcpservice
   318        port: 8080
   319      - name: otherservice
   320        port: 9999
   321        weight: 20
   322  ```
   323  
   324  The `spec.tcpproxy` key indicates that this _root_ HTTPProxy will forward the de-encrypted TCP traffic to the backend service.
   325  
   326  ### TLS Session Passthrough
   327  
   328  If you wish to handle the TLS handshake at the backend service set `spec.virtualhost.tls.passthrough: true` indicates that once SNI demuxing is performed, the encrypted connection will be forwarded to the backend service.
   329  The backend service is expected to have a key which matches the SNI header received at the edge, and be capable of completing the TLS handshake. This is called SSL/TLS Passthrough.
   330  
   331  ```yaml
   332  # httpproxy-tls-passthrough.yaml
   333  apiVersion: projectcontour.io/v1
   334  kind: HTTPProxy
   335  metadata:
   336    name: example
   337    namespace: default
   338  spec:
   339    virtualhost:
   340      fqdn: tcp.example.com
   341      tls:
   342        passthrough: true
   343    tcpproxy:
   344      services:
   345      - name: tcpservice
   346        port: 8080
   347      - name: otherservice
   348        port: 9999
   349        weight: 20
   350  ```
   351  
   352  [1]: ../configuration#fallback-certificate
   353  [2]: https://www.envoyproxy.io/docs/envoy/latest/configuration/listeners/stats#tls-statistics