DEV Community

Cover image for How to override an HTTP header in Traefik 🐲
Benjamin Rancourt
Benjamin Rancourt

Posted on • Originally published at benjaminrancourt.ca on

How to override an HTTP header in Traefik 🐲

Context

Recently, I installed Ghost on my Docker architecture and I had to override a default security HTTP header that I had implemented for all services on Traefik, because a part of the application was not working as expected. 😱

Screenshot of the error
Screenshot of the error, with the Chrome DevTools open.

Refused to display 'https://www.mamaisonsherby.ca/' in a frame because it set 'X-Frame-Options' to 'deny'.

For those unfamiliar with theX-Frame-Options HTTP response header, it is primarily used to indicate whether a browser can display a specific page in an iframe. So in my case, if someone tries to embed one of my sites into another site, the browser will fail to load my website.

Unfortunately for me, Ghost is currently using iframes to display the site in the backend, so we can see what the posts will look like when they're published. So I had 3 choices:

  1. I could lose this functionality (and keep the error page displayed);
  2. I could globally remove the X-Frame-Options or set it to SAMEORIGIN to allow frames on the same origin;
  3. I could try to override this header for my Ghost websites.

Naturally, as I try to have as much security as possible for my sites, I choose the third option. 😄

After some tries, I was finally able to get it working in just two easy steps. 🎉

Step 1 – Define a new middleware

In our case, the customFrameOptionsValue option allows us to override the frameDeny option that we used in the default Traefik configuration (via default@file below).

The customFrameOptionsValue allows the X-Frame-Options header value to be set with a custom value. This overrides the FrameDeny option.

So we just need to define a new middleware that sets this option to SAMEORIGIN:

services:
  ghost:
    deploy:
      labels:
        traefik.http.middlewares.frameOptionsSameOrigin.headers.customFrameOptionsValue: "sameorigin"
Enter fullscreen mode Exit fullscreen mode
The label added in a docker-compose.yml file.

If you need to use this middleware on multiple docker-compose.yml files, I'm pretty sure that you can set it directly in the Traefik configuration file. But this exercice is left to the reader. 😉

Step 2 – Add the middleware to the router

Once the middleware is defined, we need to apply it on a router. Since .middlewares is a list, its order is really important. In this case, they are applied in the same order as their declaration in the router, so from left to right.

# Add the new middleware to the router name ghost, after the others
services:
  ghost:
    deploy:
      labels:
        traefik.http.routers.ghost.middlewares: "default@file,frameOptionsSameOrigin"
Enter fullscreen mode Exit fullscreen mode
Our new middleware has been added after the default@file middleware to take precedence over it.

In our case, since it is not the same option that is used, the order doesn't really matter. I'm assuming that the customFrameOptionsValue is still applied after the frameDeny option.

Resume

So one way to override an HTTP header in Traefik is to simply:

  1. Define a new middleware that defines your new HTTP headers.
  2. Add the middleware to your router after the other middlewares.

Very easy when you know it, right? 😅

Top comments (0)