From 8df07f22f96e13551cb593e25ed4ebc71646a31b Mon Sep 17 00:00:00 2001 From: Jean Date: Tue, 21 Jul 2026 14:54:26 +0000 Subject: [PATCH] Complete config.example.toml with all sections --- config.example.toml | 227 +++++++++++++++++++++++++------------------- 1 file changed, 127 insertions(+), 100 deletions(-) diff --git a/config.example.toml b/config.example.toml index d5624f5..1f02c92 100644 --- a/config.example.toml +++ b/config.example.toml @@ -1,127 +1,154 @@ -# Copy to config.toml and edit. config.toml is gitignored (holds the link password). +# Copy to config.toml and edit. config.toml is gitignored (it holds the link password). +# Only [uplink] and [server] are required; every other section is optional and off when +# omitted. A few settings reload on OperServ REHASH (noted below); the rest need a restart. [uplink] host = "127.0.0.1" port = 7000 -password = "changeme" # must match the block on the uplink IRCd +password = "changeme" # must match the block on the uplink ircd +# Link over TLS instead of plaintext, pinning the server's SPKI fingerprint (base64 of +# SHA256 over its SubjectPublicKeyInfo) rather than a CA, so a self-signed link cert is +# fine. Read the fingerprint with: +# openssl s_client -connect HOST:PORT /dev/null | openssl x509 \ +# -pubkey -noout | openssl pkey -pubin -outform DER | openssl dgst -sha256 -binary | base64 +# tls = true +# spki_fingerprint = "" [server] name = "services.example.net" -sid = "42S" # 3 chars, unique on the network -description = "Federated Services" -protocol = 1206 # InspIRCd link protocol version (1206 = insp4, 1205 = insp3) +sid = "42S" # 3 chars, unique on the network +description = "Network Services" +protocol = 1206 # InspIRCd link protocol (1206 = insp4, 1205 = insp3) +# scram_iterations = 210000 # PBKDF2 cost for new SCRAM verifiers; high by default +# guest_nick = "Guest" # nick prefix after LOGOUT; must start with a letter +# service_host = "" # host the pseudo-clients wear; empty = the server name +# service_modes = "iHkB" # invisible, hideoper, servprotect (needs a U-line), bot +# service_oper_type = "Network Service" # shown in /whois; empty = non-opers +# services_channel = "#services" # channel every pseudo-client joins; empty = none +# standard_replies = false # IRCv3 FAIL/WARN/NOTE; needs m_services_stdrpl on the ircd -# Node-to-node replication. Omit this section (and [[peer]]) to run a single node. -# [gossip] -# bind = "0.0.0.0:16700" # where peers reach us; omit for a dial-only node -# secret = "shared-secret" # both nodes must present the same secret -# -# [gossip.tls] # omit for a plaintext link; see scripts/gen-certs.sh -# cert = "certs/node.crt" -# key = "certs/node.key" -# ca = "certs/ca.crt" # a peer must present a certificate signed by this CA -# -# [[peer]] # one block per other node -# addr = "other-node:16700" -# name = "other-node" # TLS name to expect; must match the peer certificate - -# Directory replication (gRPC) — lets a website mirror the account/channel -# directory (identity + metadata only, never credentials; see proto/echo.proto). -# Omit this section to run without it. -# [grpc] -# bind = "127.0.0.1:50051" # a private network hop is the expected deployment -# token = "shared-secret" # every RPC must send `authorization: Bearer ` -# -# [grpc.tls] # omit for plaintext (fine on a private/loopback hop) -# cert = "certs/node.crt" -# key = "certs/node.key" - -# Liveness + Prometheus metrics (plain HTTP, read-only, unauthenticated). Omit to -# leave it off. Bind to localhost and point a monitor at it: GET /health for a -# liveness probe (JSON), GET /metrics for a scrape (gauges: account/channel/oper -# totals, per-service counters, and event.lamport — a monotonic log-progress gauge). -# [health] -# bind = "127.0.0.1:9099" - -# Which service modules to start. Omit this section for the full standard suite -# (every service comes up by default). List names here to run a subset; add -# "example" to also start the example template service. +# Which service modules to start. Omit for the full standard suite; list names to run a +# subset. Add "example" to also start the example template service. # [modules] # services = ["nickserv", "chanserv"] # Services operators, in three tiers of increasing power: -# operator — day-to-day moderation: view hidden info, network bans, kick, -# kill, session limits, ignores, mode, spam filters, log search. -# administrator — the above plus account/channel data: suspend, drop, set flags, -# forbid, global notices, defcon, memo/info/bot administration. -# root — the above plus daemon control: add/remove opers, set, rehash, -# restart, shutdown, the activity feed. -# Name a tier with `type`, or list individual privileges with `privs` (auspex, -# oper, suspend, admin, root). Omit the whole block for a network with no opers. +# operator day-to-day moderation: view hidden info, network bans, kick, kill, +# session limits, ignores, mode, spam filters, log search. +# administrator the above plus account and channel data: suspend, drop, set flags, +# forbid, global notices, defcon, memo/info/bot administration. +# root the above plus daemon control: add/remove opers, set, rehash, +# restart, shutdown, the activity feed. +# Name a tier with `type`, or list individual privileges with `privs` (auspex, oper, +# suspend, admin, root). Repeat the block per operator. Omit for a network with no opers. # [[oper]] # account = "yournick" # type = "root" -# Staff audit feed: notable service actions (registrations, drops, vhosts, -# suspensions, akicks, access and bot changes, oper host config) are announced -# to this channel so operators can see who did what. Private material (memo -# bodies, password/verifier data) and cosmetic self-service tweaks are never -# surfaced. Omit the section to disable the feed. +# Staff audit feed: notable service actions (registrations, drops, vhosts, suspensions, +# akicks, access and bot changes) are announced here so operators see who did what. Memo +# bodies and credential material are never shown. Omit to disable the feed. # [log] # channel = "#services" -# Masks OperServ NOTIFY never announces, so they can't flood the feed. Three kinds: -# "#channel" mute a channel (keep a broad `#*` watch out of "#staff") -# "server:" mute everyone on a server (a relay whose users have clean -# nicks; alias "via:", matching the "via " in the feed) -# anything else mute a user — nick glob, user@host, or extban ("*/*" catches -# PyLink relays that suffix nicks with /network) -# Reloadable with OperServ REHASH. -# notify_exclude = ["*/*", "server:chatnova.relay", "#staff"] +# Masks OperServ NOTIFY never announces: "#channel" mutes a channel, "server:" +# (alias "via:") mutes a server, anything else mutes a user (nick glob, user@host, or an +# extban). Reloadable with OperServ REHASH. +# notify_exclude = ["*/*", "server:relay.example.net", "#staff"] -# Inactivity-expiry: accounts not identified to, and channels not joined, for -# longer than the threshold are dropped on a periodic pass (opers, live -# sessions, occupied channels, and NOEXPIRE-pinned records are spared). A zero -# or omitted field leaves that kind never expiring. Omit the section to disable -# expiry entirely. -# [expire] -# accounts_days = 90 -# channels_days = 30 -# warn_days sends the owner a heads-up email this many days before expiry (only -# where an address is on file and [email] is configured); 0 or omitted = no -# warning email. -# warn_days = 7 +# Registration policy. Reloadable with OperServ REHASH. +# [register] +# confusable_check = true # refuse look-alike, mixed-script, or invisible names +# vouch = false # invite-only: a new account waits for a NickServ VOUCH -# Per-IP session limiting: the connection that puts an IP over `default_limit` -# is killed on connect. OperServ EXCEPTION entries raise or lower the allowance -# per IP-mask (an exception limit of 0 means unlimited). 0 or omitted = off. -# [session] -# default_limit = 3 +# Extbans echo accepts. Omit (or leave empty) to accept every extban the ircd offers. +# [extban] +# enabled = ["account", "realname", "country"] -# Account authority. Omit this section (the default) and Echo owns accounts -# itself: NickServ REGISTER / IDENTIFY / SET PASSWORD all work standalone, no -# external service needed. Set external = true to hand identity to an outside -# authority (e.g. your website): IRC can then only IDENTIFY — REGISTER, DROP, -# SET PASSWORD/EMAIL, RESETPASS, CONFIRM, CERT and GROUP are refused, and the -# authority pushes accounts in via the gRPC Accounts API (see [grpc]). Echo -# still owns all channel/vhost/ban data, keyed by the account name. +# Account authority. Default (omitted): echo owns accounts and REGISTER/IDENTIFY/SET all +# work standalone. Set external = true to hand identity to an outside authority (your +# website): IRC can then only IDENTIFY, and the authority pushes accounts in over the +# gRPC Accounts API. echo still owns all channel, vhost, and ban data, keyed by account. # [auth] # external = true -# DictServ: dictionary / thesaurus / reference lookups over the DICT protocol -# (RFC 2229). Present = the service loads and channel bots answer !dict, !define, -# !thes, !acronym, !law, !element, !bible, and friends (DictServ LOOKUP lists them -# all); also queryable directly with /msg DictServ . Omit it and echo -# makes no outbound lookups at all — this is opt-in because it reaches the network. -# Lookups are globally rate-limited and the reply is truncated to one line. The log -# channel is unaffected; keep this off if you don't want echo talking to dict.org. +# Inactivity expiry: drop accounts not identified to, and channels not joined, for longer +# than the threshold (opers, live sessions, occupied channels, and NOEXPIRE records are +# spared). 0 or omitted leaves that kind never expiring. Omit the section to disable. +# [expire] +# accounts_days = 90 +# channels_days = 30 +# warn_days = 7 # email the owner this many days before expiry (needs [email]) + +# Per-IP session limiting: the connection that puts an IP over default_limit is killed on +# connect. OperServ EXCEPTION raises or lowers it per IP-mask. 0 or omitted = off. +# [session] +# default_limit = 3 + +# Reply language. echo ships en, fr, de, es, es-ar, pt, pt-br. +# [language] +# default = "en" +# dir = "lang" +# available = ["en", "fr", "de", "es", "es-ar", "pt", "pt-br"] + +# Outbound email for registration confirmation and password recovery. Omit to disable. +# [email] +# from = "services@example.net" +# command = "msmtp -t" # the message is piped on stdin, run via sh -c +# brand = "Example Network" # display name in the template +# accent = "#4f46e5" # any CSS colour +# logo = "" # hosted image URL (no inline SVG or data URIs in email) +# confirm_url = "" # e.g. https://example.net/confirm, adds a one-click link + +# Liveness and Prometheus metrics (plain HTTP, read-only, unauthenticated). GET /health +# for a liveness probe, GET /metrics for a scrape (account/channel/oper totals, per-service +# counters, event.lamport). Keep it on localhost. Omit to disable. +# [health] +# bind = "127.0.0.1:9099" + +# gRPC directory of accounts and channels for a website to mirror (identity and metadata +# only, never credentials), plus the Accounts API to register and confirm accounts with +# the token. See proto/echo.proto. Omit to disable. +# [grpc] +# bind = "127.0.0.1:50051" +# token = "a-long-shared-secret" # every RPC sends `authorization: Bearer ` +# [grpc.tls] # optional; omit on a private or loopback hop +# cert = "certs/node.crt" +# key = "certs/node.key" + +# HTTP JSON-RPC endpoint for a staff web panel. Keep on localhost behind a proxy, or +# terminate TLS here. Omit to disable. +# [jsonrpc] +# bind = "127.0.0.1:5601" +# token = "a-long-shared-secret" +# origins = ["https://example.net"] # browser origins allowed cross-site (CORS) +# [jsonrpc.tls] +# cert = "certs/node.crt" +# key = "certs/node.key" + +# Passwordless web login: a member already signed in on the website connects with a +# one-time kc_... token instead of a password, redeemed against this endpoint. Omit to disable. +# [keycard] +# url = "http://127.0.0.1:8000/accounts/api/login-token" +# api_key = "shared-key" # matches the endpoint's X-API-Key + +# DictServ: dictionary, thesaurus, and reference lookups over DICT (RFC 2229). Opt-in +# because it makes outbound requests. Lookups are rate-limited and truncated to one line. +# Omit to make no outbound lookups at all. # [dictserv] # server = "dict.org:2628" -# Registration policy. The look-alike guard refuses REGISTER of a nick or channel -# that mixes alphabets (Cyrillic "аdmin"), is built from homoglyphs or styled -# (fullwidth/math) letters imitating Latin, or hides invisible/bidi characters — -# while genuine monolingual text (including accented French) passes. It's on by -# default; turn it off for a community that legitimately uses mixed/non-Latin -# names. Reloadable with OperServ REHASH. -# [register] -# confusable_check = false +# Node-to-node replication (optional; most setups are a single node). Omit [gossip] and +# [[peer]] to run standalone. See the Federation wiki page. +# [gossip] +# bind = "0.0.0.0:16700" # where peers reach us; omit for a dial-only node +# secret = "shared-secret" # both nodes must present the same secret +# [gossip.tls] # omit for a plaintext link; see scripts/gen-certs.sh +# cert = "certs/node.crt" +# key = "certs/node.key" +# ca = "certs/ca.crt" # a peer must present a cert signed by this CA +# [gossip.signing] # optional per-origin Ed25519 signing; key from --gen-gossip-key +# key = "base64-secret-key" # this node's signing key +# trust = { "42S" = "base64-pubkey", "43S" = "base64-peer-pubkey" } +# [[peer]] # one block per other node +# addr = "other-node:16700" +# name = "other-node" # TLS name to expect; must match the peer's certificate