aboutsummaryrefslogtreecommitdiffstats
path: root/packaging
diff options
context:
space:
mode:
Diffstat (limited to 'packaging')
-rwxr-xr-xpackaging/build/build-hub.sh27
-rw-r--r--packaging/conf/hub.toml.example73
-rw-r--r--packaging/deb/meshbay-hub/DEBIAN/postinst11
-rw-r--r--packaging/rpm/meshbay-hub.spec13
4 files changed, 112 insertions, 12 deletions
diff --git a/packaging/build/build-hub.sh b/packaging/build/build-hub.sh
index 45d2ab9..be2d363 100755
--- a/packaging/build/build-hub.sh
+++ b/packaging/build/build-hub.sh
@@ -53,17 +53,26 @@ if [ -f "$REPO/packages/meshbay-hub/alembic.ini" ]; then
cp "$REPO/packages/meshbay-hub/alembic.ini" "$ROOT/opt/meshbay-hub/migrations/"
fi
-# Config example
+# Config example.
+#
+# A hard failure, not an `if [ -f ]`. This was a silent skip against a path
+# that did not exist, so every package built shipped no example config at all
+# and said nothing about it — and the postinst places no config either, on
+# purpose, which left an installed hub with nothing to copy from.
+EXAMPLE="$REPO/packaging/conf/hub.toml.example"
+[ -f "$EXAMPLE" ] || { echo "!! missing $EXAMPLE" >&2; exit 1; }
mkdir -p "$ROOT/opt/meshbay-hub/share"
-if [ -f "$REPO/packaging/conf/hub.toml.example" ]; then
- cp "$REPO/packaging/conf/hub.toml.example" "$ROOT/opt/meshbay-hub/share/"
-fi
+install -m 644 "$EXAMPLE" "$ROOT/opt/meshbay-hub/share/"
-# Also install to /etc/meshbay/ for discoverability
-mkdir -p "$ROOT/etc/meshbay"
-if [ -f "$ROOT/opt/meshbay-hub/share/hub.toml.example" ]; then
- cp "$ROOT/opt/meshbay-hub/share/hub.toml.example" "$ROOT/etc/meshbay/"
-fi
+# Also next to the real config, where an operator looks first. Never
+# hub.toml itself: an upgrade would overwrite a working deployment.
+#
+# Modes are set here rather than left to the builder's umask, which decided
+# them until now — 775/664 on a machine with umask 002, 755/644 on one with
+# 022, from the same source tree. The postinst tightens the directory too, but
+# that then repairs the package instead of the package being right.
+install -d -m 750 "$ROOT/etc/meshbay"
+install -m 644 "$ROOT/opt/meshbay-hub/share/hub.toml.example" "$ROOT/etc/meshbay/"
# --- Systemd unit ---------------------------------------------------------
mkdir -p "$ROOT/usr/lib/systemd/system"
diff --git a/packaging/conf/hub.toml.example b/packaging/conf/hub.toml.example
new file mode 100644
index 0000000..d647707
--- /dev/null
+++ b/packaging/conf/hub.toml.example
@@ -0,0 +1,73 @@
+# MeshBay Hub — example configuration.
+#
+# Copy to /etc/meshbay/hub.toml and edit. The package deliberately does not
+# install a working config: it would either ship a placeholder secret that
+# somebody runs in production, or overwrite yours on upgrade.
+#
+# Read from the first of these that exists:
+# /etc/meshbay/hub.toml <- where a packaged hub looks
+# ~/.config/meshbay/hub.toml <- a development hub, run as yourself
+#
+# Every value below can also come from the environment, which is what the
+# systemd unit's EnvironmentFile (/etc/meshbay/hub.env) is for. Secrets belong
+# there rather than in an `Environment=` line: `systemctl cat` shows a unit to
+# any user on the machine.
+
+[hub]
+# This hub's identity, as members and nodes know it. Changing it after anyone
+# has joined invalidates what they trust.
+id = "hub.example.org"
+
+# Ed25519 private key. Generate with:
+# meshbay-hub --help (see the key subcommands)
+# The packaged service runs as `meshbay`, so:
+# chown meshbay:meshbay /etc/meshbay/hub_private.pem && chmod 600 it
+private_key_path = "/etc/meshbay/hub_private.pem"
+
+# Accounts granted the admin role at creation. Everything else is set in the UI.
+admin_usernames = []
+
+[database]
+# PostgreSQL in production. The default without this key is an in-memory
+# SQLite, which is a test fixture and loses everything on restart.
+# Prefer MESHBAY_DATABASE_URL in /etc/meshbay/hub.env — it carries a password.
+url = "postgresql+asyncpg://meshbay:CHANGEME@localhost/meshbay_hub"
+
+[server]
+# Loopback: TLS is Caddy's job, and the hub should not be reachable directly.
+host = "127.0.0.1"
+port = 8000
+workers = 1
+
+[jwt]
+# The access token is not the session — the refresh token is, and the SPA
+# renews against it long before this runs out. What this bounds is a token
+# that leaks.
+access_token_ttl = 14400 # 4 h
+refresh_token_ttl = 2592000 # 30 j
+
+[captcha]
+# reCAPTCHA v2 on registration and password reset, so no mail is ever sent
+# before a human has been seen. Absent, or either key empty, disables it
+# entirely — which is right for development and for a hub nobody can reach.
+# See docs/captcha.md.
+site_key = ""
+secret_key = ""
+
+# Hostnames a solved captcha may have been solved on, checked against the one
+# `siteverify` reports — what Google observed, not what the client claims.
+#
+# Leave empty while the reCAPTCHA key does its own origin check: it is then
+# already done, one layer up. Set it when you turn that check off in the
+# reCAPTCHA console, and the two go together — turning the console check off
+# without setting this leaves no origin check anywhere.
+#
+# The desktop client is why it exists. Its interface ships inside the package
+# and is served from `app://meshbay`, so the hostname Google sees is not this
+# hub's and never can be; with the console check on, the widget shows
+# "Invalid domain for site key" and nothing client-side reaches that decision.
+# Add the client's own host only if you distribute it — it is the weak entry,
+# since any Electron application can claim the same scheme and host.
+#
+# allowed_hosts = ["hub.example.org", "localhost", "meshbay"]
+allowed_hosts = []
diff --git a/packaging/deb/meshbay-hub/DEBIAN/postinst b/packaging/deb/meshbay-hub/DEBIAN/postinst
index 3cf66a9..0484f3b 100644
--- a/packaging/deb/meshbay-hub/DEBIAN/postinst
+++ b/packaging/deb/meshbay-hub/DEBIAN/postinst
@@ -17,8 +17,15 @@ case "$1" in
install -d -o meshbay -g meshbay -m 750 /var/lib/meshbay/hub
install -d -o meshbay -g meshbay -m 750 /var/log/meshbay
- # Create config directory (files are placed by the admin, not by us)
- install -d -m 755 /etc/meshbay
+ # Create config directory (files are placed by the admin, not by us —
+ # a shipped hub.toml would be overwritten on upgrade, and a shipped
+ # secret would be run in production). The example lands in
+ # /etc/meshbay/hub.toml.example instead.
+ # 750, not 755: this directory holds the hub's private key and its
+ # database password. The file modes protect the contents, but a
+ # world-listable config directory tells anyone with a shell what a
+ # hub keeps and where. The service reads it by group.
+ install -d -o root -g meshbay -m 750 /etc/meshbay
# Reload systemd if available
if [ -d /run/systemd/system ]; then
diff --git a/packaging/rpm/meshbay-hub.spec b/packaging/rpm/meshbay-hub.spec
index 73df0b9..50bd977 100644
--- a/packaging/rpm/meshbay-hub.spec
+++ b/packaging/rpm/meshbay-hub.spec
@@ -32,7 +32,11 @@ getent passwd meshbay >/dev/null || \
%systemd_post meshbay-hub.service
install -d -o meshbay -g meshbay -m 750 /var/lib/meshbay/hub
install -d -o meshbay -g meshbay -m 750 /var/log/meshbay
-install -d -m 755 /etc/meshbay
+# 750, not 755: this directory holds the hub's private key and its
+# database password. The file modes protect the contents, but a
+# world-listable config directory tells anyone with a shell what a
+# hub keeps and where. The service reads it by group.
+install -d -o root -g meshbay -m 750 /etc/meshbay
%preun
%systemd_preun meshbay-hub.service
@@ -47,6 +51,13 @@ install -d -m 755 /etc/meshbay
/opt/meshbay-common/venv/bin/meshbay-hub
/usr/bin/meshbay-hub
%{_unitdir}/meshbay-hub.service
+# The example config, and the directory it lands in. Both have to be declared:
+# build-hub.sh stages them, and rpmbuild fails the build on an installed file
+# no %files line claims. %config so an operator's edits are kept as .rpmsave
+# rather than silently replaced — it is under /etc, whatever its name says.
+# The mode matches %post; the `meshbay` group exists by then, %pre makes it.
+%dir %attr(0750, root, meshbay) /etc/meshbay
+%config %attr(0644, root, meshbay) /etc/meshbay/hub.toml.example
%changelog
* Sun Aug 31 2026 MeshBay Team <team@meshbay.org> - %{version}-1