github.com/projectcontour/contour@v1.28.2/site/content/docs/1.22/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  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.
   170  
   171  ```yaml
   172  apiVersion: projectcontour.io/v1
   173  kind: HTTPProxy
   174  metadata:
   175    name: with-client-auth-and-ext-authz
   176  spec:
   177    virtualhost:
   178      fqdn: www.example.com
   179      authorization:
   180        # external authorization server configuration
   181      tls:
   182        secretName: secret
   183        clientValidation:
   184          caSecret: client-root-ca
   185          skipClientCertValidation: true
   186    routes:
   187      - services:
   188          - name: s1
   189            port: 80
   190  ```
   191  
   192  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.
   193  Failed validation of client certificates by Envoy will be ignored and the `fail_verify_error` [Listener statistic][2] incremented.
   194  If the `caSecret` field is omitted, Envoy will request but not require client certificates to be present on requests.
   195  
   196  Optionally, you can enable certificate revocation check by providing one or more Certificate Revocation Lists (CRLs).
   197  Attribute `crlSecret` contains a name of an existing Kubernetes Secret that must be of type "Opaque" and have a data key named `crl.pem`.
   198  The data value of the key `crl.pem` must be one or more PEM-encoded CRLs concatenated together.
   199  Large CRL lists are not supported since individual Secrets are limited to 1MiB in size.
   200  
   201  ```yaml
   202  apiVersion: projectcontour.io/v1
   203  kind: HTTPProxy
   204  metadata:
   205    name: with-client-auth-and-crl-check
   206  spec:
   207    virtualhost:
   208      fqdn: www.example.com
   209      tls:
   210        secretName: secret
   211        clientValidation:
   212          caSecret: client-root-ca
   213          crlSecret: client-crl
   214    routes:
   215      - services:
   216          - name: s1
   217            port: 80
   218  ```
   219  
   220  CRLs must be available from all relevant CAs, including intermediate CAs.
   221  Otherwise clients will be denied access, since the revocation status cannot be checked for the full certificate chain.
   222  This behavior can be controlled by `crlOnlyVerifyLeafCert` field.
   223  If the option is set to `true`, only the certificate at the end of the certificate chain will be subject to validation by CRL.
   224  
   225  ```yaml
   226  apiVersion: projectcontour.io/v1
   227  kind: HTTPProxy
   228  metadata:
   229    name: with-client-auth-and-crl-check-only-leaf
   230  spec:
   231    virtualhost:
   232      fqdn: www.example.com
   233      tls:
   234        secretName: secret
   235        clientValidation:
   236          caSecret: client-root-ca
   237          crlSecret: client-crl
   238          crlOnlyVerifyLeafCert: true
   239    routes:
   240      - services:
   241          - name: s1
   242            port: 80
   243  ```
   244  
   245  ## TLS Session Proxying
   246  
   247  HTTPProxy supports proxying of TLS encapsulated TCP sessions.
   248  
   249  _Note_: The TCP session must be encrypted with TLS.
   250  This is necessary so that Envoy can use SNI to route the incoming request to the correct service.
   251  
   252  If `spec.virtualhost.tls.secretName` is present then that secret will be used to decrypt the TCP traffic at the edge.
   253  
   254  ```yaml
   255  # httpproxy-tls-termination.yaml
   256  apiVersion: projectcontour.io/v1
   257  kind: HTTPProxy
   258  metadata:
   259    name: example
   260    namespace: default
   261  spec:
   262    virtualhost:
   263      fqdn: tcp.example.com
   264      tls:
   265        secretName: secret
   266    tcpproxy:
   267      services:
   268      - name: tcpservice
   269        port: 8080
   270      - name: otherservice
   271        port: 9999
   272        weight: 20
   273  ```
   274  
   275  The `spec.tcpproxy` key indicates that this _root_ HTTPProxy will forward the de-encrypted TCP traffic to the backend service.
   276  
   277  ### TLS Session Passthrough
   278  
   279  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.
   280  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.
   281  
   282  ```yaml
   283  # httpproxy-tls-passthrough.yaml
   284  apiVersion: projectcontour.io/v1
   285  kind: HTTPProxy
   286  metadata:
   287    name: example
   288    namespace: default
   289  spec:
   290    virtualhost:
   291      fqdn: tcp.example.com
   292      tls:
   293        passthrough: true
   294    tcpproxy:
   295      services:
   296      - name: tcpservice
   297        port: 8080
   298      - name: otherservice
   299        port: 9999
   300        weight: 20
   301  ```
   302  
   303  [1]: ../configuration#fallback-certificate
   304  [2]: https://www.envoyproxy.io/docs/envoy/latest/configuration/listeners/stats#tls-statistics