Allow Iframes on Grafana with Traefik (Docker)

Photo by Pankaj Patel on Unsplash

Overview

This document aims to show how to allow embedding iframes of panels from Grafana. However there’s a couple warnings.

  1. For the embed to work, Grafana must be open to the world and configured with SSL
  2. SameSite must be set to ‘none’ therefore, some CSRF attacks are feasible
  3. Even after embedding, loggin to grafana is mandatory so all users which access this iframe, must have a grafana user
  4. SSL configuration is mandatory since cookie_secure is set to True
  5. On how to get the iframe to display on the webpage, refer to this link

Configuring traefik

So, with the default configuration you will get an error similar to this one: Refused to display '[<https://my-domain.com/>](<https://my-domain.com>)' in a frame because it set 'X-Frame-Options' to 'deny'.

Do not waste time configuring traefik to not Deny X-Frame-Options since it’s deprecated, instead what we are going to configure is Content-Security-Policy and in this case, we are going to configure it with the frame-ancestors options, so in traefik it will look like this:

- "traefik.http.middlewares.frame.headers.contentSecurityPolicy=frame-ancestors https://my-domain.com https://*.my-other-domain.com"

This will allow the domains listed to load contents from grafana

ℹ️ When using CSP instead, the usage of X-Frame-Options gets overridden

We also need to configure via labels, that grafana HTTP router on traefik, uses this middleware, so at the end it will look like this:

- "traefik.http.middlewares.frame.headers.contentSecurityPolicy=frame-ancestors https://my-domain.com https://*.my-other-domain.com"
- "traefik.http.routers.grafana.middlewares=frame"

⚠️ Note: you need to configure these labels on grafana container in docker-compose.yml

⚠️ Note: on traefik.http.routers.grafana.middlewares grafana is the name of the router you are assigning the middleware, this might change depending on the set-up

Confirm that you are using the middleware

Refer to your Traefik dashboard, and search for the grafana router, you should see a middleware attached to it like this:

Note the middleware

Configuring Grafana

For grafana, it depends, in this case we are going to add the configuration as env variables, here you have what you need:

- GF_SECURITY_ALLOW_EMBEDDING=true
- GF_SECURITY_COOKIE_SAMESITE=none
- GF_SECURITY_COOKIE_SECURE=true
  • GF_SECURITY_ALLOW_EMBEDDING : allows usage of iframes
  • GF_SECURITY_COOKIE_SAMESITE : this cookies controls how content can be displayed, default is “lax” which only allows embedding content when is displayed inside the same domain. Setting it to “none” allows us to show from everywhere embedded content (this, by default is a security hole, but we control with traefik which domains can display content from grafana)
  • GF_SECURITY_COOKIE_SECURE : this setting only allows set-cookie if the site works through SSL, without this option, embedding will work on firefox, but not on chrome.

Results

I’ve tested the configuration, using a docker container with nginx serving a static page with the iframe I want so show, remember is important that SSL is configured, and if possible, with a valid certificate.

Results:

Firefox & chrome page both showing the panel desired

Sources

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store