secubox-deb/packages/secubox-torrent/debian/postinst
CyberMind-FR 940aa64fcf feat(haproxy,torrent): declarative per-vhost waf_bypass + durable torrent exposure (ref #917)
haproxyctl: honour an opt-in `waf_bypass = true` field per vhost so the
generator emits `use_backend <backend>` (nginx_vhosts) instead of forcing
mitmproxy_inspector under waf_enabled. Makes the WAF-bypass of media/large-
upload services (nc/photoprism/matrix/torrent) declarative, auditable and
regen-durable instead of fragile hand-edits of the generated haproxy.cfg.
Normal vhosts are unaffected (verified in isolation).

secubox-torrent postinst: register torrent.<host>.<suffix> in haproxy.toml
(backend=nginx_vhosts, waf_bypass=true, ssl=true) idempotently and run a
drift-guarded `haproxyctl generate` — which refuses safely on a board that
still has un-migrated hand-edit vhosts (live cfg untouched) and succeeds on a
fresh board. Torrent bypasses sbxwaf by design, so no sbxwaf route is needed.

CLAUDE.md: WAF-bypass section updated — default stays 'never bypass'; the ONLY
sanctioned exception is the declarative waf_bypass=true in haproxy.toml, never
a hand-edit of the generated cfg.

Co-Authored-By: Gerald KERMA <devel@cybermind.fr>
2026-07-28 19:38:59 +02:00

90 lines
4.4 KiB
Bash
Executable File

#!/bin/sh
# SPDX-License-Identifier: LicenseRef-CMSD-1.0
# Copyright (c) 2026 CyberMind — Gérald Kerma <devel@cybermind.fr>
set -e
case "$1" in
configure)
# Ensure secubox user exists (shared across all secubox-* modules).
id -u secubox >/dev/null 2>&1 || \
adduser --system --group --no-create-home \
--home /var/lib/secubox --shell /usr/sbin/nologin secubox
# Runtime + state directories (shared conventions; do not chown the
# /etc/secubox parent here — secubox-core owns it).
install -d -o root -g root -m 1777 /run/secubox
install -d -o secubox -g secubox -m 755 /var/lib/secubox
[ -d /etc/secubox ] || install -d -o secubox -g secubox -m 755 /etc/secubox
# Parse the operator-facing TOML into the env vars install-lxc.sh (via
# lxc/install-lxc.sh's torrent.env writer) expects. Minimal grep parse —
# matches the flat `key = value` lines under [engine]/[retention].
TORRENT_MAX_ACTIVE=$(grep -E '^max_active' /etc/secubox/torrent.toml 2>/dev/null | grep -oE '[0-9]+' | head -1)
TORRENT_WEBRTC=$(grep -E '^webrtc' /etc/secubox/torrent.toml 2>/dev/null | grep -oE 'true|false' | head -1)
TORRENT_TTL=$(grep -E '^ephemeral_ttl_hours' /etc/secubox/torrent.toml 2>/dev/null | grep -oE '[0-9]+' | head -1)
TORRENT_FLOOR=$(grep -E '^disk_floor_gb' /etc/secubox/torrent.toml 2>/dev/null | grep -oE '[0-9]+' | head -1)
export TORRENT_MAX_ACTIVE TORRENT_WEBRTC TORRENT_TTL TORRENT_FLOOR
# Provision/refresh the dedicated WebTorrent LXC (idempotent: creates
# the container once, then redeploys the app + restarts the in-LXC
# unit on every upgrade). Never fail the postinst if LXC tooling isn't
# ready yet (e.g. first apt run before /data is mounted).
bash /usr/lib/secubox/torrent/install-lxc.sh \
|| echo "secubox-torrent: LXC provisioning deferred (run /usr/lib/secubox/torrent/install-lxc.sh manually)"
# Load the egress visibility scope for the torrent LXC's veth.
if [ -f /etc/nftables.d/zz-torrent-egress.nft ]; then
nft -f /etc/nftables.d/zz-torrent-egress.nft 2>/dev/null || true
fi
# Symlink the public vhost into sites-enabled (idempotent). Proxies
# torrent.<host>.<suffix> -> torrent LXC at 10.100.0.160:8090.
if [ -f /etc/nginx/sites-available/torrent.conf ] && [ -d /etc/nginx/sites-enabled ]; then
ln -sf ../sites-available/torrent.conf /etc/nginx/sites-enabled/torrent.conf
fi
if command -v nginx >/dev/null 2>&1 && nginx -t >/dev/null 2>&1; then
systemctl reload nginx 2>/dev/null || true
fi
# Register the HAProxy exposure DURABLY (was previously a hand-edit that a
# `haproxyctl generate` would wipe). Torrent is a WAF-bypass vhost by design
# — like nc/photoprism/matrix, the mitmproxy inspection chain breaks its
# Range streaming / large transfers — so it declares `waf_bypass = true`
# (the sanctioned, auditable opt-in honoured by haproxyctl) and routes
# straight to the host nginx (nginx_vhosts), never through sbxwaf. This
# writes the declaration into /etc/secubox/haproxy.toml; the actual regen is
# drift-guarded (it refuses when the board still holds un-migrated hand-edit
# vhosts, leaving the live cfg untouched, and succeeds on a fresh board).
if [ -f /etc/secubox/haproxy.toml ]; then
# Canonical vhost name/domain from the board identity (falls back to gk2).
if [ -f /etc/default/secubox ]; then
. /etc/default/secubox 2>/dev/null || true
fi
SBX_HOST="${SECUBOX_HOSTNAME:-gk2}"; SBX_SUFFIX="${SECUBOX_DOMAIN_SUFFIX:-secubox.in}"
T_DOMAIN="torrent.${SBX_HOST}.${SBX_SUFFIX}"
T_NAME="torrent_$(echo "${SBX_HOST}.${SBX_SUFFIX}" | tr '.' '_')"
if ! grep -q "^\[vhosts\.${T_NAME}\]" /etc/secubox/haproxy.toml; then
{
printf '\n[vhosts.%s]\n' "$T_NAME"
printf 'domain = "%s"\n' "$T_DOMAIN"
printf 'backend = "nginx_vhosts"\n'
printf 'waf_bypass = true\n'
printf 'ssl = true\n'
printf 'ssl_redirect = true\n'
printf 'enabled = true\n'
} >> /etc/secubox/haproxy.toml
fi
if command -v haproxyctl >/dev/null 2>&1; then
if haproxyctl generate >/dev/null 2>&1; then
systemctl reload haproxy 2>/dev/null || true
else
echo "secubox-torrent: haproxy.toml updated; deferred regen (drift-guarded — run 'haproxyctl generate' once the board's hand-edit vhosts are migrated)" >&2
fi
fi
fi
;;
esac
#DEBHELPER#
exit 0