Configuration Reference¶
This document describes all configuration fields supported by Nexus GSLB. The canonical struct is internal/config/config.go.
Quick start
- Default path: /etc/gslb/config.yaml (override with -config flag).
- YAML example with common fields:
cluster:
id: "prod-eu-glb"
node:
id: "edge-lon-01"
dns:
listenAddr: "0.0.0.0"
port: 5353
domain: "example.gslb.local"
loadbalancer:
algorithm: "round-robin"
endpoints:
- "203.0.113.10"
- "2001:db8::10"
database:
path: "/var/lib/gslbd/gslbd.db"
api:
enabled: true
listenAddr: "127.0.0.1"
port: 8080
webuiPath: "/opt/gslb/webui"
health:
type: http
port: 80
checkinterval: 10s
timeout: 2s
http:
path: "/healthz"
expectedstatus: 200
tls: false
insecureSkipVerify: false
state:
healthPolicy: "prefer-local"
quorumMinPercent: 51
heartbeatInterval: "10s"
heartbeatTTL: "30s"
nats:
servers: ["nats://n1.example.com:4222"]
metrics:
enablePrometheus: true
listenAddr: "0.0.0.0"
port: 9090
license:
secret: "dev-secret-change-me"
licenseKey: ""
Sections
cluster
- id (string): cluster identifier, used in NATS subjects and metric labels. Default: dev-cluster.
node
- id (string): node identifier. If empty, hostname is used.
dns
- listenAddr (string): bind address (UDP). Default 0.0.0.0.
- port (int): UDP port. Default 5353 (use 53 in production).
- domain (string): zone served. Example gslb.local.
database
- path (string): path to the SQLite database file. Default /var/lib/gslbd/gslbd.db.
- Use :memory: for ephemeral/testing.
- The parent directory must be writable; schema is created automatically on first run.
api
- enabled (bool): start the REST API server. Default false.
- listenAddr (string): bind address. Default 127.0.0.1 (loopback-only; change to 0.0.0.0 for network access).
API Security
Set GSLB_API_KEY and create named users before exposing the API on a network interface. When GSLB_API_KEY is unset the daemon runs in dev mode — all requests are treated as system admin with no authentication required.
port(int): TCP port. Default8080.webuiPath(string): path to the Next.js WebUI build output directory. When set, the WebUI is served from/ui/. Optional.
loadbalancer
- algorithm (string): one of:
- round-robin (default)
- weighted-round-robin (aliases: wrr, weighted_rr)
- geo-ip (aliases: geoip) — requires geoip.dbPath
- map-file (aliases: mapfile) — requires mapFile.rules
- asn — routes by client autonomous system number/ISP; requires asn.dbPath and asn.rules
- failover — always serves the highest-priority healthy member; members are ranked by their priority field (1 = primary, 2 = secondary, …; 0 = last-resort)
- endpoints ([]string): list of IPv4/IPv6 addresses (used by round-robin and weighted algorithms).
- weights (map[string]int, optional): per-endpoint weights. Missing entries default to 1. Weight 0 disables.
Example (weighted round-robin)
loadbalancer:
algorithm: "weighted-round-robin"
endpoints:
- 203.0.113.10
- 203.0.113.11
- 2001:db8::10
weights:
"203.0.113.10": 5
"203.0.113.11": 1
"2001:db8::10": 3
loadbalancer.geoip — Geo IP algorithm
- dbPath (string): path to a MaxMind GeoLite2 or GeoIP2 City .mmdb file.
- endpointLocations (map[string]EndpointLocation, optional): manual lat/lon overrides for endpoints that are not in the MaxMind DB (private IPs, datacenter addresses).
- lat (float64): latitude in degrees.
- lon (float64): longitude in degrees.
Example (geo-ip)
loadbalancer:
algorithm: "geo-ip"
endpoints:
- 203.0.113.10
- 203.0.113.11
- 10.0.1.1
geoip:
dbPath: "/etc/gslbd/GeoLite2-City.mmdb"
endpointLocations:
"10.0.1.1":
lat: 51.5074
lon: -0.1278
Notes:
- Endpoints with unknown locations (not in DB and no manual override) sort to the end of the candidate list.
- The DNS client's IP is used for the distance calculation; unknown client IPs fall back to round-robin order.
- Close the balancer (balancer.Close()) to release the .mmdb file handle.
Hot reload
The GeoIP database is reloaded automatically. When geoipupdate (or any tool) replaces the .mmdb file — including via atomic rename — the new database is opened and the endpoint location cache is rebuilt within milliseconds, with no DNS queries dropped and no restart required. Any reload failure is logged as an error; the previous database remains active.
loadbalancer.mapFile — Map file (CIDR routing) algorithm
- rules ([]MapRule): ordered list of CIDR→endpoint mappings.
- cidr (string): source CIDR block (e.g., 10.0.0.0/8).
- endpoint (string): preferred endpoint IP for this CIDR.
Example (map-file)
loadbalancer:
algorithm: "map-file"
endpoints:
- 203.0.113.10
- 203.0.113.11
mapFile:
rules:
- cidr: "10.0.0.0/8"
endpoint: "203.0.113.10"
- cidr: "192.168.0.0/16"
endpoint: "203.0.113.11"
Notes:
- First matching rule wins; the matched endpoint is returned first, followed by all other endpoints.
- If no CIDR matches (or client IP is unknown), all endpoints are returned in their registered order.
- Rules can be hot-reloaded at runtime via UpdateRules.
loadbalancer.asn — ASN/ISP routing algorithm
Routes DNS clients to preferred endpoints based on their autonomous system (AS) number or ISP organisation name. Useful for ISP-level traffic engineering — e.g., send Comcast customers to a specific PoP, or route a known transit provider to a directly-peered endpoint.
dbPath(string): path to a MaxMind GeoLite2-ASN or GeoIP2-ISP .mmdb file.rules([]ASNRule): ordered list of ASN/org→endpoint mappings. First matching rule wins.asn(uint, optional): autonomous system number to match exactly (e.g.,15169for Google).org(string, optional): substring to match against the AS organisation name; case-insensitive (e.g.,"COMCAST"matches"COMCAST-7922").endpoint(string): preferred backend IP when this rule matches.
At least one of asn or org must be set per rule. When both are set, asn takes precedence (exact match checked first). Clients whose ASN is not in the database, or whose ASN does not match any rule, fall through to round-robin across all endpoints.
Example
loadbalancer:
algorithm: "asn"
endpoints:
- 203.0.113.10 # PoP-A
- 203.0.113.11 # PoP-B
asn:
dbPath: "/etc/gslbd/GeoLite2-ASN.mmdb"
rules:
- asn: 15169
endpoint: "203.0.113.10" # Google → PoP-A
- org: "COMCAST"
endpoint: "203.0.113.11" # Comcast (any ASN) → PoP-B
- org: "COGENT"
endpoint: "203.0.113.10" # Cogent → PoP-A
Notes:
- Rules are evaluated in order; first match wins.
- org matching is a case-insensitive substring match against the full AS organisation name from the MaxMind database. "COMCAST" matches "COMCAST-7922", "COMCAST CABLE", etc.
- Clients from ASNs not in the database, or not matched by any rule, fall back to standard round-robin across all endpoints.
- The preferred endpoint is returned first in the candidate list; remaining endpoints follow in registered order. The DNS server and health manager will skip unhealthy endpoints in the candidate list.
loadbalancer.failover — Priority failover algorithm
The failover algorithm always serves the highest-priority healthy member. It is configured per-service (not in the static config file) via the algorithm field on the service and the priority field on each member.
Member priorities:
- priority: 1 — primary (first choice)
- priority: 2 — secondary (used if priority-1 members are all unhealthy)
- priority: N — Nth failover tier
- priority: 0 — unset; treated as last-resort (after all explicitly numbered members)
Behaviour:
- At query time, all unhealthy and disabled members are excluded from the candidate list.
- The remaining candidates are sorted by priority ascending; the first (lowest-numbered) candidate is returned.
- Automatic failback: when a higher-priority member passes health checks again it re-enters the candidate list and is immediately preferred over lower-priority members.
- Within a priority tier, if scoreWindow is configured on the health check, the higher-scored member wins; otherwise the first member in DB order is used.
- The failover algorithm is a per-service setting (services.algorithm). The static loadbalancer.algorithm field in gslbd.yaml applies only to the static load balancer (endpoints defined in the config file), not to DB-managed services.
Example (configure via API or TUI):
# Create pool and members
POST /api/v1/pools → {"name": "web-prod"}
POST /api/v1/pools/{id}/members → {"ipAddress": "10.0.0.1", "port": 80, "priority": 1}
POST /api/v1/pools/{id}/members → {"ipAddress": "10.0.0.2", "port": 80, "priority": 2}
POST /api/v1/pools/{id}/members → {"ipAddress": "10.0.0.3", "port": 80, "priority": 3}
# Create service with failover algorithm
POST /api/v1/services → {"name": "www", "domain": "example.com.", "algorithm": "failover", "poolId": "..."}
# Configure health checks so failed members are detected and excluded
PUT /api/v1/pools/{id}/healthcheck → {"type": "http", "port": 80, "intervalMs": 5000, "timeoutMs": 2000}
health
- enabled (bool): must be true to activate health checks. Default false. When false, all endpoints are treated as healthy and no probes are sent. Omitting the health: block entirely is equivalent to enabled: false.
- type: tcp, http, icmp, script, or webhook. See Health Checks reference for per-type parameters.
- port: target port (ignored for icmp).
- checkinterval: Go duration (e.g., 10s).
- timeout: Go duration.
- http.path, http.host, http.expectedstatus, http.contains (http type).
- icmpCount: echo requests per probe interval (icmp type, default 3).
- scriptPath: path to executable on local filesystem (script type, VM/bare-metal only).
- scriptContent: script body stored in DB and replicated via NATS — works on VMs, containers, and Kubernetes (script type, takes precedence over scriptPath).
- webhookURL, webhookMethod: URL and HTTP method for webhook checks (webhook type).
- http.tls: enable HTTPS.
- http.insecureSkipVerify: skip TLS verification (default false).
gitops
- repoURL: Git repository URL (SSH or HTTPS).
- branch: branch/ref to track (default main).
- pathPrefix: directory containing gslbd.yaml.
- pollInterval: duration between checks (default 30s).
- requireSignature: require GPG-signed commits (default true).
- allowedSigners: optional list of allowed GPG fingerprints.
- auth.sshKeyPath: private key for SSH.
- auth.tokenEnv: reserved for future HTTPS token support.
state
- healthPolicy: prefer-local (default), local-only, global-any-healthy, global-quorum.
- quorumMinPercent: minimum percent healthy for global-quorum (0–100, default 51).
- heartbeatInterval, heartbeatTTL: membership heartbeat cadence and TTL.
- nats.servers: list of NATS URLs. If empty, state sync is disabled.
- nats.tls.caFile, certFile, keyFile: mTLS settings.
- nats.auth: user/password, NKey seed path, or creds file (NATS JWT).
- nats.jetStream.domain: optional JetStream domain name.
Configuration sync (JetStream)
- enableConfigSync (bool): enable JetStream-based configuration sync. Default false.
- config.mode (string): jetstream (only supported mode).
- config.stream (string): JetStream stream name. Default NEXUS.cfg.
- config.subjectPrefix (string): base subject. Messages publish to <subjectPrefix>.<cluster>. Default nexus.cfg.
- config.kvBucket (string): KV bucket for latest desired config per cluster. Default NEXUS_CFG.
- config.applyTimeout (duration): max time to apply a received config. Default 5s.
Example (enable configuration sync)
state:
enableConfigSync: true
nats:
servers: ["nats://n1.example.com:4222"]
jetStream:
domain: "gslb"
config:
mode: "jetstream"
stream: "NEXUS.cfg"
subjectPrefix: "nexus.cfg"
kvBucket: "NEXUS_CFG"
applyTimeout: "5s"
backup
- enabled (bool): enable periodic database backups. Default false.
- dir (string): directory in which backup files are written. Default /var/lib/gslbd/backups. Created automatically if absent.
- interval (Go duration): how often to take a backup. Default 1h.
- keep (int): number of backup files to retain; oldest are deleted first. 0 retains all files. Default 24 (one day of hourly backups).
Backup files are named gslbd-<YYYYMMDDTHHMMSS>.db (UTC timestamp). Each file is a self-contained, independently openable SQLite database. The backup is taken with VACUUM INTO, which produces a clean consistent snapshot without blocking DNS queries or API requests.
Example
Retention note: with interval: 1h and keep: 24 you retain 24 hours of hourly backups (~24 × ~500 KB depending on pool size).
logging
- format (string): json (default) or text. Use json for log aggregation pipelines (Loki, Datadog, Splunk); text for human-readable console output.
- level (string): debug, info (default), warn, error. Set debug to enable DNS query logging (see dns.queryLog) and other verbose output.
Example
dns (additional fields)
- queryLog (bool): emit one structured log line per DNS response. Default false. Each line includes name, type, src (client IP), rcode, answers (selected IPs), and duration_us. Useful during incident investigation; disable in high-traffic environments to avoid log volume.
dns.axfr — Zone Transfers (RFC 5936 / RFC 1995)
- enabled (bool): allow AXFR/IXFR zone transfer requests. Default false. Must be set to true to enable any transfers.
- requireTsig (bool): when true, unsigned AXFR requests are refused with REFUSED. Default false. Recommended for public-facing authoritative zones.
IXFR requests (qtype=IXFR) are answered with a full AXFR transfer, satisfying secondary nameservers (BIND 9, Knot DNS, CoreDNS) that request incremental updates.
Zone contents served via AXFR:
- SOA record (opening and closing bookend per RFC 5936)
- NS records from nsNames
- A/AAAA records for every service that has at least one enabled pool member — all enabled members are included regardless of current health state, since secondary servers have no health data
- TXT records managed via the RFC 2136 dynamic DNS API
Example
dns:
listenAddr: "0.0.0.0"
port: 53
domain: "gslb.example.com"
queryLog: true
axfr:
enabled: true
requireTsig: true
To restrict AXFR to trusted secondaries, use firewall rules on port 53/TCP in addition to (or instead of) TSIG authentication. AXFR is always TCP-only; UDP requests receive REFUSED.
See Zone Transfers reference and the Secondary DNS setup guide for full configuration examples for BIND 9, Knot DNS, CoreDNS, NSD, and Cloudflare Secondary DNS.
api (additional fields)
- Authentication: controlled by GSLB_API_KEY (see below). When unset, the daemon runs in dev mode — all requests are treated as system admin with no login required. Always set this in production.
- Audit log: set GSLB_AUDIT_LOG to an absolute file path to write a dedicated JSON audit log of all mutating API calls (POST, PUT, DELETE). Each entry includes: method, path, actor (last 4 chars of the bearer token, or anon), remote, status, duration_ms. When unset, audit entries are written to the main structured log (distinguishable by "audit":true). GET requests and /api/v1/health are never audited.
Example (systemd EnvironmentFile)
auth
- sessionTTL (duration): how long a session lives. Default 24h.
- sessionExtend (bool): if true, each authenticated request resets the TTL (sliding window). Default true.
- bcryptCost (int): bcrypt work factor for password hashing. Range 10–14; default 12. Higher values are slower for attackers but also slower at login.
- setupEndpoint (bool): when true, POST /api/v1/auth/setup is available while the user table is empty. Default true. Set to false after initial bootstrapping if desired.
auth.oidc — SSO via OpenID Connect
- enabled (bool): activate OIDC/SSO. Default false.
- discoveryUrl (string): OIDC issuer base URL (must be https://). The daemon fetches <discoveryUrl>/.well-known/openid-configuration on startup.
- clientId (string): OAuth2 client ID registered with the provider.
- clientSecret (string): OAuth2 client secret.
- redirectUri (string): full callback URL registered with the provider (https://<host>/api/v1/auth/oidc/callback).
- scopes ([]string): OAuth2 scopes to request. Default: [openid, profile, email].
- roleClaim (string): claim name to inspect for role mapping (e.g., groups). If empty, all users receive defaultRole.
- roleMapping (map[string]string): maps claim values to Nexus role names. The claim may be a string or a list; the first match wins.
- defaultRole (string): role assigned when no roleMapping entry matches. Must be one of tenant_admin, operator, viewer. Default: viewer.
- allowedDomains ([]string): when non-empty, only email addresses whose domain matches are permitted; others receive 403.
Example
auth:
sessionTTL: "24h"
sessionExtend: true
bcryptCost: 12
setupEndpoint: true
oidc:
enabled: true
discoveryUrl: "https://accounts.google.com"
clientId: "1234567890-abc.apps.googleusercontent.com"
clientSecret: "GOCSPX-..."
redirectUri: "https://nexus.example.com/api/v1/auth/oidc/callback"
roleClaim: "groups"
roleMapping:
"nexus-admins": "tenant_admin"
"nexus-operators": "operator"
defaultRole: "viewer"
allowedDomains: ["example.com"]
Environment variables used by the auth system (set via EnvironmentFile, not in config.yaml):
| Variable | Required | Purpose |
|---|---|---|
GSLB_API_KEY |
Yes (prod) | System-level admin bearer token. When unset, dev mode is active (no auth). |
GSLB_SECRET_KEY |
When TOTP used | 32-byte hex key for AES-256-GCM encryption of TOTP secrets. The daemon refuses to start if TOTP users exist and this is unset. |
Generate both values with openssl rand -hex 32.
bgp — BGP Route Health Injection
- enabled (bool): activate the embedded BGP speaker. Default false.
- localASN (uint32): required when enabled. Your autonomous system number. Private-use range: 64512–65534.
- routerID (string): required when enabled. A stable IPv4 address used as the BGP router ID. Must be unique across nodes peering with the same upstream.
- listenAddr (string): bind address for incoming BGP connections. Default 0.0.0.0.
- listenPort (int): TCP port. Default 179.
- holdTime (duration): BGP hold timer. Default 90s. RFC 4271 minimum is 3 seconds.
- keepAliveTime (duration): keepalive interval. Default 30s. Should be one third of holdTime.
- peers ([]PeerConfig): list of BGP neighbours.
- remoteASN (uint32, required): neighbour's AS number.
- remoteAddr (string, required): neighbour's IPv4 address.
- password (string, optional): MD5 TCP session authentication password.
- nodePrefixes ([]string): CIDR prefixes announced unconditionally while the daemon runs. Withdrawn on graceful shutdown (SIGTERM/SIGINT). Use for anycast VIPs that represent the GSLB service itself.
- poolPrefixes ([]PoolPrefixConfig): health-driven prefix injection.
- poolID (string, required): pool UUID from the database.
- prefixes ([]string, required): CIDR prefixes to announce when pool is healthy.
- withdrawThreshold (float64): fraction of endpoints that must be healthy to keep prefix announced. 0.0 (default) = any healthy endpoint keeps routes up; 0.5 = withdraw below 50% healthy.
Example (node VIP + pool-driven prefix):
bgp:
enabled: true
localASN: 65001
routerID: "10.0.0.1"
listenPort: 179
holdTime: "90s"
keepAliveTime: "30s"
peers:
- remoteASN: 65000
remoteAddr: "10.0.0.254"
password: ""
nodePrefixes:
- "203.0.113.0/24" # always announced while daemon runs
poolPrefixes:
- poolID: "a1b2c3d4-..." # UUID from GET /api/v1/pools
prefixes:
- "198.51.100.0/24"
withdrawThreshold: 0.5 # withdraw if <50% of pool endpoints healthy
See BGP Route Health Injection for the full reference, peer configuration examples (FRR, BIRD, Cisco IOS), and troubleshooting guidance.
alerts
All targets fire on state transitions only (healthy → unhealthy or unhealthy → healthy), not on every probe. Delivery is asynchronous and non-blocking: events are queued and retried up to 3 times with exponential backoff (2 s, 4 s). If the queue fills (> 256 pending events), new events are dropped with a WARN log. Multiple targets of any type can be configured simultaneously.
alerts.webhooks — Generic HTTP webhook
- url (string, required): full http:// or https:// URL to POST events to.
- secret (string, optional): when set, each request includes an X-Nexus-Signature: sha256=<hex> header — an HMAC-SHA256 of the request body signed with this secret. Use it to verify the sender.
Event payload (JSON):
alerts.pagerduty — PagerDuty Events API v2
- routingKey (string, required): the PagerDuty integration key (found under Services → your service → Integrations tab → Events API v2).
- severity (string, optional): PagerDuty alert severity for unhealthy events. Valid values: critical (default), error, warning, info. Resolved events always use severity info.
Nexus opens a PagerDuty incident when an endpoint goes unhealthy and resolves it automatically on recovery. Incidents are deduplicated on nexus/<poolId>/<ipAddress> so repeated transitions do not create duplicate incidents.
alerts.opsgenie — Atlassian OpsGenie Alerts API
- apiKey (string, required): OpsGenie API key with "Create and Update" and "Close" alert permissions. Found under Settings → API key management.
- priority (string, optional): OpsGenie alert priority for unhealthy events. Valid values: P1 (default, critical) through P5 (informational).
- region (string, optional): API endpoint region. us (default) → api.opsgenie.com, eu → api.eu.opsgenie.com. Use eu only if your account is on the EU data residency plan.
Nexus creates an OpsGenie alert when an endpoint goes unhealthy and closes it automatically on recovery. Alerts are deduplicated on alias nexus/<poolId>/<ipAddress>.
Example
alerts:
webhooks:
- url: "https://hooks.slack.com/services/..."
pagerduty:
- routingKey: "a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4"
severity: "critical"
opsgenie:
- apiKey: "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
priority: "P1"
region: "us"
Signature verification for webhooks (Go):
mac := hmac.New(sha256.New, []byte(secret))
mac.Write(body)
expected := "sha256=" + hex.EncodeToString(mac.Sum(nil))
ok := hmac.Equal([]byte(r.Header.Get("X-Nexus-Signature")), []byte(expected))
See Health Alerting for setup walkthroughs, curl-based test commands, and troubleshooting.
redirect — HTTP Redirect Service
- enabled (bool): start the HTTP redirect listener. Default false.
- listenAddr (string): bind address. Default 0.0.0.0.
- port (int): TCP port to listen on. No default — must be set when enabled: true. Use 80 for a first-class HTTP redirect listener, or another port if a reverse proxy (Caddy, nginx) is in front.
The redirect service looks up the incoming HTTP Host header against the redirect rule table and responds with the configured 301 or 302. Rules are managed via POST /api/v1/redirects and take effect immediately without a restart. Rules are replicated to all cluster nodes via state sync.
Example
See HTTP Redirects reference and HTTPS Redirects user guide.
metrics
- enablePrometheus: expose /metrics endpoint (default false).
- listenAddr, port: server binding.
license
- secret: HMAC-SHA256 signing secret. Override with GSLB_LICENSE_SECRET env var.
- licenseKey: signed license token. Override with GSLB_LICENSE_KEY env var.
- Env vars take precedence over config file values.
- See docs/Licensing.md for license generation details. Use NEXUS_LICENSE_SECRET when running licensegen.
Validation
internal/config/validator/validate.go is called at startup and rejects invalid configuration with a descriptive error. Checks performed:
| Section | Validated fields |
|---|---|
dns |
listenAddr valid IP; port 1–65535; domain valid DNS label format (no adjacent dots, no leading/trailing hyphens) |
api |
(when enabled) listenAddr valid IP; port 1–65535 |
metrics |
(when enablePrometheus) listenAddr valid IP; port 1–65535 |
loadbalancer |
endpoints all valid IPs; algorithm one of the recognised values; weights keys valid IPs and values ≥ 0; geoip.dbPath required when algorithm is geo-ip; geoip.endpointLocations lat ∈ [−90, 90] and lon ∈ [−180, 180]; mapFile.rules each CIDR valid and endpoint a valid IP; asn.dbPath required when asn rules are set; each asn.rules entry must have at least one of asn/org and a valid endpoint IP |
health |
(when enabled) type must be tcp or http; port 1–65535; checkinterval and timeout parseable Go durations |
state |
healthPolicy one of the four recognised values; quorumMinPercent 0–100; heartbeatInterval and heartbeatTTL parseable durations; config-sync fields validated when enableConfigSync is true |
backup |
(when enabled) interval parseable duration; keep ≥ 0 |
logging |
format must be json or text; level must be debug, info, warn, or error |
alerts |
each webhooks[].url must be a valid http:// or https:// URL; pagerduty[].routingKey must not be empty; pagerduty[].severity one of critical/error/warning/info; opsgenie[].apiKey must not be empty; opsgenie[].priority one of P1–P5; opsgenie[].region one of us/eu |
auth.oidc |
(when enabled) discoveryUrl and redirectUri must be valid URLs; discoveryUrl must be https://; clientId and clientSecret must be non-empty; defaultRole must be one of tenant_admin, operator, viewer (or empty) |
bgp |
(when enabled) localASN non-zero; routerID valid IPv4 address; listenPort 1–65535 if set; holdTime/keepAliveTime parseable Go durations if set; each peer remoteASN non-zero and remoteAddr valid IP; all nodePrefixes and poolPrefixes[].prefixes valid CIDRs; withdrawThreshold in 0.0–1.0 |