Header manipulation
Append or remove HTTP request and response headers at the route level.Appending or removing headers can increase the security of your network. You can even manipulate headers on ingress traffic that goes through Gloo mesh Gateway to services outside your service mesh environment. For example, you might append a custom request header and then also enable a cross-origin request sharing (CORS) policy that requires this custom header. You might also remove any headers that provide details about your server, such as the operating system or upstream service time, to reduce the amount of information that could be used in targeted attacks.
For more information, see the following resources.
If you import or export resources across workspaces, your policies might not apply. For more information, see Import and export policies.
Before you begin
- Complete the multicluster getting started guide to set up the following testing environment.
- Three clusters along with environment variables for the clusters and their Kubernetes contexts.
- The Gloo Platform CLI,
meshctl
, along with other CLI tools such askubectl
andistioctl
. - The Gloo management server in the management cluster, and the Gloo agents in the workload clusters.
- Istio installed in the workload clusters.
- A simple Gloo workspace setup.
- Install Bookinfo and other sample apps.
Configure header manipulation policies
You can apply a header manipulation policy at the route level. For more information, see Applying policies.
Review the following sample configuration file.
apiVersion: trafficcontrol.policy.gloo.solo.io/v2
kind: HeaderManipulationPolicy
metadata:
name: modify-header-hsts
namespace: bookinfo
spec:
applyToRoutes:
- route:
labels:
route: ratings
config:
appendRequestHeaders:
x-custom-request: bookinfo
appendResponseHeaders:
strict-transport-security: max-age=16070400; includeSubDomains
x-content-type-options: nosniff
x-frame-options: deny
x-custom-response: bookinfo
removeRequestHeaders:
- user-agent
removeResponseHeaders:
- x-server
- x-envoy-upstream-service-time
Review the following table to understand this configuration. For more information, see the API docs.
Setting | Description |
---|---|
spec.applyToRoutes |
Configure which routes to apply the policy to, by using labels. The label matches the app and the route from the route table. If omitted, the policy applies to all routes in the workspace. |
spec.config.appendRequestHeaders |
Specify the HTTP headers to add before forwarding a request to the destination. Headers are specified in a key: value pair. The example sets strict-transport-security and x-custom-request headers. |
spec.config.appendResponseHeaders |
Specify the HTTP headers to add before returning a response to the caller. Headers are specified in a key: value pair. The example sets x-content-type-options , x-frame-options , and x-custom-response headers. |
spec.config.removeRequestHeaders |
Specify the HTTP headers to remove before forwarding a request to the destination. Headers are specified by their key names. The example removes user-agent headers. |
spec.config.removeResponseHeaders |
Specify the HTTP headers to remove before returning a response to the caller. Headers are specified by their key names. The example removes x-server and x-envoy-upstream-service-time headers. |
Verify header manipulation policies
-
Apply the example header manipulation policy in the cluster with the Bookinfo workspace in your example setup.
kubectl apply --context ${REMOTE_CONTEXT1} -f - << EOF apiVersion: trafficcontrol.policy.gloo.solo.io/v2 kind: HeaderManipulationPolicy metadata: name: modify-header-hsts namespace: bookinfo spec: applyToRoutes: - route: labels: route: ratings config: appendRequestHeaders: x-custom-request: bookinfo appendResponseHeaders: strict-transport-security: max-age=16070400; includeSubDomains x-content-type-options: nosniff x-frame-options: deny x-custom-response: bookinfo removeRequestHeaders: - user-agent removeResponseHeaders: - x-server - x-envoy-upstream-service-time EOF
-
Create a route table for the ratings app. Because the policy applies at the route level, Gloo checks for the route in a route table resource.
kubectl apply --context ${REMOTE_CONTEXT1} -f - << EOF apiVersion: networking.gloo.solo.io/v2 kind: RouteTable metadata: name: ratings-rt namespace: bookinfo spec: hosts: - ratings http: - forwardTo: destinations: - ref: name: ratings namespace: bookinfo labels: route: ratings workloadSelectors: - {} EOF
Review the following table to understand this configuration. For more information, see the API docs.
Setting Description hosts
The host that the route table routes traffic for. In this example, the ratings
host matches the ratings service within the mesh.http.forwardTo.destinations
The destination to forward requests that come in along the host route. In this example, the ratings service is selected. http.labels
The label for the route. This label must match the label that the policy selects. workloadSelectors
The source workloads within the mesh that this route table routes traffic for. In the example, all workloads are selected. This way, the curl container that you create in subsequent steps can send a request along the ratings route. -
Send a request to the ratings app from within the mesh.
Create a temporary curl pod in the
bookinfo
namespace, so that you can test the app setup. You can also use this method in Kubernetes 1.23 or later, but an ephemeral container might be simpler, as shown in the other tab.- Create the curl pod.
kubectl run -it -n bookinfo --context $REMOTE_CONTEXT1 curl \ --image=curlimages/curl:7.73.0 --rm -- sh
- Send a request to the ratings app.
curl http://ratings:9080/ratings/1 -v
- Exit the temporary pod. The pod deletes itself.
exit
Use the
kubectl debug
command to create an ephemeral curl container in the deployment. This way, the curl container inherits any permissions from the app that you want to test. If you don't run Kubernetes 1.23 or later, you can deploy a separate curl pod or manually add the curl container as shown in the other tab.kubectl --context ${REMOTE_CONTEXT1} -n bookinfo debug -i pods/$(kubectl get pod --context ${REMOTE_CONTEXT1} -l app=reviews -A -o jsonpath='{.items[0].metadata.name}') --image=curlimages/curl -- curl -v http://ratings:9080/ratings/1
If the output has an error about
EphemeralContainers
, see Ephemeral containers don’t work when testing Bookinfo. - Create the curl pod.
-
Verify that you notice the added or removed request and response headers.
Example response:
< HTTP/1.1 200 OK < content-type: application/json < date: Mon, 05 Sep 2022 19:02:58 GMT < server: envoy < x-content-type-options: nosniff < x-custom-response: bookinfo < x-frame-options: deny < transfer-encoding: chunked
-
Optional: Clean up the resources that you created.
kubectl --context $REMOTE_CONTEXT1 -n bookinfo delete routetable ratings-rt kubectl --context $REMOTE_CONTEXT1 -n bookinfo delete HeaderManipulationPolicy modify-header-hsts