Securing routes
You can secure a route with HTTP strict transport security (HSTS).
HTTP Strict Transport Security
To enhance security and optimize website performance, use the HTTP Strict Transport Security (HSTS) policy. This mechanism signals browsers to use only HTTPS traffic on the route host, eliminating the need for HTTP redirects and speeding up user interactions.
When HSTS policy is enforced, HSTS adds a Strict Transport Security header to HTTP and HTTPS responses from the site. You can use the insecureEdgeTerminationPolicy value in a route to redirect HTTP to HTTPS. When HSTS is enforced, the client changes all requests from the HTTP URL to HTTPS before the request is sent, eliminating the need for a redirect.
Cluster administrators can configure HSTS to do the following:
-
Enable HSTS per-route
-
Disable HSTS per-route
-
Enforce HSTS per-domain, for a set of domains, or use namespace labels in combination with domains
Important
HSTS works only with secure routes, either edge-terminated or re-encrypt. The configuration is ineffective on HTTP or passthrough routes.
Enabling HTTP Strict Transport Security per-route
To enforce secure HTTPS connections for specific applications, enable HTTP Strict Transport Security (HSTS) on a per-route basis. Applying the haproxy.router.openshift.io/hsts_header annotation to edge and re-encrypt routes ensures that browsers reject unencrypted traffic.
-
You are logged in to the cluster with a user with administrator privileges for the project.
-
You installed the OpenShift CLI (
oc).
-
To enable HSTS on a route, add the
haproxy.router.openshift.io/hsts_headervalue to the edge-terminated or re-encrypt route. You can use theoc annotatetool to do this by running the following command. To properly run the command, ensure that the semicolon (;) in thehaproxy.router.openshift.io/hsts_headerroute annotation is also surrounded by double quotation marks ("").Exampleannotatecommand that sets the maximum age to31536000ms (approximately 8.5 hours)$ oc annotate route <route_name> -n <namespace> --overwrite=true "haproxy.router.openshift.io/hsts_header=max-age=31536000;\ includeSubDomains;preload"Example route configured with an annotationapiVersion: route.openshift.io/v1 kind: Route metadata: annotations: haproxy.router.openshift.io/hsts_header: max-age=31536000;includeSubDomains;preload # ... spec: host: def.abc.com tls: termination: "reencrypt" ... wildcardPolicy: "Subdomain" # ...where:
max-age-
Specifies the measurement of the length of time, in seconds, for the HSTS policy. If set to
0, it negates the policy. includeSubDomains-
Specifies that all subdomains of the host must have the same HSTS policy as the host. Optional parameter.
preload-
Specifies that the site is included in the HSTS preload list when
max-ageis greater than0. For example, sites such as Google can construct a list of sites that havepreloadset. Browsers can then use these lists to determine which sites they can communicate with over HTTPS, even before they have interacted with the site. Withoutpreloadset, browsers must have interacted with the site over HTTPS, at least once, to get the header. Optional parameter.
Disabling HTTP Strict Transport Security per-route
To allow unencrypted connections or troubleshoot access issues, disable HTTP Strict Transport Security (HSTS) for a specific route. Setting the max-age route annotation to 0 instructs browsers to stop enforcing HTTPS requirements on the route host.
-
You are logged in to the cluster with a user with administrator privileges for the project.
-
You installed the OpenShift CLI (
oc).
-
To disable HSTS, enter the following to set the
max-agevalue in the route annotation to0:$ oc annotate route <route_name> -n <namespace> --overwrite=true "haproxy.router.openshift.io/hsts_header"="max-age=0"Example of disabling HSTS per-route
You can alternatively apply the following YAML to create the config map:
kind: Route apiVersion: route.openshift.io/v1 metadata: annotations: haproxy.router.openshift.io/hsts_header: max-age=0 -
To disable HSTS for every route in a namespace, enter the following command:
$ oc annotate route --all -n <namespace> --overwrite=true "haproxy.router.openshift.io/hsts_header"="max-age=0"
-
To query the annotation for all routes, enter the following command:
$ 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}}'Example outputName: routename HSTS: max-age=0
Enforcing HTTP Strict Transport Security per-domain
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.
If you configure a requiredHSTSPolicy to enforce HSTS, then any newly created route must be configured with a compliant HSTS policy annotation.
Note
To handle upgraded clusters with non-compliant HSTS routes, you can update the manifests at the source and apply the updates.
Note
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.
Important
HSTS cannot be applied to insecure, or non-TLS routes, even if HSTS is requested for all routes globally.
-
You are logged in to the cluster with a user with administrator privileges for the project.
-
You installed the OpenShift CLI (
oc).
-
Edit the Ingress configuration YAML by running the following command and updating fields as needed:
$ oc edit ingresses.config.openshift.io/clusterExample HSTS policyapiVersion: config.openshift.io/v1 kind: Ingress metadata: name: cluster spec: domain: 'hello-openshift-default.apps.username.devcluster.openshift.com' requiredHSTSPolicies: - domainPatterns: - '*hello-openshift-default.apps.username.devcluster.openshift.com' - '*hello-openshift-default2.apps.username.devcluster.openshift.com' namespaceSelector: matchLabels: myPolicy: strict maxAge: smallestMaxAge: 1 largestMaxAge: 31536000 preloadPolicy: RequirePreload includeSubDomainsPolicy: RequireIncludeSubDomains - domainPatterns: - 'abc.example.com' - '*xyz.example.com' namespaceSelector: matchLabels: {} maxAge: {} preloadPolicy: NoOpinion includeSubDomainsPolicy: RequireNoIncludeSubDomains- Required.
requiredHSTSPoliciesare validated in order, and the first matchingdomainPatternsapplies. - Required. You must specify at least one
domainPatternshostname. Any number of domains can be listed. You can include multiple sections of enforcing options for differentdomainPatterns. - 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 thenamespaceSelectorand not thedomainPatternsare not validated. - Required.
max-agemeasures the length of time, in seconds, that the HSTS policy is in effect. This policy setting allows for a smallest and largestmax-ageto be enforced.-
The
largestMaxAgevalue must be between0and2147483647. It can be left unspecified, which means no upper limit is enforced. -
The
smallestMaxAgevalue must be between0and2147483647. Enter0to disable HSTS for troubleshooting, otherwise enter1if you never want HSTS to be disabled. It can be left unspecified, which means no lower limit is enforced.
-
- Optional. Including
preloadinhaproxy.router.openshift.io/hsts_headerallows 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. Withoutpreloadset, browsers need to interact at least once with the site to get the header.preloadcan be set with one of the following:-
RequirePreload:preloadis required by theRequiredHSTSPolicy. -
RequireNoPreload:preloadis forbidden by theRequiredHSTSPolicy. -
NoOpinion:preloaddoes not matter to theRequiredHSTSPolicy.
-
- Optional.
includeSubDomainsPolicycan be set with one of the following:-
RequireIncludeSubDomains:includeSubDomainsis required by theRequiredHSTSPolicy. -
RequireNoIncludeSubDomains:includeSubDomainsis forbidden by theRequiredHSTSPolicy. -
NoOpinion:includeSubDomainsdoes not matter to theRequiredHSTSPolicy.
-
- Required.
-
You can apply HSTS to all routes in the cluster or in a particular namespace by entering the
oc annotate command.-
To apply HSTS to all routes in the cluster, enter the
oc annotate command. For example:$ oc annotate route --all --all-namespaces --overwrite=true "haproxy.router.openshift.io/hsts_header"="max-age=31536000" -
To apply HSTS to all routes in a particular namespace, enter the
oc annotate command. For example:$ oc annotate route --all -n my-namespace --overwrite=true "haproxy.router.openshift.io/hsts_header"="max-age=31536000"
-
You can review the HSTS policy you configured. For example:
-
To review the
maxAgeset for required HSTS policies, enter the following command:$ oc get clusteroperator/ingress -n openshift-ingress-operator -o jsonpath='{range .spec.requiredHSTSPolicies[*]}{.spec.requiredHSTSPolicies.maxAgePolicy.largestMaxAge}{"\n"}{end}' -
To review the HSTS annotations on all routes, enter the following command:
$ 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}}'Example outputName: <_routename_> HSTS: max-age=31536000;preload;includeSubDomains