Repository navigation
Guide Linux Commandes
Fichier : Guide-Linux-Commandes.md · Dossier : wiki racine Branche : master (wiki) · Auteur : hprzeta · MAJ : 2026-09-05 (§28 diagnostic IPv6 vs VPN tiers Proton) · 2026-08-22 (référence rapide correspondance Linux↔OpenBSD ; §27 diagnostic réseau WireGuard/IPv6 ; §1/§5/§6 enrichis) · 2026-08-18 (§26 post-mortem crash machine — journalctl --list-boots, smartctl, upower, dmesg, systemd-inhibit) · 2026-08-16 (§6 OpenBSD — diagnostic arrêt brutal : logs, last/last -x, sysctl hw.sensors ; §2 exemple
uname -amis à jour — migration PC4 Compaq CQ58)
📖 Guide vivant. Chaque nouvelle commande utilisée dans le projet est ajoutée ici. Couvre Linux (Ubuntu/Debian) et OpenBSD (PC4 zeta-secure). Mis à jour à chaque session où de nouvelles commandes sont découvertes.
À consulter en premier. Source d'erreur n° 1 récurrente sur PC4 (
command not found) : réflexe d'utiliser une commande Linux sur OpenBSD. Détail de chaque commande dans les sections correspondantes ci-dessous.
| Objectif | Linux (PC1/PC2/PC3) | OpenBSD (PC4) |
|---|---|---|
| Élévation de privilèges | sudo |
doas |
| Lister les interfaces | ip link show |
ifconfig |
| Adresses d'une interface | ip addr show <if> |
ifconfig <if> |
| Table de routage | ip route show |
route -n show / netstat -rn
|
| Cache de voisinage | ip neigh |
ndp -a / arp -a
|
| Vider le cache de voisinage | ip neigh flush all |
ndp -c / arp -da
|
| Services | systemctl |
rcctl |
| Journaux | journalctl |
/var/log/messages, dmesg (pas de journal binaire) |
| Historique boots/reboots |
last -x (ajoute shutdown/reboot) |
last (suffit seul, pas d'option -x) |
| Tâches planifiées |
systemctl list-timers ou crontab
|
crontab uniquement |
| Pare-feu |
iptables / nftables
|
pfctl |
| Forwarding IPv4 | net.ipv4.ip_forward |
net.inet.ip.forwarding |
| Téléchargement HTTP |
curl, wget
|
ftp -o (client HTTP intégré) |
sed -i |
-i seul suffit (GNU sed) |
-i '' avec extension obligatoire (BSD sed) — voir §13 |
# Voir toutes les interfaces et IPs
ip addr show
# Voir seulement les IPv4
ip addr show | grep "inet "
ip -4 addr
# Voir une interface spécifique
ip addr show wlp2s0 # WiFi PC1
ip addr show enp0s25 # Ethernet PC2
ip addr show enp2s0 # Ethernet PC3
# Voir les routes
ip route
# Voir les IPs + interfaces en une ligne
ip -4 addr | grep inet | awk '{print $2, $NF}'
# Lister les interfaces (existence, MAC) sans afficher les adresses
ip link show
ip link show wg0 # → "Device \"wg0\" does not exist." si absente
# IPv6 globales uniquement (exclut fe80 lien-local)
ip -6 addr show scope global
ip -6 addr show wlp2s0 && ip -6 route show default
# Vider le cache de voisinage (équivalent ARP/NDP)
sudo ip neigh flush allLecture d'une sortie ip -6 addr :
| Marqueur | Signification |
|---|---|
scope link + fe80::
|
Adresse lien-local, non routable sur Internet |
scope global |
Adresse publique |
temporary |
Adresse de confidentialité RFC 4941, tourne régulièrement |
mngtmpaddr |
Adresse « mère » qui engendre les temporaires |
valid_lft 517sec |
Durée de validité restante — se renouvelle à chaque RA |
# Voir toutes les interfaces
ifconfig
# Voir une interface spécifique
ifconfig re0 # carte réseau principale
ifconfig wg0 # interface WireGuard
# Voir seulement IPv4
ifconfig re0 | grep "inet "
# Voir IPv6 (sauf lien-local fe80 et temporary)
ifconfig re0 | grep "inet6" | grep -v "fe80\|temporary"
# Voir les routes
netstat -rnLecture d'une sortie ifconfig OpenBSD :
| Marqueur | Signification |
|---|---|
autoconf |
Adresse obtenue par SLAAC |
temporary |
Adresse de confidentialité |
deprecated |
Encore valide en réception, plus utilisée en émission |
pltime / vltime
|
Durées preferred / valid, en secondes |
Distinction utile — une adresse
autoconfsanstemporaryest stable (RFC 7217) : elle ne change que si le préfixe ou l'interface physique change. C'est celle à publier dans le DNS. Voir Diagnostic-WireGuard-Hotspot §2 pour un cas réel où un changement d'interface (migration matérielle) a suffi à faire changer cette adresse malgré un préfixe/64inchangé.
ping -c 3 [IP_PC4] # IPv4
ping6 -c 3 [IPV6] # IPv6
# Adresse publique vue depuis l'extérieur
curl -s4 https://api.ipify.org ; echo
curl -s6 --max-time 5 https://api64.ipify.org ; echo # --max-time évite de bloquer si pas d'IPv6| TTL observé | Interprétation |
|---|---|
ttl=64 |
Hôte Linux, joint directement (0 saut) |
ttl=63 |
Hôte Linux, 1 routeur traversé — preuve que le forwarding fonctionne |
ttl=255 |
Hôte BSD ou équipement réseau, joint directement |
uname -a # noyau complet
uname -sr # OS + version courte
cat /etc/os-release # distribution (Ubuntu, Debian...)
lsb_release -a # infos distribution (si installé)uname -a # seule commande nécessaire
# Exemple : OpenBSD 'zeta-secure'.local 7.9 GENERIC.MP#449 amd64
# /etc/os-release n'existe pas sous OpenBSD# Charge CPU et mémoire
top # interactif (Linux et OpenBSD)
top -b -n 1 # une seule capture (Linux)
uptime # charge moyenne 1/5/15 min
# Mémoire
free -h # Linux seulement
# OpenBSD : voir top
# Espace disque
df -h # tous les systèmes de fichiers
df -h /home # dossier spécifique
du -sh ~/dossier/ # taille d'un dossier
du -sh ~/*/ | sort -h # trier par taille
# Processus
ps aux # tous les processus (Linux + OpenBSD)
ps aux | grep python # filtrer
kill -SIGTERM PID # arrêter proprement
kill -9 PID # forcer (dernier recours)
# Gouverneur CPU (Linux)
cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor
# performance = mode calcul, powersave = mode économie# Connexion simple
ssh user@ip
ssh hprzeta@[IP_PC2] # PC2
ssh hprzeta@[IP_PC3] # PC3
ssh hprzeta@[IP_PC4] # PC4 (OpenBSD)
# Via alias (définis dans ~/.ssh/config sur PC1)
ssh zeta-calc-second
ssh zeta-backup
ssh zeta-secure
# Connexion avec clé SSH spécifique
ssh -i ~/.ssh/id_acer hprzeta@[IP_PC3]
# Mode verbose (debug)
ssh -v hprzeta@[IP_PC2]
# Copier un fichier vers une machine distante
scp fichier.txt hprzeta@[IP_PC3]:~/destination/
# Copier depuis une machine distante
scp hprzeta@[IP_PC3]:~/fichier.txt ./local/doas (OpenBSD) et sudo en mode interactif ont besoin d'un pseudo-terminal pour
demander le mot de passe. Sur une commande SSH non-interactive, il faut forcer le
TTY avec -t :
ssh zeta-secure "doas syspatch -c"
# → doas: a tty is required
ssh -t zeta-secure "doas syspatch -c" # ✅ TTY forcé
⚠️ Erreur de syntaxe à éviter :ssh doas zeta-secure "..."— SSH interprètedoascomme un hostname, pas comme une commande à exécuter côté distant.doas/sudodoit toujours être à l'intérieur de la commande entre guillemets, jamais avant le nom d'hôte.
Pattern général :
ssh -t <alias_machine> "doas <commande>"
ssh -t <alias_machine> "sudo <commande>"# Démarrer le tunnel
sudo wg-quick up wg0
# Arrêter le tunnel
sudo wg-quick down wg0
# Cycle complet avec observation du handshake
sudo wg-quick down wg0 ; sudo wg-quick up wg0 ; sleep 10 ; sudo wg show
# Voir l'état du tunnel
sudo wg show
# Inspecter la config sans révéler la clé privée
sudo grep -iE "PublicKey|Endpoint|AllowedIPs" /etc/wireguard/wg0.conf
# Forcer l'endpoint en IPv6 sans modifier le fichier (test temporaire)
sudo wg set wg0 peer <CLE_PUBLIQUE_DU_PAIR> \
endpoint [[IPV6]]:51820
# ⚠️ Crochets obligatoires autour d'une adresse IPv6 suivie d'un :port,
# sans quoi le : est ambigu.
# Corriger un fichier de config corrompu (NBSP mobiles)
sudo sed -i 's/\xc2\xa0/ /g' /etc/wireguard/wg0.conf# Démarrer l'interface WireGuard
doas ifconfig wg0 up
doas sh /etc/netstart wg0
# Arrêter l'interface
doas ifconfig wg0 down
# Voir l'état WireGuard
doas wg show
# Ajouter/modifier un peer à chaud
doas wg set wg0 peer CLE_PUBLIQUE \
allowed-ips [WG_TEL]/32
# Modifier les AllowedIPs d'un peer
doas wg set wg0 peer CLE_PUBLIQUE \
allowed-ips [RESEAU_WG],[LAN]| Champ | Ce qu'il indique |
|---|---|
endpoint: 93.1.105.194:51820 |
Résolution en IPv4 — vérifier le DNS (A périmé ?) |
endpoint: [2a02:...]:51820 |
Résolution en IPv6 |
(pas de ligne latest handshake) |
Aucun échange établi |
latest handshake: 7 seconds ago |
Tunnel opérationnel (contrôle uniquement — ne garantit pas le transport de données, cf. Diagnostic-WireGuard-Hotspot §7) |
transfer: 0 B received, N KiB sent |
Émission seule → blocage sur le trajet retour |
| (sortie totalement vide) | Aucune interface WireGuard active — vérifier avec ip link show wg0
|
# OpenBSD utilise doas (pas sudo)
doas commande # exécuter en root
doas whoami # vérifier → doit afficher "root"
# Configurer doas
echo 'permit persist hprzeta' > /etc/doas.conf
# persist = pas de re-demande pendant un moment💡 Exécution via SSH non-interactif : voir §4 « SSH à distance avec doas/sudo — piège du TTY » (nécessite
ssh -t).
# Lister les patches EN ATTENTE (dry-run, rien n'est modifié)
doas syspatch -c
# Appliquer les patches
doas syspatch
# Historique des patches déjà installés (rempli après usage, normal)
doas syspatch -l
# Si patch noyau → reboot obligatoire
doas reboot💡
syspatch -l= historique (toujours rempli après usage).syspatch -c= ce qui reste à appliquer (vide = système à jour). Ne pas confondre les deux.
# Installer un paquet
doas pkg_add nom_paquet
# Simuler la mise à jour de tous les paquets (dry-run, rien n'est modifié)
doas pkg_add -u -n
# Appliquer la mise à jour de tous les paquets
doas pkg_add -u
# Chercher un paquet
pkg_info -Q mot_cle
# Lister les paquets installés
pkg_info# Voir les règles actives
doas pfctl -sr
# Filtrer sur un critère
doas pfctl -sr | grep -iE "51820|wireguard|wg|block"
doas pfctl -sr | grep -i icmp6
doas pfctl -sr | grep -i nat-to
# Vérifier syntaxe avant chargement
doas pfctl -nf /etc/pf.conf
# Charger les règles
doas pfctl -f /etc/pf.conf
# Statistiques
doas pfctl -s info
# Activer/désactiver pf
doas pfctl -e # enable
doas pfctl -d # disable (ATTENTION : plus de pare-feu !)
⚠️ pfctl -sn(règles NAT) est obsolète sur OpenBSD moderne : les règlesnat-tosont intégrées aux règles normales, visibles via-sr.
# Reconfigurer une interface (relit /etc/hostname.re0)
doas sh /etc/netstart re0
# Voir la config d'une interface
cat /etc/hostname.re0
cat /etc/hostname.wg0
# Voir la passerelle par défaut
cat /etc/mygate
netstat -rn | grep default
# Tester la connectivité
ping -c 2 1.1.1.1
ping6 -c 2 2606:4700:4700::1111 # ping IPv6
# Vérifier la résolution DNS
host google.com
host -t AAAA [DDNS_PC4] # enregistrement IPv6# Voir tous les sysctls
sysctl -a
# IP forwarding (pour WireGuard NAT)
doas sysctl net.inet.ip.forwarding=1
# ⚠️ net.inet6.ip6.accept_rtadv n'existe PAS sous OpenBSD
# (c'est FreeBSD/NetBSD) — SLAAC est géré nativementLe shell par défaut d'OpenBSD est ksh (pas bash), et n'interprète pas les
séquences \u, \h, \w de bash. Utiliser la syntaxe ksh avec substitution de
commande :
doas vi ~/.profileAjouter en fin de fichier :
PS1='$(whoami)@$(hostname -s):$(pwd)\$ 'Recharger sans redémarrer :
. ~/.profile
⚠️ Piège clavier AZERTY : l'apostrophe droite'(nécessaire pour le shell) est sur la touche 4 (sans Shift). La touche 7 produitè— un caractère accentué qui ne ferme pas la chaîne shell → erreurno closing quote. Toujours vérifier visuellement que le caractère est un simple bâton vertical', pas un accent.
Pour stopper depuis une autre machine une boucle qui tourne sur la console physique
ttyC0 de PC4 :
ssh -t zeta-secure "doas pkill -t ttyC0"Vérification :
ssh zeta-secure "ps aux | grep sleep"Pour supprimer une ligne ajoutée dans /etc/rc.local (empêcher qu'elle revienne au
prochain boot) :
ssh -t zeta-secure "doas sed -i '/while true; do clear/d' /etc/rc.local"
ssh zeta-secure "tail -5 /etc/rc.local" # vérifier que la ligne a disparu# Extinction immédiate (power off réel)
ssh -t zeta-secure "doas shutdown -p now"
# Avec délai et message
ssh -t zeta-secure "doas shutdown -p +2 'Extinction de zeta-secure dans 2 min'"
# Redémarrage
ssh -t zeta-secure "doas reboot"
⚠️ Pile CMOS morte sur PC3 et PC4 (Dell Dimension 4500 / E2140, matériel ancien) : au redémarrage, écranCMOS Checksum Bad/Press F1 to continue— unrebootoushutdownlancé à distance ne suffit pas à faire redémarrer la machine seule, il faut intervenir physiquement (F1) pour valider le boot. Pas de contournement logiciel trouvé à ce jour sur le BIOS AMI de PC4 (Quick Boot/Silent Bootdisponibles mais sans effet sur ce blocage —Silent Bootdoit rester désactivé pour voir le message d'erreur). Solution durable : remplacement de la pile CMOS (CR2032) sur les deux machines.
Ctrl+Alt+F1 # console 1 (ttyC0, par défaut au boot)
Ctrl+Alt+F2 # console 2 (ttyC1)
Ctrl+Alt+F3 # console 3 (ttyC2)
Chaque console garde son état indépendamment (utile pour laisser un heartbeat visuel tourner sur une console pendant qu'on travaille sur une autre).
# Chercher le warning caractéristique d'un arrêt non propre (coupure secteur, crash)
doas grep 'not properly unmounted' /var/log/messages
# Chercher les événements sur une plage horaire précise (ex. 20h-23h le 15 août)
doas grep 'Aug 15 2[0-3]:' /var/log/messages
# Historique des boots/arrêts/crashes
last # OpenBSD — pas d'option -x
last -x # Linux (Debian/Ubuntu) — ajoute les événements shutdown/reboot au wtmp
# Diagnostic rapide combiné (uptime + 20 dernières entrées)
uptime && last -x | head -20 # Linux
uptime && last | head -20 # OpenBSD (sans -x)
# Capteurs matériels (température, tension, ventilateurs) — si le chipset les expose
sysctl hw.sensors
⚠️ lastsans-xsous OpenBSD : OpenBSD ne supporte pas l'option-xdelast(spécifique à util-linux/GNU sur Linux). Sur OpenBSD,lastseul suffit à voir les cycles boot/shutdown/crash ; sur Linux,-xest nécessaire pour inclure les événements système (shutdown,runlevel) dans la sortie, sinon seules les sessions utilisateur apparaissent.
ℹ️
sysctl hw.sensorspeut renvoyer une sortie vide sur du matériel ancien (chipsets pré-2005, ex. Intel 82845) — aucun capteur exposé à l'OS, pas de monitoring hardware logiciel possible sur ces machines.
# Voir /etc/pf.conf actuel
doas cat /etc/pf.confExemple de règles clés pour le bastion WireGuard :
# Bloquer tout en entrée par défaut
block in
# Autoriser tout en sortie
pass out
# SSH
pass in on $ext_if proto tcp to port 22
# WireGuard UDP (IPv4 et IPv6)
pass in on $ext_if proto udp to port 51820
# ICMPv6 nécessaire pour SLAAC (Router Advertisements)
pass in on $ext_if inet6 proto icmp6 \
icmp6-type {routeradv, neighbradv, neighbrsol, redir}
# ⚠️ neighbrsol (pas neighbrsolicit — invalide sous pf)
# Trafic depuis le VPN vers le LAN
pass in on $wg_if
# Mise à jour manuelle (depuis PC4 OpenBSD)
# ftp = équivalent de curl sous OpenBSD base
doas ftp -o /var/log/duckdns.log \
"https://www.duckdns.org/update?domains=[DDNS_NOM]&token=TOKEN&ip=&ipv6=ADRESSE_IPv6"
# Script automatique /etc/duckdns/duck.sh
# Extrait l'IPv6 stable de re0 (pas fe80, pas temporary)
IP6=$(ifconfig re0 | awk '/inet6/ && !/fe80/ && !/temporary/ {print $2; exit}')
# Voir le résultat du dernier update
doas cat /var/log/duckdns.log
# → "OK" = succès, "KO" = échec
# Vérifier la résolution DNS (depuis n'importe quelle machine)
host -t A [DDNS_PC4] # IPv4 (inutile car CGNAT)
host -t AAAA [DDNS_PC4] # IPv6 (celle utilisée)# Voir les crons de l'utilisateur courant
crontab -l
# Éditer les crons
crontab -e
# Workaround si crontab -e cassé (ex: PC3 Python 3.5)
(crontab -l; echo "*/5 * * * * /chemin/script.sh") | crontab -# Voir les crons
doas crontab -l
# Éditer sans vi (OpenBSD n'a pas nano par défaut)
doas crontab -l > /tmp/cron.txt
echo '*/5 * * * * /etc/duckdns/duck.sh' >> /tmp/cron.txt
doas crontab /tmp/cron.txt
rm /tmp/cron.txt# ┌──── minute (0-59)
# │ ┌── heure (0-23)
# │ │ ┌─ jour du mois (1-31)
# │ │ │ ┌ mois (1-12)
# │ │ │ │ ┌ jour semaine (0=dim)
# │ │ │ │ │
* * * * * commande
*/5 * * * * # toutes les 5 minutes
0 2 * * * # tous les jours à 02h00
50 1 * * * # tous les jours à 01h50
# Sync logs de PC1 vers PC3 (backup nocturne 01h50)
rsync -avz --progress \
~/projet_zeta/logs/ \
hprzeta@[IP_PC3]:~/backup/logs/
# Sync wiki
rsync -avz \
~/projet_zeta/Riemann_Lab.wiki/ \
hprzeta@[IP_PC3]:~/backup/Riemann_Lab.wiki/
# Options utiles
# -a : archive (préserve permissions, dates, liens)
# -v : verbose
# -z : compression
# -n : dry-run (simuler sans modifier)
# --delete : supprimer les fichiers absents de la source
# --progress : afficher la progression# Copier vers Proton Drive
rclone copy ~/projet_zeta/pdf/cours/ \
protondrive:hprzeta/Riemann_Lab/cours/ --progress
# Lister les fichiers sur Proton Drive
rclone ls protondrive:hprzeta/Riemann_Lab/
# Re-authentifier si erreur 401
rclone config reconnect protondrive:
# Erreur 422 = fichier déjà présent → normal, ignoré# Créer une nouvelle session nommée
tmux new-session -s zeta
tmux new -s zeta-cluster # forme courte
# Rejoindre une session existante
tmux attach -t zeta
tmux attach-session -t zeta-cluster
# Lister les sessions actives
tmux ls
# Tuer une session depuis l'extérieur
tmux kill-session -t zeta-clusterCtrl+B d Détacher (quitter sans fermer la session)
Ctrl+B & Tuer la fenêtre courante (avec confirmation)
Ctrl+B " Diviser horizontalement (nouveau panneau en bas)
Ctrl+B % Diviser verticalement (nouveau panneau à droite)
Ctrl+B ←→↑↓ Naviguer entre les panneaux
Ctrl+B z Zoom sur le panneau courant (toggle)
Ctrl+B q Afficher les numéros des panneaux
# Diviser horizontalement (panneau en bas)
tmux split-window -v
# Diviser verticalement (panneau à droite)
tmux split-window -h
# Sélectionner un panneau par numéro
tmux select-pane -t 0
tmux select-pane -t 3
# Agrandir un panneau
tmux resize-pane -D 5 # vers le bas de 5 lignes
tmux resize-pane -R 10 # vers la droite de 10 colonnes# -P 'bg=couleur,fg=couleur' colorie le fond ET le texte du panneau
tmux select-pane -t 0 -P 'bg=colour3,fg=colour0' # jaune texte noir → PC2 Debian
tmux select-pane -t 1 -P 'bg=colour6,fg=colour0' # cyan texte noir → PC3 backup
tmux select-pane -t 2 -P 'bg=colour0,fg=colour2' # noir texte vert → PC4 OpenBSD
tmux select-pane -t 3 -P 'bg=colour5,fg=colour15' # magenta texte blanc → PC1 local
# Changer la barre de statut globale (toute la session)
tmux set-option -g status-bg colour3 # jaune (PC2 Debian)
tmux set-option -g status-bg colour6 # cyan (PC3 backup)
tmux set-option -g status-bg colour0 # noir (PC4 OpenBSD)# Envoyer une commande dans un panneau sans y accéder
# Format : session:fenêtre.panneau
tmux send-keys -t zeta-cluster:0.0 "ssh zeta-calc-second" Enter
tmux send-keys -t zeta-cluster:0.1 "ssh hprzeta@[IP_PC3]" Enter
tmux send-keys -t zeta-cluster:0.2 "ssh zeta-secure" Enter
# Envoyer sans Enter (pour préparer une commande)
tmux send-keys -t zeta-cluster:0.3 "python3 zeta_monitor.py" ""# Lancer la session cluster (4 panneaux colorés + monitor)
zeta-cluster # alias dans ~/.bashrc
# Ou directement :
bash ~/projet_zeta/scripts/zeta_tmux.shLe script scripts/zeta_tmux.sh crée la session zeta-cluster avec :
- Panneau haut-gauche : PC2
zeta-calc-second— fond jaune (colour3) - Panneau bas-gauche : PC3
zeta-backup— fond cyan (colour6) - Panneau haut-droite : PC4
zeta-secure(OpenBSD) — fond noir (colour0) - Panneau bas-droite : PC1 local +
zeta_monitor.py— fond magenta (colour5)
# Alias cluster — à ajouter dans ~/.bashrc sur PC1
alias zeta-cluster='bash ~/projet_zeta/scripts/zeta_tmux.sh'# Remplacer une chaîne dans un fichier (Linux GNU sed)
sed -i 's/ancien/nouveau/g' fichier.txt
# Remplacer avec séparateur alternatif (si / dans les chemins)
sed -i 's|/ancien/chemin|/nouveau/chemin|g' fichier.txt
# ⚠️ OpenBSD/macOS (BSD sed) : -i nécessite une extension
sed -i '' 's/ancien/nouveau/g' fichier.txt
# Supprimer les caractères NBSP (espace insécable, fréquent en copier-coller mobile)
sed -i 's/\xc2\xa0/ /g' fichier.conf
# ⚠️ Cause l'erreur "wrong length or format" dans les clés WireGuard# Voir les connexions réseau actives
ss -tlnp # Linux
netstat -an # Linux + OpenBSD
# Tester un port distant
nc -zv [IP_PC4] 51820 # test UDP WireGuard
nc -zv [IP_PC4] 22 # test SSH
# Voir les logs système
journalctl -f # Linux systemd (temps réel)
doas tail -f /var/log/messages # OpenBSD
# Générer un QR code (pour WireGuard Android)
qrencode -t ansiutf8 < /tmp/phone_wg0.conf
# Voir l'IP publique vue depuis internet
curl -4 -s ifconfig.me # IPv4 (attention : ne détecte pas CGNAT depuis l'intérieur)
curl -6 -s ifconfig.me # IPv6
# ⚠️ CGNAT : curl -4 ifconfig.me depuis l'intérieur du réseau retourne l'IP
# vue par les services externes, pas l'IP WAN de la box.
# Pour voir la vraie IP WAN : admin box → [IP_BOX] → WAN → CaractéristiquesPC3 tourne Ubuntu 14.04 LTS avec Python 3.5.2 (fin de vie 2017). Les adaptations ci-dessous sont obligatoires pour les scripts déployés sur PC3.
# ❌ INTERDIT sous Python 3.5 — SyntaxError immédiate
msg = f"CPU: {cpu_percent}%"
# ✅ CORRECT — .format() valide depuis Python 2
msg = "CPU: {}%".format(cpu_percent)
msg = "CPU: {cpu}%".format(cpu=cpu_percent)
msg = "Host {h} — CPU {c:.1f}%".format(h=hostname, c=cpu_pct)# Symptôme : ImportError bizarre ou exception au démarrage Python
# Cause : distutils-precedence.pth (présent sur certains Ubuntu 14.04 mis à jour)
# modifie sys.path dès le démarrage → conflits de versions de setuptools
# Solution : désactiver le site-packages utilisateur
PYTHONNOUSERSITE=1 python3 script.py
# Dans un script SSH lancé depuis PC1 (CMD_LINUX dans zeta_monitor.py) :
CMD_LINUX = "PYTHONNOUSERSITE=1 python3 /home/hprzeta/projet_zeta/scripts/mon_script.py"# ❌ INTERDIT sous OpenBSD — /proc n'existe pas (kernel OpenBSD)
with open('/proc/stat') as f:
...
# ✅ CORRECT sous OpenBSD — lire top en mode batch (-b -n 1 = une seule capture)
top -b -n 1
# Extraire le % idle puis calculer cpu = 100 - idle
# Ligne typique de top OpenBSD :
# CPU: 2.3% user, 0.0% nice, 1.5% sys, 0.0% interrupt, 96.2% idle
# NF-1 = avant-dernier champ = valeur idle sans le symbole "%"
top -b -n 1 | awk '/^CPU/{gsub(/%/,"",$NF); idle=$NF; print 100-idle; exit}'
# Parser en Python (len(p) >= 5 suffit pour OpenBSD — NF ~ 10 champs)
p = line.split() # ['CPU:', '2.3%', 'user,', ...]
if len(p) >= 5:
idle = float(p[-1].replace('%','')) # dernier champ = idle%
cpu = 100.0 - idle| Fonctionnalité | Python 3.5 | Python 3.6+ | Solution |
|---|---|---|---|
f-strings f"..."
|
❌ SyntaxError | ✅ |
.format() ou %
|
asyncio.run() |
❌ | ✅ 3.7+ | loop.run_until_complete() |
Walrus operator :=
|
❌ | ✅ 3.8+ | Variable intermédiaire |
dict ordonné garanti |
❌ | ✅ 3.7+ | collections.OrderedDict |
PYTHONNOUSERSITE |
✅ (contournement) | souvent inutile | Utiliser si erreur import |
| Piège | Explication | Solution |
|---|---|---|
net.inet6.ip6.accept_rtadv |
N'existe pas sous OpenBSD (FreeBSD/NetBSD seulement) | SLAAC natif, juste passer les RA dans pf |
neighbrsolicit dans pf |
Nom invalide sous OpenBSD | Utiliser neighbrsol
|
| NBSP dans config WireGuard | Copier-coller depuis mobile insère \xc2\xa0
|
sed -i 's/\xc2\xa0/ /g' fichier |
curl -4 ifconfig.me pour détecter CGNAT |
Teste depuis l'intérieur = résultat trompeur | Comparer avec IP WAN de la box (admin [IP_BOX]) |
crontab -e cassé sur vieille machine |
Python 3.5 / distutils absent | (crontab -l; echo "...") | crontab - |
sed -i 's|...|' sous BSD |
BSD sed n'accepte pas | comme séparateur |
Utiliser -i '' et / ou #
|
SVG dans scripts/
|
Scripts .sh → scripts/, SVG → docs/images/
|
Toujours vérifier le bon dossier |
| IPv6 DuckDNS champ séparé | Dashboard DuckDNS : champ A ≠ champ AAAA | Remplir le champ "adresse ipv6" séparément |
| pf bloque SLAAC |
block in bloque les Router Advertisements ICMPv6 |
Ajouter pass in ... icmp6-type {routeradv,...}
|
| f-string sur PC3 Python 3.5 |
SyntaxError: invalid syntax à l'exécution |
Remplacer tous les f"..." par .format()
|
PYTHONNOUSERSITE absent |
PC3 Ubuntu 14.04 : distutils-precedence.pth corrompt le path |
Préfixer : PYTHONNOUSERSITE=1 python3 ...
|
CPU OpenBSD via /proc/stat
|
/proc n'existe pas sous OpenBSD → FileNotFoundError
|
Utiliser top -b -n 1 + awk, len(p) >= 5 pour parser |
len(p) >= 7 pour parser top OpenBSD |
OpenBSD top -b -n 1 produit ~10 champs (moins que Linux) |
Utiliser len(p) >= 5 ; idle = dernier champ (p[-1]) |
ssh doas host "..." |
SSH interprète doas comme un hostname, pas une commande |
doas doit être à l'intérieur des guillemets : ssh -t host "doas ..."
|
Apostrophe AZERTY dans PS1 ksh |
Touche 7 produit è accentué au lieu de ' → no closing quote
|
Vérifier visuellement le caractère : bâton vertical ', pas un accent |
reboot/shutdown à distance sur PC3/PC4 |
Pile CMOS morte → écran CMOS Checksum Bad, bloque au redémarrage |
Intervention physique (F1) obligatoire ; remplacer la pile CR2032 |
ping6 vers PC4 silencieux |
pf autorise routeradv/neighbradv/redir mais pas echoreq
|
Ne pas conclure d'une panne — vérifier pfctl -sr | grep icmp6 avant |
nc -u ... succeeded |
UDP sans connexion : « succeeded » dès qu'aucun ICMP d'erreur ne revient, même sur port filtré | Tester depuis l'extérieur du LAN, jamais depuis le même /64 que la cible |
pfctl -sn pour voir le NAT |
Obsolète — les règles nat-to sont intégrées aux règles normales |
Utiliser pfctl -sr
|
| Règle IPv6 manuelle de la box périmée | Ne suit pas automatiquement un changement d'adresse IPv6 de PC4 (contrairement au AAAA DuckDNS) |
Comparer dig +short AAAA <domaine> avec la règle box à chaque nouvelle panne — voir Diagnostic-WireGuard-Hotspot §2 |
Protocole de diagnostic quand un .so ne fonctionne pas ou produit des résultats suspects entre deux machines.
# Lister toutes les fonctions publiques (T = text, symbole global)
nm -D scan_arb.so | grep " T "
# Exemples de sortie :
# 00000000000014c0 T scan_zeros_arb ← fonction exportée ✅
# (rien) ← fonction introuvable → .so mal compilé ou mauvais fichier
# Comparer les exports entre deux machines
nm -D local/scan_arb.so | grep " T "
ssh -i ~/.ssh/id_acer hprzeta@[IP_PC2] "nm -D ~/projet_zeta/.../scan_arb.so | grep ' T '"# Voir toutes les dépendances
ldd scan_arb.so
# Chercher une lib spécifique ou les libs manquantes
ldd illinois_arb.so | grep -E 'arb|flint|not found'
# Sortie typique :
# libflint-arb.so.2 => /lib/x86_64-linux-gnu/libflint-arb.so.2 ← trouvé ✅
# libflint-arb.so.2 => not found ← manquant ❌
# Sur une machine distante
ssh -i ~/.ssh/id_acer hprzeta@[IP_PC2] "ldd ~/projet_zeta/.../illinois_arb.so"Note : ldd | grep arb retourne exit code 1 si aucune correspondance (comportement grep normal). Ce n'est pas une erreur si la lib utilise volontairement libm uniquement (ex: scan_arb.so = C pur sans arb).
# Chercher un paquet par nom
dpkg -l | grep -E 'flint|arb'
# Sortie typique :
# ii libflint-arb2:amd64 1:2.23.0-1+b1 amd64 C library for arbitrary-precision ball arithmetic
# ii libflint-arb-dev 1:2.23.0-1+b1 amd64 development files
# Installer si manquant
sudo apt install libflint-arb-dev libflint-arb2
# OpenBSD (PC4) — équivalent
pkg_info | grep flint
pkg_add flint| Paquet | Source | Usage |
|---|---|---|
libflint-arb2 (apt) |
Bibliothèque système | Liée par les .so C (illinois_arb.so) |
python-flint (pip) |
Package Python |
arb_wrapper.py → arb_hardy_z() en Python |
libflint-arb2 présent + python-flint absent → illinois_arb.so fonctionne (C) mais ARB_DISPONIBLE=False en Python → fallback mpmath.siegelz. Installer séparément :
# Sur PC2 (système Python3) — si pip3 disponible
pip3 install python-flint
# Vérifier
python3 -c "from arb_wrapper import ARB_DISPONIBLE; print(ARB_DISPONIBLE)"Debian 12 et Ubuntu 23.04+ bloquent pip install système par défaut (PEP 668).
# Option 1 — install utilisateur (sans sudo, packages dans ~/.local/)
pip3 install paquet --user
# Option 2 — forcer install système (machines dédiées calcul, pas de serveur de prod)
pip3 install paquet --break-system-packages
# Option 3 — venv (isolation propre, recommandé pour projets)
python3 -m venv ~/mon_venv
source ~/mon_venv/bin/activate
pip install paquetAttention PYTHONPATH en SSH : un package installé --user est dans ~/.local/lib/pythonX.Y/site-packages/.
Si le script est lancé via ssh host "python3 script.py" (shell non-interactif), ce chemin peut être absent.
Vérifier : ssh host "python3 -c 'import sys; print([p for p in sys.path if \".local\" in p])'".
Si vide : passer PYTHONUSERSITE=1 dans la commande SSH, ou utiliser --break-system-packages.
Leçon session 2026-06-17 — python-flint 0.8.0 installé sur PC2 (Debian 12, Python 3.11).
Alias ajoutés au ~/.bashrc de PC1 (session 2026-06-17) pour lancer la distribution
PC1+PC2 sans passer par Claude Code — script autonome scripts/zeta_distribute_run.sh.
zeta-distribute 500000 # lance T=500k distribué PC1+PC2 + dashboard
zeta-distribute 1000000 # lance T=1M
zeta-distribute 500000 --no-dashboard # sans dashboard tmux
zeta-progress # s'attacher au dashboard en cours
zeta-pid # voir PID du run actif
zeta-log # suivre le log en temps réelDétail du script zeta_distribute_run.sh :
- Active le turbo (
sudo scripts/zeta_turbo_on.sh— sudoers NOPASSWD, non interactif). - Lance
zeta_run_progress.pydans une session tmuxzeta-progress(sauf--no-dashboard). - Lance
zeta_distribute.py $T_MAXennohup, détaché, avec confirmation auto-répondue (printf "O\n" |) — sans quoi le script plante enEOFError(pas de TTY pourinput()). - PID écrit dans
/tmp/zeta_distribute.pid, log danslogs/distribute_T<T_MAX>_nohup_<horodatage>.log.
Limites connues :
-
--helpn'est pas géré :zeta-distribute --helplancerait un vrai run avecT_MAX="--help"(ne pas l'utiliser ; pas de validation d'argument dans le script). -
zeta-log(tail -f ... | tail -1) ne s'arrête jamais tout seul (tail -fest bloquant) — utile pour suivre en direct, mais ne convient pas à un usage scripté/non interactif.
| Situation | Test | Action |
|---|---|---|
| 🏠 Maison | PC4 ([IP_PC4]) joignable en ping direct sur l'interface physique |
wg0 DOWN (LAN direct, plus rapide) |
| 🧳 Déplacement | PC4 injoignable en LAN |
wg0 UP (tunnel via DuckDNS) |
Cause du besoin : les AllowedIPs du tunnel incluent [LAN] (LAN maison).
Si wg0 reste monté à la maison, le routage tente de passer par le tunnel au lieu du
LAN direct — or la box SFR ne fait pas de NAT loopback (pas de hairpinning), donc le
trafic vers l'IP publique/DuckDNS depuis l'intérieur du LAN échoue ou boucle. Il faut
donc désactiver wg0 quand PC4 est joignable en direct, et l'activer sinon.
scripts/wg_auto.sh :
- Ping
[IP_PC4](PC4) en forçant l'interface physique (ip route ... | grep -v wg0, jamaiswg0lui-même, sinon le test est faussé par le tunnel en cours). -
Maison (ping OK) → si
wg0actif :sudo wg-quick down wg0. -
Déplacement (ping KO) → si
wg0inactif :sudo wg-quick up wg0, puis vérifie le tunnel avec un ping sur[WG_PC4](passerelle VPN côté PC4). - Log dans
logs/wg_auto.log(append) + notification bureau (notify-send) systématique.
🏠 MAISON — WireGuard DÉSACTIVÉ # wg0 était up, vient d'être coupé
🏠 MAISON — WireGuard déjà désactivé # rien à faire (mode --quiet : silencieux)
🧳 DÉPLACEMENT — WireGuard ACTIVÉ # wg0 monté, tunnel [WG_PC4] répond
🧳 DÉPLACEMENT — WireGuard déjà activé # rien à faire (mode --quiet : silencieux)
⚠️ DÉPLACEMENT — WireGuard activé mais tunnel NE RÉPOND PAS # wg0 up mais [WG_PC4] ne répond pas
# → vérifier connexion internet / DuckDNS
wg-auto # alias ~/.bashrc — affiche le message dans le terminal
bash scripts/wg_auto.sh # équivalent direct
bash scripts/wg_auto.sh --quiet # pas d'affichage terminal si déjà dans le bon état
# (utilisé par le dispatcher NetworkManager)
zeta-cluster # scripts/zeta_tmux.sh appelle wg_auto.sh (sans --quiet)
# avant de monter la session tmux du cluster/etc/NetworkManager/dispatcher.d/99-wg-auto appelle wg_auto.sh --quiet à chaque
événement up/vpn-up — la notification bureau prévient du basculement sans action
manuelle. Nécessite sudo -u riemann (le dispatcher tourne en root) et une entrée
sudoers NOPASSWD ciblée pour wg-quick/wg show (sinon sudo bloque en
non-interactif, faute de TTY).
Run distribué T=5 000 000 lancé le 02/08/2026 20:29 sur PC1+PC2, jamais abouti
(dossier de résultats vide). Reconstitution via sar (accounting persistant —
le journal systemd, lui, est volatile et ne conserve qu'un seul boot) :
| Heure | Événement |
|---|---|
| 02/08 20:40 | CPU → 98 % (run en cours) |
| 03/08 00:45 |
LINUX RESTART non planifié — run tué après ~4h, aucun résultat écrit |
| 03/08 19:19 | 2ᵉ LINUX RESTART
|
| 03/08 23:34 → 04/08 18:19 | Machine éteinte ~18h45 |
Cause : PC1 (portable) tournait sur batterie, débranché, avec deux alertes
"Running on LOW Battery" le 03/08. CriticalPowerAction=HybridSleep était
configuré à 5 % de batterie (action forcée à 2 %) — mais aucun resume= n'est
câblé (ni dans /proc/cmdline, ni dans /etc/initramfs-tools/conf.d/resume),
malgré une swapfile de 16G disponible (/mnt/data/swapfile, sur fichier — donc
nécessiterait en plus un resume_offset= précis, pas juste resume=UUID).
Résultat : la tentative de veille hybride ne peut pas reprendre proprement et
dégénère en redémarrage/extinction sauvage au lieu d'une vraie mise en veille.
Débranchement accidentel identifié comme cause réelle (pas une panne récurrente) → correctif volontairement simple plutôt qu'une réparation complète du hibernate/resume :
sudo sed -i 's/CriticalPowerAction=HybridSleep/CriticalPowerAction=PowerOff/' \
/etc/UPower/UPower.conf
sudo systemctl restart upower # sinon la nouvelle valeur n'est prise qu'au prochain démarrage du démon/etc/UPower/UPower.conf — valeurs pertinentes après correctif :
PercentageLow=20
PercentageCritical=5
PercentageAction=2
CriticalPowerAction=PowerOff
À 2 % de batterie critique : arrêt propre et prévisible (systemctl poweroff-like),
plutôt qu'une veille hybride non fiable sur ce matériel.
grep CriticalPowerAction /etc/UPower/UPower.conf # → PowerOff
upower -i $(upower -e | grep -i AC) # → online: yes (secteur branché)
ps -o pid,lstart,cmd -C upowerd # → démon redémarré après l'édition du fichier| Machine | OS | Politique de veille automatique |
|---|---|---|
| PC1 (zeta-lab) | Linux/systemd |
sleep-inactive-*=nothing, idle-delay=0, IdleAction=ignore — aucune veille auto. Résiduel : HandleLidSwitch=suspend (défaut) → fermer le capot suspend la machine, à éviter pendant un run. |
| PC2 (zeta-calc-second) | Linux/systemd | Défauts systemd (IdleAction=ignore) — aucune veille auto. |
| PC3 (zeta-backup) | Linux/systemd |
HandleLidSwitch=lock (override de 2017), pas de IdleAction — aucune veille auto. |
| PC4 (zeta-secure) | OpenBSD 7.9 | Aucun démon apmd actif (absent de rcctl ls on) — aucune gestion d'énergie automatique possible. |
PC2/PC3/PC4 sont alimentés en continu (pas de batterie) : le risque UPower/HybridSleep ne concerne que PC1.
Leçon durable : nohup/setsid protègent un process d'une fermeture de session
ou d'une déconnexion SSH, pas d'un vrai poweroff/reboot de la machine — seul
un secteur branché en continu (ou un onduleur) garantit la survie d'un run long.
Le pipeline de backup (STACK.md § Infrastructure backup) est silencieux par
construction : rsync -aq (PC1→PC3) ne journalise rien, et le succès du rclone copy (PC3→ProtonDrive) n'était jusqu'ici jamais vérifié activement — le statut
✅ auto supposé pour PC3 (mémoire de session) n'avait en réalité jamais été
contrôlé sur le fond. Premier lancement du script le 05/08/2026 :
7/7 jours en ÉCHEC côté rclone (crash Go répété — fatal error: found bad pointer/found pointer to free object, précédé de 401 Invalid access token et de
conflits 422 — cause probable : rclone_cron.log fait partie de son propre
périmètre de sauvegarde et grossit pendant la copie, provoquant source file is being updated, sur un i686 32 bits à mémoire limitée). Aucune ligne Transferred:
de succès trouvée dans tout l'historique du log (50 000+ lignes). Non résolu à ce
jour — nécessite une investigation dédiée (hors périmètre de cette entrée).
scripts/zeta_backup_status.py — deux tableaux :
-
Sync 1 (PC1→PC3, rsync) : déclenchement du cron via
/var/log/syslog(.1)(preuve d'exécution seulement —rsync -aqne dit rien sur son succès) + atterrissage réel via la fraîcheur des fichiers sous~/backup/{logs,wiki,pdf}côté PC3 (find -newermt). -
Sync 2 (PC3→ProtonDrive, rclone) : parsing de
~/backup/rclone_cron.log— succès (ligneTransferred:), échec (ERROR/fatal error:Go), ou sauté (aucune ligne pour la date).
~/backup/
doit utiliser l'utilisateur pjexosql (clé ~/.ssh/id_acer), pas l'alias
zeta-backup du cluster (~/.ssh/config, utilisateur hprzeta) — ce sont deux
comptes Unix différents sur la même machine [IP_PC3] ; le dossier ~/backup/
n'existe que sous pjexosql.
zeta-backup-status # 7 derniers jours
zeta-backup-status --date 2026-08-04 # une date précise (AAAA-MM-JJ)Alias ~/.bashrc : zeta-backup-status='cd ~/projet_zeta && source zeta_env/bin/activate && python scripts/zeta_backup_status.py'.
Gère un PC3 injoignable proprement (timeout SSH 6-20s selon la commande, ok=False
propagé sans lever d'exception) — affiche PC3 injoignable / PC3 INJOIGNABLE (timeout SSH) au lieu de planter.
Avant d'optimiser illinois_arb.c (piste v16), profiler avec de vrais chiffres
plutôt que deviner où va le temps. perf (linux-tools) donne une répartition par
fonction/bibliothèque directement sur le .so compilé, sans instrumentation.
cat /proc/sys/kernel/perf_event_paranoid # 4 sur zeta-lab = perf réservé rootNiveau 4 (Ubuntu récent) : perf record échoue pour un utilisateur normal, même
avec sudo -n (pas de règle NOPASSWD dédiée dans /etc/sudoers.d/zeta_turbo).
Le préfixe ! de Claude Code ne peut PAS saisir de mot de passe sudo (pas de
tty) — la commande doit être lancée par hprzeta directement dans un terminal réel
(le prompt [sudo] Mot de passe : s'affiche normalement dans ce cas).
sudo perf record -F 4000 -g -o sortie.data -- python3 harnais.py
sudo chown $(whoami):$(whoami) sortie.data # rendre le fichier lisible sans sudo ensuite
perf report -i sortie.data --stdio --sort=overhead,symbol -g none # flat, par fonction
perf report -i sortie.data --stdio --sort=dso -g none # par bibliothèque-
-F 4000: fréquence d'échantillonnage (Hz) — 4000 est largement suffisant pour des appels de l'ordre de la milliseconde. - Le harnais Python doit boucler suffisamment longtemps (~15-20s) pour accumuler assez d'échantillons — un run trop court donne un profil bruité/vide.
-
perf reportsur un binaire lié à de grosses bibliothèques (icilibflint,libgmp) peut prendre plusieurs minutes la première fois (résolution de symboles) — normal, pas un blocage.
Pour lire une version/chaîne exposée comme variable globale C (pas une fonction) :
# ❌ crash (segfault) : flint_version est un tableau char[], pas un char*
ver = ctypes.c_char_p.in_dll(lib, "flint_version")
# ✅ correct : lire les octets bruts à l'adresse du symbole comme un tableau
arr = (ctypes.c_char * 32).in_dll(lib, "flint_version")
print(bytes(arr)) # b'3.3.1\x00...'c_char_p.in_dll traite la valeur au symbole comme un pointeur vers une chaîne
et le déréférence — si le symbole est en réalité le buffer lui-même (char v[32]),
ça lit un pointeur invalide (les premiers octets de la chaîne interprétés comme une
adresse) → segfault immédiat.
apt install libflint-dev installe une version figée par la distribution (3.0.1
sur Ubuntu 24.04) qui peut être plus ancienne que la bibliothèque réellement
chargée en runtime par un paquet Python (ex. python-flint bundlant FLINT 3.3.1).
Pour des types de structure activement modifiés entre versions (dirichlet_group_t,
dirichlet_char_t), compiler contre des headers d'une mauvaise version = risque de
corruption mémoire silencieuse (mauvais offsets de champs), pas juste un mauvais
résultat numérique. Solution : récupérer les headers de la version EXACTE utilisée
au runtime, directement depuis les sources.
nm -D chemin/vers/libflint*.so | grep flint_version # symbole "D" = donnée, pas fonction
# cf. §21 ci-dessus pour la lecture correcte en ctypescurl -sL -o flint-X.Y.Z.tar.gz \
"https://github.com/flintlib/flint/releases/download/vX.Y.Z/flint-X.Y.Z.tar.gz"
tar xzf flint-X.Y.Z.tar.gz && cd flint-X.Y.Z
# ./configure génère flint.h/flint-config.h (FLINT_BITS, etc.) sans lancer la
# compilation complète — seuls ces 2 fichiers générés + les headers statiques du
# dépôt sont nécessaires pour compiler CONTRE la .so déjà présente sur le système.
./configure --with-gmp-include=/usr/include/x86_64-linux-gnu \
--with-gmp-lib=/usr/lib/x86_64-linux-gnu \
--with-mpfr-include=/usr/include \
--with-mpfr-lib=/usr/lib/x86_64-linux-gnuDépendance cachée : m4 (souvent absent d'une installation Ubuntu minimale) —
./configure échoue tard (« checking for suitable m4 ») sans lui :
sudo apt install -y m4 # à lancer dans un terminal réel, même remarque sudo que §21FLINT complet expose des centaines de headers (théorie des nombres, algèbre —
bien au-delà de ce qu'utilise un module qui n'a besoin que de acb/arb/dirichlet).
Extraire la fermeture transitive réelle plutôt que tout copier :
gcc -Iflint-X.Y.Z/src -M mon_fichier.c | tr ' \\' '\n\n' \
| grep "^$(pwd)/flint-X.Y.Z/src" | sort -u-M liste toutes les dépendances d'inclusion sans compiler — donne la liste exacte
des .h à copier (23 fichiers / 276 Ko dans le cas illinois_arb.c, contre 800+
pour FLINT complet). Vérifier ensuite qu'aucun chemin absolu machine-spécifique ne
s'est glissé dans les fichiers générés (flint.h, flint-config.h) avant de les
committer :
grep -l "/home/\|/tmp/" headers_extraits/*.h # doit être videssh -t zeta-calc-second "sudo apt update && apt list --upgradable"
ssh -t zeta-backup "sudo apt update && apt list --upgradable"ssh -t zeta-calc-second "sudo apt upgrade -y"
ssh -t zeta-backup "sudo apt upgrade -y"Note session 15/08/2026 : PC3 (Ubuntu 14.04, Python 3.5.2 — cf. §15) a répondu 0 mise à jour, 0 installé, 0 à enlever — système déjà à jour, Python inchangé après vérification (
python3 --version→ toujours 3.5.2, aucun risque pour le fix f-string dezeta_monitor.py).
for h in zeta-lab zeta-calc-second zeta-backup zeta-secure; do
echo "=== $h ==="
ssh $h whoami
doneVersion pas-à-pas (PC1 en local, pas de SSH sur lui-même) :
echo "=== PC1 (local) ===" && whoami
echo "=== PC2 ===" && ssh zeta-calc-second whoami
echo "=== PC3 ===" && ssh zeta-backup whoami
echo "=== PC4 ===" && ssh zeta-secure whoami📌 Rappel cluster : chaque machine a un user local d'origine (propre à l'installation de la distro) en plus du user
hprzetacréé pour le cluster :
- PC2 : user local
emmabuntus(distro Emmabuntüs)- PC3 : user local
pjexosql- PC4 : pas de user local distinct identifié à ce jour (OpenBSD, install manuelle)
hprzetareste identique sur les 4 machines — ne pas le renommer par machine, tout le cluster (~/.ssh/config,zeta_monitor.py,zeta_tmux.sh, cron de backup, chemins/home/hprzeta/...) suppose ce nom unique partout.
Identifier le display manager actif :
cat /etc/X11/default-display-managerChanger le mot de passe du user local :
# En local sur la machine
passwd
# À distance depuis PC1 (avec sudo)
ssh zeta-calc-second
sudo passwd emmabuntusDésactiver l'auto-login — si GDM3 :
sudo nano /etc/gdm3/custom.confChercher et commenter/désactiver :
AutomaticLoginEnable = true
AutomaticLogin = emmabuntusDésactiver l'auto-login — si LightDM :
sudo nano /etc/lightdm/lightdm.confChercher et commenter :
autologin-user=emmabuntusVérification après reboot :
sudo rebootAu redémarrage, un écran de connexion doit apparaître (au lieu du login automatique).
| Action | Touche(s) |
|---|---|
| Aller à la fin du fichier |
G (mode normal) |
| Aller à une ligne précise (ex. 11) | 11G |
| Ouvrir une nouvelle ligne en dessous + passer en insertion | o |
| Sortir du mode insertion | Échap |
| Supprimer la ligne courante (mode normal) | dd |
| Sauvegarder et quitter |
:wq puis Entrée
|
| Quitter sans sauvegarder | :q! |
Le
~en début de ligne dans vi = ligne vide, pas de contenu. Ce n'est pas une erreur.
Règle à retenir :
dd,G, les flèches sont des commandes mode normal. En cas de doute sur le mode courant, appuyer surÉchapd'abord (ramène toujours en mode normal sans risque), puis relancer la commande voulue.
Utilisées pour diagnostiquer le crash PC1 du 18/08 (03h12) et évaluer la fiabilité d'une machine avant un run long. Résultat de ce diagnostic : JOURNAL du 18/08.
# Historique des boots/reboots connus du journal systemd persistant
journalctl --list-boots
# Occupation disque du journal (repère un journal quasi vide = pas persistant longtemps)
journalctl --disk-usage
# Vérifier si le stockage persistant est actif et depuis quand
ls -ld /var/log/journal/ # dossier parent
ls -la /var/log/journal/*/ # sous-dossier machine-id — sa date de
# création = début réel de la persistance,
# PAS forcément celle du dossier parent
systemd-analyze cat-config systemd/journald.conf | grep -i storage
# Historique des reboots (Linux — voir §24 pour la variante OpenBSD sans -x)
last -x reboot
# Santé disque SMART — nécessite root
sudo smartctl -a /dev/sda | grep -A20 "SMART Attributes"
sudo smartctl -H /dev/sda # résumé PASSED/FAILED uniquement
# État et historique de la batterie
upower -e | grep BAT
upower -i $(upower -e | grep BAT)
# Erreurs matérielles/thermiques dans le tampon noyau — nécessite root,
# et ne couvre QUE le boot courant (tampon volatile, remis à zéro à chaque démarrage)
sudo dmesg | grep -iE "thermal|mce|hardware error|critical|ACPI Error"
# Empêcher toute extinction/veille système pendant un calcul long
systemd-inhibit --what=shutdown:sleep:idle --mode=block <commande longue>Piège découvert le 18/08 : un dossier /var/log/journal peut exister depuis
longtemps (créé par un paquet) sans que le journal soit réellement persistant — le
sous-dossier <machine-id> à l'intérieur ne se crée qu'au premier boot où
systemd-journald bascule réellement en stockage disque. Vérifier la date du
sous-dossier, pas seulement celle du dossier parent.
Complète §1/§5/§6 ci-dessus. Contexte complet et causes racines : Diagnostic-WireGuard-Hotspot.
# Enregistrement A (IPv4) uniquement
dig +short A [DDNS_PC4]
# Enregistrement AAAA (IPv6) uniquement
dig +short AAAA [DDNS_PC4]
# Les deux d'affilée
dig +short A [DDNS_PC4] ; dig +short AAAA [DDNS_PC4]Une sortie vide pour
Aet une adresse pourAAAA= le nom résout exclusivement en IPv6 — état recherché depuis la suppression volontaire de l'enregistrementApérimé (voir Diagnostic-WireGuard-Hotspot §5.5).digethost -t AAAA(§8 ci-dessus) sont équivalents ;dig +shortest plus rapide à lire en script.
ssh hprzeta@[WG_PC4] # via le tunnel
ssh -i ~/.ssh/id_acer -o IdentitiesOnly=yes hprzeta@[IP_PC2] # clé explicite| Message | Cause probable |
|---|---|
Connection timed out |
Paquets perdus : pare-feu, routage absent, ou route vers une interface morte |
Connection refused |
Hôte joint, mais rien n'écoute sur le port 22 |
Broken pipe |
Session existante coupée (changement de réseau, tunnel démonté) |
The authenticity of host ... can't be established |
Première connexion via cette adresse |
Détail rassurant — si le message ajoute
This host key is known by the following other names/addresses:, la clé du serveur est déjà connue sous une autre adresse. C'est la même machine, jointe par un chemin différent. Répondreyessans risque.
nc -u sur un port UDP ne prouve rien :
nc -u -v -w2 -6 [IPV6] 51820
# → "succeeded!" ... qui ne prouve rienEn UDP il n'y a pas de connexion : nc affiche « succeeded » dès qu'aucun ICMP
d'erreur ne revient dans le délai — un port filtré silencieusement produit le
même résultat qu'un port ouvert. Vérifier en plus que le test part bien de
l'extérieur du LAN : un paquet lancé depuis le même /64 que la cible
n'atteint jamais l'interface WAN de la box, donc ne traverse aucun pare-feu
périmétrique.
ping6 vers PC4 échoue même quand tout va bien : voir §1 (TTL) et
pfctl -sr | grep -i icmp6 (§6) avant d'interpréter un silence — les règles
pf de PC4 autorisent routeradv/neighbradv/neighbrsol/redir mais pas
echoreq.
Monter un tunnel depuis le réseau domestique — voir §18 (wg_auto.sh,
nm-dispatcher) : aucun test de tunnel n'est possible depuis le LAN
domestique, le dispatcher coupe wg0 automatiquement.
sudo wg-quick up wg0
# → "wg0 already exists" : réseau externe, le tunnel tient
# → interface détruite : réseau domestique, le dispatcher a coupéAprès toute modification touchant l'accès distant :
# ── Étape 1 : sur le LAN — appliquer les changements (box, PC4) ──
# ── Étape 2 : basculer sur un partage de connexion mobile ──
# ── Étape 3 : sur PC1, hors réseau domestique ──
curl -s6 --max-time 5 https://api64.ipify.org ; echo # l'IPv6 sort-elle ?
dig +short AAAA [DDNS_PC4] # le DNS est-il à jour ?
sudo wg-quick down wg0 ; sudo wg-quick up wg0
sleep 10
sudo wg show # handshake ?
ping -c 2 [WG_PC4] # PC4 via le tunnel
ping -c 2 [IP_PC2] # PC2 via le routage PC4
ssh hprzeta@[WG_PC4] # accès complet| Étage qui échoue | Où chercher |
|---|---|
| Pas d'IPv6 publique sur PC1 | Le réseau d'accès (hotspot) est IPv4 seul |
AAAA absent ou obsolète |
Updater DuckDNS sur PC4 |
| Pas de handshake | Règle IPv6 de la box, ou pf sur PC4 |
[WG_PC4] muet |
Configuration WireGuard côté serveur |
[IP_PC2] muet |
net.inet.ip.forwarding ou nat-to sur PC4 |
⚠️ Inverser les étapes 2 et 3 produit un faux négatif (le dispatcher coupewg0). Ne jamais modifier la configuration réseau de la box via le tunnel : une erreur coupe l'accès jusqu'au retour physique sur le LAN.
Complète §27. Contexte complet et cause racine : Diagnostic-WireGuard-Hotspot §9, procédure de référence : Guide-WireGuard-Acces-Distant.
Le 05/09/2026, l'accès distant semblait cassé (aucune IPv6 globale en déplacement) alors que le hotspot fournissait bien l'IPv6 depuis le début — un VPN tiers (Proton VPN) actif sur le portable la bloquait. Commandes de diagnostic utilisées, dans l'ordre :
# 1. IPv6 globale présente ? (exclut fe80:: lien-local, toujours présent)
ip -6 addr show scope global
# équivalent : ip -6 addr show | grep -v fe80
# 2. Route par défaut IPv6 ?
ip -6 route show default
# 3. Sortie IPv6 réellement fonctionnelle ?
ping6 -c2 2001:4860:4860::8888
# 4. Endpoint toujours résolu correctement côté DuckDNS ?
dig +short AAAA [DDNS_PC4]
# 5. Seul test valide du tunnel lui-même (PC4 ne répond jamais à un ping6 direct) :
sudo wg show wg0
ping -c2 [WG_PC4]Piège : un
ping6échoue de la même façon que le réseau soit vraiment sans IPv6 ou qu'un VPN tiers la bloque en local. Les deux premières commandes (ip -6 addr/route) ne distinguent pas ces deux cas non plus — seule l'observation « ça marchait avant sur ce même réseau » (ou couper le VPN et retester immédiatement) permet de trancher. Ne pas conclure trop vite à un problème d'opérateur mobile sans avoir d'abord vérifié qu'aucun VPN commercial (Proton, Mullvad, NordVPN, etc.) n'est actif.
Pour éviter que le script de bascule automatique ne spamme des notifications en tentant de réparer un tunnel injoignable par construction (pas d'IPv6), une garde a été ajoutée en tête du bloc déplacement — voir Diagnostic-WireGuard-Hotspot §9 et Guide-WireGuard-Acces-Distant §3.4 pour le détail et le diff complet.
Guide-Linux-Commandes.md · wiki racine · branche master · hprzeta · MAJ 2026-09-05 (§28 — diagnostic IPv6 vs VPN tiers, session Proton VPN du 05/09) · 1656 lignes