mirror of
https://github.com/CyberMind-FR/secubox-deb.git
synced 2026-07-28 21:17:36 +00:00
build(toolbox): package rlevel (policyctl, sudoers, panel, seed default_mode) + changelog
secubox-toolbox: install sbxmitm-policyctl (0755), the /rlevel panel + menu.d entry, and a scoped sudoers.d/secubox-toolbox granting the portal (User=secubox-toolbox) exactly the 5 policyctl subcommands (set-floor|force|set-chosen|set-default|list) — no blanket ctl grant. postinst seeds /var/lib/secubox/toolbox/peer-rlevel.json with defaults.mode="reel" (never overwritten on upgrade, leaf-only chown) to preserve current fleet-wide MITM behaviour instead of a surprise fleet-wide downgrade; operators opt individual peers down afterwards. control: + sudo (transport for the ctl delegation). secubox-toolbox-ng: changelog bump only — rlevel.go/rlevel_test.go build into the existing sbxmitm binary (same Go package), no rules/control change needed. Cross-build verified: GOARCH=arm64 GOOS=linux go build -mod=vendor produces a valid ARM aarch64 ELF; go test ./... passes in full. nftables.d @rlevel_off set + off-bypass rule were already shipped by the existing execute_after_dh_auto_install block — verified, not touched. Co-Authored-By: Gerald KERMA <devel@cybermind.fr>
This commit is contained in:
parent
668d920076
commit
8dc288db78
|
|
@ -1,234 +1,149 @@
|
|||
# Task 8 — Rapport : TLS pour la série Z (nginx dans le LXC, secubox-picobrew)
|
||||
# Task 8 — Rapport : Packaging + cross-build + rolling-deploy recipe (rlevel-per-peer)
|
||||
|
||||
**Statut :** Terminé.
|
||||
|
||||
(Note : ce fichier contenait précédemment un rapport Task-8 sans rapport avec
|
||||
ce plan — sleeper `serve` daemon loop / secubox-profiles, ref #896 — écrasé
|
||||
ici car il ne concernait pas ce plan.)
|
||||
ce plan — TLS série Z / secubox-picobrew — écrasé ici car il ne concernait pas
|
||||
le plan `feat/rlevel-per-peer`.)
|
||||
|
||||
## Commit
|
||||
`bde53fb0` — "feat(picobrew): terminaison TLS dans le LXC pour la série Z"
|
||||
|
||||
Fichiers modifiés (scope volontairement limité à ces deux-là) :
|
||||
- `packages/secubox-picobrew/sbin/picobrewctl` (modifié)
|
||||
- `packages/secubox-picobrew/tests/test_ctl_tls.py` (créé)
|
||||
`build(toolbox): package rlevel (policyctl, sudoers, panel, seed default_mode) + changelog`
|
||||
|
||||
## Séquence TDD
|
||||
Fichiers modifiés/créés :
|
||||
- `packages/secubox-toolbox/debian/rules` — installe `sbxmitm-policyctl` (0755),
|
||||
`www/rlevel/` → `usr/share/secubox/www/rlevel/`, `menu.d/27-rlevel.json`, et
|
||||
`debian/secubox-toolbox.sudoers` → `/etc/sudoers.d/secubox-toolbox` (0440).
|
||||
- `packages/secubox-toolbox/debian/secubox-toolbox.sudoers` (créé) — 5 lignes,
|
||||
une par sous-commande fixée (`set-floor *`, `force *`, `set-chosen *`,
|
||||
`set-default *`, `list`), user `secubox-toolbox` (le `User=` du
|
||||
`systemd/secubox-toolbox.service`), pas de `sbxmitm-policyctl ALL`.
|
||||
Validé `visudo -cf` : OK.
|
||||
- `packages/secubox-toolbox/debian/postinst` — seed idempotent de
|
||||
`/var/lib/secubox/toolbox/peer-rlevel.json`
|
||||
(`{"defaults":{"mode":"reel","floor":"passive"},"peers":{}}`), jamais
|
||||
écrasé sur upgrade, chown/chmod du fichier seul (aucun parent partagé
|
||||
touché). Choix `default_mode="reel"` documenté en commentaire +
|
||||
changelog : préserve le comportement actuel (tout peer MITM'd + block
|
||||
honoré) pour éviter un downgrade fleet-wide surprise au déploiement ;
|
||||
les opérateurs abaissent ensuite par-peer.
|
||||
- `packages/secubox-toolbox/debian/control` — ajoute `sudo` aux `Depends`
|
||||
(transport de délégation `sudo -n` utilisé par `secubox_toolbox/api.py`
|
||||
pour appeler le ctl).
|
||||
- `packages/secubox-toolbox/debian/changelog` — bump `2.8.6` → `2.8.7-1~bookworm1`.
|
||||
- `packages/secubox-toolbox-ng/debian/changelog` — bump `0.1.37` → `0.1.38-1~bookworm1`
|
||||
(aucun changement `control`/`rules` : `rlevel.go` compile dans le binaire
|
||||
`sbxmitm` existant, même package Go, aucun fichier d'install nouveau).
|
||||
|
||||
1. Test écrit (`test_ctl_tls.py`, verbatim du brief, 3 cas : TLS sur 443,
|
||||
`proxy_pass` vers `127.0.0.1:80`, absence de `listen 80`).
|
||||
2. Run initial → échec confirmé, `__emit-nginx` inconnu :
|
||||
```
|
||||
FFF
|
||||
AssertionError: usage: picobrewctl {install|start|stop|status [--json]|update <sha>|logs}
|
||||
assert 1 == 0
|
||||
3 failed in 0.08s
|
||||
```
|
||||
3. Implémentation ajoutée (verbatim du brief) avant `usage()` :
|
||||
`_emit_nginx_config` (heredoc `<<'EOF'` — délimiteur **quoté**, donc pas
|
||||
d'interpolation bash de `$host`/`$remote_addr`) et `_ensure_cert`
|
||||
(génération de certificat auto-signé via `lxc_attach`, effet de bord
|
||||
confiné au conteneur, jamais sur l'hôte). Branche
|
||||
`__emit-nginx) _emit_nginx_config ;;` ajoutée dans le `case`, avant `*)`.
|
||||
Câblage dans `cmd_install` juste avant `_install_service_unit` :
|
||||
`_ensure_cert`, écriture de la config dans `sites-available`, symlink vers
|
||||
`sites-enabled`, suppression du vhost `default`, `nginx -t` puis
|
||||
`systemctl enable --now nginx`.
|
||||
4. Re-run → vert :
|
||||
```
|
||||
syntaxe OK
|
||||
...
|
||||
3 passed in 0.06s
|
||||
```
|
||||
Vérifié déjà en place (rien à ajouter) :
|
||||
- `nftables.d/secubox-toolbox-wg.nft` + `-wg-fanout.nft` (named set
|
||||
`@rlevel_off` + `ip saddr @rlevel_off return`) sont déjà installés par
|
||||
`execute_after_dh_auto_install` dans `debian/rules` (confirmé par grep).
|
||||
- API `/rlevel` déjà dans `secubox_toolbox/api.py`, packagée avec le reste
|
||||
du module Python (`cp -r secubox_toolbox`), rien à ajouter.
|
||||
|
||||
## Vérifications obligatoires — sorties réelles
|
||||
## Cross-build Go arm64
|
||||
|
||||
### `cd packages/secubox-picobrew && python3 -m pytest tests/ -q` (suite complète)
|
||||
```
|
||||
................... [100%]
|
||||
19 passed in 0.34s
|
||||
cd packages/secubox-toolbox-ng && GOARCH=arm64 GOOS=linux go build -mod=vendor -o /tmp/sbxmitm ./cmd/sbxmitm
|
||||
file /tmp/sbxmitm
|
||||
# ELF 64-bit LSB executable, ARM aarch64, ..., statically linked
|
||||
```
|
||||
→ **OK**. `rlevel.go`/`rlevel_test.go`/`rlevel_wire_test.go` déjà présents dans
|
||||
`cmd/sbxmitm/`, même package `main` — inclus automatiquement, aucune
|
||||
modification de `debian/rules` (toolbox-ng) nécessaire.
|
||||
|
||||
### `bash tests/test_picobrewctl_guards.sh`
|
||||
## Tests
|
||||
|
||||
- `go test -mod=vendor ./cmd/sbxmitm/` → **PASS**.
|
||||
- `go test -mod=vendor ./...` (suite complète toolbox-ng : sbx-sentinel,
|
||||
sbxmitm, sbxwaf, internal/forge, httpcodec, relay, reload, sentinel) →
|
||||
**PASS** (8/8 packages ok).
|
||||
- `pytest tests/test_rlevel_api.py tests/test_rlevel_panel.py` (secubox-toolbox)
|
||||
→ **36 passed**.
|
||||
- Suite complète `pytest tests/` (secubox-toolbox, 373 tests) → **335 passed,
|
||||
3 failed** — les 3 échecs sont **préexistants, hors scope** :
|
||||
`test_bypass_sources.py::test_load_bypass_tagged_missing_source_skipped`
|
||||
(drift schéma non lié à rlevel, commit `45f8397e` antérieur à cette
|
||||
branche) et 2 échecs `test_media_stats.py` (`ModuleNotFoundError:
|
||||
secubox_core` — artefact d'environnement local, module hors PYTHONPATH du
|
||||
venv de test, pas un régression rlevel). Vérifié : ces 3 tests échouent
|
||||
déjà indépendamment de nos modifications.
|
||||
|
||||
## Build des `.deb`
|
||||
|
||||
**secubox-toolbox (arch:all)** :
|
||||
```
|
||||
PASS accept sha '0123456789abcdef0123456789abcdef01234567'
|
||||
PASS reject sha 'HEAD'
|
||||
PASS reject sha 'main'
|
||||
PASS reject sha '0123456789abcdef0123456789abcdef0123456'
|
||||
PASS reject sha '0123456789ABCDEF0123456789ABCDEF01234567'
|
||||
PASS reject sha 'v1.0; rm -rf /'
|
||||
PASS reject unknown cmd
|
||||
cd packages/secubox-toolbox && dpkg-buildpackage -us -uc -b
|
||||
```
|
||||
7/7 PASS.
|
||||
|
||||
### `bash -n sbin/picobrewctl`
|
||||
→ **OK**, `secubox-toolbox_2.8.7-1~bookworm1_all.deb` produit.
|
||||
`dpkg-deb -c` confirme :
|
||||
```
|
||||
syntaxe OK
|
||||
./etc/sudoers.d/secubox-toolbox (0440 root:root)
|
||||
./usr/sbin/sbxmitm-policyctl (0755)
|
||||
./usr/share/secubox/menu.d/27-rlevel.json
|
||||
./usr/share/secubox/www/rlevel/index.html
|
||||
```
|
||||
(aucune sortie d'erreur — syntaxe bash valide, `set -e` toujours absent du
|
||||
script, `set -uo pipefail` inchangé)
|
||||
`bash -n postinst` (extrait du .deb, post `#DEBHELPER#` substitution par
|
||||
dh_installsystemd) → OK, `#DEBHELPER#` correctement remplacé (aucune
|
||||
occurrence littérale restante), `exit 0` final présent.
|
||||
|
||||
### Sortie réelle de `bash sbin/picobrewctl __emit-nginx` (preuve du non-interpolage)
|
||||
Avertissements préexistants, hors scope de cette tâche (non liés à rlevel) :
|
||||
`${python3:Depends}` non substituée et conffile `/etc/secubox/toolbox.toml`
|
||||
« dupliqué » — déjà présents avant ce commit.
|
||||
|
||||
**secubox-toolbox-ng (arch:arm64)** :
|
||||
```
|
||||
# SecuBox-Deb :: PicoBrew — terminaison TLS pour la série Z.
|
||||
#
|
||||
# picobrew_pico écoute déjà en clair sur :80 — c'est le comportement upstream,
|
||||
# et c'est ce que les Pico/Zymatic attendent. nginx ne prend donc QUE le 443 :
|
||||
# le faire écouter aussi sur :80 tout en proxifiant vers 127.0.0.1:80 le ferait
|
||||
# se parler à lui-même (boucle infinie). Les appareils non-Z continuent de
|
||||
# joindre Flask directement en :80.
|
||||
server {
|
||||
listen 443 ssl;
|
||||
server_name picobrew.com _;
|
||||
client_max_body_size 32m;
|
||||
ssl_certificate /etc/picobrew/tls/cert.pem;
|
||||
ssl_certificate_key /etc/picobrew/tls/key.pem;
|
||||
location / {
|
||||
proxy_pass http://127.0.0.1:80;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Forwarded-For $remote_addr;
|
||||
}
|
||||
}
|
||||
cd packages/secubox-toolbox-ng && dpkg-buildpackage -a arm64 -us -uc -b
|
||||
```
|
||||
`$host` et `$remote_addr` apparaissent **littéralement** dans la sortie (pas
|
||||
de substitution bash — ces variables n'existent pas dans le shell hôte, une
|
||||
interpolation les aurait remplacées par une chaîne vide). Le heredoc utilise
|
||||
le délimiteur quoté `<<'EOF'`, ce qui désactive toute expansion. Confirmé
|
||||
aussi dans cette même sortie : `listen 443 ssl` présent une seule fois,
|
||||
`proxy_pass http://127.0.0.1:80` présent, et **aucune** occurrence de
|
||||
`listen 80`.
|
||||
→ **Bloqué par le dependency-checker** : `dpkg-checkbuilddeps` exige
|
||||
`golang-go` pour l'arch hôte **arm64** (`golang-go:arm64`), absent de cette
|
||||
machine (seul `golang-go:amd64` est installé — pas de support multiarch Go
|
||||
sur ce poste). C'est une limitation de l'outillage dpkg de vérification des
|
||||
Build-Depends pour une cross-compilation Go pure (`CGO_ENABLED=0`), pas un
|
||||
problème du build lui-même : Go cross-compile sans avoir besoin d'un
|
||||
toolchain arm64 installé.
|
||||
Contournement de **vérification uniquement** (`dpkg-buildpackage -a arm64 -d
|
||||
...`, `-d` = ignore les dépendances de build) : le build réel a ensuite
|
||||
**réussi** — `secubox-toolbox-ng_0.1.38-1~bookworm1_arm64.deb` produit,
|
||||
`dpkg-deb -c` confirme `./usr/sbin/sbxmitm` (0755), et le binaire extrait est
|
||||
bien `ELF ... ARM aarch64 ... stripped`. `bash -n` sur le postinst extrait →
|
||||
OK, `#DEBHELPER#` correctement substitué.
|
||||
Le `.deb` produit avec `-d` est donc valide et déployable, mais un build CI
|
||||
« propre » sur cette machine échouerait à la porte `dpkg-checkbuilddeps` tant
|
||||
que `golang-go:arm64` (ou l'équivalent multiarch) n'est pas installé — ceci
|
||||
est indépendant de ce plan et déjà vrai avant ce commit (aucune régression
|
||||
introduite ici). Le binaire cross-buildé de l'étape 4 (`/tmp/sbxmitm`) reste
|
||||
la référence pour un déploiement manuel immédiat si le `.deb` CI n'est pas
|
||||
disponible.
|
||||
|
||||
## Diff appliqué (`sbin/picobrewctl`)
|
||||
## Nettoyage post-build
|
||||
|
||||
Conforme verbatim au brief : ajout de `_emit_nginx_config`, `_ensure_cert`,
|
||||
branche `__emit-nginx` avant `*)` dans le `case`, et câblage dans
|
||||
`cmd_install` juste avant `_install_service_unit`. Vérifié via `git diff` :
|
||||
deux blocs d'ajout uniquement, aucune suppression ni altération de code
|
||||
existant.
|
||||
Un fichier binaire préexistant et suivi par git,
|
||||
`packages/secubox-toolbox-ng/sbx-sentinel` (déjà commité avant ce plan, non
|
||||
gitignoré contrairement à `/sbxmitm`/`/sbxwaf`), a été régénéré à l'identique
|
||||
(diff binaire, mêmes octets logiques mais horodatage/BuildID différents) par
|
||||
`dh_auto_build`. Restauré via `git restore` pour ne pas polluer le commit
|
||||
avec un artefact de build — signalé ici pour traçabilité, aucune action
|
||||
requise côté plan (préexistant, hors scope).
|
||||
|
||||
```diff
|
||||
@@ cmd_install() { ... } @@
|
||||
+ _ensure_cert || { err "génération du certificat échouée"; return 1; }
|
||||
+ _emit_nginx_config > "$LXC_PATH/$CONTAINER/rootfs/etc/nginx/sites-available/picobrew"
|
||||
+ lxc_attach 'ln -sf /etc/nginx/sites-available/picobrew /etc/nginx/sites-enabled/picobrew
|
||||
+ rm -f /etc/nginx/sites-enabled/default
|
||||
+ nginx -t >/dev/null 2>&1 && systemctl enable --now nginx' \
|
||||
+ || { err "configuration nginx invalide"; return 1; }
|
||||
+
|
||||
_install_service_unit
|
||||
...
|
||||
|
||||
@@ après cmd_update(), avant usage() @@
|
||||
+_emit_nginx_config() {
|
||||
+ cat <<'EOF'
|
||||
+ ...(config nginx, listen 443 ssl uniquement)...
|
||||
+EOF
|
||||
+}
|
||||
+
|
||||
+_ensure_cert() {
|
||||
+ lxc_attach 'set -e
|
||||
+ mkdir -p /etc/picobrew/tls
|
||||
+ [ -s /etc/picobrew/tls/cert.pem ] && exit 0
|
||||
+ openssl req -x509 -newkey rsa:2048 -nodes -days 3650 \
|
||||
+ -subj "/CN=picobrew.com" \
|
||||
+ -addext "subjectAltName=DNS:picobrew.com,DNS:*.picobrew.com" \
|
||||
+ -keyout /etc/picobrew/tls/key.pem \
|
||||
+ -out /etc/picobrew/tls/cert.pem >/dev/null 2>&1
|
||||
+ chmod 600 /etc/picobrew/tls/key.pem'
|
||||
+}
|
||||
|
||||
@@ case "${1:-}" in ... @@
|
||||
__emit-config) _emit_lxc_config ;;
|
||||
+ __emit-nginx) _emit_nginx_config ;;
|
||||
```
|
||||
Aucun `.deb`, `.buildinfo`, `.changes`, `debian/secubox-toolbox*/` de staging,
|
||||
`.substvars` n'a été ajouté au commit — tous confirmés `git status
|
||||
--ignored` sous les règles `.gitignore` existantes.
|
||||
|
||||
## Préoccupations
|
||||
|
||||
- `_ensure_cert` et le câblage nginx de `cmd_install` (symlink,
|
||||
`nginx -t`, `systemctl enable --now nginx`) dépendent de `lxc_attach`,
|
||||
donc d'un conteneur LXC réellement démarré — non testable en CI hors
|
||||
environnement LXC. Seule `_emit_nginx_config` (sans effet de bord, stdout
|
||||
uniquement, comme exigé) est couverte par des tests automatisés ; c'est le
|
||||
même niveau de couverture que le reste du module (`_emit_lxc_config` /
|
||||
`cmd_install` suivent déjà ce schéma — pas de régression de rigueur).
|
||||
- Aucune régression détectée : 19/19 tests pytest du module (dont les 3
|
||||
nouveaux) et 7/7 gardes shell passent après la modification.
|
||||
|
||||
---
|
||||
|
||||
## Correctif de revue — `enable --now nginx` → `enable && restart` (post-Task 8)
|
||||
|
||||
**Statut :** Terminé.
|
||||
|
||||
### Défaut relevé en revue
|
||||
|
||||
`nginx` figure dans `--include=` du debootstrap ; le paquet Debian
|
||||
auto-active son unit via preset. Sur un conteneur fraîchement débootstrappé,
|
||||
nginx tourne donc déjà (vhost `default` stock, `listen 80 default_server`)
|
||||
avant même l'écriture de la config TLS. `systemctl enable --now nginx` sur
|
||||
une unit **déjà active** est un no-op côté (re)démarrage : la nouvelle
|
||||
config 443 n'est jamais chargée par le process en mémoire, et nginx reste
|
||||
planté sur `:80`, empêchant ensuite `picobrew.service` (Flask) de se lier
|
||||
sur ce port. Installation bloquée sur tout conteneur neuf.
|
||||
|
||||
### Correctif
|
||||
|
||||
Dans `cmd_install`, remplacement de :
|
||||
```bash
|
||||
nginx -t >/dev/null 2>&1 && systemctl enable --now nginx
|
||||
```
|
||||
par :
|
||||
```bash
|
||||
nginx -t >/dev/null 2>&1 && systemctl enable nginx && systemctl restart nginx
|
||||
```
|
||||
Commentaire ajouté juste avant le bloc `lxc_attach` expliquant pourquoi
|
||||
`restart` (et non `enable --now`) est requis, pour empêcher qu'un futur
|
||||
lecteur ne « simplifie » en réintroduisant le bug.
|
||||
|
||||
Conservé à l'identique : `nginx -t` avant toute (re)activation, le
|
||||
`|| { err "configuration nginx invalide"; return 1; }`, `set -uo pipefail`
|
||||
en tête sans `set -e` au niveau du script, et le reste de `cmd_install`
|
||||
(ordre `_ensure_cert` → écriture config → nginx → `picobrew.service`).
|
||||
|
||||
### Vérifications obligatoires — sorties réelles
|
||||
|
||||
`bash -n sbin/picobrewctl` → aucune sortie, syntaxe OK.
|
||||
|
||||
`bash tests/test_picobrewctl_guards.sh` (depuis `packages/secubox-picobrew`) :
|
||||
```
|
||||
PASS accept sha '0123456789abcdef0123456789abcdef01234567'
|
||||
PASS reject sha 'HEAD'
|
||||
PASS reject sha 'main'
|
||||
PASS reject sha '0123456789abcdef0123456789abcdef0123456'
|
||||
PASS reject sha '0123456789ABCDEF0123456789ABCDEF01234567'
|
||||
PASS reject sha 'v1.0; rm -rf /'
|
||||
PASS reject unknown cmd
|
||||
```
|
||||
7/7 PASS.
|
||||
|
||||
`cd packages/secubox-picobrew && python3 -m pytest tests/ -q` :
|
||||
```
|
||||
................... [100%]
|
||||
19 passed in 0.31s
|
||||
```
|
||||
|
||||
`bash sbin/picobrewctl __emit-nginx` : sortie strictement identique à celle
|
||||
documentée plus haut dans ce fichier (mêmes octets, `listen 443 ssl`
|
||||
uniquement, `proxy_pass http://127.0.0.1:80`), confirmée par
|
||||
`grep -n "listen 80"` → aucune occurrence.
|
||||
|
||||
`git diff` sur `packages/secubox-picobrew/sbin/picobrewctl` : diff minimal,
|
||||
un commentaire ajouté + une ligne modifiée (`enable --now nginx` →
|
||||
`enable nginx && systemctl restart nginx`), aucun autre changement.
|
||||
|
||||
### Préoccupations
|
||||
|
||||
- Comme pour le reste du câblage nginx/LXC de ce module, ce chemin dépend de
|
||||
`lxc_attach` (conteneur réellement démarré) et n'est donc pas couvert par
|
||||
un test automatisé direct — même limite déjà documentée plus haut pour
|
||||
`_ensure_cert`/`cmd_install`. Seule la non-régression de `_emit_nginx_config`
|
||||
(sortie statique) est vérifiable en CI, et elle est confirmée inchangée.
|
||||
- Le correctif n'a pas été testé en conditions réelles sur un LXC fraîchement
|
||||
débootstrappé (pas d'accès à un tel environnement dans cette session) ;
|
||||
la garantie repose sur la sémantique documentée de `systemctl restart`
|
||||
(fonctionne indifféremment sur une unit active ou arrêtée).
|
||||
1. **arm64 cross-build CI** : si le runner CI n'a pas `golang-go:arm64`
|
||||
(multiarch) installé, `dpkg-checkbuilddeps` bloquera le build
|
||||
`secubox-toolbox-ng` même si le binaire compile parfaitement (Go pur,
|
||||
`CGO_ENABLED=0`). À vérifier sur l'environnement CI réel — probablement
|
||||
déjà résolu là-bas (image cross dédiée) puisque ce n'est pas nouveau à ce
|
||||
plan.
|
||||
2. **3 tests pytest préexistants en échec** (`test_bypass_sources.py` +
|
||||
`test_media_stats.py` ×2) — sans rapport avec rlevel, mais à corriger
|
||||
séparément (drift de schéma bypass-sources ; `secubox_core` absent du
|
||||
PYTHONPATH de test local).
|
||||
3. **Recette de rolling-deploy** (rolling restart des 4 workers,
|
||||
`sudo -n` avant chaque appel ctl, vérification bypass nft "off") reste à
|
||||
exécuter manuellement sur le board — hors périmètre de cette tâche de
|
||||
packaging (cf. section « Recette de déploiement » du brief).
|
||||
|
|
|
|||
|
|
@ -1,3 +1,18 @@
|
|||
secubox-toolbox-ng (0.1.38-1~bookworm1) bookworm; urgency=medium
|
||||
|
||||
* sbxmitm: per-peer R-level MITM policy (rlevel-per-peer, task 8). The
|
||||
worker fleet (cmd/sbxmitm/rlevel.go) now loads/hot-reloads
|
||||
/var/lib/secubox/toolbox/peer-rlevel.json (written by the new
|
||||
sbxmitm-policyctl in secubox-toolbox) and computes each peer's effective
|
||||
inspection level (off < passive < active < reel = forced ?? clamp(chosen,
|
||||
floor, reel)). Companion secubox-toolbox package seeds
|
||||
defaults.mode="reel" on first install to preserve today's fleet-wide
|
||||
behaviour (no silent downgrade); operators opt individual peers down via
|
||||
the /rlevel panel or the ctl. No control/rules change here — rlevel.go
|
||||
builds into the existing sbxmitm binary (same package, no new file).
|
||||
|
||||
-- Gerald KERMA <devel@cybermind.fr> Fri, 24 Jul 2026 09:00:00 +0200
|
||||
|
||||
secubox-toolbox-ng (0.1.37-1~bookworm1) bookworm; urgency=medium
|
||||
|
||||
* sbxwaf: fingerprint scanners on static-asset paths. Previously any path
|
||||
|
|
|
|||
|
|
@ -1,3 +1,24 @@
|
|||
secubox-toolbox (2.8.7-1~bookworm1) bookworm; urgency=medium
|
||||
|
||||
* rlevel-per-peer: package the R-level MITM policy surface (#rlevel-per-peer,
|
||||
task 8). Ships sbxmitm-policyctl (root-scoped ctl owning peer-rlevel.json +
|
||||
the @rlevel_off nft set), the /rlevel admin+self-service panel and its
|
||||
menu.d entry, and a scoped sudoers.d/secubox-toolbox that only lets the
|
||||
portal (User=secubox-toolbox) invoke the five fixed policyctl subcommands
|
||||
(set-floor|force|set-chosen|set-default|list) — no blanket
|
||||
`sbxmitm-policyctl ALL`. The panel's nftables.d off-bypass (@rlevel_off set
|
||||
in secubox-toolbox-wg.nft + secubox-toolbox-wg-fanout.nft) already ships
|
||||
via the existing nftables.d install block.
|
||||
postinst seeds /var/lib/secubox/toolbox/peer-rlevel.json with
|
||||
defaults.mode="reel" (never overwritten on upgrade) — a DELIBERATE choice
|
||||
to PRESERVE current fleet-wide behaviour (every peer fully MITM'd + the
|
||||
existing block policy honoured) instead of a surprise fleet-wide downgrade
|
||||
to a lighter default at deploy time; operators opt individual peers DOWN
|
||||
afterwards via the panel or the ctl.
|
||||
Depends: + sudo (delegation transport for the ctl).
|
||||
|
||||
-- Gerald KERMA <devel@cybermind.fr> Fri, 24 Jul 2026 09:00:00 +0200
|
||||
|
||||
secubox-toolbox (2.8.6-1~bookworm2) bookworm; urgency=medium
|
||||
|
||||
* autolearn: NEVER-SPLICE guard so ad/tracker networks are never promoted to
|
||||
|
|
|
|||
|
|
@ -34,7 +34,8 @@ Depends: ${misc:Depends}, ${python3:Depends},
|
|||
python3-qrcode,
|
||||
python3-geoip2 | geoipupdate,
|
||||
lxc,
|
||||
debian-archive-keyring
|
||||
debian-archive-keyring,
|
||||
sudo
|
||||
Recommends: bridge-utils,
|
||||
tor,
|
||||
obfs4proxy,
|
||||
|
|
|
|||
|
|
@ -104,6 +104,28 @@ SBXFILTERS
|
|||
mkdir -p /var/lib/secubox/toolbox
|
||||
chown secubox-toolbox:secubox-toolbox /var/lib/secubox/toolbox 2>/dev/null || true
|
||||
chmod 0750 /var/lib/secubox/toolbox 2>/dev/null || true
|
||||
|
||||
# rlevel-per-peer (#task-8) : seed the per-peer wg-toolbox MITM policy
|
||||
# store consumed by sbxmitm-policyctl + the Go workers (cmd/sbxmitm/
|
||||
# rlevel.go). NEVER overwrite an existing file (would clobber operator
|
||||
# per-peer settings on upgrade — leaf file only, no shared-parent chown).
|
||||
#
|
||||
# default_mode="reel" is a DELIBERATE choice: it PRESERVES today's
|
||||
# behaviour (every wg-toolbox peer fully MITM'd + the existing block
|
||||
# policy honoured), so installing/upgrading this package does NOT
|
||||
# silently downgrade inspection for the whole fleet. Operators/admins
|
||||
# opt individual peers DOWN to active/passive/off afterwards via the
|
||||
# /rlevel panel or sbxmitm-policyctl — this is a privacy-forward
|
||||
# opt-DOWN model, not an opt-in-UP one, to avoid a surprise fleet-wide
|
||||
# relaxation at deploy time.
|
||||
if [ ! -f /var/lib/secubox/toolbox/peer-rlevel.json ]; then
|
||||
cat > /var/lib/secubox/toolbox/peer-rlevel.json <<'SBXRLEVEL'
|
||||
{"defaults":{"mode":"reel","floor":"passive"},"peers":{}}
|
||||
SBXRLEVEL
|
||||
chown secubox-toolbox:secubox-toolbox /var/lib/secubox/toolbox/peer-rlevel.json 2>/dev/null || true
|
||||
chmod 0640 /var/lib/secubox/toolbox/peer-rlevel.json 2>/dev/null || true
|
||||
fi
|
||||
|
||||
# #577 : shared media proxy-cache dir (opt-in via filters ; 2 GB LRU).
|
||||
mkdir -p /var/cache/secubox/toolbox/media
|
||||
chown secubox-toolbox:secubox-toolbox /var/cache/secubox/toolbox/media 2>/dev/null || true
|
||||
|
|
|
|||
|
|
@ -21,13 +21,25 @@ override_dh_auto_install:
|
|||
# WebUI
|
||||
install -d debian/secubox-toolbox/usr/share/secubox/www/toolbox
|
||||
cp -r www/toolbox/. debian/secubox-toolbox/usr/share/secubox/www/toolbox/
|
||||
# rlevel-per-peer (task 8) : panel is served alongside the toolbox WebUI.
|
||||
install -d debian/secubox-toolbox/usr/share/secubox/www/rlevel
|
||||
cp -r www/rlevel/. debian/secubox-toolbox/usr/share/secubox/www/rlevel/
|
||||
# Menu
|
||||
install -d debian/secubox-toolbox/usr/share/secubox/menu.d
|
||||
install -m 0644 menu.d/26-toolbox.json debian/secubox-toolbox/usr/share/secubox/menu.d/
|
||||
install -m 0644 menu.d/27-rlevel.json debian/secubox-toolbox/usr/share/secubox/menu.d/
|
||||
# Helpers
|
||||
install -d debian/secubox-toolbox/usr/sbin
|
||||
install -m 0755 scripts/toolbox-up debian/secubox-toolbox/usr/sbin/
|
||||
install -m 0755 scripts/ca-init debian/secubox-toolbox/usr/sbin/secubox-toolbox-ca-init
|
||||
# rlevel-per-peer (task 4/8) : root-scoped ctl owning peer-rlevel.json +
|
||||
# the @rlevel_off nft set (see sbin/sbxmitm-policyctl header).
|
||||
install -m 0755 sbin/sbxmitm-policyctl debian/secubox-toolbox/usr/sbin/
|
||||
# Scoped sudoers: the portal (User=secubox-toolbox) may only invoke the
|
||||
# 5 fixed policyctl subcommands — no wildcard, no arbitrary root command.
|
||||
install -d debian/secubox-toolbox/etc/sudoers.d
|
||||
install -m 0440 debian/secubox-toolbox.sudoers \
|
||||
debian/secubox-toolbox/etc/sudoers.d/secubox-toolbox
|
||||
# sbin/ helpers (Phase 5 LXC, Phase 6 R3 WG, Phase 9 fanout, Phase 11 social).
|
||||
# Pre-2.6.0 only db-tune + lxc-provision shipped — the mitm-wg-launch
|
||||
# wrapper had to be hand-installed on the board. This block ships them
|
||||
|
|
|
|||
17
packages/secubox-toolbox/debian/secubox-toolbox.sudoers
Normal file
17
packages/secubox-toolbox/debian/secubox-toolbox.sudoers
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
# rlevel-per-peer (#task-8) : the portal (User=secubox-toolbox, see
|
||||
# systemd/secubox-toolbox.service) delegates every privileged mutation of
|
||||
# /var/lib/secubox/toolbox/peer-rlevel.json + the @rlevel_off nft set to
|
||||
# sbxmitm-policyctl (see sbin/sbxmitm-policyctl header) via `sudo -n`.
|
||||
#
|
||||
# Fixed verbs only — no blanket `sbxmitm-policyctl ALL`, so a future
|
||||
# subcommand added to the ctl is NOT automatically grantable without a
|
||||
# packaging change here. Trailing `*` wildcards only the pubkey/mode
|
||||
# ARGUMENTS of an already-pinned verb (mirrors the wg show * pattern in
|
||||
# secubox-wireguard) — the verb itself never has a wildcard.
|
||||
# Relies on sudo's default env_reset (do NOT add SETENV/env_keep — the ctl
|
||||
# also refuses env overrides as root, see the SBXMITM_POLICYCTL_TEST guard).
|
||||
secubox-toolbox ALL=(root) NOPASSWD: /usr/sbin/sbxmitm-policyctl set-floor *
|
||||
secubox-toolbox ALL=(root) NOPASSWD: /usr/sbin/sbxmitm-policyctl force *
|
||||
secubox-toolbox ALL=(root) NOPASSWD: /usr/sbin/sbxmitm-policyctl set-chosen *
|
||||
secubox-toolbox ALL=(root) NOPASSWD: /usr/sbin/sbxmitm-policyctl set-default *
|
||||
secubox-toolbox ALL=(root) NOPASSWD: /usr/sbin/sbxmitm-policyctl list
|
||||
Loading…
Reference in New Issue
Block a user