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