New deployments/ergo/: the Ergo IRC server behind Caddy for Let's Encrypt TLS and the IRC-over-WebSocket endpoint. Docker rather than a native OpenRC/systemd service, because Alpine's apk ergo trails upstream (3.24 ships 2.18.0 against a 2.19.1 security release) and Debian/Alma package it at all -- so native would mean three install paths plus a per-distro ACME client. Both containers run with network_mode: host. IRC bans, throttling and cloaking key on the client's address, and Docker's userland proxy would hide every IPv6 client behind the bridge gateway; host mode also makes the repo's INPUT firewall genuinely govern 80/443/6697. Caddy reaches Ergo over loopback, which is what lets Ergo honour X-Forwarded-For (proxy-allowed-from defaults to localhost) and mark web sessions secure. - deploy.sh generates ircd.yaml ONCE from the pulled image's own default.yaml (version-matched), rewriting the listeners/websockets blocks wholesale rather than patching lines, then asserts hard post-conditions and validates with `ergo run --smoke` in a throwaway container before anything starts. - update.sh: pinned vX.Y.Z tags, GHSA + "### Security" release-note policies, pre-flight against the new image, user NOTICE + grace, stop-consistent DB snapshot, health check (IRC-level, not a bare TCP connect) and rollback that restores the DB only when the schema actually moved. Compatibility-break releases are held for review. certsync copies Caddy's cert pairwise-atomically and verifies the fingerprint served on 6697 after the rehash. - ergoctl: status/users/logs, validated edit+rehash, oper add/passwd/rm, moderation, backup/restore, cert and update passthrough. Talks IRC to the loopback listener over bash /dev/tcp and strips control characters from replies. - Ergo runs as a non-root system user, read-only rootfs, all caps dropped; Caddy keeps only NET_BIND_SERVICE, with admin API and HTTP/3 off. Reviewed adversarially across six lenses; 20 confirmed findings fixed, notably a dead SIGHUP fallback (`rc=$?` after an `if` is always 0), several `set -e` aborts from non-total pipelines, a release-list cache that only ever populated in a subshell, and re-runs that used shell defaults instead of the deployed .env. Verified locally: bash -n, LF endings, the ircd.yaml render against the real 2.19.1 template in both PLAINTEXT modes, the yaml/oper/version/env helpers, and the IRC client against a fake server (registration, oper, rehash success and 400-failure, control-character stripping, server-down paths). Not yet exercised on a Docker host: the containers themselves, ACME issuance and cert sync. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
64 lines
3.1 KiB
Bash
64 lines
3.1 KiB
Bash
# Copy to .env and fill in. docker compose picks .env up automatically.
|
|
# deploy.sh seeds this file on first run and never rewrites it afterwards.
|
|
#
|
|
# NOTE: values are NOT quoted and must not contain a dollar sign (Compose
|
|
# interpolates .env). Secrets never live here: the admin oper password is in
|
|
# secrets/admin.pass (0600) and only its bcrypt hash is in ircd/ircd.yaml.
|
|
|
|
# --- Identity -----------------------------------------------------------------
|
|
# Public hostname (lower-case). Becomes Ergo's server.name, the Let's Encrypt
|
|
# cert subject, the Caddy site and the allowed websocket origin. Immutable after
|
|
# the first deploy (Ergo refuses to rehash a changed server name).
|
|
ERGO_DOMAIN=irc.example.com
|
|
|
|
# Email for Let's Encrypt registration / expiry notices.
|
|
ACME_EMAIL=admin@example.com
|
|
|
|
# IRC network name (ISUPPORT NETWORK=, welcome line). Letters, digits, . _ -
|
|
# only -- no spaces. deploy.sh defaults it to ERGO_DOMAIN.
|
|
NETWORK_NAME=irc.example.com
|
|
|
|
# --- Image --------------------------------------------------------------------
|
|
# ghcr.io tags carry the leading 'v' (v2.19.1). deploy.sh pins the newest
|
|
# release on first deploy; update.sh bumps this when it updates. Never pin
|
|
# 'stable'/'latest' here -- those are separate builds and defeat rollback.
|
|
ERGO_IMAGE=ghcr.io/ergochat/ergo
|
|
ERGO_TAG=v2.19.1
|
|
|
|
# uid:gid Ergo runs as inside the container = the host's `ergo` system user
|
|
# (created by deploy.sh; owns ./ircd). Filled in by deploy.sh.
|
|
ERGO_UID=
|
|
ERGO_GID=
|
|
|
|
# --- Listeners ----------------------------------------------------------------
|
|
# 0 (default): plaintext 6667 on 127.0.0.1 only (healthcheck + ergoctl).
|
|
# 1: ALSO serve plaintext IRC on :6667 publicly, with STS advertised so capable
|
|
# clients pin TLS. Credentials sent over 6667 cross the internet in clear.
|
|
# Chosen at the FIRST deploy: it selects a listener in ircd/ircd.yaml, which
|
|
# deploy.sh never rewrites. To change it later, edit that listener with
|
|
# 'ergoctl edit', set the value here, 'ergoctl restart', then re-run deploy.sh
|
|
# so the host firewall matches.
|
|
PLAINTEXT=0
|
|
|
|
# --- Updates (update.sh) ------------------------------------------------------
|
|
# This file is where the scheduled jobs read these four knobs from; edit them
|
|
# here. (An explicit environment variable, or a value pinned in
|
|
# /etc/ergo-update.conf, overrides what is set here for that run.)
|
|
# latest - update to the newest release whenever one exists (default)
|
|
# security - update ONLY when a published GitHub security advisory covers the
|
|
# running version, or a release in range has a "### Security"
|
|
# section in its notes
|
|
# off - never change the running version (check/notify only)
|
|
UPDATE_POLICY=latest
|
|
# Releases whose notes announce "Compatibility breaks" are held for review and
|
|
# only notified, unless FORCE_UPDATE=1.
|
|
FORCE_UPDATE=0
|
|
# Seconds of warning (NOTICE to all users) before an update restarts Ergo.
|
|
UPDATE_GRACE=60
|
|
# 1 = the daily run also pulls a newer Caddy image and recreates it (drops every
|
|
# web-client websocket at that moment). 0 = Caddy updates via `ergoctl update caddy`.
|
|
CADDY_AUTOUPDATE=0
|
|
|
|
# --- Image tags ---------------------------------------------------------------
|
|
CADDY_TAG=2-alpine
|