Files
2026-04-14 12:07:17 +10:00

2.5 KiB

mTLS Bridge Service

Internal HTTP-to-mTLS bridge for services that cannot present client certificates directly (for example, Grafana webhooks).

How it works

  1. Accepts plain HTTP requests inside the Docker network.
  2. Forwards requests to an upstream base URL.
  3. Preserves the incoming request path/method/body/query string.
  4. Presents a client certificate/key pair for mTLS authentication.

Environment variables

  • TARGET_URL (required): upstream base URL (for example http://node-red:1880).
  • CLIENT_CERT (default /certs/client.crt): client certificate path.
  • CLIENT_KEY (default /certs/client.key): client private key path.
  • UPSTREAM_CA_CERT (optional, alias: CA_CERT): CA bundle path to verify upstream TLS. Use false/0/no to disable verification.
  • TIMEOUT (default 5): request timeout in seconds.
  • LOG_LEVEL (default INFO): Python logging level.
  • HEALTH_ENDPOINT (default /_mtls_bridge/health): local container health endpoint path.
  • ALLOWED_PATHS_FILE (optional): file path containing one allowed endpoint path per line (for example /health). Blank lines and # comments are ignored. If unset, all paths are allowed.
  • MTLS_BRIDGE_BASIC_AUTH_USERS (required for Traefik auth): value for traefik.http.middlewares.*.basicauth.users (e.g. user:$$apr1$$...).
  • MTLS_BRIDGE_CORS_ALLOW_ORIGIN (default https://grafana.lan.ddnsgeek.com): origin allowed for browser-based panel actions.

Endpoints

  • GET /_mtls_bridge/health returns 200 OK for container health checks.
  • /* proxies requests to ${TARGET_URL}/* with method/body/headers/query string preserved (subject to optional allow-list checks).

Examples with TARGET_URL=http://node-red:1880:

  • https://mtls-bridge.../docker-update-lockouts/clear -> http://node-red:1880/docker-update-lockouts/clear
  • https://mtls-bridge.../health -> http://node-red:1880/health
  • https://mtls-bridge.../uptime-kuma -> http://node-red:1880/uptime-kuma

Compose integration

This repository includes monitoring/mtls-bridge/docker-compose.yml:

  • No public port exposure.
  • Read-only cert mount (${PROJECT_ROOT}/core/traefik/certs:/certs:ro).
  • Joined to internal monitoring/traefik networks.

Example test

curl http://mtls-bridge:8080/_mtls_bridge/health
curl -X POST http://mtls-bridge:8080/docker-update-lockouts/clear

Allow-list file example

# one path per line
/docker-update-lockouts/clear
/health
/uptime-kuma

When ALLOWED_PATHS_FILE is set, any path not listed returns 403 Endpoint not allowed.