# 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
# 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 = "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
# 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 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) 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: "#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"]
# 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
# Extbans echo accepts. Omit (or leave empty) to accept every extban the ircd offers.
# [extban]
# enabled = ["account", "realname", "country"]
# 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
# 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"
# 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