-
Notifications
You must be signed in to change notification settings - Fork 1.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add http header modification feature
- Loading branch information
Showing
6 changed files
with
254 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,122 @@ | ||
// Module included in the following assemblies: | ||
// | ||
// * networking/ingress-operator.adoc | ||
// * networking/route-configuration.adoc | ||
|
||
:_content-type: CONCEPT | ||
[id="nw-http-header-configuration_{context}"] | ||
= HTTP header configuration | ||
|
||
{product-title} provides different methods for working with HTTP headers. When setting or deleting headers, you can use specific fields in the Ingress Controller or an individual route to modify request and response headers. You can also set certain headers by using route annotations. The various ways of configuring headers can present challenges when working together. | ||
|
||
[NOTE] | ||
==== | ||
You can only set or delete headers within an `IngressController` or `Route` CR, you cannot append them. If an HTTP header is set with a value, that value must be complete and not require appending in the future. In situations where it makes sense to append a header, such as the X-Forwarded-For header, use the `spec.httpHeaders.forwardedHeaderPolicy` field, instead of `spec.httpHeaders.actions`. | ||
==== | ||
|
||
[id="nw-http-header-configuration-order_{context}"] | ||
== Order of precedence | ||
|
||
When the same HTTP header is modified both in the Ingress Controller and in a route, HAProxy prioritizes the actions in certain ways depending on whether it is a request or response header. | ||
|
||
* For HTTP response headers, actions specified in the Ingress Controller are executed after the actions specified in a route. This means that the actions specified in the Ingress Controller take precedence. | ||
|
||
* For HTTP request headers, actions specified in a route are executed after the actions specified in the Ingress Controller. This means that the actions specified in the route take precedence. | ||
|
||
For example, a cluster administrator sets the X-Frame-Options response header with the value `DENY` in the Ingress Controller using the following configuration: | ||
|
||
.Example `IngressController` spec | ||
[source,yaml] | ||
---- | ||
apiVersion: operator.openshift.io/v1 | ||
kind: IngressController | ||
# ... | ||
spec: | ||
httpHeaders: | ||
actions: | ||
response: | ||
- name: X-Frame-Options | ||
action: | ||
type: Set | ||
set: | ||
value: DENY | ||
---- | ||
|
||
A route owner sets the same response header that the cluster administrator set in the Ingress Controller, but with the value `SAMEORIGIN` using the following configuration: | ||
|
||
.Example `Route` spec | ||
[source,yaml] | ||
---- | ||
apiVersion: route.openshift.io/v1 | ||
kind: Route | ||
# ... | ||
spec: | ||
httpHeaders: | ||
actions: | ||
response: | ||
- name: X-Frame-Options | ||
action: | ||
type: Set | ||
set: | ||
value: SAMEORIGIN | ||
---- | ||
|
||
When both the `IngressController` spec and `Route` spec are configuring the X-Frame-Options header, then the value set for this header at the global level in the Ingress Controller will take precedence, even if a specific route allows frames. | ||
|
||
This prioritzation occurs because the `haproxy.config` file uses the following logic, where the Ingress Controller is considered the front end and individual routes are considered the back end. The header value `DENY` applied to the front end configurations overrides the same header with the value `SAMEORIGIN` that is set in the back end: | ||
|
||
[source,text] | ||
---- | ||
frontend public | ||
http-response set-header X-Frame-Options 'DENY' | ||
frontend fe_sni | ||
http-response set-header X-Frame-Options 'DENY' | ||
frontend fe_no_sni | ||
http-response set-header X-Frame-Options 'DENY' | ||
backend be_secure:openshift-monitoring:alertmanager-main | ||
http-response set-header X-Frame-Options 'SAMEORIGIN' | ||
---- | ||
|
||
Additionally, any actions defined in either the Ingress Controller or a route override values set using route annotations. | ||
|
||
[id="nw-http-header-configuration-special-cases_{context}"] | ||
== Special case headers | ||
|
||
The following headers are either prevented entirely from being set or deleted, or allowed under specific circumstances: | ||
|
||
.Special case header configuration options | ||
[cols="5*a",options="header"] | ||
|=== | ||
|Header name |Configurable using `IngressController` spec |Configurable using `Route` spec |Reason for disallowment |Configurable using another method | ||
|
||
|`proxy` | ||
|No | ||
|No | ||
|The `proxy` HTTP request header can be used to exploit vulnerable CGI applications by injecting the header value into the `HTTP_PROXY` environment variable. The `proxy` HTTP request header is also non-standard and prone to error during configuration. | ||
|No | ||
|
||
|`host` | ||
|No | ||
|Yes | ||
|When the `host` HTTP request header is set using the `IngressController` CR, HAProxy can fail when looking up the correct route. | ||
|No | ||
|
||
|`strict-transport-security` | ||
|No | ||
|No | ||
|The `strict-transport-security` HTTP response header is already handled using route annotations and does not need a separate implementation. | ||
|Yes: the `haproxy.router.openshift.io/hsts_header` route annotation | ||
|
||
|`cookie` and `set-cookie` | ||
|No | ||
|No | ||
|The cookies that HAProxy sets are used for session tracking to map client connections to particular back-end servers. Allowing these headers to be set could interfere with HAProxy's session affinity and restrict HAProxy's ownership of a cookie. | ||
|Yes: | ||
|
||
* the `haproxy.router.openshift.io/disable_cookie` route annotation | ||
* the `haproxy.router.openshift.io/cookie_name` route annotation | ||
|
||
|=== |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
// Module included in the following assemblies: | ||
// | ||
// * networking/ingress-operator.adoc | ||
|
||
:_content-type: PROCEDURE | ||
[id="nw-ingress-set-or-delete-http-headers_{context}"] | ||
= Setting or deleting HTTP request and response headers in an Ingress Controller | ||
|
||
You can set or delete certain HTTP request and response headers for compliance purposes or other reasons. You can set or delete these headers either for all routes served by an Ingress Controller or for specific routes. | ||
|
||
For example, you might want to migrate an application running on your cluster to use mutual TLS, which requires that your application checks for an X-Forwarded-Client-Cert request header, but the {product-title} default Ingress Controller provides an X-SSL-Client-Der request header. | ||
|
||
The following procedure modifies the Ingress Controller to set the X-Forwarded-Client-Cert request header, and delete the X-SSL-Client-Der request header. | ||
|
||
.Prerequisites | ||
* You have installed the OpenShift CLI (`oc`). | ||
* You have access to an {product-title} cluster as a user with the `cluster-admin` role. | ||
.Procedure | ||
. Edit the Ingress Controller resource: | ||
+ | ||
[source,terminal] | ||
---- | ||
$ oc -n openshift-ingress-operator edit ingresscontroller/default | ||
---- | ||
|
||
. Replace the X-SSL-Client-Der HTTP request header with the X-Forwarded-Client-Cert HTTP request header: | ||
+ | ||
[source,yaml] | ||
---- | ||
apiVersion: operator.openshift.io/v1 | ||
kind: IngressController | ||
metadata: | ||
name: default | ||
namespace: openshift-ingress-operator | ||
spec: | ||
httpHeaders: | ||
actions: <1> | ||
request: <2> | ||
- name: X-Forwarded-Client-Cert <3> | ||
action: | ||
type: Set <4> | ||
set: | ||
value: "%{+Q}[ssl_c_der,base64]" <5> | ||
- name: X-SSL-Client-Der | ||
action: | ||
type: Delete | ||
---- | ||
<1> The list of actions you want to perform on the HTTP headers. | ||
<2> The type of header you want to change. In this case, a request header. | ||
<3> The name of the header you want to change. For a list of available headers you can set or delete, see _HTTP header configuration_. | ||
<4> The type of action being taken on the header. This field can have the value `Set` or `Delete`. | ||
<5> When setting HTTP headers, you must provide a `value`. The value can be a string from a list of available directives for that header, for example `DENY`, or it can be a dynamic value that will be interpreted using HAProxy's dynamic value syntax. In this case, a dynamic value is added. | ||
+ | ||
[NOTE] | ||
==== | ||
For setting dynamic header values for HTTP responses, allowed sample fetchers are `res.hdr` and `ssl_c_der`. For setting dynamic header values for HTTP requests, allowed sample fetchers are `req.hdr` and `ssl_c_der`. Both request and response dynamic values can use the `lower` and `base64` converters. | ||
==== | ||
|
||
. Save the file to apply the changes. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
// Module included in the following assemblies: | ||
// | ||
// * networking/route-configuration.adoc | ||
|
||
:_content-type: PROCEDURE | ||
[id="nw-route-set-or-delete-http-headers_{context}"] | ||
= Setting or deleting HTTP request and response headers in a route | ||
|
||
You can set or delete certain HTTP request and response headers for compliance purposes or other reasons. You can set or delete these headers either for all routes served by an Ingress Controller or for specific routes. | ||
|
||
For example, you might want to enable a web application to serve content in alternate locations for specific routes if that content is written in multiple languages, even if there is a default global location specified by the Ingress Controller serving the routes. | ||
|
||
The following procedure creates a route that sets the Content-Location HTTP request header so that the URL associated with the application, `\https://app.example.com`, directs to the location `\https://app.example.com/lang/en-us`. Directing application traffic to this location means that anyone using that specific route is accessing web content written in American English. | ||
|
||
.Prerequisites | ||
* You have installed the OpenShift CLI (`oc`). | ||
* You are logged into an {product-title} cluster as a project administrator. | ||
* You have a web application that exposes a port and an HTTP or TLS endpoint listening for traffic on the port. | ||
.Procedure | ||
. Create a route definition and save it in a file called `app-example-route.yaml`: | ||
+ | ||
.YAML definition of the created route with HTTP header directives | ||
[source,yaml] | ||
---- | ||
apiVersion: route.openshift.io/v1 | ||
kind: Route | ||
# ... | ||
spec: | ||
host: app.example.com | ||
tls: | ||
termination: edge | ||
to: | ||
kind: Service | ||
name: app-example | ||
httpHeaders: | ||
actions: <1> | ||
response: <2> | ||
- name: Content-Location <3> | ||
action: | ||
type: Set <4> | ||
set: | ||
value: /lang/en-us <5> | ||
---- | ||
<1> The list of actions you want to perform on the HTTP headers. | ||
<2> The type of header you want to change. In this case, a response header. | ||
<3> The name of the header you want to change. For a list of available headers you can set or delete, see _HTTP header configuration_. | ||
<4> The type of action being taken on the header. This field can have the value `Set` or `Delete`. | ||
<5> When setting HTTP headers, you must provide a `value`. The value can be a string from a list of available directives for that header, for example `DENY`, or it can be a dynamic value that will be interpreted using HAProxy's dynamic value syntax. In this case, the value is set to the relative location of the content. | ||
|
||
. Create a route to your existing web application using the newly created route definition: | ||
+ | ||
[source,terminal] | ||
---- | ||
$ oc -n app-example create -f app-example-route.yaml | ||
---- | ||
|
||
For HTTP request headers, the actions specified in the route definitions are executed after any actions performed on HTTP request headers in the Ingress Controller. This means that any values set for those request headers in a route will take precedence over the ones set in the Ingress Controller. For more information on the processing order of HTTP headers, see _HTTP header configuration_. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters