If Traefik’s dashboard, API endpoints (/api/rawdata, /api/http/services, /api/http/routers), or /debug/pprof answer requests from the public internet, you are publishing a map of your infrastructure. The API returns every router rule, backend server URL, middleware configuration, and upstream health status. /debug/pprof adds Go runtime profiling data. Automated scanners fingerprint Traefik continuously, and the dashboard API has a history of information-disclosure issues. The fix is usually a ten-minute configuration change, but only if you know the exposure exists. Many teams never test from outside their own network.

This guide covers how to probe for the exposure from an untrusted network, the common misconfiguration patterns, and how to lock the management surface down with an IP allowlist, authentication, network policy, or a non-public entrypoint.

What this means

Traefik has two planes. The data plane serves your entrypoints (ports 80/443) and proxies traffic to backends. The control plane serves the dashboard, the REST API, and optionally the Go debug endpoints. The control plane is where the sensitive material lives:

  • /api/rawdata returns the complete dynamic configuration: routers, services, middlewares, their status, and dependency relations. In effect, your entire routing table.
  • /api/http/services reveals every backend server URL, so an attacker learns internal hostnames, ports, and IP addresses directly.
  • /api/http/routers shows every routing rule, including rules for internal-only services that should not be publicly known.
  • /dashboard/ is the web UI backed by the same API.
  • /debug/pprof/ (when api.debug is enabled) exposes Go profiling data: goroutine dumps, heap profiles, CPU profiles. Beyond reconnaissance value, profiling endpoints can be abused to burn CPU on the proxy itself.

An attacker with this map knows which backends exist, which are unhealthy, which middleware protects which route, and where the soft targets are. In some configurations the API also exposes certificate details. Combined with known auth-middleware bypass CVEs in unpatched Traefik versions (for example CVE-2024-45410, fixed in v2.11.9 and v3.1.3), an exposed API is both an information leak and an attack surface.

The rule is simple: the dashboard entrypoint must never be published to the public internet. Not “protected later”, not “obscured on a weird port”. Never published.

flowchart LR
  Internet[Public internet] -->|probe /api, /dashboard, /debug| Entry{Entrypoint}
  Entry -->|published, no auth| API[Traefik API + dashboard]
  Entry -->|allowlist + auth, or not published| Deny[403 / connection refused]
  API --> Raw[/api/rawdata: full routing table/]
  API --> Svcs[/api/http/services: backend URLs + health/]
  API --> Pprof[/debug/pprof: Go profiling/]

Common causes

CauseWhat it looks likeFirst thing to check
api.insecure=true left onAPI and dashboard served directly on the traefik entrypoint (default port 8080), no authentication, middleware does not applyStatic config: api.insecure or --api.insecure flag
Dashboard entrypoint bound to a public interfacePort 8080 (or the custom dashboard port) reachable from the internet via the load balancer or host firewallProbe the public IP on the dashboard port from outside
Kubernetes Service exposing the dashboard portA Service of type LoadBalancer or NodePort includes the dashboard/API port alongside 80/443kubectl get svc and check the published ports
Router for the API without auth middlewareapi@internal routed on a public entrypoint with no BasicAuth, ForwardAuth, or IPAllowList attachedDynamic config for the router targeting api@internal
api.debug=true in production/debug/pprof/ and /debug/vars answering on the API surfaceStatic config: api.debug or --api.debug flag
Firewall/security group wider than intendedThe management port is firewalled on some paths but the cloud security group allows 0.0.0.0/0Probe from a genuinely external network, not from a VPN

A subtle trap with api.insecure=true: it bypasses middleware entirely. Operators often enable insecure mode “temporarily”, then try to bolt on BasicAuth via labels or dynamic config, and it silently does nothing because the insecure API handler never passes through the middleware chain. If you want middleware-based protection, you must disable insecure mode and route api@internal explicitly.

Quick checks

Run these from a network that is genuinely outside your perimeter: a personal hotspot, a VPS in another cloud, or a scanner host. Probing from the office LAN or VPN will give you false reassurance.

# Probe the management surface from an external host.
# Any 200 here from the public internet is a finding.
for path in /api/rawdata /api/http/services /api/http/routers /dashboard/ /debug/pprof/; do
  code=$(curl -s -o /dev/null -w '%{http_code}' --max-time 5 "http://traefik-public-ip:8080${path}")
  echo "${code}  ${path}"
done
# Check whether the dashboard port is even open on the public address
nc -zv traefik-public-ip 8080
# On the host or in the pod: inspect how the API is configured
# Static config flags (process args)
ps aux | grep -o '\-\-api[^ ]*' 

# Or in the static config file
grep -A5 '^api:' /etc/traefik/traefik.yml
# Kubernetes: check which ports the Traefik Service publishes
kubectl -n traefik get svc -o wide
kubectl -n traefik get svc traefik -o jsonpath='{.spec.ports[*].port}'
# See what the API actually discloses (run against the internal address)
curl -s http://localhost:8080/api/http/services | head -c 2000

Interpretation: 401 or 403 from outside means some protection exists (verify it is real and not bypassable). 404 or connection refused means the surface is not published. 200 means you have an exposure to fix now.

How to diagnose it

  1. Establish the external truth first. Run the probe loop above from an untrusted network. Record which paths return 200, which return 401/403, and which are unreachable. This is your exposure inventory.

  2. Determine how the API is being served. Check the static configuration for api.insecure. If it is true, the API is bound to the traefik entrypoint directly and no middleware can protect it. If it is false (the default), look for a router in the dynamic configuration that targets the api@internal service and note which entrypoints it is attached to.

  3. Map the network path. If the API answers on the public IP, find out why: is the dashboard entrypoint bound to 0.0.0.0 and published by a cloud load balancer? Is there a Kubernetes Service or Ingress that includes the management port? Is a security group allowing the port from 0.0.0.0/0?

  4. Check whether debug mode is on. Look for api.debug=true in the static config or --api.debug in the process arguments. If /debug/pprof/ answered in step 1, treat it as part of the exposure even if the dashboard itself is protected.

  5. Check the Traefik version. An exposed management surface on an unpatched version compounds the risk, because several auth-middleware bypass CVEs (path normalization, header normalization, middleware ordering issues) have been fixed in recent patch releases. If you must keep the API reachable from anywhere beyond localhost, being current on patches is not optional.

  6. Review the audit trail. If the API was exposed, pull access logs (Traefik’s and any upstream LB logs) and look for requests to /api/*, /dashboard/*, and /debug/* from source IPs you do not recognize. Assume anything returned by /api/rawdata is now known.

Metrics and signals to monitor

This exposure is primarily detected by external probing and network audit, not by metrics. But Traefik’s Prometheus metrics give you supporting evidence of probing and exploitation attempts:

SignalWhy it mattersWarning sign
Entrypoint 404 rate (traefik_entrypoint_requests_total{code="404"})Scanners enumerating paths and hosts show up as unmatched requests at the entrypointSudden increase over 3x baseline, especially concentrated on unknown Host headers
401/403 rate (traefik_entrypoint_requests_total{code=~"40[13]"})Tells you whether auth middleware on the API is being exercised or attackedSustained rate above 5x baseline from concentrated sources
Requests hitting the management entrypointA management entrypoint that should see near-zero traffic should see near-zero trafficAny sustained request rate on the dashboard/API entrypoint from outside your admin ranges
Access log review of /api/*, /debug/* pathsConfirms actual reads of the routing table, not just probes200 responses to these paths from unrecognized source IPs

Source IP caveat: if Traefik sits behind a CDN or cloud load balancer, access log source IPs are the intermediary’s. Parse X-Forwarded-For for the real client address.

Fixes

Disable insecure mode and route the API deliberately

Turn off api.insecure. It exists for local development, and it disables any possibility of middleware-based protection. In production, the API and dashboard are disabled by default (api: false); if you need them, enable the API and expose api@internal through an explicit router in the dynamic configuration, with protection attached. That router is where your defenses live.

Attach an IPAllowList middleware

Restrict the management router to known admin networks using the IPAllowList middleware with sourceRange in CIDR notation. The default rejection status is 403; rejectStatusCode can be changed if you prefer to return 404 and not confirm the endpoint exists. If Traefik is behind a proxy or load balancer, configure ipStrategy (depth or excludedIPs) so the allowlist evaluates the real client IP from X-Forwarded-For rather than the LB address, otherwise you either allow nothing or allow everything.

Add authentication as a second layer

IP allowlisting plus BasicAuth or ForwardAuth on the management router gives you defense in depth: a network change alone does not open the door. Put auth middleware before any path-manipulation middleware in the chain; several published auth-bypass CVEs exploit the strip-before-auth ordering. Never ship default or placeholder credentials.

Bind the dashboard to a non-public entrypoint

The cleanest fix is architectural: serve the dashboard and API on a dedicated entrypoint bound to localhost or an internal interface only, and reach it through a VPN, bastion, or kubectl port-forward. If the port is never published by a load balancer, Service, or security group, there is nothing to misconfigure later. In Kubernetes, double-check that no Service of type LoadBalancer or NodePort includes the management port.

Turn off debug mode

Set api.debug=false (the default) in production. If you need pprof for an investigation, enable it temporarily on an internal-only entrypoint and turn it back off when done. Go profiling endpoints are both a disclosure risk and a cheap way to burn proxy CPU.

Rotate what the exposure leaked

If the API was publicly reachable for an unknown period, treat the leaked data as known: internal hostnames, ports, backend topology, and any secrets that were visible in the dynamic configuration. Review access logs for reads of /api/*, and patch Traefik to a current release before re-exposing anything, even internally.

Prevention

  • Probe continuously, not once. Add an external check that periodically requests /dashboard/ and /api/rawdata against your public addresses and alerts if any return 200. Exposure often reappears after a Helm upgrade, a new Service, or a security group change.
  • Keep the API disabled unless you use it. api: false is the default. If nobody on the team queries the API or opens the dashboard, leave it off.
  • Deny by default in network policy. In Kubernetes, use NetworkPolicy so only intended namespaces can reach the management port. At the cloud layer, scope the security group for the management port to admin CIDRs, or do not create a rule at all.
  • Review middleware ordering in CI. Lint dynamic configuration for routers serving api@internal and verify auth and allowlist middleware are present and ordered before any path rewriting.
  • Patch Traefik on a schedule. Auth-middleware bypass fixes land in patch releases regularly. An allowlist you trust today is only as strong as the proxy version enforcing it.

How Netdata helps

  • Netdata collects Traefik’s Prometheus metrics per second, so a sudden burst of entrypoint 404s or 401/403s from scanner activity is visible as it happens, not five minutes later.
  • Per-entrypoint request charts make it obvious when a management entrypoint that should be idle starts serving real traffic, which is exactly what an accidental exposure looks like from the inside.
  • Code-level breakdowns of traefik_entrypoint_requests_total let you separate scanner noise (404s on unknown hosts) from auth pressure (401/403 on the API router) without touching raw logs.
  • ML-based anomaly detection on request rates and error ratios catches the low-and-slow probing pattern that static thresholds miss, like a scanner spreading requests across hours.
  • Alerting on the 4xx ratio at the entrypoint level gives you an early tripwire when new paths, including management paths, start receiving external attention after a config or network change.