Skip to content

Latest commit

 

History

History
237 lines (194 loc) · 8.98 KB

File metadata and controls

237 lines (194 loc) · 8.98 KB

Server configuration

Status: implemented, pre-alpha

The daemon can still run from its loopback-safe defaults and existing environment variables. A deployment should instead select one versioned TOML file with IRC_CONFIG and use environment variables only for deliberate runtime overrides.

The merge order is:

  1. compiled loopback-safe defaults;
  2. the complete TOML file selected by IRC_CONFIG; and
  3. explicitly present IRC_* overrides.

An unset environment variable leaves the file value intact. An empty variable is still an explicit override and will normally fail validation; edit the file to remove an optional listener. The loader never silently falls back when a selected file is absent or invalid.

Validation boundary

Every file must contain version = 1. The loader rejects unknown keys, unsupported versions, invalid TOML and UTF-8, unsafe listener combinations, and files larger than 64 KiB. Listener addresses, names, origins, registration mode, retention ranges, timeouts, and connection bounds pass through the same validation used by programmatic and environment-only configurations.

Validate the merged policy without opening sockets, creating a database, or reading certificate files:

IRC_CONFIG=/etc/telex/server.toml \
  telex-ircd config check

This command is suitable for an installation or service preflight. A successful check does not prove that the configured ports are free or that certificate, key, database, and directory permissions are correct. Normal server startup checks those runtime resources before advertising readiness.

Offline administrative commands use the selected file's database path without requiring valid listener settings. They acquire the same exclusive database lease as the daemon and therefore require it to be stopped. IRC_DATABASE can override only that path:

IRC_CONFIG=/etc/telex/server.toml \
  telex-ircd content epoch
IRC_CONFIG=/etc/telex/server.toml \
IRC_DATABASE=/srv/recovery/irc.db \
  telex-ircd content epoch

database backup <new-file> creates a read-only online snapshot without migrating the selected source; database prepare intentionally migrates, validates, and checkpoints an existing selected restore candidate. Their operational boundary and safe swap procedure are in the database runbook.

File format

The complete public shape is represented by the generalized example profile. All sections except the top-level version are optional; omitted settings retain their safe defaults.

version = 1

[server]
name = "irc.example.net"
network = "ExampleNet"

[storage]
database = "/var/lib/telex/irc.db"

[listeners]
irc = "0.0.0.0:6697"
websocket = "0.0.0.0:8097"
control = "0.0.0.0:8098"
allow_insecure_remote = false

[tls]
certificate_chain = "/etc/letsencrypt/live/irc.example.net/fullchain.pem"
private_key = "/etc/letsencrypt/live/irc.example.net/privkey.pem"

[admission]
authentication_required = true
account_registration = "invite"
initial_channel = "#general"

[websocket]
origins = ["https://chat.example.net"]

[operators]
accounts = ["operator"]

[history]
legacy_replay_limit = 50

[retention]
channel_days = 90
direct_message_days = 180
channel_min_days = 1
channel_max_days = 400
allow_indefinite = false
prune_interval_seconds = 3600

[limits]
registration_timeout_seconds = 30
heartbeat_idle_seconds = 180
heartbeat_timeout_seconds = 90
max_connections = 128

[limits.protocol]
per_minute = 600
burst = 60

[limits.admission]
per_minute = 120
burst = 64

[limits.authentication]
per_minute = 120
burst = 64

[limits.invitation]
per_minute = 5
burst = 5

[limits.messages]
per_minute = 120
burst = 20

[limits.history]
per_minute = 60
burst = 20

[limits.administration]
per_minute = 60
burst = 20

The scopes, rejection behavior, anonymity tradeoff, and aggregate counters are defined in runtime rate limits.

Relative storage.database and TLS paths are resolved against the directory containing the TOML file. Relative environment overrides remain relative to the daemon's working directory. Bare-metal profiles should normally use absolute paths.

The configuration contains policy and paths, not passwords, invitation bearer tokens, account credentials, or TLS private-key contents. Keep the referenced private-key file readable only by the eventual service account.

Environment mapping

TOML setting Environment override
server.name IRC_SERVER_NAME
server.network IRC_NETWORK_NAME
storage.database IRC_DATABASE
listeners.irc IRC_LISTEN
listeners.websocket IRC_WEBSOCKET_LISTEN
listeners.control IRC_CONTROL_LISTEN
listeners.allow_insecure_remote IRC_ALLOW_INSECURE_REMOTE
tls.certificate_chain IRC_TLS_CERT
tls.private_key IRC_TLS_KEY
admission.authentication_required IRC_REQUIRE_AUTHENTICATION
admission.account_registration IRC_ACCOUNT_REGISTRATION
admission.initial_channel IRC_INITIAL_CHANNEL
websocket.origins IRC_WEBSOCKET_ORIGINS as a comma-separated list
operators.accounts IRC_OPERATOR_ACCOUNTS as a comma-separated list
history.legacy_replay_limit IRC_LEGACY_REPLAY_LIMIT
retention.channel_days IRC_CHANNEL_RETENTION_DAYS
retention.direct_message_days IRC_DM_RETENTION_DAYS
retention.channel_min_days IRC_CHANNEL_RETENTION_MIN_DAYS
retention.channel_max_days IRC_CHANNEL_RETENTION_MAX_DAYS
retention.allow_indefinite IRC_ALLOW_INDEFINITE_RETENTION
retention.prune_interval_seconds IRC_RETENTION_PRUNE_INTERVAL_SECS
limits.registration_timeout_seconds IRC_REGISTRATION_TIMEOUT_SECS
limits.heartbeat_idle_seconds IRC_HEARTBEAT_IDLE_SECS
limits.heartbeat_timeout_seconds IRC_HEARTBEAT_TIMEOUT_SECS
limits.max_connections IRC_MAX_CONNECTIONS
limits.protocol.per_minute IRC_PROTOCOL_RATE_PER_MINUTE
limits.protocol.burst IRC_PROTOCOL_RATE_BURST
limits.admission.per_minute IRC_ADMISSION_RATE_PER_MINUTE
limits.admission.burst IRC_ADMISSION_RATE_BURST
limits.authentication.per_minute IRC_AUTHENTICATION_RATE_PER_MINUTE
limits.authentication.burst IRC_AUTHENTICATION_RATE_BURST
limits.invitation.per_minute IRC_INVITATION_RATE_PER_MINUTE
limits.invitation.burst IRC_INVITATION_RATE_BURST
limits.messages.per_minute IRC_MESSAGE_RATE_PER_MINUTE
limits.messages.burst IRC_MESSAGE_RATE_BURST
limits.history.per_minute IRC_HISTORY_RATE_PER_MINUTE
limits.history.burst IRC_HISTORY_RATE_BURST
limits.administration.per_minute IRC_ADMINISTRATION_RATE_PER_MINUTE
limits.administration.burst IRC_ADMINISTRATION_RATE_BURST

RUST_LOG remains a process logging setting rather than server policy. No configuration source enables remote plaintext control traffic; invitation and account credentials require TLS outside loopback regardless of the development IRC override.

operators.accounts contains at most 32 human account names. Names are validated with the ordinary account-name rules, normalized to ASCII lowercase, and rejected if two entries become equal. These names authorize /operator/; they are not stored global capabilities and cannot be added or removed by the panel. The named human account must already exist and remain active. Changing the list requires a configuration update and daemon restart, while capability changes made through the panel take effect immediately. An empty list disables operator login without removing the page assets. See the operator panel.

websocket.origins is also the exact browser-origin allowlist for authenticated avatar reads from the control listener. This lets a static web client on HTTPS 443 retrieve images from the TLS control port without opening general control API CORS. Each listed origin must therefore be one you trust to receive an account password in tab memory. See account avatars.

admission.initial_channel is optional and must be one valid IRC channel name. When set, it is atomically assigned only to newly created human accounts; each authenticated device autojoins it until the account parts it. Adding or changing the setting does not backfill existing accounts. Keep this room public and unkeyed. The exact account/device behavior is documented in initial channel.

limits.heartbeat_idle_seconds controls how long a registered IRC connection may send no client traffic before Telex sends PING. The default is 180 seconds. The client must return that exact token in PONG within limits.heartbeat_timeout_seconds, which defaults to 90 seconds. Ordinary traffic postpones the next heartbeat; unregistered connections remain governed only by the separate registration deadline. Heartbeats apply to both IRC/TLS and IRC-over-WebSocket, bypass command throttles, create no stored event or cursor, and are not logged individually. Keep any TCP proxy idle timeout longer than the combined heartbeat window.