|
| 1 | +// Module included in the following assemblies: |
| 2 | +// * networking/configuring-routing.adoc |
| 3 | + |
| 4 | +[id="nw-enforcing-hsts-per-domain_{context}"] |
| 5 | += Enforcing HTTP Strict Transport Security per-domain |
| 6 | + |
| 7 | +To enforce HTTP Strict Transport Security (HSTS) per-domain for secure routes, add a `requiredHSTSPolicies` record to the Ingress spec to capture the configuration of the HSTS policy. |
| 8 | + |
| 9 | +If you configure a `requiredHSTSPolicy` to enforce HSTS, then any newly created route must be configured with a compliant HSTS policy annotation. |
| 10 | + |
| 11 | +[NOTE] |
| 12 | +==== |
| 13 | +To handle upgraded clusters with non-compliant HSTS routes, you can update the manifests at the source and apply the updates. |
| 14 | +==== |
| 15 | + |
| 16 | +[NOTE] |
| 17 | +==== |
| 18 | +You cannot use `oc expose route` or `oc create route` commands to add a route in a domain that enforces HSTS, because the API for these commands does not accept annotations. |
| 19 | +==== |
| 20 | + |
| 21 | +[IMPORTANT] |
| 22 | +==== |
| 23 | +HSTS cannot be applied to secure, or non-TLS routes, even if HSTS is requested for all routes globally. |
| 24 | +==== |
| 25 | + |
| 26 | +.Prerequisites |
| 27 | + |
| 28 | +* You are logged in to the cluster with a user with `cluster-admin` privileges. |
| 29 | +* You installed the `oc` CLI. |
| 30 | + |
| 31 | +.Procedure |
| 32 | + |
| 33 | +. Edit the Ingress config file: |
| 34 | ++ |
| 35 | +[source,terminal] |
| 36 | +---- |
| 37 | +$ oc edit ingresses.config.openshift.io/cluster |
| 38 | +---- |
| 39 | ++ |
| 40 | +.Example HSTS policy |
| 41 | +[source,yaml] |
| 42 | +---- |
| 43 | +apiVersion: config.openshift.io/v1 |
| 44 | +kind: Ingress |
| 45 | +metadata: |
| 46 | + name: cluster |
| 47 | +spec: |
| 48 | + domain: 'hello-openshift-default.apps.username.devcluster.openshift.com' |
| 49 | + requiredHSTSPolicies: <1> |
| 50 | + - domainPatterns: <2> |
| 51 | + - '*hello-openshift-default.apps.username.devcluster.openshift.com' |
| 52 | + - '*hello-openshift-default2.apps.username.devcluster.openshift.com' |
| 53 | + namespaceSelector: <3> |
| 54 | + matchLabels: |
| 55 | + myPolicy: strict |
| 56 | + maxAge: <4> |
| 57 | + smallestMaxAge: 1 |
| 58 | + largestMaxAge: 31536000 |
| 59 | + preloadPolicy: RequirePreload <5> |
| 60 | + includeSubDomainsPolicy: RequireIncludeSubDomains <6> |
| 61 | + - domainPatterns: <2> |
| 62 | + - 'abc.example.com' |
| 63 | + - '*xyz.example.com' |
| 64 | + namespaceSelector: |
| 65 | + matchLabels: {} |
| 66 | + maxAge: {} |
| 67 | + preloadPolicy: NoOpinion |
| 68 | + includeSubDomainsPolicy: RequireNoIncludeSubDomains |
| 69 | +---- |
| 70 | +<1> Required. `requiredHSTSPolicies` are validated in order, and the first matching `domainPatterns` applies. |
| 71 | +<2> Required. You must specify at least one `domainPatterns` hostname. Any number of domains can be listed. You can include multiple sections of enforcing options for different `domainPatterns`. |
| 72 | +<3> Optional. If you include `namespaceSelector`, it must match the labels of the project where the routes reside, to enforce the set HSTS policy on the routes. Routes that only match the `namespaceSelector` and not the `domainPatterns` are not validated. |
| 73 | +<4> Required. `max-age` measures the length of time, in seconds, that the HSTS policy is in effect. This policy setting allows for a smallest and largest `max-age` to be enforced. |
| 74 | + |
| 75 | +- The `largestMaxAge` value must be between `0` and `2147483647`. It can be left unspecified, which means no upper limit is enforced. |
| 76 | +- The `smallestMaxAge` value must be between `0` and `2147483647`. Enter `0` to disable HSTS for troubleshooting, otherwise enter `1` if you never want HSTS to be disabled. It can be left unspecified, which means no lower limit is enforced. |
| 77 | +<5> Optional. Including `preload` in `haproxy.router.openshift.io/hsts_header` allows external services to include this site in their HSTS preload lists. Browsers can then use these lists to determine which sites they can communicate with over HTTPS, before they have interacted with the site. Without `preload` set, browsers need to interact at least once with the site to get the header. `preload` can be set with one of the following: |
| 78 | + |
| 79 | +- `RequirePreload`: `preload` is required by the `RequiredHSTSPolicy`. |
| 80 | +- `RequireNoPreload`: `preload` is forbidden by the `RequiredHSTSPolicy`. |
| 81 | +- `NoOpinion`: `preload` does not matter to the `RequiredHSTSPolicy`. |
| 82 | +<6> Optional. `includeSubDomainsPolicy` can be set with one of the following: |
| 83 | + |
| 84 | +- `RequireIncludeSubDomains`: `includeSubDomains` is required by the `RequiredHSTSPolicy`. |
| 85 | +- `RequireNoIncludeSubDomains`: `includeSubDomains` is forbidden by the `RequiredHSTSPolicy`. |
| 86 | +- `NoOpinion`: `includeSubDomains` does not matter to the `RequiredHSTSPolicy`. |
| 87 | ++ |
| 88 | +. You can apply HSTS to all routes in the cluster or in a particular namespace by entering the `oc annotate command`. |
| 89 | ++ |
| 90 | +* To apply HSTS to all routes in the cluster, enter the `oc annotate command`. For example: |
| 91 | ++ |
| 92 | +[source,terminal] |
| 93 | +---- |
| 94 | +$ oc annotate route --all --all-namespaces --overwrite=true "haproxy.router.openshift.io/hsts_header"="max-age=31536000" |
| 95 | +---- |
| 96 | ++ |
| 97 | +* To apply HSTS to all routes in a particular namespace, enter the `oc annotate command`. For example: |
| 98 | ++ |
| 99 | +[source,terminal] |
| 100 | +---- |
| 101 | +$ oc annotate route --all -n my-namespace --overwrite=true "haproxy.router.openshift.io/hsts_header"="max-age=31536000" |
| 102 | +---- |
| 103 | + |
| 104 | +.Verification |
| 105 | + |
| 106 | +You can review the HSTS policy you configured. For example: |
| 107 | + |
| 108 | +* To review the `maxAge` set for required HSTS policies, enter the following command: |
| 109 | ++ |
| 110 | +[source,terminal] |
| 111 | +---- |
| 112 | +$ oc get clusteroperator/ingress -n openshift-ingress-operator -o jsonpath='{range .spec.requiredHSTSPolicies[*]}{.spec.requiredHSTSPolicies.maxAgePolicy.largestMaxAge}{"\n"}{end}' |
| 113 | +---- |
| 114 | ++ |
| 115 | +* To review the HSTS annotations on all routes, enter the following command: |
| 116 | ++ |
| 117 | +[source,terminal] |
| 118 | +---- |
| 119 | +$ oc get route --all-namespaces -o go-template='{{range .items}}{{if .metadata.annotations}}{{$a := index .metadata.annotations "haproxy.router.openshift.io/hsts_header"}}{{$n := .metadata.name}}{{with $a}}Name: {{$n}} HSTS: {{$a}}{{"\n"}}{{else}}{{""}}{{end}}{{end}}{{end}}' |
| 120 | +---- |
| 121 | ++ |
| 122 | +.Example output |
| 123 | +[source,terminal] |
| 124 | +---- |
| 125 | +Name: <_routename_> HSTS: max-age=31536000;preload;includeSubDomains |
| 126 | +---- |
0 commit comments