# 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