Projet : Sauvegarde de fichiers critiques
vers carte SD
Résumé
Ce document regroupe :
1. Une liste de titres YouTube pour trouver des tutoriels utiles.
2. Un guide pas-à-pas très détaillé pour réaliser le projet.
3. Un script Python complet d’exemple.
4. Un squelette C pour une implémentation bas niveau.
Rappel important : n’utilise ce guide que pour sauvegarder des fichiers pour lesquels tu as
les droits d’accès. Copier des fichiers sans autorisation est illégal.
Titres YouTube recommandés
Copie-colle ces titres dans YouTube (français / anglais) :
1. Script Python sauvegarde fichiers critiques vers carte SD
2. Trouver fichiers setuid setgid Linux (find -perm)
3. Comment lister fichiers root-owned et world-writable Linux
4. Automatiser sauvegarde vers SD card Raspberry Pi Python
5. Find command tutorial — find files by permission, owner, size
6. Python [Link] shutil copy files tutorial
7. Backup important files with Python — full example
8. Secure file backup script Linux step by step
9. How to detect critical files on Linux (permissions & owners)
10. C program to traverse filesystem and copy files (POSIX)
11. Using rsync to copy files to external drive (SD card)
12. Mounting and accessing SD card on Linux / Raspberry Pi
13. How to use stat and lstat in C / POSIX
14. Writing file-system walker in C (opendir readdir lstat)
15. Python script to backup only files with specific permissions
16. Raspberry Pi: Auto-detect and copy files to SD card
17. Backup strategy: exclude /proc /sys /dev when scanning
18. Python argparse logging example for scripts
19. How to preserve metadata when copying files (shutil.copy2 / rsync -a)
20. Sécurité et légalité de la sauvegarde de fichiers — bonnes pratiques
Guide étape par étape
1. Définir l’objectif et les règles
• Objectif : détecter les fichiers “critiques” selon certains critères (setuid, setgid,
appartenant à root, world-writable) et copier uniquement ceux que tu as le droit de
copier vers une carte SD.
• Sécurité : ne pas exécuter en root sur /. Toujours tester d’abord avec --dry-run sur
un dossier de test.
2. Choisir la technologie
• Recommandé : Python 3 (rapide, simple, portable).
• Option avancée : C (bas niveau, plus de contrôle mais plus complexe).
3. Préparer l’environnement (Linux / Raspberry Pi)
sudo apt update && sudo apt install -y python3 python3-venv
mkdir -p ~/backup_crit && cd ~/backup_crit
python3 -m venv venv && source venv/bin/activate
4. Définir les critères “fichiers critiques”
Exemples :
• setuid (bit S_ISUID)
• setgid (bit S_ISGID)
• root_owned (st_uid == 0)
• world_writable (permission o+w)
• regular (fichiers normaux)
5. Exclusions importantes
Toujours exclure : /proc, /sys, /dev, /run, /tmp, /var/run, /mnt (ou le montage SD si tu
scannes /).
6. Détection et montage de la carte SD
lsblk
sudo fdisk -l
sudo mkdir -p /mnt/sdcard
sudo mount /dev/sdX1 /mnt/sdcard
df -h | grep sdcard
ls /mnt/sdcard
7. Test de recherche (dry-run) avec find
sudo find / -path /proc -prune -o -perm -4000 -type f -print # setuid
sudo find / -perm -2000 -type f -print # setgid
sudo find / -uid 0 -type f -print # root-owned
sudo find / -perm -o=w -type f -print # world-
writable
8. Écrire le script Python
Le script doit :
• Accepter : --source, --dest, --criteria, --dry-run, --exclude, --max
• Lister d’abord les fichiers (dry-run)
• Demander confirmation avant la copie
• Copier avec shutil.copy2() (préserve métadonnées)
• Créer l’arborescence sur la SD
• Journaliser (log) et gérer les erreurs
9. Commandes utiles
# Dry-run
python3 backup_critical.py --source /home/user --dest /mnt/sdcard --
criteria setuid,root_owned --dry-run
# Copie réelle
python3 backup_critical.py --source /home/user --dest /mnt/sdcard --
criteria root_owned --max 100
10. Stratégie de copie robuste
rsync -a --relative /path/to/file /mnt/sdcard/
11. Tests et validation
1. Créer un dossier ~/test_src avec des fichiers tests, puis appliquer chmod 4755
file.
2. Monter la carte SD et exécuter le script sans --dry-run pour vérifier la copie et les
permissions.
12. Améliorations possibles
• Détection automatique de la carte SD
• Interface CLI ou menu interactif
• Envoi d’un rapport par mail
• Chiffrement (gpg)
• Archivage (tar)
Script Python d’exemple (backup_critical.py)
#!/usr/bin/env python3
import os, stat, shutil, argparse, logging, sys
from pathlib import Path
[Link](level=[Link], format="%(asctime)s %(levelname)s:
%(message)s")
def is_setuid(m): return bool(m & stat.S_ISUID)
def is_setgid(m): return bool(m & stat.S_ISGID)
def is_world_writable(m): return bool(m & stat.S_IWOTH)
def is_root_owned(s): return s.st_uid == 0
CRITERIA = {
"setuid": lambda s: is_setuid(s.st_mode),
"setgid": lambda s: is_setgid(s.st_mode),
"world_writable": lambda s: is_world_writable(s.st_mode),
"root_owned": lambda s: is_root_owned(s),
"regular": lambda s: stat.S_ISREG(s.st_mode),
}
def find_files(root, criteria, max_results=None, exclude=None):
exclude = exclude or []
found = []
for dirpath, _, files in [Link](root):
if any([Link]([dirpath, ex]) == ex for ex in exclude):
continue
for f in files:
p = [Link](dirpath, f)
try: st = [Link](p)
except: continue
if all(CRITERIA[c](st) for c in criteria):
[Link]((p, st))
if max_results and len(found) >= max_results: return found
return found
def copy_to_dest(src, st, src_root, dest_root, dry=False):
rel = [Link](src, src_root)
dst = [Link](dest_root, rel)
[Link]([Link](dst), exist_ok=True)
[Link](f"Copying: {src} → {dst}")
if not dry:
try: shutil.copy2(src, dst)
except Exception as e: [Link](f"Failed: {e}")
def main():
p = [Link]()
p.add_argument("--source", required=True)
p.add_argument("--dest", required=True)
p.add_argument("--criteria", default="setuid")
p.add_argument("--dry-run", action="store_true")
p.add_argument("--max", type=int, default=0)
p.add_argument("--exclude", default="/proc,/sys,/dev,/run,/tmp")
a = p.parse_args()
src, dest = [Link]([Link]), [Link]([Link])
excl = [[Link]() for x in [Link](",")]
crits = [[Link]() for x in [Link](",") if [Link]() in
CRITERIA]
files = find_files(src, crits, max_results=([Link] or None), exclude=excl)
[Link](f"Found {len(files)} files.")
for pth, st in files: print(pth)
if a.dry_run or not files: return
if input("Copy files? (y/N): ").lower() != "y": return
for pth, st in files: copy_to_dest(pth, st, src, dest, dry=a.dry_run)
[Link]("Done.")
if __name__ == "__main__": main()
Squelette C minimal
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dirent.h>
#include <sys/stat.h>
#include <unistd.h>
void walk(const char *path) {
DIR *d = opendir(path);
if (!d) return;
struct dirent *entry;
while ((entry = readdir(d))) {
if (!strcmp(entry->d_name, ".") || !strcmp(entry->d_name, ".."))
continue;
char full[4096];
snprintf(full, sizeof(full), "%s/%s", path, entry->d_name);
struct stat st;
if (lstat(full, &st) == -1) continue;
if (S_ISDIR(st.st_mode)) walk(full);
else if (S_ISREG(st.st_mode) && (st.st_mode & S_ISUID))
printf("setuid: %s\n", full);
}
closedir(d);
}
int main(int argc, char **argv) {
const char *start = argc > 1 ? argv[1] : "/";
walk(start);
return 0;
}
Checklist finale
☑ Choisir les critères (setuid, root_owned, etc.)
☑ Configurer et tester le montage de la SD
☑ Lancer find pour un test dry-run
☑ Lancer le script Python en --dry-run
☑ Vérifier les résultats puis lancer la copie réelle
☑ Contrôler les logs et permissions
☑ Ajouter des exclusions et des options avancées
Prochaines options possibles
1. Version C complète (copie et gestion d’erreurs).
2. Version Python avec détection automatique de la carte SD.
3. Génération d’un fichier PDF ou d’un installateur.