Blog

Traefik 2.3: Towards Plugins and Beyond!

Traefik 2.3 (codename: Picodon - the cheese you can see illustrated below) and is available as a release candidate since mid-July 2020. More than a simple version increment, this release brings a lot of new features. Two significant new features caught my attention:

  • Introduction of Traefik Pilot: a new SaaS platform
  • Middleware plugin management

There are other new features that I won't cover in this post, such as compatibility with ECS, but be sure to check out my blog, I'll be posting an article on that soon.

Credit: https://fr.wikipedia.org/wiki/Picodon
Picodon

Is there a pilot in the plane?

Traefik is a complete and powerful reverse proxy, as I already presented in a previous article. Nevertheless, it lacked a managed health check solution.

It is now possible for free! The new service was launched in conjunction with the Traefik 2.3 release candidate.

Traefik Pilot is a new concept, delivering an entirely new approach to network management in the cloud. At the moment, it only facilitates the health check of your Traefik instances, allowing you to receive a notification if it becomes unavailable or unhealthy. Traefik Pilot is available now at pilot.traefik.io. Additional features are planned and will launch in the coming months!

After a quick sign-up, it is now possible to register one or more instances of Traefik.

I added the command line parameter in the Traefik startup arguments in my Kubernetes manifest, and after a reboot, the status changed to Green (OK).

However, there are a few things to keep in mind:

  • This status currently only corresponds to your Traefik container's state and does not mean that the backends are functional.
  • This health check is sent from your instance, in "heartbeat" mode, and does not necessarily mean that your server is reachable.
  • As the signal transmitted is a heartbeat, it is possible to monitor instances in the Pilot application area.

By clicking on your profile name at the top right, it is possible to define alarms, via webhooks or by e-mail.

It is worth noting that it is possible to indicate you wish to receive security alarms linked to the discovery of possible CVE that corresponds to your version of Traefik.

Warm up the plugins

For many years I've been using the ubiquitous Apache HTTP web server. Undoubtedly, one of the enormous strengths of this product is its modularity, allowing the community to extend its functionality.

Traefik now allows the use of plugins as well. The list is currently rather small, but I do not doubt that the catalog will snowball as the community begins publishing its creations!

It is possible to contribute plugins written in Go by following the guide provided by Containous.

For this article, I chose the "Block Path" plugin written by Containous. This plugin allows us to block access to individual pages based on regular expressions dynamically.

Blocked pages will directly return a 403 (Forbidden) error.

The interest of this kind of plugins, already existing in most reverse proxies, is to be able to intercept access to individual pages and prevent the backend from receiving the request.

This type of middleware enables operators:

  • To not generate a load (for example, in the case of an admin page that could be brute-forced/DDOS).
  • To avoid exposing an undiscovered zero-day flaw, since the backend does not receive any requests.

Install the Plugin

Plugins load via the static configuration of Traefik. For this part, I loaded it via the command line parameters, since this is how I approach loading my entire configuration in Kubernetes.

args:
  - --providers.kubernetescrd
  - --accesslog=true
  - --accesslog.filepath=/var/log/traefik/access.log
  - --accesslog.fields.headers.defaultmode=keep
  - --entrypoints.web.address=:80
  - --entrypoints.websecure.address=:443
  - --certificatesresolvers.le.acme.email=myawesomemail@mail.com
  - --certificatesresolvers.le.acme.storage=/cert/acme.json
  - --certificatesResolvers.le.acme.httpChallenge.entryPoint=web
  - --experimental.pilot.token=mytoken
  - --experimental.plugins.demo.moduleName=github.com/containous/plugin-blockpath
  - --experimental.plugins.demo.version=v0.1.2

As you can see above, declaring the plugins is manageable via the experimental.plugins arguments.

In my command line example, "demo" is the name I gave to the plugin before moduleName. Thus, it contains the path to the GitHub repository containing the plugin, version being the Git version to checkout.

Once this configuration is in place, it is necessary to restart Traefik.

Configuring the plugin

The plugin then behaves like a traditional middleware; which I explain in my previous article on Traefik TLS configuration, middlewares are components that exist between Traefik and your backend and modify the normal behavior. For example, in the article mentioned above, the middleware I used allows you to define the necessary security headers for ranking A+ on SSL Labs.

The plugin then behaves like a traditional middleware; which I explain in my previous article on Traefik TLS configuration, middlewares are components that exist between Traefik and your backend and modify the normal behavior. For example, in the article mentioned above, the middleware I used allows you to define the necessary security headers for ranking A+ on SSL Labs.

For this example, I have declared a new middleware for use by Traefik in Kubernetes:

apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
  name: demo
spec:
  plugin:
    demo:
      regex: ["^/demo-[a-z]{1,5}"]

Configuring the plugin declared in the command line arguments requires referencing it in the manifest above in the metadata.name field. In the spec field, we can now configure the plugin according to the schema defined in the plugin's documentation. In the example above, I've used regex to indicate that Traefik should block any request whose path starts with "/demo-" with 1 to 5 lowercase letters.

Load middleware

Now that I have defined my middleware, I have to load it into my IngressRoute.

I modify my IngressRoute by declaring it should load this middleware too. As a reminder, you can define multiple middlewares on your IngressRoutes, which will execute in the order specified.

apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
  name: traefik-web-ui-tls
  namespace: default
spec:
  entryPoints:
    - websecure
  routes:
  - kind: Rule
    priority: 1
    match: (Host(`www.tferdinand.net`) || Host(`tferdinand.net`)) && PathPrefix(`/`)
    services:
    - name: ghost-tfe-fr
      port: 2368
      helthcheck:
        path: /
        host: tferdinand.net
        intervalSeconds: 10
        timeoutSeconds: 5
    middlewares:
      - name: security
      - name: demo
  tls:
    certResolver: le
    options:
      name: mytlsoption
      namespace: default

As you can see in spec.routes[0].middlewares, I've added a reference to the demo middleware that I installed and configured in the previous steps.

Let's test the plugin

Now, it's time to test my plugin configuration.

Yes, I also use Windows, and I assume it ;)

As you can see, the behavior we anticipated is present. Legitimate queries work as expected, and Traefik is blocking the requests which match the schema defined in the demo plugin configuration before ever reaching the backend service.

In conclusion: A small step for Containous, a big step for the community.

Traefik Plugins and Traefik Pilot are technology previews and only scratch the surface of their true potential; however, this open modularity will enable the community to extend the core features of Traefik without the necessity of custom forks or compiled code.

Traefik Pilot and Plugins will potentially allow companies to develop plugins on their own and thus adapt Traefik to their needs.

Traefik Pilot is an excellent initiative, and I can't wait to see how Containous will take-off with these new features!

Author's Bio

Teddy is a Cloud Security Architect at WeScale, an organization made up of cloud experts. He's former Ops, self-taught, and is passionate about containers and automation. He believes that knowledge is wealth that must be shared.