Hardening Traefik when using the Docker Provider
— Docker, Architecture, Python — 1 min read
This issue on the Traefik GitHub tracker piqued my interest the other day. The Docker Socket does come up as the Achilles heel at times, with different mitigations to secure it - Proxy Containers, exposing via TLS with Authentication and Authorisation. What you choose is down to your risk appetite and your broader environment.
In this scenario, having the Docker Socket bound to an Internet-facing container wasn't a risk I wanted to take. A few options have been floated already (Sock Proxy, Switch to TLS etc., Switch to static file config). However, I wanted to take a stab at an alternative route.
The result is traefik-prism
. It is a simple Python script that takes a valid Traefik Dynamic Config and publishes it to an Internet-facing container, which isn't attached to Docker.
Example Deployment for traefik-prism
It takes advantage of the built in APIs in Traefik, no magic here. It is designed to handle different Traefik providers, not just Docker (hint: comments from other provider users warmly welcomed). Roughly, the script;
- retrieves the current Dynamic config (the frontends and backends) from
/api
on the API Endpoint (normally port 8080), - extracts the frontends and backends from the response, based off the
PROVIDERS
environment variable, then merge the potentially multiple blocks (sayfile
anddocker
), into one config, - finally, pushes the new merged config to
/api/endpoints/rest
. The new config should be active immediately.
The security model of pushing from a higher security level zone (in this case a container with access to the Docker socket), and pushing to a lower one is a common pattern for securing systems. There isn't any 'sensitive' data to leak here, so I'm not too bothered about content checking as we move from high to low.
Check out the code on GitHub or pull the image straight from Docker Hub.
As ever, thoughts and comments always welcome!