38bcad1ebd81c5eab60229b7bd4f20f21e7498bbe00ed5bd3b678d34a10d300d — 21235 octetspublier-md-html.sh (python-markdown, local).
Le .md fait foi ; cette page en est dérivée.
sudo par projet et rotation automatique des bridges Torc3b, hôte One127.0.0.1:20130)webtech3.comsudo qui l'accompagne.sudoers n'a été modifié.https://webtech3.com/publications/ (vérifié en HTTPS le 15/10 : HTTP 200,
application/pdf). Les empreintes de la version publiée sont dans
MANIFESTE.sha256, déposé à côté des fichiers.Trois jours de travail sur la sécurisation de Tor n'avaient produit aucun résultat visible. Ce document explique pourquoi, ce qui est réellement livré, et comment le prouver.
| Question | Réponse mesurée |
|---|---|
| Tor fonctionne-t-il aujourd'hui ? | Oui. tor@default active, Bootstrapped 100%, sortie {"IsTor":true} |
| Que corrige le livrable ? | Les bridges d'entrée : 2 des 4 en service sont fermés, dont un réinstallé à chaque rotation |
| Le correctif est-il testé ? | Oui : harnais 40 PASS / 0 FAIL, manifeste 7/7 OK, installation 4/4 empreintes |
| Pourquoi n'est-il pas installé ? | sudo exige un mot de passe ; DSH tourne sans TTY (§7) |
| Un bridge peut-il être un nœud de sortie ? | Non — c'est une règle du protocole, pas un réglage (§6) |
Le blocage n'est pas technique. C'est une porte que seul un humain peut ouvrir. Le reste est fini.
Contrairement à ce qu'on pouvait croire, la rotation automatique existait depuis le 24/09/2026 :
tor-securise-rotate.timer OnCalendar=daily, RandomizedDelaySec=6h
tor-securise-rotate.service ExecStart=/usr/local/bin/tor-securise-rotation
Dernière exécution : Thu 2026-10-15 01:23:46 CEST status=0/SUCCESS
Elle a tourné le 15/10 à 01:23 et a écrit un nouveau jeu de bridges, puis redémarré Tor — qui a bootstrappé en 15 s. Le problème n'était donc pas l'absence d'automatisation, mais sa qualité : elle écrivait une liste non filtrée.
L'API moat (source des bridges) ne filtre pas les bridges morts. Mesure :
moat/circumvention/builtin → obfs4 : 7 candidats
51.222.13.177:80 ← en production, sonde TCP 3/3 FERMÉ
146.57.248.225:22 ← en production, sonde TCP 3/3 FERMÉ, port 22
45.145.95.6:27015 ← OUVERT
La v1 installée prenait cette liste brute. Résultat : des bridges morts
sont réinstallés à chaque passage, et Tor consomme 15 tentatives de connexion
échouées par jour (general SOCKS server failure, de 01:23 à 09:52).
Ce qui a sauvé la connexion : sur 4 bridges, 3 étaient vivants. Tor sélectionne un bridge vivant et bootstrappe. Le service n'est pas tombé — sa marge de sécurité, si.
Le projet a suivi un cycle reproductible, applicable à tout futur automatisme privilégié :
1. MESURER établir l'état réel par commande, jamais par supposition
2. MODÉLISER écrire le correctif dans un dossier de travail isolé
3. ÉPROUVER harnais de tests : chaque test doit pouvoir ÉCHOUER
4. SIMULER rejouer l'installation sur une racine factice (/tmp)
5. PROUVER empreintes sha256 + manifeste + test négatif du manifeste
Outils et commandes employés (tous rejouables) :
sudo -n -l # droits réellement accordés
systemctl list-timers tor-securise-rotate.timer --no-pager
journalctl -u tor@default --since '-12h' # échecs de connexion bridge
grep -c '^Bridge' /etc/tor/torrc.d/50-bridges.conf
curl -s --socks5-hostname 127.0.0.1:9050 https://check.torproject.org/api/ip
bash scripts/tor-securise-rotation --list # sonde TCP par bridge
Le correctif v3 ajoute, par rapport à la v1 :
| Ajout v3 | Effet |
|---|---|
| Sonde TCP avant retenue | un bridge injoignable n'est jamais écrit |
| Liste noire | les morts récurrents sont rejetés et nommés dans la sortie |
| Élagage des morts en service | nettoie le drop-in existant, pas seulement les nouveaux |
| Rejet des ports privilégiés | élimine les bridges sur port 22 (inutilisables par Tor) |
| Déduplication + tri stable | sortie reproductible, comparable d'une exécution à l'autre |
| Contrôle de vivacité APRÈS redémarrage | vérifie chaque bridge, pas seulement « Bootstrapped 100% » |
| Rollback automatique | si le bootstrap échoue, restaure les bridges précédents |
Le harnais compte 40 tests, dont deux sections décisives :
--- 9. Anti-régression : les bridges de PRODUCTION passent le filtre ---
info production : 4 bridges en service, 3 survivent au filtre
PASS 209.148.46.65:443 (production) conserve
PASS 212.83.43.95:443 (production) conserve
PASS 212.83.43.74:443 (production) conserve
--- 10. [reseau] moat reel ---
PASS moat renvoie >= 2 bridges joignables (4)
PASS bridge mort absent
PASS bridge port 22 absent
PASS aucun doublon exact (0)
BILAN : 40 PASS / 0 FAIL
Le test §9 est un anti-régression : il garantit que le filtre ne casse pas les bridges déjà en production. Le test §10 interroge le réseau réel.
L'installation complète a été rejouée sur une racine factice (/tmp/simul-root),
où sudo cp est remplacé par cp :
=== 2. Empreintes après installation simulée ===
7ab312bb… usr/local/bin/tor-securise-rotation
84134dcd… usr/local/lib/tor-securise/moat.sh
1c423d55… etc/systemd/system/tor-securise-rotate.service
d97482c2… etc/systemd/system/tor-securise-rotate.timer
=== 3. Attendus du livrable ===
7ab312bb… scripts/tor-securise-rotation
84134dcd… lib/moat.sh
1c423d55… unites/tor-securise-rotate.service
d97482c2… unites/tor-securise-rotate.timer
4/4 identiques : la chaîne d'installation produit bien les fichiers attendus, avant d'avoir touché au système réel.
$ sha256sum -c MANIFESTE.sha256
INSTALLER-v3.1.sh: OK unites/tor-securise-rotate.service: OK
ROLLBACK.sh: OK unites/tor-securise-rotate.timer: OK
VERIFIER-apres-installation.sh: OK
LISEZ-MOI.md: OK A-COLLER.md: OK
Test négatif (vérifier que le manifeste détecte vraiment une altération) :
une ligne du manifeste a été volontairement corrompue → sha256sum -c a
répondu FAILED, puis restaurée et revérifiée 7/7 OK. Un manifeste qui
ne sait pas échouer ne prouve rien.
La version v3 du service portait cette ligne :
ProtectSystem=full
En apparence, une bonne pratique de durcissement. En réalité, un piège.
systemd monte alors /etc en lecture seule pour le service. Or la
rotation doit écrire /etc/tor/torrc.d/50-bridges.conf.
Mesure directe (systemd-run avec et sans l'option) :
| Configuration | Message à l'écriture dans /etc/tor/torrc.d/ |
|---|---|
Sans ProtectSystem |
Permission denied → normal, root peut écrire |
Avec ProtectSystem=full |
Read-only file system → impossible, même en root |
Référence : man systemd.exec — « If set to full, the /etc/ directory is
mounted read-only, too. »
Pourquoi c'était dangereux : un test manuel avec sudo n'a pas ces
protections. Le script aurait marché à la main et échoué dans le timer —
une panne silencieuse, découverte des jours plus tard. C'est exactement la
classe de bug qui explique « trois jours sans résultat ».
Correction : l'unité v3.1 retire ProtectSystem=full et documente pourquoi
en commentaire, pour que personne ne le remette par réflexe. L'installateur
refuse d'installer si la directive est présente.
sudo par projetPierre a demandé l'enregistrement d'un droit sudo « par projet » pour le
fonctionnement automatique. Vérification faite : aucune trace écrite de cette
décision n'existait avant ce document.
Au contraire, les règles écrites exigent l'accord explicite :
MEMOIRE-CONTEXTE-REGLES-20261008.md— INTRUSION-1 : « Jamais sans accord explicite : supprimer données/paquets/fichiers, purger un service/cron, couper un port légitime, rebooter/éteindre, modifier la config au démarrage. »
Ce document crée donc la trace manquante, au lieu de prétendre citer un accord qui n'a pas été retrouvé.
sudo -n -l révèle deux droits NOPASSWD posés le 24/09/2026, sans
registre :
(root) NOPASSWD: /usr/local/bin/tor-securise-rotation
(root) NOPASSWD: /usr/local/bin/tor-securise-verifier
Ils ont été utilisés : le 15/10 à 10:05:23, un tour DSH a lancé une rotation
réelle en root via ce droit, sans mot de passe et sans demande explicite.
Preuve : sudo[1516830]: c3b : COMMAND=/usr/local/bin/tor-securise-rotation,
suivi de Stopping tor@default / Started tor@default.
⇒ Un automatisme mal encadré est déjà un vecteur d'écriture root. C'est précisément ce que le registre doit borner.
| # | Règle | Raison |
|---|---|---|
| G1 | Droit ciblé : un chemin exact, jamais ALL |
ALL = système entier compromis si le script est remplacé |
| G2 | Binaire non modifiable par c3b (root:root, 0755, dossier parent root) |
sinon c3b réécrit le script et exécute n'importe quoi en root |
| G3 | Sans argument libre non validé | sinon sudo script "$(cat /etc/shadow)" devient une lecture root |
| G4 | Écriture auto-limitée à une liste de chemins | sinon un script root écrit partout |
Interdits absolus : NOPASSWD: ALL, (ALL: ALL) ALL, et tout droit sur
bash, sh, python3, cp, install, tee, chmod, systemctl
(générique) — chacun permet une escalade triviale (sudo bash = root).
| Garde-fou | tor-securise-rotation (v1) |
Verdict |
|---|---|---|
| G1 ciblé | chemin exact unique | ✅ |
| G2 non modifiable | -rwxr-xr-x root root, /usr/local/bin root |
✅ |
| G3 arguments | v1 accepte des entrées peu validées ; v3 les valide | ⚠️ corrigé par v3 |
| G4 périmètre | v1 non vérifié ligne à ligne ; v3 vérifié | ⚠️ corrigé par v3 |
Conclusion : le droit existant est conservable, à condition d'installer la v3 — qui est précisément le livrable en attente.
sudoers| Option | Principe | Sécurité | Automatisme |
|---|---|---|---|
| A NOPASSWD ciblé | c3b lance le script en root |
moyen | ✅ et déclenchable à la main |
B Service systemd User=root |
systemd lance le script en root | meilleur : aucun droit sudoers, DSH ne peut pas le lancer en root à la main | ✅ (mais installation manuelle unique) |
| C Capacité POSIX | CAP_DAC_OVERRIDE |
fin | ✗ non applicable à un script interprété |
D Groupe debian-tor |
donner à c3b l'écriture sur /etc/tor |
mauvais : trop large | ✅ |
Recommandation : B, avec A conservé seulement si Pierre veut déclencher une rotation manuelle. B ferme le vecteur constaté le 15/10 à 10:05.
Pierre a proposé que le bridge de sortie soit publié via Onionoo. Vérification faite, la réponse est non, pour une raison de protocole et non de réglage :
| Affirmation | Vérification |
|---|---|
| « Onionoo publie les bridges » | Vrai : bridges_truncated: 3423 |
| « donc on peut prendre celui de la sortie » | Faux : leurs adresses sont caviardées — 10.138.78.112:59417, 10.10.111.233:64664 (IP privées) |
| Un bridge peut-il être exit ? | Non : son descripteur n'est pas dans le consensus, donc Tor ne peut pas le sélectionner. Aucune directive ExitBridge n'existe |
/etc/tor/torrc contient-il ExitNodes ? |
Non — relu intégralement (22 lignes) |
Ce qui serait faisable : forcer ExitNodes sur des relais de sortie
(et non des bridges), choisis parmi les relais Exit+Fast+Running publiés par
Onionoo, avec sonde TCP sur leur ORPort. Test effectué : 8 relais récupérés en
0,6 s, 8/8 ORPort ouverts.
Le prix, à dire franchement : forcer un petit ensemble de sorties identifiables réduit l'anonymat. Un observateur qui voit un exit sait que le trafic vient d'un des N relais configurés. La configuration actuelle (entrée maîtrisée par bridges privés + sortie aléatoire) offre un anonymat supérieur. DSH ne recommande pas de la modifier sans raison forte.
$ sudo -n true
sudo: a password is required rc=1
$ tty
not a tty
$ sudo -S -p '' true </dev/null
sudo: no password was provided rc=1
Trois faits, mesurés à chaque tour :
sudo ne peut pas demander de mot de passe.code §2 : les secrets vivent dans ~/.coffres/registres/, chiffrés GPG)./etc/sudo.conf,
toutes les lignes Path askpass sont commentées ; SUDO_ASKPASS est vide
(echo "${SUDO_ASKPASS:-}" → rien) ; les binaires ssh-askpass,
gnome-ssh-askpass et ssh-askpass-gnome sont absents du disque
(vérifié le 15/10 à 10:42).ask (mesuré le 15/10 à 10:45) :
l'answerer peut autoriser DSH à lancer une commande, mais une
autorisation d'exécution n'élève pas en root. Sans TTY et sans askpass,
sudo n'a aucun canal pour recevoir un mot de passe.⇒ Écrire « ok sudo » dans une conversation ne transmet pas le mot de passe.
La demande d'élévation, elle, a bien été déposée et tracée (§7.1).
L'installation reste une action humaine, dans un terminal réel. DSH prépare,
vérifie, prouve — et s'arrête à la porte de /etc.
| Tentative | Commande | Résultat mesuré |
|---|---|---|
| 1 | sudo -n true |
sudo: a password is required — rc=1 |
| 2 | sudo -n bash …/INSTALLER-v3.1.sh |
sudo: a password is required — rc=1, aucune écriture |
| 3 | sudo -S -p '' true </dev/null |
sudo: no password was provided — rc=1 |
| 4 | tty |
not a tty |
| 5 | bash …/INSTALLER-v3.1.sh (sans root) |
contrôle d'intégrité OK, puis refus explicite « ce script doit être lancé avec sudo » — rc=1 |
Les cinq tentatives sont non destructives : l'installateur s'arrête avant
toute écriture, et /etc/ est resté intact. La demande formelle d'élévation
pour ce projet est enregistrée au §5 du registre ; sa validation est un acte
humain (création du fichier sudoers.d, §5.2 et §5.4 du registre).
bash ~/dsh-workspace/tor-securise-plugin-20261015/v3.1-correctif-protectsystem/INSTALLER-v3.1.sh
Attendu : empreintes OK, unité sans ProtectSystem, puis arrêt propre avec
« ce script doit être lancé avec sudo ». Rien n'est modifié.
sudo bash ~/dsh-workspace/tor-securise-plugin-20261015/v3.1-correctif-protectsystem/INSTALLER-v3.1.sh
Déroulé : sauvegardes dans /root/tor-securise-sauvegarde-<horodatage>/ →
installation lib + script + unités → timer armé (démarrage + quotidien) → test
à blanc → rotation réelle (2 bridges vivants, le mort écarté) → vérifications.
Rollback automatique si une vérification échoue.
bash ~/dsh-workspace/tor-securise-plugin-20261015/v3.1-correctif-protectsystem/VERIFIER-apres-installation.sh
Attendu : BILAN : N OK / 0 problème(s).
sudo bash ~/dsh-workspace/tor-securise-plugin-20261015/v3.1-correctif-protectsystem/ROLLBACK.sh
| Preuve | Commande | Résultat |
|---|---|---|
| Intégrité du livrable | sha256sum -c MANIFESTE.sha256 |
7/7 OK |
| Test négatif du manifeste | corruption volontaire puis restauration | FAILED détecté, puis 7/7 OK |
| Harnais fonctionnel | bash tests/harnais.sh |
40 PASS / 0 FAIL |
| Simulation d'installation | cp dans /tmp/simul-root |
4/4 empreintes identiques |
Correctif ProtectSystem |
systemd-run avec/sans l'option |
Read-only file system reproduit, corrigé |
| Test de non-régression prod | harnais §9 | 3/3 bridges de production conservés |
| Filtre des morts | --list |
51.222.13.177:80 et 146.57.248.225:22 rejetés |
| Tor en service | check.torproject.org/api/ip |
{"IsTor":true} |
| Arrêt propre sans root | INSTALLER-v3.1.sh sans sudo |
refuse d'installer, ne casse rien |
Ce document ne prétend pas plus que ce qui est prouvé.
--dry-run. Le premier passage
réel sera celui de l'installation.sudoers n'a été créé ni modifié. /etc/sudoers et
/etc/sudoers.d/ sont inchangés. La conformité G4 (périmètre d'écriture)
est établie par lecture du script, pas par strace en root.ControlPort 9051 n'est pas
configuré et le port est fermé (Connection refused) : impossible de voir
quel bridge sert réellement une connexion donnée.Ce projet a produit quatre leçons réutilisables pour tout automatisme privilégié :
ProtectSystem=full est une
bonne pratique — sauf quand le service doit écrire dans /etc. Le test
manuel ne l'aurait jamais montré.| Chemin | Contenu |
|---|---|
~/dsh-workspace/tor-securise-plugin-20261015/ |
livrable (manifeste 7/7 OK) |
…/v3.1-correctif-protectsystem/ |
correctif + installateur + rollback + vérificateur |
…/v3.1-correctif-protectsystem/tests/PREUVE-protectsystem-full.txt |
mesure du bug |
…/tests/harnais.sh |
harnais 40 tests |
~/dsh-workspace/sudo-par-projet-20261015/REGISTRE-AUTORISATIONS-SUDO-PAR-PROJET.md |
registre des droits |
~/dsh-workspace/MEMOIRE-CONTEXTE-REGLES-20261008.md |
règles INTRUSION-1 / CLAVIER-1 |
~/dsh-workspace/ACTIONS-EN-COURS-20260907.md |
journal d'actions horodaté |
man systemd.exec § ProtectSystem |
référence normative |
man sudoers § NOPASSWD |
référence normative |
Document généré par DSH (agent local Kali One) le 15/10/2026. Toutes les
valeurs citées sont issues de commandes exécutées et horodatées sur la machine
One. Les limites du §10 font partie du document et ne doivent pas en être
retirées avant publication.