Skip to content

Middleware

Middleware is everything that happens to a request between "this router matched" and "the service gets it". Each piece is a small, single job — change a header, demand a password, rewrite the path, refuse the request outright — and a router carries a list of them, applied in order. This chapter proves three of the everyday ones against the lab backends; the catalogue is longer (rate limits, compression, retries, forwarding authentication to another service) and all of it follows the same pattern: define once, name it on routers.

Definitions and use

Middlewares are defined in dynamic configuration, next to the routers, in the middlewares: section — and a router opts in by name (transcript t04's setup is examples/dynamic-middlewares.yml):

http:
  middlewares:
    lab-header:
      headers:
        customRequestHeaders:
          X-Lab-Seen: "traefik-was-here"
  routers:
    otter:
      middlewares:
        - lab-header

From a Docker or other provider, the name needs its provider suffix — lab-header@file. Within one file, the bare name works, which is why the lab's file-based examples omit it.

Three proofs

A header the backend can see. With lab-header on the otter router, the backend's echo reports x-lab-seen: traefik-was-here — a header the visitor never sent. This is how proxies tell backends things: which site this is, whether the visitor is authenticated further out, anything both ends agree on. The security warning runs the other way, and chapter 14 states it.

stripPrefix: rewriting the path. The fern-files router matches PathPrefix(/files) and carries:

    files-strip:
      stripPrefix:
        prefixes:
          - "/files"

A request for /files/readme.txt arrives at the backend as /readme.txt — transcript t04 shows the backend's own path: line. This is the standard trick for a backend that insists on living at / while the public name gives it a folder, and the cause of a classic confusion (chapter 15) when a backend builds links using the unstripped path it never saw.

basicAuth: a password on the door.

    warden-auth:
      basicAuth:
        users:
          - "warden:$apr1$iCOobVYU$tJeYVtogvgtgcIwBRMV7L."

The entry is name:hash; the hash is an apr1 (Apache MD5) or bcrypt digest, made with openssl passwd -apr1 (chapter 3's companion file, examples/commands.txt, has it). Never write a plaintext password in this list — Traefik will not use one usefully, and the file would become a secret you have to protect. With the middleware on the otter router: no credentials, 401; wrong password, 401; right password, the page (transcript t04).

Honest notes on basicAuth

  • It is a lock, not a vault. It keeps the curious and the casual scanner out of an admin page. It is not a substitute for the service having its own accounts.
  • Over plain HTTP it is barely a lock at all: the password travels encoded, not encrypted, and anyone on the path can replay it. Chapter 7 is the fix; put passwords only on HTTPS routers.
  • The lab's password (lantern42) and its published hash are invented fixtures for a throwaway local service, included so the transcripts reproduce. Yours must be neither published nor reused.
  • Browsers remember basic-auth logins per site and are notoriously bad at letting you log out. For anything people use daily, the service's own login page is the kinder tool; basicAuth shines on rarely-visited admin corners.