No description
Find a file
Oleksii Khilkevych af59879bd7
All checks were successful
Test and Lint / test (3.12) (push) Successful in 49s
Test and Lint / test (3.11) (push) Successful in 49s
Build and Push Docker Image / build-and-push (push) Successful in 1m2s
Test and Lint / test (3.13) (push) Successful in 57s
Test and Lint / build (push) Successful in 50s
Revamp docs
2025-12-06 03:12:55 +01:00
.claude Bless 2025-12-05 15:42:43 +01:00
.forgejo Fix typecheck errors 2025-12-05 16:05:53 +01:00
examples/hooks Revamp docs 2025-12-06 03:12:55 +01:00
tls_leech Revamp docs 2025-12-06 03:12:55 +01:00
.dockerignore Fix issues 2025-12-05 16:01:35 +01:00
.gitignore Bless 2025-12-05 15:42:43 +01:00
docker-compose.yml Auto batchin via timer, extract domain from certificate itself 2025-12-05 19:28:23 +01:00
docker-entrypoint.sh Use gosu 2025-12-05 16:25:37 +01:00
DOCKER.md Revamp docs 2025-12-06 03:12:55 +01:00
Dockerfile More tools in the image for hooks 2025-12-05 19:36:11 +01:00
justfile Dual stack and configurable uid/gid 2025-12-05 16:19:48 +01:00
pyproject.toml Bump v0.1.1 2025-12-05 19:48:01 +01:00
README.md Revamp docs 2025-12-06 03:12:55 +01:00

TLS Leech

Build Tests

TLS certificate extraction and distribution tool.

Components

  • Server: HTTP API that accepts certificate uploads, saves to disk, runs hooks
  • Exporters: Extract certs from certbot, Kubernetes secrets, Traefik acme.json

Installation

Docker

docker pull cr.noroutine.me/catalyst/tls-leech:latest

Git

uv pip install git+https://nrtn.dev/catalyst/tls-leech.git

Run without install

uv run --with tls-leech@git+https://nrtn.dev/catalyst/tls-leech.git tls-leech --help

Server

tls-leech server \
    --cert-dir /var/lib/tls/certs \
    --hook-dir /etc/tls-leech/hooks \
    --user haproxy \
    --group haproxy \
    --api-keys secret123 \
    --port 8080

Endpoints:

  • GET /health - health check
  • POST /upload - upload certificate (JSON: {"cert": "...", "key": "..."})

Hook scripts:

  • All executable files in --hook-dir are run after uploads (debounced 3s)
  • No arguments passed - scripts discover certs in --cert-dir
  • Logs show script name, output, and exit status

Certificate storage:

  • Format: domain.pem (fullchain + key in single PEM file)
  • Permissions: 640 (or 600 if group ownership fails)
  • Domain extracted from certificate CN/SAN, sanitized for filesystem safety

Environment variables:

  • TLS_LEECH_API_KEYS - comma-separated API keys
  • TLS_LEECH_HOST - bind address (default: *)
  • TLS_LEECH_PORT - port (default: 8080)
  • TLS_LEECH_THREADS - workers (default: 4)
  • TLS_LEECH_HOOK_DELAY - debounce delay in seconds (default: 3.0)

Exporters

Certbot

Auto-detects deploy hook mode via RENEWED_LINEAGE env var.

# As certbot deploy hook (/etc/letsencrypt/renewal-hooks/deploy/)
tls-leech certbot --upload-url http://10.1.10.33:8080/upload --api-key secret123

# Manual export all certs
tls-leech certbot --upload-url http://10.1.10.33:8080/upload

Kubernetes

# All namespaces
tls-leech k8s --upload-url http://10.1.10.33:8080/upload

# Specific namespace
tls-leech k8s --namespace cert-manager --upload-url http://10.1.10.33:8080/upload

Traefik

tls-leech traefik \
    --acme-json /etc/traefik/acme.json \
    --upload-url http://10.1.10.33:8080/upload

Docker

See DOCKER.md.

Quick start:

docker run -d \
  -p 8080:8080 \
  -v ./certs:/var/lib/tls-leech/certs \
  -v ./hooks:/etc/tls-leech/hooks:ro \
  -e TLS_LEECH_API_KEYS=key1,key2 \
  cr.noroutine.me/catalyst/tls-leech:latest

Hook Script Example

#!/bin/bash
# /etc/tls-leech/hooks/01-reload-haproxy.sh

# Find all certs in cert directory
CERT_DIR="${TLS_LEECH_CERT_DIR:-/var/lib/tls-leech/certs}"

# Copy to HAProxy directory
rsync -a "$CERT_DIR/" /var/lib/haproxy/certs/

# Reload HAProxy
systemctl reload haproxy

Development

git clone https://nrtn.dev/catalyst/tls-leech.git
cd tls-leech
uv pip install -e ".[dev]"

# Format
just fmt

# Lint
just lint

# Type check
just typecheck

# All checks
just check

License

MIT