Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.allthingslinux.org/llms.txt

Use this file to discover all available pages before exploring further.

This page covers day-to-day and first-time operational tasks for the IRC stack: granting IRC operator access, initialising Atheme services, reloading configuration, and rotating SSL certificates.

Oper setup

IRC operators are configured in the UnrealIRCd config template via oper {} blocks. The default admin oper block uses environment variables for the password and vhost.

Generating an oper password

Oper passwords must be stored as argon2id hashes. Generate one using the UnrealIRCd container:
docker run --rm ghcr.io/allthingslinux/unrealircd \
  ./unrealircd mkpasswd argon2 'your-secure-password-here'
This outputs a hash like $argon2id$v=19$m=6144,t=2,p=2$.... Set it in your .env:
IRC_OPER_PASSWORD='$argon2id$v=19$m=6144,t=2,p=2$...'
Then regenerate the config and reload:
scripts/prepare-config.sh
just irc reload

Default oper block

The template defines an admin oper with these properties:
PropertyValueNotes
classopersHigher sendq/recvq limits
mask*@172.16.0.0/12Restricted to Docker network
password${IRC_OPER_PASSWORD}Argon2id hash from .env
operclassnetadmin-with-overrideFull admin privileges
vhost${IRC_STAFF_VHOST}Custom hostname for opers
require-modeszMust connect via TLS

Becoming an operator

Once connected to the IRC server via a TLS connection, authenticate with:
/OPER admin your-plaintext-password
You will receive modes +xwsH and be auto-joined to #mod-chat.

Bridge oper

A separate bridge oper exists for the Discord-IRC bridge with minimal permissions (channel override and relaymsg only). Its password is set via BRIDGE_IRC_OPER_PASSWORD in .env.

Atheme bootstrap

On first start, Atheme’s database is empty. You need to register the first account and claim founder status.

First-run sequence

  1. Connect to the IRC server and register a nickname with NickServ:
    /MSG NickServ REGISTER your-password your-email@example.com
    
  2. Check your email and confirm the registration (if email verification is enabled):
    /MSG NickServ VERIFY REGISTER yournick confirmation-code
    
  3. Identify with your registered account:
    /MSG NickServ IDENTIFY your-password
    
  4. OPER up to gain admin privileges:
    /OPER admin your-oper-password
    
  5. Register the primary channel:
    /JOIN #your-channel
    /MSG ChanServ REGISTER #your-channel
    
  6. Set yourself as network administrator in Atheme (requires oper):
    /MSG OperServ SOPER yournick add SRA
    
    SRA (Services Root Administrator) gives full control over all Atheme services.

Atheme database

Atheme stores its database in data/atheme/data/. The database is written periodically and on clean shutdown. If Atheme crashes, you may lose recent registrations since the last write.

Configuration reload

UnrealIRCd supports live config reloads without disconnecting users. Atheme does not support live reloads and requires a restart.

Rehash vs restart

ActionCommandEffectWhen to use
Rehash (reload)just irc reloadRe-reads config without disconnecting usersMost config changes: set blocks, oper blocks, listen options, anti-flood, spamfilters
Restartdocker compose restart atl-irc-serverFull process restart, disconnects all usersModule changes (loadmodule/unloadmodule), TLS library updates, binary upgrades

What requires a restart

These changes cannot be applied via rehash:
  • Adding or removing loadmodule directives
  • Changing the me {} block (server name, SID)
  • Upgrading the UnrealIRCd binary
  • Changes to listen block socket types (adding/removing Unix sockets)

What can be rehashed

Most configuration changes take effect immediately after rehash:
  • set {} block changes (modes, anti-flood, connthrottle, etc.)
  • oper {} block changes (passwords, masks, permissions)
  • allow {} and deny {} blocks
  • ban nick {} and except ban {} blocks
  • blacklist {} (DNSBL) changes
  • link {} block changes
  • Spamfilter rules
  • TLS certificate paths (triggers automatic cert reload)

Performing a rehash

# Via just recipe (sends HUP signal)
just irc reload

# Or directly via docker
docker compose -f compose.yaml -p atl-chat kill -s HUP atl-irc-server
Verify the rehash succeeded by checking logs:
docker compose -f compose.yaml -p atl-chat logs --tail=20 atl-irc-server
Look for Configuration loaded in the output.

SSL certificate rotation

Certificates are managed by the cert-manager service (Lego/Let’s Encrypt). When a certificate is renewed, UnrealIRCd needs to pick up the new cert.

How cert renewal works

  1. The cert-manager container runs Lego to obtain/renew certificates via DNS-01 challenge (Cloudflare)
  2. Certificates are written to data/certs/live/<domain>/ (Let’s Encrypt directory layout)
  3. UnrealIRCd mounts data/certs/ at /home/unrealircd/unrealircd/certs/

Triggering a TLS reload

After certificate renewal, signal UnrealIRCd to reload the new certificate:
# Rehash picks up new cert files automatically
just irc reload
UnrealIRCd re-reads the certificate and key files on every rehash. No restart is needed.

Manual certificate check

Verify the certificate currently in use:
# Check cert expiry from outside
echo | openssl s_client -connect localhost:6697 -servername irc.atl.chat 2>/dev/null | \
  openssl x509 -noout -dates

# Check cert files on disk
openssl x509 -in data/certs/live/irc.atl.chat/fullchain.pem -noout -dates

Certificate expiry notifications

UnrealIRCd has built-in certificate expiry monitoring (certificate-expiry-notification yes in the config). It warns IRC operators when the certificate is approaching expiry.

Health checks

The UnrealIRCd container includes a health check that verifies the process is running.

Container health

# Check container health status
docker inspect --format='{{.State.Health.Status}}' atl-irc-server

# Check all IRC stack containers
docker compose -f compose.yaml -p atl-chat ps

Log inspection

# Follow UnrealIRCd logs
docker compose -f compose.yaml -p atl-chat logs -f atl-irc-server

# Follow Atheme logs
docker compose -f compose.yaml -p atl-chat logs -f atl-irc-services

# Check for errors in the last 50 lines
docker compose -f compose.yaml -p atl-chat logs --tail=50 atl-irc-server | grep -i error

Connectivity test

# Test TLS connection to IRC
echo "QUIT" | openssl s_client -connect localhost:6697 -servername irc.atl.chat 2>/dev/null

# Test WebSocket port
curl -s -o /dev/null -w "%{http_code}" http://localhost:8000

# Test RPC port
curl -sk https://localhost:8600/api/server.list

Common failure modes

SymptomLikely causeResolution
Container exits immediatelyConfig syntax errorCheck logs: docker compose logs atl-irc-server
TLS handshake failsMissing or expired certificateVerify cert paths and expiry dates
Atheme won’t linkWrong IRC_SERVICES_PASSWORDEnsure password matches in both configs
WebSocket 502Port 8000 not listeningCheck UnrealIRCd started with websocket module loaded
RPC auth failsWrong WEBPANEL_RPC_PASSWORDEnsure password matches between WebPanel and UnrealIRCd