github.com/projectcontour/contour@v1.28.2/site/content/docs/v1.17.2/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 contain keys named tls.crt and tls.key that contain the certificate and private key to use for TLS, e.g.:
    17  
    18  ```yaml
    19  # ingress-tls.secret.yaml
    20  apiVersion: v1
    21  data:
    22    tls.crt: base64 encoded cert
    23    tls.key: base64 encoded key
    24  kind: Secret
    25  metadata:
    26    name: testsecret
    27    namespace: default
    28  type: kubernetes.io/tls
    29  ```
    30  
    31  The HTTPProxy can be configured to use this secret using `tls.secretName` property:
    32  
    33  ```yaml
    34  # httpproxy-tls.yaml
    35  apiVersion: projectcontour.io/v1
    36  kind: HTTPProxy
    37  metadata:
    38    name: tls-example
    39    namespace: default
    40  spec:
    41    virtualhost:
    42      fqdn: foo2.bar.com
    43      tls:
    44        secretName: testsecret
    45    routes:
    46      - services:
    47          - name: s1
    48            port: 80
    49  ```
    50  
    51  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`.
    52  See TLS Certificate Delegation below for more information.
    53  
    54  The TLS **Minimum Protocol Version** a virtual host should negotiate can be specified by setting the `spec.virtualhost.tls.minimumProtocolVersion`:
    55  
    56  - 1.3
    57  - 1.2  (Default)
    58  
    59  ## Fallback Certificate
    60  
    61  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.
    62  
    63  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.
    64  
    65  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.
    66  
    67  _**Note:**
    68  The minimum TLS protocol version for any fallback request is defined by the `minimum TLS protocol version` set in the Contour configuration file.
    69  Enabling the fallback certificate is not compatible with TLS client authentication._
    70  
    71  ### Fallback Certificate Configuration
    72  
    73  First define the `namespace/name` in the [Contour configuration file][1] of a Kubernetes secret which will be used as the fallback certificate.
    74  Any HTTPProxy which enables fallback certificate delegation must have the fallback certificate delegated to the namespace in which the HTTPProxy object resides.
    75  
    76  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.
    77  Finally, for each root HTTPProxy, set the `Spec.TLS.enableFallbackCertificate` parameter to allow that HTTPProxy to opt-in to the fallback certificate routing.
    78  
    79  ```yaml
    80  apiVersion: projectcontour.io/v1
    81  kind: HTTPProxy
    82  metadata:
    83    name: fallback-tls-example
    84    namespace: defaultub
    85  spec:
    86    virtualhost:
    87      fqdn: fallback.bar.com
    88      tls:
    89        secretName: testsecret
    90        enableFallbackCertificate: true
    91    routes:
    92      - services:
    93          - name: s1
    94            port: 80
    95  ---
    96  apiVersion: projectcontour.io/v1
    97  kind: TLSCertificateDelegation
    98  metadata:
    99    name: fallback-delegation
   100    namespace: www-admin
   101  spec:
   102    delegations:
   103      - secretName: fallback-secret-name
   104        targetNamespaces:
   105        - "*"
   106  ```
   107  
   108  ## Permitting Insecure Requests
   109  
   110  A HTTPProxy can be configured to permit insecure requests to specific Routes.
   111  In this example, any request to `foo2.bar.com/blog` will not receive a 301 redirect to HTTPS, but the `/` route will:
   112  
   113  ```yaml
   114  apiVersion: projectcontour.io/v1
   115  kind: HTTPProxy
   116  metadata:
   117    name: tls-example-insecure
   118    namespace: default
   119  spec:
   120    virtualhost:
   121      fqdn: foo2.bar.com
   122      tls:
   123        secretName: testsecret
   124    routes:
   125      - services:
   126          - name: s1
   127            port: 80
   128      - conditions:
   129        - prefix: /blog
   130        permitInsecure: true
   131        services:
   132          - name: s2
   133            port: 80
   134  ```
   135  
   136  ## Client Certificate Validation
   137  
   138  It is possible to protect the backend service from unauthorized external clients by requiring the client to present a valid TLS certificate.
   139  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.
   140  Only those requests with a valid client certificate will be accepted and forwarded to the backend service.
   141  
   142  ```yaml
   143  apiVersion: projectcontour.io/v1
   144  kind: HTTPProxy
   145  metadata:
   146    name: with-client-auth
   147  spec:
   148    virtualhost:
   149      fqdn: www.example.com
   150      tls:
   151        secretName: secret
   152        clientValidation:
   153          caSecret: client-root-ca
   154    routes:
   155      - services:
   156          - name: s1
   157            port: 80
   158  ```
   159  
   160  The preceding example enables validation by setting the optional `clientValidation` attribute.
   161  Its mandatory attribute `caSecret` contains a name of an existing Kubernetes Secret that must be of type "Opaque" and have a data key named `ca.crt`.
   162  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.
   163  
   164  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.
   165  
   166  ```yaml
   167  apiVersion: projectcontour.io/v1
   168  kind: HTTPProxy
   169  metadata:
   170    name: with-client-auth-and-ext-authz
   171  spec:
   172    virtualhost:
   173      fqdn: www.example.com
   174      authorization:
   175        # external authorization server configuration
   176      tls:
   177        secretName: secret
   178        clientValidation:
   179          caSecret: client-root-ca
   180          skipClientCertValidation: true
   181    routes:
   182      - services:
   183          - name: s1
   184            port: 80
   185  ```
   186  
   187  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.
   188  Failed validation of client certificates by Envoy will be ignored and the `fail_verify_error` [Listener statistic][2] incremented.
   189  If the `caSecret` field is omitted, Envoy will request but not require client certificates to be present on requests.
   190  
   191  ## TLS Session Proxying
   192  
   193  HTTPProxy supports proxying of TLS encapsulated TCP sessions.
   194  
   195  _Note_: The TCP session must be encrypted with TLS.
   196  This is necessary so that Envoy can use SNI to route the incoming request to the correct service.
   197  
   198  If `spec.virtualhost.tls.secretName` is present then that secret will be used to decrypt the TCP traffic at the edge.
   199  
   200  ```yaml
   201  # httpproxy-tls-termination.yaml
   202  apiVersion: projectcontour.io/v1
   203  kind: HTTPProxy
   204  metadata:
   205    name: example
   206    namespace: default
   207  spec:
   208    virtualhost:
   209      fqdn: tcp.example.com
   210      tls:
   211        secretName: secret
   212    tcpproxy:
   213      services:
   214      - name: tcpservice
   215        port: 8080
   216      - name: otherservice
   217        port: 9999
   218        weight: 20
   219  ```
   220  
   221  The `spec.tcpproxy` key indicates that this _root_ HTTPProxy will forward the de-encrypted TCP traffic to the backend service.
   222  
   223  ### TLS Session Passthrough
   224  
   225  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.
   226  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.
   227  
   228  ```yaml
   229  # httpproxy-tls-passthrough.yaml
   230  apiVersion: projectcontour.io/v1
   231  kind: HTTPProxy
   232  metadata:
   233    name: example
   234    namespace: default
   235  spec:
   236    virtualhost:
   237      fqdn: tcp.example.com
   238      tls:
   239        passthrough: true
   240    tcpproxy:
   241      services:
   242      - name: tcpservice
   243        port: 8080
   244      - name: otherservice
   245        port: 9999
   246        weight: 20
   247  ```
   248  
   249  [1]: ../configuration#fallback-certificate
   250  [2]: https://www.envoyproxy.io/docs/envoy/latest/configuration/listeners/stats#tls-statistics