docs: full configuration guide — minimal starter + complete annotated example + section-by-section walkthrough
This commit is contained in:
parent
276dd39a05
commit
a3525411ca
1 changed files with 277 additions and 33 deletions
|
|
@ -1,62 +1,306 @@
|
||||||
# Configuration
|
# Configuration
|
||||||
|
|
||||||
echoIRCd is configured from a single file (`echoircd.conf` by default). The format is a set of
|
echoIRCd reads one file — `echoircd.conf` by default. This page walks you from a two-line starter
|
||||||
**blocks** made of `key value;` fields.
|
config to a full, production-ready one, section by section. Every option (with its default) is listed
|
||||||
|
in the [Configuration reference](/docs/config-reference), and the shipped `echoircd.conf.example` is
|
||||||
|
the same thing as a file you can copy.
|
||||||
|
|
||||||
> Inline `#` comments are **not** stripped from a value — keep active lines to bare values and put
|
```sh
|
||||||
> comments on their own line.
|
cp echoircd.conf.example echoircd.conf # then edit it
|
||||||
|
```
|
||||||
|
|
||||||
## Format
|
## The format
|
||||||
|
|
||||||
|
Config is a set of **blocks** — `section { field value; … }`:
|
||||||
|
|
||||||
|
- **One field per `;`.** A block may span multiple lines.
|
||||||
|
- **Comments:** `#` and `//` for a line, `/* … */` for a range. An inline `#` on an active line is
|
||||||
|
part of the value unless you quote the value, so quote anything containing `#` or spaces.
|
||||||
|
- **Booleans** are `yes` / `no`. A bare field (e.g. `operprefix;`) means `yes`.
|
||||||
|
- **Defaults are built in** — you only set a field to *change* it.
|
||||||
|
- Most changes re-apply on **`echoircd rehash`** (SIGHUP) with no restart; the TLS cert is re-read
|
||||||
|
too.
|
||||||
|
|
||||||
|
> `echoircd.conf` holds secrets (oper password, cloak key, link password) — it's gitignored in the
|
||||||
|
> source tree for that reason. Never commit your real config.
|
||||||
|
|
||||||
|
## Minimal config
|
||||||
|
|
||||||
|
The smallest thing that boots — plaintext on 6667:
|
||||||
|
|
||||||
```ini
|
```ini
|
||||||
network "echoiRCd";
|
server {
|
||||||
sid "0AA";
|
name "irc.example.net"; # your server's unique name
|
||||||
|
network "ExampleNet"; # the network name clients see
|
||||||
|
sid "0AA"; # 3 chars: a digit + 2 alphanumerics
|
||||||
|
}
|
||||||
|
|
||||||
listen { ip "[::]"; port 6697; tls yes; } # dual-stack v4 + v6
|
listen { ip "[::]"; port 6667; } # plaintext, IPv4 + IPv6
|
||||||
```
|
```
|
||||||
|
|
||||||
|
That's a working IRC server. Everything below adds TLS, operators, services, and hardening.
|
||||||
|
|
||||||
|
## A complete example
|
||||||
|
|
||||||
|
A realistic config you can copy and adapt. Uncommented lines are a sensible starting point;
|
||||||
|
commented lines show common extras.
|
||||||
|
|
||||||
|
```ini
|
||||||
|
# ── server identity ──────────────────────────────────────────────
|
||||||
|
server {
|
||||||
|
name "irc.example.net";
|
||||||
|
network "ExampleNet";
|
||||||
|
sid "0AA";
|
||||||
|
description "ExampleNet IRC";
|
||||||
|
pidfile "echoircd.pid"; # lets `echoircd rehash` find the process
|
||||||
|
}
|
||||||
|
|
||||||
|
# ── listeners (repeatable; [::] = IPv4 + IPv6) ───────────────────
|
||||||
|
listen { ip "[::]"; port 6667; } # plaintext
|
||||||
|
listen { ip "[::]"; port 6697; tls yes; } # direct TLS
|
||||||
|
listen { ip "[::]"; port 7799; wss yes; } # WebSocket (browser clients)
|
||||||
|
listen { ip "[::]"; port 7000; type server; } # server-to-server links
|
||||||
|
|
||||||
|
# ── TLS (cert re-read on rehash) ─────────────────────────────────
|
||||||
|
tls {
|
||||||
|
cert "./tls/cert.pem";
|
||||||
|
key "./tls/key.pem";
|
||||||
|
# backend openssl; # or rustls (pure-Rust, no system OpenSSL)
|
||||||
|
}
|
||||||
|
|
||||||
|
# ── message of the day ───────────────────────────────────────────
|
||||||
|
motd {
|
||||||
|
"Welcome to ExampleNet.";
|
||||||
|
"Be excellent to each other.";
|
||||||
|
}
|
||||||
|
|
||||||
|
# ── host cloaking: mode +x hides a user's real host ──────────────
|
||||||
|
cloak { key "REPLACE-WITH-A-LONG-RANDOM-HEX-STRING"; }
|
||||||
|
|
||||||
|
# ── operators ────────────────────────────────────────────────────
|
||||||
|
# Hash the password: printf '%s' 'yourpass' | ./echoircd mkpasswd
|
||||||
|
oper {
|
||||||
|
name "admin";
|
||||||
|
password "$2b$11$REPLACE_WITH_A_BCRYPT_HASH";
|
||||||
|
type netadmin; # full access (a built-in type)
|
||||||
|
# fingerprint "<sha256-cert-fp>"; # optional TLS-cert 2FA
|
||||||
|
}
|
||||||
|
|
||||||
|
# ── link to services (NickServ / ChanServ / …) ───────────────────
|
||||||
|
# link {
|
||||||
|
# name "services.example.net";
|
||||||
|
# ip 127.0.0.1;
|
||||||
|
# port 7000;
|
||||||
|
# password "REPLACE-WITH-A-LINK-SECRET";
|
||||||
|
# services yes; # mark it a U-lined services server
|
||||||
|
# }
|
||||||
|
# services { sasl_server "services.example.net"; }
|
||||||
|
|
||||||
|
# ── sensible tuning ──────────────────────────────────────────────
|
||||||
|
flood { flood_messages 8; flood_seconds 4; }
|
||||||
|
timeouts { registration_timeout 60; ping_frequency 90; ping_timeout 60; }
|
||||||
|
antiabuse { antirandom yes; solvemsg yes; }
|
||||||
|
logging { metrics_bind "127.0.0.1:9109"; }
|
||||||
|
```
|
||||||
|
|
||||||
|
The rest of this page explains each piece.
|
||||||
|
|
||||||
## Listeners
|
## Listeners
|
||||||
|
|
||||||
Each `listen` block opens one port. `tls yes` makes it a direct-TLS port, `wss yes` a
|
Each `listen` block opens one socket; add as many as you need. `ip "[::]"` (or `"*"`) binds IPv4 and
|
||||||
WebSocket-over-TLS port, and `type server` a server-to-server port.
|
IPv6 at once. `type server` is the port other servers (and the services package) link to.
|
||||||
|
|
||||||
```ini
|
```ini
|
||||||
listen { ip "[::]"; port 6667; } # plaintext clients
|
listen { ip "[::]"; port 6667; } # plaintext
|
||||||
listen { ip "[::]"; port 6697; tls yes; } # direct-TLS clients
|
listen { ip "[::]"; port 6697; tls yes; } # direct TLS
|
||||||
listen { ip "[::]"; port 7799; wss yes; } # WebSocket (wss)
|
listen { ip "[::]"; port 7799; wss yes; } # WebSocket-over-TLS
|
||||||
listen { ip "[::]"; port 7700; type server; } # server links
|
listen { ip "127.0.0.1"; port 8097; ws yes; } # plaintext WebSocket (behind a proxy)
|
||||||
|
listen { ip "[::]"; port 7000; type server; } # S2S
|
||||||
```
|
```
|
||||||
|
|
||||||
## TLS
|
## TLS
|
||||||
|
|
||||||
Point the `tls` block at a certificate and private key. Both the OpenSSL and rustls backends are
|
Point the `tls` block at a certificate and key. Use a real certificate (Let's Encrypt) in production;
|
||||||
available, and certificates are re-read on rehash. Per-host certificates can be supplied with
|
for a quick test, a self-signed one works:
|
||||||
repeatable `sni` entries.
|
|
||||||
|
```sh
|
||||||
|
openssl req -x509 -newkey rsa:2048 -keyout tls/key.pem -out tls/cert.pem \
|
||||||
|
-days 3650 -nodes -subj "/CN=irc.example.net"
|
||||||
|
```
|
||||||
|
|
||||||
```ini
|
```ini
|
||||||
tls {
|
tls {
|
||||||
cert "/etc/echoircd/tls/cert.pem";
|
cert "./tls/cert.pem";
|
||||||
key "/etc/echoircd/tls/key.pem";
|
key "./tls/key.pem";
|
||||||
backend openssl; # or: rustls
|
backend openssl; # or: rustls
|
||||||
sni "irc.example.net ./tls/example.crt ./tls/example.key";
|
# Per-host certificate by TLS SNI (repeatable):
|
||||||
|
# sni "irc.other.net ./tls/other.crt ./tls/other.key";
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
## Cloaking
|
The certificate is re-read on `echoircd rehash`, so a renewed cert applies without a restart.
|
||||||
|
|
||||||
Set a secret `cloak` key to enable host masking:
|
## Operators
|
||||||
|
|
||||||
```ini
|
First hash a password:
|
||||||
cloak { key "a-long-random-secret"; }
|
|
||||||
```
|
|
||||||
|
|
||||||
## Applying changes
|
|
||||||
|
|
||||||
Validate, then rehash the running server — no restart required:
|
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
echoircd checkconfig echoircd.conf
|
printf '%s' 'my-strong-password' | ./echoircd mkpasswd
|
||||||
echoircd rehash echoircd.conf # sends SIGHUP
|
|
||||||
```
|
```
|
||||||
|
|
||||||
See the shipped `echoircd.conf.example` for every available option.
|
Then an `oper` block ties a login to a role. `type netadmin` gives full access; drop `type` for full
|
||||||
|
access with no role. A block with neither a password nor a fingerprint is refused.
|
||||||
|
|
||||||
|
```ini
|
||||||
|
oper {
|
||||||
|
name "alice";
|
||||||
|
password "$2b$11$…"; # from mkpasswd
|
||||||
|
type netadmin;
|
||||||
|
host "*@192.0.2.0/24"; # optional: restrict where alice may oper from
|
||||||
|
# fingerprint "AA:BB:…"; # require this TLS client-cert (2FA, or alone)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
`/oper alice my-strong-password` logs in. For custom roles — limiting which commands, privileges, and
|
||||||
|
modes an operator has — define `class` and `opertype` blocks; see [Operators](/docs/operators).
|
||||||
|
|
||||||
|
## Host cloaking
|
||||||
|
|
||||||
|
Mode `+x` replaces a user's host with a stable, keyed cloak. Set a long random secret and keep it
|
||||||
|
private (changing it re-cloaks everyone):
|
||||||
|
|
||||||
|
```ini
|
||||||
|
cloak {
|
||||||
|
key "a-long-random-hex-secret";
|
||||||
|
# method hmac-sha256; # default; or account / fingerprint / static
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Connection classes
|
||||||
|
|
||||||
|
Fine-grained per-client policy, matched by IP/host/TLS/port — first match wins. Each class is one
|
||||||
|
quoted string of `key=value` tokens.
|
||||||
|
|
||||||
|
```ini
|
||||||
|
classes {
|
||||||
|
connectclass "trusted allow=10.0.0.0/8 maxchans=200 pingfreq=120 fakelag=no";
|
||||||
|
connectclass "secure allow=* requiressl=yes";
|
||||||
|
connectclass "vpn allow=* parent=trusted localmax=2 maxchans=20 modes=+ix";
|
||||||
|
connectclass "banned allow=1.2.3.0/24 deny=yes";
|
||||||
|
# connectclass_required yes; # refuse clients matching no allow class
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Common tokens: `allow=`, `deny=yes`, `requiressl=yes|trusted`, `password=`, `port=`, `asn=`,
|
||||||
|
`localmax=`/`globalmax=`, `maxchans=`, `pingfreq=`/`timeout=`, `modes=`, `recvq=`/`softsendq=`/
|
||||||
|
`hardsendq=`, `fakelag=no`, `useident=yes`. The full list is in the
|
||||||
|
[reference](/docs/config-reference#classes).
|
||||||
|
|
||||||
|
## DNS & ident
|
||||||
|
|
||||||
|
```ini
|
||||||
|
dns {
|
||||||
|
resolve_hosts yes; # reverse-DNS on connect (no = show the bare IP)
|
||||||
|
use_resolved_host yes; # use the resolved name in the hostmask
|
||||||
|
# useident yes; # RFC 1413 ident lookups (adds connect latency)
|
||||||
|
# requireident yes;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Limits, timeouts & flood
|
||||||
|
|
||||||
|
All optional — the defaults are sane. Set only what you want to change.
|
||||||
|
|
||||||
|
```ini
|
||||||
|
limits { maxchannel 50; maxnick 30; chathistory_limit 256; }
|
||||||
|
timeouts { registration_timeout 60; ping_frequency 90; ping_timeout 60; }
|
||||||
|
flood { flood_messages 8; flood_seconds 4; connflood "5 10"; }
|
||||||
|
```
|
||||||
|
|
||||||
|
## Anti-abuse
|
||||||
|
|
||||||
|
Layered spam/drone defence — turn on what you need:
|
||||||
|
|
||||||
|
```ini
|
||||||
|
antiabuse {
|
||||||
|
antirandom yes; # score random-looking nick/ident/realname
|
||||||
|
solvemsg yes; # unvouched users answer a sum before PMs deliver
|
||||||
|
# badword "spamword ***"; # +G censor (omit the replacement to block)
|
||||||
|
}
|
||||||
|
|
||||||
|
restrictions {
|
||||||
|
# restrictmsg yes; # only opers/services may be PM'd by regular users
|
||||||
|
autodrop_commands "GET POST HEAD CONNECT PUT DELETE OPTIONS TRACE PATCH";
|
||||||
|
}
|
||||||
|
|
||||||
|
# DNS blocklists (repeatable):
|
||||||
|
# dnsbl {
|
||||||
|
# dnsbl "dnsbl.dronebl.org";
|
||||||
|
# dnsbl_action "mark"; # mark | kill | kline | gline | zline
|
||||||
|
# }
|
||||||
|
```
|
||||||
|
|
||||||
|
See [Security & anti-abuse](/docs/security) for the whole picture.
|
||||||
|
|
||||||
|
## Logging & metrics
|
||||||
|
|
||||||
|
```ini
|
||||||
|
logging {
|
||||||
|
metrics_bind "127.0.0.1:9109"; # Prometheus endpoint (keep it private)
|
||||||
|
# syslog yes; # mirror to the system logger
|
||||||
|
# syslog_target "/dev/log";
|
||||||
|
# log_json "/var/log/echoircd/events.jsonl";
|
||||||
|
# chanlog "#snotices"; # mirror oper notices into a channel
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
See [Metrics & RPC](/docs/metrics-rpc).
|
||||||
|
|
||||||
|
## Linking services
|
||||||
|
|
||||||
|
The services package (NickServ, ChanServ, …) connects over the S2S port. Give it a `link` block, mark
|
||||||
|
it U-lined, and name it as the SASL server:
|
||||||
|
|
||||||
|
```ini
|
||||||
|
listen { ip "[::]"; port 7000; type server; }
|
||||||
|
|
||||||
|
link {
|
||||||
|
name "services.example.net";
|
||||||
|
ip 127.0.0.1;
|
||||||
|
port 7000;
|
||||||
|
password "shared-link-secret";
|
||||||
|
services yes; # U-lined services server
|
||||||
|
}
|
||||||
|
|
||||||
|
services { sasl_server "services.example.net"; }
|
||||||
|
```
|
||||||
|
|
||||||
|
Full details on both sides are in [Server links](/docs/linking) and [Services](/docs/services).
|
||||||
|
|
||||||
|
## WebSocket & STS
|
||||||
|
|
||||||
|
If you run a `ws`/`wss` listener, tune it and (once TLS is solid) advertise STS to push plaintext
|
||||||
|
clients onto TLS:
|
||||||
|
|
||||||
|
```ini
|
||||||
|
websocket {
|
||||||
|
ws_origin "https://webchat.example.net"; # allowed Origins (repeatable; empty = any)
|
||||||
|
ws_proxyranges "127.0.0.1"; # trusted reverse-proxy IPs
|
||||||
|
}
|
||||||
|
|
||||||
|
# sts {
|
||||||
|
# sts_duration 2592000; # seconds clients should stick to TLS (0 = off)
|
||||||
|
# sts_port 6697;
|
||||||
|
# }
|
||||||
|
```
|
||||||
|
|
||||||
|
## Validate & apply
|
||||||
|
|
||||||
|
Always check a config before deploying it, then reload in place:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
echoircd checkconfig echoircd.conf # parse + print every resolved key (catches typos)
|
||||||
|
echoircd rehash echoircd.conf # SIGHUP the running server — no restart, no disconnects
|
||||||
|
```
|
||||||
|
|
||||||
|
For every field and its default, see the [Configuration reference](/docs/config-reference).
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue