Configuring luadch
This document covers how to configure a running hub: edit cfg/cfg.tbl,
register your operator account, manage plugins, set up TLS. For getting
the hub built and deployed in the first place, see
BUILDING.md and INSTALLING.md.
Status: parts of this document are scaffolding with
TODOmarkers. The skeleton lays out the topics; detailed semantics for individualcfg.tblkeys and plugins will be filled in as the documentation matures.
First-run checklist
After a fresh install, before opening the hub to real users:
-
Start the hub. On first boot the hub auto-generates a self-signed P-256 ECDSA cert at
certs/servercert.pemandcerts/serverkey.pemand logs the keyprint to stdout (and Dockerdocker logs):cert_bootstrap: generated self-signed P-256 cert at certs/servercert.pemTLS keyprint (SHA256, base32): NUB44T3WNOUAC4QIG7CHGGRNOMNL3RDI5ZRWRSLUWAC2NT7YZMQAshare with users as: adcs://<your-host>:5001/?kp=SHA256/NUB44T3WNOUAC4QIG7CHGGRNOMNL3RDI5ZRWRSLUWAC2NT7YZMQAPin the cert deterministically: hand users the
adcs://host:port/?kp=SHA256/<keyprint>URL. DC++ clients trust the keyprint, not a CA chain - no Let's Encrypt or paid cert needed (seedocs/SECURITY.md§6).To regenerate later, delete
certs/servercert.pemandcerts/serverkey.pemand restart the hub. The bundledcerts/make_cert.{sh,bat}scripts are still around for manual regeneration outside the hub process (e.g. for cron-based rotation). -
Connect with an ADC client (AirDC++, EiskaltDC++, …):
- Address:
adcs://127.0.0.1:5001/?kp=SHA256/<keyprint from step 1> - Nick:
dummy - Password:
test
The default cfg ships TLS-only (#77). To enable plain ADC alongside, add port numbers to
tcp_ports/tcp_ports_ipv6incfg/cfg.tbl- empty arrays mean "no plain listener." - Address:
-
Register your own operator account:
+reg <yournick> 100Level 100 = HUBOWNER. Reconnect as that user.
-
Delete the dummy account:
+delreg dummyThis is not optional. The dummy account is a hubowner with public credentials.
-
Edit
cfg/cfg.tblto your deployment (see "cfg.tbl tour" below), then reload:+reload
File layout (configuration-relevant parts)
| Path | What it is |
|---|---|
cfg/cfg.tbl | Main hub configuration (Lua-serialised table) |
cfg/user.tbl | Registered users (nick, password hash, level, …) |
cfg/user.tbl.bak | Rolling backup the hub maintains automatically |
lang/de.tbl, en.tbl | Hub-side strings (greeting, error messages, …) |
scripts/lang/*.lang.de / *.lang.en | Per-script translations |
scripts/data/*.tbl | Per-script runtime state (bans, chatlog, records, …) |
certs/ | TLS keys + helpers |
Editing rules:
- All
.tblfiles are Lua tables. Don't open them in a UTF-16 editor. - Use a UTF-8 capable editor with Lua syntax highlighting.
- After edits, run
+reloadin the hub for changes to take effect (no full restart needed for cfg/script changes).
cfg.tbl tour
The shipped cfg/cfg.tbl has comments alongside every key. The
high-impact ones to set on first run:
-- TODO(maintainer): expand this with the most common keys
-- (hub_name, hub_hostaddress, hub_owner, hub_email, hub_topic,
-- tcp_ports / ssl_ports, max_users, ssl_params.certificate / .key,
-- scripts list, language)
For now, open cfg/cfg.tbl in your editor — every key has an inline
explanation in the file itself.
TLS configuration
The hub auto-generates a self-signed cert on first boot if none exists at the configured ssl_params paths. The default cfg.tbl already points at the right locations:
ssl_params = {
mode = "server",
protocol = "any",
options = { "all", "no_sslv2", "no_sslv3", "no_tlsv1", "no_tlsv1_1" },
cafile = "certs/cacert.pem",
certificate = "certs/servercert.pem",
key = "certs/serverkey.pem",
verify = { "none" },
},
The verified TLS posture out of the box is TLS 1.3 + AES-256-GCM (verified during the modernization phases). Nothing else needs to be hardened for a default deploy.
Port configuration
Default: TLS-only on v4 + v6, no plain ADC listener:
tcp_ports = { }, -- empty = no plain ADC listener
ssl_ports = { 5001 }, -- TLS ADC v4
tcp_ports_ipv6 = { }, -- empty = no plain ADC v6 listener
ssl_ports_ipv6 = { 5003 }, -- TLS ADC v6
To enable plain ADC alongside TLS, set tcp_ports = { 5000 } (and / or tcp_ports_ipv6 = { 5002 }) in cfg/cfg.tbl. luadch's listener registry is currently port-keyed - same port number on v4 and v6 is not supported, see #107.
Default account warning
The bundled [BOT]HubSecurity script warns in main chat as long as the
dummy account is still registered. Take that warning seriously —
do not run a public hub with dummy / test active.
User levels
The hub uses an integer-based user level system. Higher levels grant more permissions. Bundled defaults:
| Level | Name | What it can do |
|---|---|---|
| 100 | HUBOWNER | Everything (registers / deletes / shutdown) |
| 80 | OPERATOR | (TODO: list typical OP-level capabilities) |
| 60 | VIP | (TODO) |
| 40 | REG | Registered user, basic chat / commands |
| 20 | UNREG | Anonymous connection |
| 0 | BANNED | Refused |
Customise per-script minlevel in cfg.tbl to grant or restrict
specific commands.
TODO(maintainer): full level table is in docs/Luadch_Default_Levels.txt — pull the authoritative list from there.
Registering and deleting users
+reg <nick> <level> # register a new user at <level>
+delreg <nick> # remove a registered user
+regme <nick> <password> # self-register (if cfg allows it)
+setpass <newpass> # change your own password
+accinfo <nick> # show registration info for someone
user.tbl is updated atomically; the rolling backup user.tbl.bak
captures the previous state.
Plugins (scripts/)
Plugins live in scripts/ and are loaded at hub start in the order
listed under cfg.scripts in cfg.tbl. Adding or removing a plugin:
- Add the
.luafile underscripts/(or remove it). - Edit
cfg.scriptsincfg/cfg.tblto include / exclude the plugin name (without.lua). +reloadto apply.
Bundled plugin categories
| Prefix | What | Examples |
|---|---|---|
cmd_ | User chat commands | cmd_help, cmd_ban, cmd_uptime |
bot_ | Bots that appear in user list | bot_opchat, bot_regchat |
etc_ | Background features | etc_chatlog, etc_motd |
hub_ | Core hub-level scripts | hub_runtime, hub_cmd_manager |
usr_ | Per-user constraints | usr_share, usr_slots, usr_uptime |
TODO(maintainer): per-script descriptions / common configuration snippets for the plugins that have non-trivial settings (
etc_motd,etc_blacklist,etc_msgmanager, …).
Writing your own plugin
The plugin API is documented in docs/Luadch_Lua_API.txt. The core hooks:
onStart,onExitonLogin,onFailedAuthonBroadcast(main chat),onPrivateMessageonReg,onDelregonTimer,onError
Register a listener with hub.setlistener(event, id, function). See any
of the bundled cmd_*.lua files for working examples.
Languages
Two layers:
- Hub-side strings (
lang/de.tbl,lang/en.tbl) — chosen viacfg.languageincfg.tbl. Affects core hub messages. - Per-script strings (
scripts/lang/<scriptname>.lang.de/.lang.en) — overrides the script's default texts. Edit the file matching your selected language; missing keys fall back to the script's hardcoded defaults.
After editing language files: +reload.
Operational commands at a glance
| Command | Effect |
|---|---|
+reload | Re-read cfg.tbl, reload all scripts (no restart) |
+restart | Full hub restart |
+shutdown | Stop the hub gracefully |
+hubinfo | Show OS / CPU / RAM / uptime / connected user counts |
+uptime | Just the uptime line |
+userlist | Online users |
+usercleaner | Prune stale registrations |
+ban <nick> | Ban a user (see cmd_ban for full syntax) |
+gag <nick> | Mute a user temporarily |
A full command list is generated in-hub by +help. Each registered
plugin appends its own entries.
Troubleshooting
| Symptom | Likely cause |
|---|---|
Hub starts but [BOT]HubSecurity keeps warning about dummy | dummy not yet +delreg'd |
| TLS port 5001 binds but client cannot connect | Self-signed cert; accept the warning once OR generate a CA-signed cert |
+help from main chat returns "I am the Hubbot…" | Older issue, fixed in modernization PR #13 (5.4 build only) |
wmic errors on Windows 11 24H2+ | Older issue, fixed in modernization PR closing #16 |
+hubinfo crashes on attempt to concatenate a nil value | Older bug, fixed in modernization PR closing it |
| Hub starts but does not bind ports | Cert path wrong in ssl_params, OR firewall blocking, OR another process on the port |
TODO(maintainer): expand this with deployment-specific debugging patterns (systemd unit failures, log lines that point to specific misconfigurations).
Where to look for more
- The shipped
cfg/cfg.tblitself — every key has an inline comment - Luadch_Lua_API.txt — the plugin API
- SCRIPTS.md — bundled plugin reference + rate-limit configuration
- docs/phases/ — modernization journals (what changed and why)