Proton Drive — Miroir iSCSI (Jean et Maryse)

1. Contexte et objectif

Proton Drive n’a pas encore de client natif pour Linux. Pistes explorées avant cette solution :

  • rclone (backend protondrive) : fonctionne par moments, mais Proton bloque régulièrement les connexions via son système anti-fraude/CAPTCHA — instable, abandonné comme solution principale.
  • VHDX sur partage SMB : fonctionne, mais ajoute une couche de virtualisation imbriquée plus complexe à diagnostiquer.
  • iSCSI (solution retenue) : expose un vrai disque bloc local à Windows, sans couche VHD supplémentaire. Plus robuste, et l’occasion d’apprendre cette technologie.

Architecture générale

Le flux de données est à sens unique, en trois maillons :

NAS Ubuntu (source de vérité, Samba)
        |  robocopy /MIR (sens unique)
        v
Disque NTFS local (iSCSI, dans la VM Windows WinBoat)
        |  synchro bidirectionnelle
        v
Cloud Proton Drive (+ partage avec Maryse)

À retenir : les modifications de fichiers doivent toujours se faire sur le NAS. Le disque iSCSI/NTFS n’est qu’un miroir de transit : robocopy l’écrase à chaque passage. Toute modification faite directement sur ce disque, ou via le cloud Proton/un autre appareil, sera effacée au prochain cycle.

Pourquoi deux disques iSCSI séparés (Jean et Maryse)

Le client Proton Drive Windows ne supporte qu’un seul compte actif à la fois. Comme un second conteneur WinBoat serait trop lourd pour le mini-PC, et que Windows Home/Pro ne permet qu’une session interactive à la fois : un seul WinBoat, deux disques iSCSI distincts. Les fichiers de Maryse sont temporairement hébergés sous le compte Proton de Jean, puis partagés avec elle via l’interface web.

Solution temporaire — à la sortie du client Linux natif, les fichiers de Maryse seront remis sous son propre compte.

2. Particularité réseau de WinBoat

Le réseau interne de WinBoat (host.lan) ne résout pas les noms d’hôtes du réseau local. La connectivité IP fonctionne, mais pas la résolution de noms.

À retenir : toujours utiliser l’adresse IP directe du NAS (192.168.0.11), jamais son nom d’hôte, depuis la VM Windows.

Test-NetConnection -ComputerName 192.168.0.11 -Port 445

3. Configuration côté NAS (Ubuntu) — targetcli / iSCSI

À répéter une fois par disque (Jean : 2 To, Maryse : 1 To).

3.1 Installer targetcli

sudo apt update
sudo apt install targetcli-fb -y

targetcli est l’outil de configuration du sous-système iSCSI LIO intégré au noyau Linux.

3.2 Créer le fichier qui servira de disque (backing store)

sudo truncate -s 2T /media/nas2/Image_iSCSI/proton-mirror-jean.img
sudo truncate -s 1T /media/nas2/Image_iSCSI/proton-mirror-maryse.img

L’espace est prélevé sur le système de fichiers monté à l’endroit choisi (/media/nas2), pas sur la partition système. truncate crée un fichier « creux » (sparse) : la taille affichée est la limite maximale, l’espace réel consommé grandit avec les écritures (vérifier avec du -h, pas ls -lh).

3.3 Créer le backstore, le target, le LUN et l’ACL (CHAP)

sudo targetcli

Pour Jean :

/backstores/fileio create protonmirror /media/nas2/Image_iSCSI/proton-mirror-jean.img
/iscsi create iqn.2026-06.ca.jean:protonmirror
cd /iscsi/iqn.2026-06.ca.jean:protonmirror/tpg1/luns
create /backstores/fileio/protonmirror
cd ../acls
create iqn.1991-05.com.microsoft:win-5pk8ip7kbuc
cd iqn.1991-05.com.microsoft:win-5pk8ip7kbuc
set auth userid=jeanmirror
set auth password=changemoi
cd /
saveconfig
exit

Pour Maryse :

/backstores/fileio create marysemirror /media/nas2/Image_iSCSI/proton-mirror-maryse.img
/iscsi create iqn.2026-06.ca.jean:marysemirror
cd /iscsi/iqn.2026-06.ca.jean:marysemirror/tpg1/luns
create /backstores/fileio/marysemirror
cd ../acls
create iqn.1991-05.com.microsoft:win-5pk8ip7kbuc
cd iqn.1991-05.com.microsoft:win-5pk8ip7kbuc
set auth userid=marysemirror
set auth password=changemoi
cd /
saveconfig
exit

backstore = représente le fichier .img comme périphérique de stockage. target (IQN) = identité de la cible sur le réseau iSCSI. LUN = relie le backstore au target. ACL = liste blanche d’initiateurs autorisés (même IQN Windows pour les deux targets, même VM). CHAP = authentification exigée à la connexion.

3.4 Pare-feu et persistance

sudo ufw allow 3260/tcp
sudo systemctl enable --now target

3.5 En cas d’erreur : nettoyer et repartir à zéro

sudo targetcli
clearconfig confirm=true
ls
saveconfig
exit

clearconfig efface toute la configuration targetcli. Le fichier .img doit être supprimé séparément avec rm.

4. Configuration côté Windows (VM WinBoat)

4.1 Connexion à la cible iSCSI

  • Lancer iscsicpl.exe (Initiateur iSCSI)
  • Onglet Découverte → « Détecter portail » → IP du NAS (192.168.0.11), port 3260
  • Onglet Cibles → sélectionner la cible → Connecter
  • Cocher « Ajouter cette connexion à la liste des cibles favorites »
  • Avancé → « Activer la connexion CHAP » → entrer userid/password configurés à l’étape 3.3

4.2 Initialiser et formater le disque

  • Gestion des disques (diskmgmt.msc)
  • Disque « Hors connexion » → clic droit → Mettre en ligne
  • Clic droit → Initialiser le disque → GPT
  • Espace non alloué → Nouveau volume simple → NTFS → lettre (P: Jean, Q: Maryse)

5. Accès réseau Samba depuis Windows

cmdkey /add:192.168.0.11 /user:nas /pass:changemoi

Identifiants enregistrés une seule fois pour toutes les opérations vers ce NAS. Toujours utiliser l’IP (192.168.0.11), jamais un nom d’hôte (le réseau host.lan de WinBoat ne résout pas les noms du LAN).

6. Scripts PowerShell de synchronisation

Architecture en deux couches : un fichier de mapping (liste des dossiers) et un script d’exécution (boucle robocopy). Ajouter un dossier plus tard = une ligne dans le mapping, rien d’autre à modifier.

6.1 Politique d’exécution PowerShell (une fois)

Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy RemoteSigned

6.2 Fichier de mapping — Jean (C:\scripts\mappings-jean.ps1)

@(
    @{ Source = "\\192.168.0.11\nas1\Documents\Vers_Proton\Communs";            Dest = "P:\Communs" },
    @{ Source = "\\192.168.0.11\nas1\Documents\Vers_Proton\Personne - Francis"; Dest = "P:\Personne - Francis" },
    @{ Source = "\\192.168.0.11\nas1\Documents\Vers_Proton\Personne - Jean";    Dest = "P:\Personne - Jean" },
    @{ Source = "\\192.168.0.11\nas1\Documents\Vers_Proton\Personne - Olivier";Dest = "P:\Personne - Olivier" },
    @{ Source = "\\192.168.0.11\nas1\Photographies";                            Dest = "P:\Photographies" },
    @{ Source = "\\192.168.0.11\nas1\Backups\Pixel-9";                          Dest = "P:\Backups\Pixel-9" },
    @{ Source = "\\192.168.0.11\nas1\Backups\S6lite_Jean";                      Dest = "P:\Backups\S6lite_Jean" },
    @{ Source = "\\192.168.0.11\nas1\Backups\S6lite_Maryse";                    Dest = "P:\Backups\S6lite_Maryse" },
    @{ Source = "\\192.168.0.11\nas1\Backups\S24";                              Dest = "P:\Backups\S24" },
    @{ Type = "File"; SourceDir = "\\192.168.0.11\nas1\Conteneurs"; DestDir = "P:\Sauvegardes\Conteneurs"; FileName = "Veracrypt-e1" },
    @{ Type = "File"; SourceDir = "\\192.168.0.11\nas1\Conteneurs"; DestDir = "P:\Sauvegardes\Conteneurs"; FileName = "Veracrypt-e2" }
)

Veracrypt-e1/e2 sont des fichiers (conteneurs chiffrés), pas des dossiers — structure Type=File différente. Choix délibéré de « liste blanche » plutôt que copier tout le dossier Conteneurs avec exclusions : un nouveau conteneur ajouté plus tard reste invisible au script jusqu’à ajout explicite.

6.3 Fichier de mapping — Maryse (C:\scripts\mappings-maryse.ps1)

@(
    @{ Source = "\\192.168.0.11\nas1\Documents\Vers_Proton\Personne - Gabrielle Desrochers";      Dest = "Q:\Personne - Gabrielle Desrochers" },
    @{ Source = "\\192.168.0.11\nas1\Documents\Vers_Proton\Personne - Hélène Desrochers-Argouin"; Dest = "Q:\Personne - Hélène Desrochers-Argouin" },
    @{ Source = "\\192.168.0.11\nas1\Documents\Vers_Proton\Personne - Maryse";                     Dest = "Q:\Personne - Maryse" }
)

6.4 Scripts d’exécution

C:\scripts\protonmirror-daily.ps1 (idem -maryse- avec mappings-maryse.ps1 et son propre log) :

$mappings = & "C:\scripts\mappings-jean.ps1"
$logFile = "C:\logs\protonmirror-daily.log"
foreach ($m in $mappings) {
    if ($m.Type -eq "File") {
        robocopy $m.SourceDir $m.DestDir $m.FileName /R:2 /W:5 /Z /LOG+:$logFile /NFL /NDL
    } else {
        robocopy $m.Source $m.Dest /MIR /R:2 /W:5 /MT:4 /Z /LOG+:$logFile /NFL /NDL
    }
}

C:\scripts\protonmirror-monthly.ps1 — identique, ajoute /IS sur la branche dossier :

$mappings = & "C:\scripts\mappings-jean.ps1"
$logFile = "C:\logs\protonmirror-monthly.log"
foreach ($m in $mappings) {
    if ($m.Type -eq "File") {
        robocopy $m.SourceDir $m.DestDir $m.FileName /R:2 /W:5 /Z /LOG+:$logFile /NFL /NDL
    } else {
        robocopy $m.Source $m.Dest /MIR /IS /R:2 /W:5 /MT:4 /Z /LOG+:$logFile /NFL /NDL
    }
}

6.5 Signification des options robocopy

Option Rôle
/MIR Mode miroir : copie les nouveautés ET supprime côté destination ce qui n’existe plus côté source.
/IS Force la recopie même si taille/date semblent identiques (vérification complète, usage mensuel).
/R:2 Nombre de tentatives en cas d’échec (défaut : 1 000 000).
/W:5 Secondes d’attente entre tentatives (défaut : 30 s).
/MT:4 Copie multithread (4 fichiers en parallèle).
/Z Mode redémarrable : reprend un gros fichier interrompu.
/LOG+:fichier Ajoute le résultat au journal (sans écraser l’historique).
/NFL /NDL N’inscrit pas le détail fichier par fichier (journal compact).

À retenir : robocopy compare seulement taille + date de modification, jamais le contenu (pas de hash). Vérifier que les outils de tagging (ex. Puddletag) mettent à jour la date de modification.

6.6 Lecture des journaux : encodage

Robocopy écrit en encodage OEM (souvent CP850). Pour un affichage correct des accents :

Get-Content C:\logs\protonmirror-daily.log -Tail 40 -Encoding OEM

7. Tâches planifiées

Tâche Fréquence Script Rôle
ProtonMirror-Daily Quotidienne, 03:00 protonmirror-daily.ps1 Synchro rapide, incrémentale
ProtonMirror-Monthly-Deep Mensuelle, 1er, 01:00 protonmirror-monthly.ps1 Vérification complète (/IS)
ProtonMirror-Maryse-Daily Quotidienne, 04:00 protonmirror-maryse-daily.ps1 Idem, dossiers Maryse
ProtonMirror-Maryse-Monthly-Deep Mensuelle, 1er, 01:30 protonmirror-maryse-monthly.ps1 Idem, vérification complète

Pour chaque tâche (Planificateur de tâches → Créer une tâche) :

  • Général : « Exécuter que l’utilisateur soit connecté ou non » + « Exécuter avec les autorisations maximales »
  • Action : powershell.exe, argument -NoProfile -ExecutionPolicy Bypass -File "chemin\script.ps1"
  • Paramètres : « Ne pas démarrer une nouvelle instance » si déjà en cours

8. Intégration avec Proton Drive

  • Client Proton Drive natif (compte de Jean) → ajouter le dossier de synchronisation → P:\
  • Partager les dossiers de Maryse via l’interface web de Proton Drive (seul endroit possible pour du contenu venant de « Ordinateur »)

9. Points de vigilance — résumé

  • Ne jamais éditer directement sur P:/Q: ni via le cloud Proton — ces changements seront écrasés. Modifier uniquement sur le NAS.
  • Toujours utiliser l’IP (192.168.0.11), jamais un nom d’hôte, côté VM Windows.
  • Vérifier les dates de modification des outils de tagging — robocopy ne détecte pas les changements si taille+date restent identiques.
  • Un compte Proton actif à la fois — d’où les deux disques iSCSI distincts dans la même VM.
  • Solution temporaire — à remplacer à la sortie du client Linux natif de Proton Drive.

Annexe — Dossiers synchronisés

Disque de Jean (P:, 2 To) : Communs, Personne – Francis, Personne – Jean, Personne – Olivier, Photographies, Backups/Pixel-9, Backups/S6lite_Jean, Backups/S6lite_Maryse, Backups/S24, Conteneurs/Veracrypt-e1 (fichier), Conteneurs/Veracrypt-e2 (fichier).

Disque de Maryse (Q:, 1 To) : Personne – Gabrielle Desrochers, Personne – Hélène Desrochers-Argouin, Personne – Maryse.