Skip to main content

Configuration Reference

Synapse supports three configuration methods (highest to lowest priority):

  1. Command Line Arguments - override specific settings via CLI flags
  2. Environment Variables - e.g. export API_KEY="your-key"
  3. YAML Configuration File - via config.yaml
Environment variable prefix

The AX_ (and AX_ARXIGNIS_) environment-variable prefix is deprecated. Use the unprefixed variable names (e.g. API_KEY, not AX_API_KEY). The old prefixes still work but log a deprecation warning and will be removed in a future release.

Operating Modes

mode: "agent" # or "proxy"
  • agent (default) - Access rules, fingerprinting, IDS, and monitoring only. The reverse proxy (pingora) is disabled.
  • proxy - Full reverse proxy functionality plus everything in agent mode.

Terminal Mode (TUI)

Synapse ships a real-time ratatui terminal UI that displays live JA4+ fingerprints, traffic, and threat data. Works on Linux and Windows.

# Embedded: TUI runs in the same process as the agent/proxy
synapse --mode agent --terminal

# Standalone: attach to a running daemon over its unix socket (Linux only)
synapse --terminal

YAML Configuration

Basic Example

mode: "agent"

network:
iface: "auto" # auto-attach physical uplinks only
ip_version: "auto" # processes both IPv4 and IPv6

firewall:
mode: "auto" # auto, xdp, nftables, iptables, none

platform:
api_key: "your-api-key"
base_url: "https://api.gen0sec.com/v1"
telemetry_sending_enabled: true

logging:
level: "info"

Feature Toggles

FeatureYAML PathEnvironment VariableDefault
Packet Capturecapture.enabledCAPTURE_MODEtrue
Inline IDS (Thalamus)ids.enabledtrue
ML Classifierclassifier.enabledfalse
Threat Intelligenceplatform.threat.enabledtrue
GeoIPplatform.geoip.enabledtrue
Telemetry Sending (API)platform.telemetry_sending_enabledLOG_SENDING_ENABLEDtrue
Unified Fingerprint Loglogging.fingerprint_log.enabledtrue
File Logginglogging.file_logging_enabledLOGGING_FILE_ENABLEDtrue
Syslog (Linux)logging.syslog.enabledLOGGING_SYSLOG_ENABLEDfalse
ETW (Windows)logging.etw.enabledLOGGING_ETW_ENABLEDfalse
Windows Event Loglogging.windows_event_log.enabledLOGGING_WINDOWS_EVENT_LOG_ENABLEDfalse
Content Scanningproxy.content_scanning.enabledCONTENT_SCANNING_ENABLEDfalse
CAPTCHA Protection(enabled when keys are set)CAPTCHA_SITE_KEY, CAPTCHA_SECRET_KEYdisabled
ACME (Auto TLS)deprecatedproxy.acme.enabledACME_ENABLEDtrue
Internal Servicesproxy.internal_services.enabledINTERNAL_SERVICES_ENABLEDtrue
PROXY Protocolproxy.protocol.enabledPROXY_PROTOCOL_ENABLEDfalse
HTTP/2 cleartext (h2c)proxy.h2ctrue
telemetry_sending_enabled (renamed)

The platform log/telemetry toggle is now platform.telemetry_sending_enabled (formerly log_sending_enabled). Its environment override remains LOG_SENDING_ENABLED.

Core Sections

Network

network:
# "auto" attaches XDP ONLY to physical UP uplink interfaces. Loopback and
# CNI/virtual/tunnel devices (veth*, lxc*, cilium*, docker*, bridges,
# vxlan/tunnels, etc.) are excluded, so it never clobbers a CNI datapath
# (e.g. Cilium) on Kubernetes nodes. bond*/VLAN uplinks (eth0.100) are kept.
iface: "auto"

# Explicit list overrides `iface`; entries are attached as-is (bypasses the
# "auto" filtering above — use this to opt in to a virtual interface).
ifaces: []

# "auto" (default) processes both IPv4 and IPv6.
ip_version: "auto"

Packet Capture

Controls the backend used for JA4+ fingerprint packet capture.

capture:
enabled: true

# Backend:
# auto — Auto-detect: XDP > af_packet_recv > pfring (default)
# xdp — eBPF/XDP BPF map polling (highest performance)
# af_packet — AF_PACKET TPACKET_V3 mmap ring buffer (zero-copy)
# af_packet_recv — AF_PACKET plain recvfrom() (works on all kernels,
# including 4.19 where TPACKET_V3 poll() is broken)
# pfring — PF_RING zero-copy (requires pf_ring.ko + libpfring,
# build with --features pfring-capture)
mode: auto

# interface: auto # "auto" = all interfaces; or a specific iface
snaplen: 65535 # max bytes per packet (af_packet/af_packet_recv/pfring)
filter: "tcp" # tcpdump-syntax BPF filter (af_packet, pfring)

af_packet: # only used when mode: af_packet
block_size: 4194304 # ring block size (power of 2, default 4MB)
block_count: 4 # number of blocks; total ring = block_size * block_count
block_timeout_ms: 100
promiscuous: true

pfring: # only used when mode: pfring
zero_copy: true
# cluster_id: 1 # multi-queue NIC load balancing (optional)

Environment overrides: CAPTURE_MODE, CAPTURE_SNAPLEN, CAPTURE_FILTER, PFRING_ZERO_COPY, PFRING_CLUSTER_ID.

Collector hygiene. capture.dedup_ttl_secs (default 600) suppresses re-processing a source already seen, so an established ban is not re-emitted on every poll. capture.collector_stale_secs (default 900) evicts idle entries from the fingerprint map. Keep the stale age comfortably above the dedup window, or live flows get dropped from the map while still inside their suppression period.

Firewall

firewall:
# auto: XDP > nftables > iptables > none
# xdp / nftables / iptables: force a backend
# none: disable kernel firewall, userland enforcement only
mode: "auto"

Blocklist capacity. firewall.max_ip_filter_entries_v4 and _v6 size the kernel maps, 50,000 each by default.

Raising it needs the pins gone

The maps are pinned and reused across restarts, and a pinned map keeps the size it was created with. A raised value takes effect only once the pins are removed — synapse --force-stop, or a reboot. A plain restart silently keeps the old size.

Inline IDS (Thalamus)

Synapse embeds the Thalamus IDS engine for inline, signature-based detection on captured traffic.

ids:
enabled: true
capture_mode: xdp
rule_paths:
- "/etc/synapse/rules/*.rules"
address_vars: {} # Suricata-style address variable definitions
port_vars: {} # Suricata-style port variable definitions
snaplen: 512
poll_timeout_ms: 100
flow_timeout_secs: 120
max_flows: 200000
cleanup_interval_secs: 30
stats_log_interval_secs: 5
enforce_block: true # drop matching flows (false = alert only)
Rule loading

Thalamus loads one rule per line — there is no \ line-continuation. A rule split across multiple lines silently loads as zero rules. Validate offline before deploying.

ML Classifier

Optional ONNX-based JA4+ fingerprint classification (ships with the -ml package variant).

ml:
fingerprint_classifier:
enabled: false
model_path: "" # path to the ONNX model file
cache_size: 10000 # max cached predictions (0 = no cache)
threshold: 0.5 # malicious probability threshold (0.0–1.0)

# Platform-managed models. `enabled: true` is enough — the model is
# downloaded and the remaining paths default.
traffic_classifier:
enabled: false
flow_classifier:
enabled: false
penalty:
enabled: false
jepa_embedder:
enabled: false
The top-level keys are deprecated

classifier, traffic_classifier, flow_classifier and penalty were once top-level. They are still accepted, but nest them under ml: instead — and note that the fingerprint model is now ml.fingerprint_classifier, not classifier.

Platform

platform:
api_key: ""
base_url: "https://api.gen0sec.com/v1"

# Send access logs / telemetry to the platform (formerly log_sending_enabled)
telemetry_sending_enabled: true

# WARNING: may capture PII, tokens, or API responses in logs
include_response_body: false
max_body_size: 1048576 # bytes; do not raise above the Basic plan maximum

# Threat intelligence MMDB
threat:
enabled: true
url: "https://download.gen0sec.com/v1"
path: "/var/lib/synapse"
headers: null
refresh_secs: 300 # 5 minutes

# GeoIP MMDB — ships with the IPinfo Lite bundle (single combined DB with
# both country + ASN). Synapse auto-detects the IPinfo schema, so the DB
# configured under `country` serves both country and ASN lookups; `asn`
# and `city` are unused and their refresh workers don't run.
geoip:
enabled: true
country:
url: "https://github.com/gen0sec/geoip-databases/raw/download/ipinfo_lite.mmdb"
path: "/var/lib/synapse/ipinfo_lite.mmdb"
headers: null
asn: { url: "", path: "", headers: null } # unused with IPinfo Lite
city: { url: "", path: "", headers: null } # unused with IPinfo Lite
refresh_secs: 28800 # 8 hours
GeoIP changed to IPinfo Lite

Synapse now defaults to a single combined IPinfo Lite database (ipinfo_lite.mmdb) instead of the split MaxMind GeoLite2 country/ASN/city files. To switch back to GeoLite2, point country/asn at the respective GeoLite2-*.mmdb URLs.

Platform integrations

Four platform.* subsections govern what the agent exchanges with the platform beyond threat intelligence. Two are on by default.

platform:
# Upload this agent's bans so the fleet can corroborate them. On by default.
ban_ledger:
enabled: true
interval_secs: 60

# Download the corroborated result. On by default; the refresh is a cheap
# version check and the artifact is only fetched when the version changes.
fleet_bans:
enabled: true
refresh_secs: 60
advisory: true
advisory_dedup_secs: 300

# East-west workload identity. Off by default: it needs a cluster-side
# producer publishing the identity MMDB before there is anything to fetch.
identity:
enabled: false
url: ""
path: "/var/lib/synapse"

# Report the observed service graph. Off by default.
service_graph:
enabled: false
interval_secs: 300

ban_ledger and fleet_bans are the two halves of one loop (see Fleet Bans) — you upload what this agent blocked, and pull back what the fleet corroborated. They share a 60-second cadence so neither leg is the slow one. Turning off the upload while leaving the download on is valid; you consume the fleet's conclusions without contributing.

identity and service_graph both ship disabled because each needs something on the other side. Identity needs a producer publishing the MMDB; enabling it without one just produces periodic failures. See Service Graph.

Logging

logging:
level: "info" # error, warn, info, debug, trace
file_logging_enabled: true
log_directory: "/var/log/synapse" # Windows: C:\ProgramData\Gen0Sec\Synapse\logs
max_log_size: 104857600 # 100MB
log_file_count: 10 # rotated files are gzip-compressed

# Syslog (Linux/Unix only; ignored on Windows)
syslog:
enabled: false
facility: "daemon"
identifier: "synapse"
levels: # per-log-type priority
error: "err"
app: "info"
access: "info" # proxy mode only

# Event Tracing for Windows — Windows equivalent of syslog.
# Events emit to ETW provider "Gen0Sec.Synapse".
etw:
enabled: false

# Classic Windows Event Log (Event Viewer → Windows Logs → Application)
windows_event_log:
enabled: false
source: "Synapse"

# Unified per-connection fingerprint/BPF event log (agent mode).
fingerprint_log:
enabled: true
# file: /var/log/synapse/fingerprints.log # default: {log_directory}/fingerprints.log
Per-type fingerprint logging is deprecated

The six per-type sections — bpf_stats, tcp_fingerprint, ssh_fingerprint, latency_fingerprint, tls_fingerprint, and http_fingerprint — are superseded by fingerprint_log (a.k.a. eventbridge_log), which emits every fingerprint/BPF event through one unified JSON log. They now ship disabled and will be removed in a future release. Use fingerprint_log.

When file_logging_enabled is true, Synapse writes (and rotates/compresses) error.log, app.log, and — in proxy mode — access.log (JSON).

Daemon / Service

Linux runs as a Unix daemon; Windows registers with the Service Control Manager (synapse --service install / sc start synapse; sc control synapse paramchange triggers a config reload).

daemon:
enabled: true
pid_file: "/var/run/synapse.pid" # Linux only
working_directory: "/var/lib/synapse"
user: root # Linux only
group: root # Linux only
chown_pid_file: true # Linux only

# Sockets used by standalone terminal clients
# event_socket: "/var/run/synapse-events.sock" # Windows: TCP, e.g. 127.0.0.1:19199
# control_socket: "/var/run/synapse-control.sock"

Proxy (proxy mode)

ACME is deprecated

The embedded ACME client is no longer a supported way to obtain certificates, and it is not documented as a feature anywhere else. It still ships and still defaults to enabled: true, so the keys are listed here for anyone who has it running — but do not build on it.

Provide your own certificate and key, or pass the connection through to a backend that holds them. On Kubernetes, use cert-manager — see Kubernetes Ingress.

proxy:
address_http: "0.0.0.0:80"
address_tls: "0.0.0.0:443"
certificates: "/etc/synapse/certs" # cert files: {NAME}.crt, {NAME}.key
tls_grade: "medium" # high, medium, unsafe
default_certificate: "default" # fallback cert (file stem)

# Enable HTTP/2 cleartext on the plaintext listener (gRPC over plaintext,
# --http2-prior-knowledge clients).
h2c: true

# Allow proxying HTTP CONNECT (tunneling/WebSocket upgrades). When false,
# CONNECT is rejected with 405.
allow_connect_method_proxying: false

# Max requests per connection before closing (frees per-connection memory).
# null = no limit (default).
keepalive_request_limit: null

redis:
url: "redis://127.0.0.1:6379/0"
prefix: "g0s:synapse"
# ssl:
# ca_cert_path: "/path/to/ca.crt"
# client_cert_path: "/path/to/client.crt" # optional, mutual TLS
# client_key_path: "/path/to/client.key" # optional, mutual TLS
# insecure: false

upstream:
conf: "/etc/synapse/upstreams.yaml"
healthcheck:
method: "HEAD" # HEAD, GET, POST
interval: 2 # seconds

protocol:
enabled: true
timeout_ms: 1000

captcha:
site_key: null
secret_key: null
jwt_secret: null # openssl rand -base64 48
provider: "hcaptcha" # hcaptcha, recaptcha, turnstile, prosopo
token_ttl: 7200
cache_ttl: 300

acme:
enabled: true
port: 9180 # binds to 127.0.0.1 only
email: null
storage_type: null # "file" or "redis" (defaults by whether redis is set)
storage_path: "/var/lib/synapse/acme"
development: false # true = Let's Encrypt staging
redis_url: null # overrides global redis.url for ACME storage

# Enabling the scanner scans nothing on its own — a WAF rule with action
# `content_scanning` is what selects the traffic. Requires Synapse 0.8.3+.
content_scanning:
enabled: false
clamav_server: "localhost:3310"
max_file_size: 10485760 # 10MB
# A selected request whose body cannot be inspected: block (413) or pass.
unscannable: block
# Ceiling on body memory held across all in-flight scans. Over it, scans
# fall back to streaming rather than refusing — load shedding, not policy.
scan_memory_budget: 268435456
# Reuse a verdict for an identical body. 0 disables. Failures never cached.
verdict_cache_ttl_secs: 300
verdict_cache_entries: 8192

internal_services:
enabled: true # auto-disabled in agent mode
port: 9180
bind_ip: "127.0.0.1"

# CIDRs whose L4 peer is a trusted upstream reverse proxy. Empty by default.
trusted_proxies: []

Client address behind a proxy

Two things key off the client address: the WAF rate-limit bucket, and ip.src in the wirefilter context. Both default to the L4 socket peer — which, when Synapse sits behind a load balancer, is the load balancer.

That breaks quietly rather than loudly:

  • An LB that rotates its source addresses scatters one client across many rate-limit buckets, so no bucket reaches the threshold and the rule never fires.
  • An LB that collapses many clients onto a few addresses puts unrelated users in one bucket, where they rate-limit each other.

proxy.trusted_proxies fixes both. List the CIDRs your proxies connect from, and for connections arriving from those ranges Synapse takes the client address from the first X-Forwarded-For token instead of the socket peer:

proxy:
trusted_proxies:
- "35.191.0.0/16" # GCP LB health checks and GFE
- "130.211.0.0/22" # GCP LB health checks
- "10.10.0.0/20" # an internal NLB range
Why a list, and not just trusting the header

X-Forwarded-For is client-supplied and trivially forged. A client connecting directly is not inside any listed range, so its header is ignored and the socket peer wins. Trust is granted to the hop, never to the header — which is why an empty list is the safe default and why widening these ranges beyond your actual proxies hands clients a way to spoof their own address.

PROXY protocol v2 (proxy.protocol.enabled) solves the same problem for L4 proxies that speak it. Use trusted_proxies when the upstream does not — a GCP Global External Application Load Balancer, for instance.

Environment Variables

# Application mode & runtime
export MODE="agent" # or "proxy"
export MULTI_THREAD="false" # enable multi-threaded runtime
export WORKER_THREADS="4" # worker threads when MULTI_THREAD=true

# Redis
export REDIS_URL="redis://127.0.0.1:6379/0"
export REDIS_PREFIX="g0s:synapse"
export REDIS_SSL_CA_CERT_PATH="..."
export REDIS_SSL_CLIENT_CERT_PATH="..."
export REDIS_SSL_CLIENT_KEY_PATH="..."
export REDIS_SSL_INSECURE="false"

# Network & capture
export NETWORK_IFACE="auto"
export NETWORK_IFACES="eth0,eth1"
export NETWORK_IP_VERSION="auto"
export CAPTURE_MODE="auto" # xdp, af_packet, af_packet_recv, pfring
export CAPTURE_SNAPLEN="65535"
export CAPTURE_FILTER="tcp"
export PFRING_ZERO_COPY="true"
export PFRING_CLUSTER_ID="1"
export FIREWALL_MODE="auto"

# Gen0Sec Platform
export API_KEY="your-api-key"
export BASE_URL="https://api.gen0sec.com/v1"
export LOG_SENDING_ENABLED="true" # platform.telemetry_sending_enabled

# Logging
export LOGGING_LEVEL="info"
export LOGGING_FILE_ENABLED="true"
export LOGGING_DIRECTORY="/var/log/synapse"
export LOGGING_MAX_FILE_SIZE="104857600"
export LOGGING_FILE_COUNT="10"
export LOGGING_SYSLOG_ENABLED="false" # Linux
export LOGGING_SYSLOG_FACILITY="daemon"
export LOGGING_SYSLOG_IDENTIFIER="synapse"
export LOGGING_ETW_ENABLED="false" # Windows
export LOGGING_WINDOWS_EVENT_LOG_ENABLED="false" # Windows
export LOGGING_WINDOWS_EVENT_LOG_SOURCE="Synapse"

# Content scanning
export CONTENT_SCANNING_ENABLED="true"
export CLAMAV_SERVER="localhost:3310"
export CONTENT_MAX_FILE_SIZE="10485760"
export CONTENT_SCAN_CONTENT_TYPES="application/json,multipart/form-data"
export CONTENT_SKIP_EXTENSIONS="jpg,png"
export CONTENT_SCAN_EXPRESSION='http.request.method eq "POST"'

# CAPTCHA
export CAPTCHA_SITE_KEY="your-site-key"
export CAPTCHA_SECRET_KEY="your-secret-key"
export CAPTCHA_JWT_SECRET="your-jwt-secret"
export CAPTCHA_PROVIDER="hcaptcha" # hcaptcha, recaptcha, turnstile, prosopo
export CAPTCHA_TOKEN_TTL="7200"
export CAPTCHA_CACHE_TTL="300"

# Internal services & PROXY protocol
export INTERNAL_SERVICES_ENABLED="true"
export INTERNAL_SERVICES_PORT="9180"
export INTERNAL_SERVICES_BIND_IP="127.0.0.1"
export PROXY_PROTOCOL_ENABLED="true"
export PROXY_PROTOCOL_TIMEOUT="1000"

# Daemon
export DAEMON_ENABLED="true"
export DAEMON_PID_FILE="/var/run/synapse.pid"
export DAEMON_WORKING_DIRECTORY="/var/lib/synapse"
export DAEMON_USER="root"
export DAEMON_GROUP="root"
export DAEMON_CHOWN_PID_FILE="true"

Upstreams Configuration

Routing lives in its own file, upstreams.yaml, hot-reloaded independently of the main config. It declares which hosts Synapse serves, how TLS is handled for each, and which backends a path forwards to.

File discovery is the only provider

provider accepts "file". Nothing else is implemented — the discovery match has one arm and a fallthrough that logs Unknown discovery type and loads no upstreams at all, leaving the proxy running with nothing to route to.

Earlier revisions of this page documented Consul and Kubernetes providers. They do not exist. For Kubernetes, use the Ingress and Gateway API controller, which is a different and fully supported mechanism.

The v2 schema

version: 2

proxy:
# JA4+ fingerprints forwarded to your backend as X-JA4, X-JA4T, X-JA4H,
# X-JA4S, X-JA4L and X-JA4X. Default: true.
fingerprints:
forward: true
# Consistent-hash a client to the same backend across reconnects.
sticky_sessions:
enabled: false

# Defaults, in seconds. Per-host and per-route blocks override these.
timeouts:
connect: 30
read: 120
write: 30
idle: 60

# Applied to every terminated host. Per-route headers extend these.
headers:
response:
- "Strict-Transport-Security: max-age=31536000; includeSubDomains"

hosts:
example.com:
tls:
terminate:
cert: /etc/synapse/example.com.crt
# key: defaults to the cert path with a .key extension
paths:
"/":
# Single backend, the common case.
upstream: 127.0.0.1:8000
force_https: true
headers:
request:
- "Host: api.example.com"

# Several backends, weighted.
api.example.com:
tls:
terminate:
cert: /etc/synapse/api.example.com.crt
paths:
"/":
upstreams:
- addr: 127.0.0.1:8001
weight: 3
- addr: 127.0.0.1:8002
weight: 2

# Forward the connection encrypted, by SNI, without decrypting it.
legacy.example.com:
tls:
passthrough: true

Terminate or pass through, per host. These are exclusive. A terminated host can be inspected — WAF, content scanning, HTTP rules. A passthrough host cannot, because there is no decrypted request to inspect.

Layering. Headers and timeouts resolve global → host → route, each layer extending the one above rather than replacing it. Set a security header once at the top; override one slow endpoint's read timeout at the route.

Upstream DNS caching

When an upstream is named by hostname, the resolved address is cached for proxy.upstream.dns_cache_ttl_secs (default 60) rather than resolved on every connection.

On Kubernetes that matters more than it sounds: without it, every upstream connection makes a blocking call to the cluster resolver, which becomes the floor on peer-select latency. Raise it where Service ClusterIPs are stable; lower it if you rely on DNS-level failover.

Health checks

Backends are probed on an interval and dropped from rotation when they stop answering. Method and interval are set under proxy.upstream.healthcheck in the main config, not here.

Migrating from v1

Both schemas are supported side by side. Synapse sniffs the top-level version: key: 2 gets the v2 parser, and anything else — including no version: at all — is read as v1. Both lower into the same in-memory shape, so nothing downstream changes.

That default is the thing to watch: a v2 file that forgets version: 2 is not rejected, it is parsed as v1 and fails on fields v1 has never heard of. If you write v2, write the version line.

v2 is the newer schema and the one to prefer for new deployments — it makes host modes explicit and adds TLS passthrough, which v1 has no way to express. Existing v1 files keep working:

v1v2
upstreams:hosts:
certificate: / acme: at host leveltls.terminate.cert: (a path) / tls.passthrough:
servers:upstream: for one, upstreams: with addr/weight for several
request_headers: / response_headers:headers.request / headers.response
per-route connection_timeout, read_timeout, …timeouts: at whichever layer applies

SIGHUP Configuration Reload

Synapse supports runtime configuration reload via SIGHUP signal (Windows: sc control synapse paramchange):

kill -HUP $(cat /var/run/synapse.pid)

Hot-reloadable Settings

SettingConfig PathNotes
Log levellogging.levelSwitches log verbosity instantly
Telemetry sendingplatform.telemetry_sending_enabledEnable/disable API log sending
API keyplatform.api_keyUpdate platform credentials
Base URLplatform.base_urlChange API endpoint
Include response bodyplatform.include_response_bodyToggle body capture in access logs
Max body sizeplatform.max_body_sizeAdjust body size limit for logs
Upstreamsproxy.upstream.confRe-reads upstreams YAML file
Security rulesLocal file or APIRe-fetches access rules, WAF rules, and IDS rules
Threat / GeoIP MMDBsplatform.threat.*, platform.geoip.*Re-downloads MMDB files

Settings That Require Restart

SettingConfig PathReason
Listen addressesproxy.address_http, proxy.address_tlsPort bindings set at startup
Network interfacenetwork.iface, network.ifacesXDP attached at startup
Firewall modefirewall.modeBPF programs loaded at startup
Capture backendcapture.*Capture ring/sockets set up at startup
Inline IDSids.* (except rule files)Engine/capture initialized at startup
Classifierclassifier.*ONNX model loaded at startup
Runtime threadsmulti_thread, worker_threadsTokio runtime created at startup
Daemon settingsdaemon.*Process daemonization is one-time
Redis connectionproxy.redis.*Connection pool created at startup
CAPTCHA configproxy.captcha.*Provider initialized once
Content scanningproxy.content_scanning.*Scanner initialized once
Certificate pathsproxy.certificatesLoaded at startup
ACME settingsproxy.acme.*ACME manager created at startup
Internal servicesproxy.internal_services.*Server bound at startup
Fingerprint loglogging.fingerprint_log.*Appender built at startup
File / syslog / Windows logginglogging.file_logging_enabled, logging.syslog.*, logging.etw.*, logging.windows_event_log.*Appenders built at startup
IP versionnetwork.ip_versionBPF filter compiled at startup
PROXY protocolproxy.protocol.*Listener configured at startup

Internal Services Endpoints

When proxy.internal_services.enabled is true, the following endpoints are available:

EndpointMethodPurpose
/healthGETHealth check
/cgi-bin/captcha/verifyPOSTCAPTCHA verification
/.well-known/acme-challenge/*GETACME HTTP-01 challenges
/cert/expirationGETCheck all certificate expiration status
/cert/expiration/:domainGETCheck specific certificate status
/cert/renew/:domainPOSTManually trigger certificate renewal

Next Steps