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
|
||||
|
||||
echoIRCd is configured from a single file (`echoircd.conf` by default). The format is a set of
|
||||
**blocks** made of `key value;` fields.
|
||||
echoIRCd reads one file — `echoircd.conf` by default. This page walks you from a two-line starter
|
||||
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
|
||||
> comments on their own line.
|
||||
```sh
|
||||
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
|
||||
network "echoiRCd";
|
||||
sid "0AA";
|
||||
server {
|
||||
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
|
||||
|
||||
Each `listen` block opens one port. `tls yes` makes it a direct-TLS port, `wss yes` a
|
||||
WebSocket-over-TLS port, and `type server` a server-to-server port.
|
||||
Each `listen` block opens one socket; add as many as you need. `ip "[::]"` (or `"*"`) binds IPv4 and
|
||||
IPv6 at once. `type server` is the port other servers (and the services package) link to.
|
||||
|
||||
```ini
|
||||
listen { ip "[::]"; port 6667; } # plaintext clients
|
||||
listen { ip "[::]"; port 6697; tls yes; } # direct-TLS clients
|
||||
listen { ip "[::]"; port 7799; wss yes; } # WebSocket (wss)
|
||||
listen { ip "[::]"; port 7700; type server; } # server links
|
||||
listen { ip "[::]"; port 6667; } # plaintext
|
||||
listen { ip "[::]"; port 6697; tls yes; } # direct TLS
|
||||
listen { ip "[::]"; port 7799; wss yes; } # WebSocket-over-TLS
|
||||
listen { ip "127.0.0.1"; port 8097; ws yes; } # plaintext WebSocket (behind a proxy)
|
||||
listen { ip "[::]"; port 7000; type server; } # S2S
|
||||
```
|
||||
|
||||
## TLS
|
||||
|
||||
Point the `tls` block at a certificate and private key. Both the OpenSSL and rustls backends are
|
||||
available, and certificates are re-read on rehash. Per-host certificates can be supplied with
|
||||
repeatable `sni` entries.
|
||||
Point the `tls` block at a certificate and key. Use a real certificate (Let's Encrypt) in production;
|
||||
for a quick test, a self-signed one works:
|
||||
|
||||
```sh
|
||||
openssl req -x509 -newkey rsa:2048 -keyout tls/key.pem -out tls/cert.pem \
|
||||
-days 3650 -nodes -subj "/CN=irc.example.net"
|
||||
```
|
||||
|
||||
```ini
|
||||
tls {
|
||||
cert "/etc/echoircd/tls/cert.pem";
|
||||
key "/etc/echoircd/tls/key.pem";
|
||||
backend openssl; # or: rustls
|
||||
sni "irc.example.net ./tls/example.crt ./tls/example.key";
|
||||
cert "./tls/cert.pem";
|
||||
key "./tls/key.pem";
|
||||
backend openssl; # or: rustls
|
||||
# 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
|
||||
cloak { key "a-long-random-secret"; }
|
||||
```
|
||||
|
||||
## Applying changes
|
||||
|
||||
Validate, then rehash the running server — no restart required:
|
||||
First hash a password:
|
||||
|
||||
```sh
|
||||
echoircd checkconfig echoircd.conf
|
||||
echoircd rehash echoircd.conf # sends SIGHUP
|
||||
printf '%s' 'my-strong-password' | ./echoircd mkpasswd
|
||||
```
|
||||
|
||||
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