Notifications: - Warn once when a counter reaches warn_percent of its limit, through separate warn_*_url endpoints. - Write ntf/ markers so a lost Redis reply cannot re-send a breach. - Retry only when the request never left or the web app answered 429/5xx. Fixes: - Retry transactions Redis rejected; treat pool timeouts as definite. - Install the signal handler before startup work. - Stop logging the login suffix; redact notify URL credentials. - Reject corrupt or empty CDBs, truncated hash tables included. - Require a Sentinel password, refuse example placeholders, and default admin_addr to localhost. - Normalise /counters domains, count on the arrival day, log rejections, hide internals in errors and exit 1 on a failed drain. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
64 lines
3.3 KiB
TOML
64 lines
3.3 KiB
TOML
# migadu_counters configuration
|
|
# Install as /usr/local/etc/migadu_counters/config.toml (or pass -config PATH).
|
|
|
|
addr = ":5555" # API: POST /in, POST /out, GET /counters
|
|
admin_addr = "127.0.0.1:9095" # /health and /metrics, no auth: keep it private
|
|
auth_token = "…" # REQUIRED (or MIGADU_COUNTERS_AUTH_TOKEN); same value in mailqueuer's config
|
|
allowed_cidrs = [] # optional source-IP allowlist for the API, e.g. ["10.0.0.0/8"]
|
|
domains_cdb = "/usr/local/etc/migadu_counters/db/rspamd_domains_db" # where contrib/pull-domains.sh installs it
|
|
exempt = ["support@migadu.com", "contact@migadu.com"] # mail to/from these never counts
|
|
count_junk = false # count /in requests flagged junk by mizu
|
|
|
|
# Counting runs off the request path: /in and /out validate, enqueue and
|
|
# answer 202; workers drain the queue. A full queue answers 503 (dropped_total).
|
|
queue_size = 10000
|
|
workers = 8
|
|
# Parsed CDB records cached per loaded table (some domains carry thousands of
|
|
# per-mailbox overrides); 0 disables the cache.
|
|
max_cached_domains = 20000
|
|
|
|
# HTTP server timeouts (seconds); handler_timeout bounds the synchronous part
|
|
# of a request and each queued counting job.
|
|
read_header_timeout = 5
|
|
write_timeout = 30
|
|
idle_timeout = 60
|
|
handler_timeout = 4
|
|
|
|
[logging]
|
|
output = "stderr" # daemon(8) -o captures it; or a file path (reopened on SIGHUP)
|
|
format = "console" # or "json"
|
|
level = "info"
|
|
counting_output = "/var/log/migadu_counters/counting.log" # default: same as output; "off" disables
|
|
counting_format = "text" # Lua-like lines (default) or "json"
|
|
|
|
[redis]
|
|
db = 0 # must stay 0: migadu_web reads message counters from DB 0
|
|
password = "…" # or MIGADU_COUNTERS_REDIS_PASSWORD; required with sentinels
|
|
# password_optional = true # development only: allow Sentinel without a password
|
|
pool_size = 32
|
|
timeout_ms = 500
|
|
# Sentinel mode (production): writes -> master, reads -> replicas
|
|
master_name = "mymaster"
|
|
sentinels = ["10.0.0.10:26379", "10.0.0.11:26379", "10.0.0.12:26379"]
|
|
sentinel_password = ""
|
|
# Static mode (used when sentinels is empty)
|
|
# write_addr = "127.0.0.1:6379"
|
|
# read_addrs = ["127.0.0.1:6379"]
|
|
|
|
[notify]
|
|
# One URL per level; leave empty to disable notifications for that level.
|
|
# Placeholders: $LEVEL $ID $FLOW $PERIOD $ADDRESS $COUNT $LIMIT (all URL-escaped).
|
|
org_url = "https://admin.migadu.com/api/limits?level=$LEVEL&id=$ID&flow=$FLOW&period=$PERIOD&by=$ADDRESS&count=$COUNT"
|
|
address_url = "https://admin.migadu.com/api/limits?level=$LEVEL&id=$ID&flow=$FLOW&period=$PERIOD&by=$ADDRESS&count=$COUNT"
|
|
domain_url = "" # web app's D branch is still a TODO
|
|
# Early warning: one call when a counter reaches warn_percent of its limit
|
|
# (0 = off). Empty URLs disable a level. These must not be the /api/limits
|
|
# URLs above: the web app treats every call there as a breach.
|
|
warn_percent = 80
|
|
warn_org_url = "" # e.g. https://admin.migadu.com/api/limits/warning?level=$LEVEL&id=$ID&flow=$FLOW&period=$PERIOD&by=$ADDRESS&count=$COUNT&limit=$LIMIT&percent=$PERCENT
|
|
warn_address_url = ""
|
|
warn_domain_url = ""
|
|
user = "…"
|
|
password = "…" # or MIGADU_COUNTERS_NOTIFY_PASSWORD
|
|
timeout_seconds = 15 # per attempt; a request sent but unanswered is not retried
|