github.com/projectcontour/contour@v1.28.2/site/content/docs/1.26/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