Спасяване на данни от стар NAS през мрежата
Реален случай: данни от стари дискове на Zyxel NSA325 (ext4 върху md „linear“ том) се връщат върху съживен NSA325 с 4 TB диск, по мрежата. Ще видиш как се чете том, който ядрото не сглобява, как се копира през CIFS без да се удариш в капаните — и какво реално рискуваш с SMBv1.
--inplace вече включва --partial; уточнено е, че ядра 6.8–6.13 нямат linear, а 6.14 и по-нови го имат отново. Адресите, имената на хостове, споделяния и потребители и вътрешните пътища са заменени с плейсхолдъри. Командите не са пускани наново за това издание, затова няма етикет „ТЕСТВАНО“.01Какво ще научиш
- Как да четеш том от стар NAS през loop устройство, когато ядрото не може да го сглоби като md, и кога да направиш образ с ddrescue първо.
- Кои rsync флагове са безопасни за CIFS цел и защо
-aе капан. - Четирите капана, които на практика губят часове.
- Какво е SMBv1, защо е слаба защита и как да го ползваш само временно и изолирано.
- Как трайна systemd услуга довършва копирането след спиране на тока.
02Преди да започнеш
- Linux машина с root достъп и свързан по SATA/USB стар диск (или дискове) от NAS-а.
- Целева система с достатъчно място — поне колкото данните на източника — и мрежова връзка до нея.
- Инсталирани
rsync(от 3.1.0 нагоре — тогава е добавен--info=progress2) иcifs-utils; по желаниеddrescue. - Диск, чието съдържание е единствено копие, не се пипа със запис: ако има признаци на повреда, първо правиш образ, после работиш върху образа.
- Данни за вход към целта, които не ползваш никъде другаде, и изолирана мрежа за стъпка 5.
03Стъпки
-
Правило номер едно: източникът е само за четене
Старите томове са single-disk md „linear“ томове с ext4 от Zyxel NSA325; целта е съживен NSA325 с 4 TB диск. Копираме по мрежата (CIFS/SMB). Не рискуваме единственото копие — затова четем само за четене на всеки слой: loop устройство и монтиране.
Етап Описание Стар NSA325 диск linear ext4 том · само за четене · никога не се пише в него loop-mount + rsync Четем тома през loop устройство, копираме с CIFS-безопасни флагове Съживен NSA325 4 TB цел, достъпна по мрежата (CIFS/SMB) 💾Диск, който се чупи — първо образАко дискът дава грешки при четене, rsync върху него може да го довърши.ddrescueне записва нули на мястото на лошите сектори и води mapfile, така че можеш да го прекъснеш и да продължиш. Пример от ръководството му (за дял):ddrescue -f -n /dev/sdX2 /път/образ.img /път/mapfileи послеddrescue -d -f -r3 /dev/sdX2 /път/образ.img /път/mapfile. Работиш върху образа, не върху диска. Ръководството казва да ползваш mapfile, освен ако не знаеш какво правиш. -
Loop-mount трикът
Първо провери дали изобщо ти трябва. Опцията
MD_LINEARлипсва в изходния код на ядрата 6.8 до 6.13 (проверено в технитеdrivers/md/Kconfig; в 6.7 още я има) и е отново там в 6.14, 6.17 и текущия master. Дистрибуционните ядра могат да се различават — виж своето:modinfo linearилиgrep MD_LINEAR /boot/config-$(uname -r). В нашия случай ядрото беше 6.8 и не можеше да сглоби стария том като md, затова го заобиколихме: монтираме дяла през loop устройство с офсет, само за четене.bash · намери офсета и монтирай# Офсет = начален сектор на дяла × размер на сектора (виж "Start" и "Sector size") fdisk -l /dev/sdX # При нас дялът почваше от сектор 2048: 2048 × 512 = 1 MiB losetup --find --show --read-only --offset $((2048*512)) /dev/sdX2 # --show печата името на устройството, напр. /dev/loop0; noload пропуска ext4 журнала mount -o ro,noload /dev/loop0 /mnt/old # проверка ls -la /mnt/old✅Защо тези опцииСпоредlosetup(8)--read-onlyправи устройството само за четене, а--offsetпремества началото на данните с толкова байта. Споредext4(5)noloadне зарежда журнала.⚠️Два капана тук1. Ако файловата система не е била размонтирана чисто,noloadводи до несъгласувани данни — ext4 документацията го казва изрично. Затова при съмнение работи върху образ (стъпка 1) и пусниe2fsckвърху него. 2. Офсетът 2048 е за нашия диск. Ако md метаданните стоят в началото на члена, данните може да почват по-късно (виж „Data Offset“ вmdadm --examine); това не е проверено от нас ⚠️ — не копирай офсета сляпо. -
rsync през CIFS — безопасни флагове
CIFS целта отхвърля част от операциите, които rsync прави по подразбиране: временен файл + преименуване, смяна на собственик и права. Затова ползваме флагове, които пишат директно и не пипат атрибути, които NAS-ът отказва.
Флаг Защо --inplaceПише директно във файла вместо да създава ново копие и да го премества. Подразбира и --partial(прекъснат файл не се трие). Цената: файлът е в несъгласувано състояние, докато се копира, и остава такъв при прекъсване.--no-perms --no-owner --no-groupИзключва права и собственик, които -aиначе включва--omit-dir-timesНе пипа времената на директориите -rt --modify-window=2Рекурсия и запазване на времената; два времена се смятат за равни, ако се разминават най-много с 2 секунди. Ръководството посочва 1 за файлови системи с 2-секундна точност (FAT); 2 е стойността, с която минахме при нас --info=progress2Общ прогрес на целия пренос (rsync от 3.1.0) bash · копиране, което може да се пуска отново# Повторно пускане сравнява размер и време и прескача вече копираното rsync -rt --modify-window=2 --inplace --no-perms --no-owner --no-group --omit-dir-times --info=progress2 /mnt/old/ /mnt/target/dest/⛔Не добавяй-aсляпо-aе съкращение за-rlptgoD— влече права, собственик и групи, които CIFS целта отхвърля. Обратното също важи: без-lсимволните връзки не се копират. Ако в данните има такива, ще ги пропуснеш мълчаливо — прегледай изхода или ги обработи отделно.bash · проверка преди да обявиш успех# Само сравнява (-n), по контролни суми (-c) — бавно, но надеждно; списъкът показва какво се различава rsync -rtnc --itemize-changes /mnt/old/ /mnt/target/dest/Опциите в тази проверка са потвърдени в
rsync(1), но самата комбинация не е пускана в нашия случай. -
Четирите капана от случая
Това са наблюдения от реалното спасяване върху NSA325. Документацията не ги потвърждава изрично ⚠️ — приеми ги като полеви опит, не като закон.
⚠️Капан 1 — „close failed: Permission denied (13)“На CIFS целта rsync се провали при преименуването на временния файл. Лекува се с--inplace— пише директно, без преименуване.⚠️Капан 2 —mkdirдава „Permission denied“ заради квотаНа том с квота (имашеaquota.userфайл, макар томът да е почти празен) създаването на папка се отхвърляше с общо „Permission denied“. Пренасочихме към том, който приема запис. Реалната корекция на квотата е през уеб интерфейса на NAS-а. Преди да търсиш грешка в правата, потърси такъв файл.⚠️Капан 3 —dfпоказва фалшив размерПрез SMBv1 NSA325 върнаdfс размер, който не отговаряше на диска (3.6T). Не го ползвай като измерител на прогреса.⚠️Капан 4 —duзабива под натоварванеduпрез CIFS се заби, докато rsync работеше. Чети прогреса от самия rsync (--info=progress2) в журнала, като превърнеш връщането на каретката в нов ред:bash · прогрес — не df, не dujournalctl -u rescue.service -o cat | tr '\r' '\n' | grep % -
Монтиране на SMBv1 споделяне — и цената му
⛔SMBv1 е слаба защита — ползвай го само временно и изолираноSMBv1 е най-старият диалект на протокола. Документацията на ядрото обяснява, че SMB 2.1 и по-новите имат допълнителна защита — срещу „човек по средата“ и по-силни хешове — и затова старите диалекти се препоръчват да не се ползват. Ръководството наmount.cifsказва, че SMB1 вече не се иска по подразбиране при монтиране и има „много по-слаба сигурност“. Samba по подразбиране има минимален протокол SMB2_02, а Microsoft отдавна призовава „Stop using SMB1“.
Затова: само в изолирана мрежа (директен кабел или отделен суич, без интернет и чужди устройства); само докато трае спасяването; с данни за вход, които не ползваш никъде другаде; размонтирай и изключи услугата след края. Най-добре: ако можеш, извади диска и го чети директно със стъпка 2, вместо да вдигаш SMBv1.Старият NSA325 в нашия случай работеше само по SMBv1: със
vers=2.0/2.1монтирането завършваше с „Host is down“. Ако виждаш това, подозирай версията. Дали по-нов фърмуер на NSA325 говори SMB2 — не сме проверявали ⚠️.ℹ️Поддръжка в ядрото днесВ Linux master опциятаCIFS_ALLOW_INSECURE_LEGACYе включена по подразбиране; ако е изключена,vers=1.0иvers=2.0не се приемат. Модулът има и параметърdisable_legacy_dialects=y, който изключва SMB1. Дистрибуционните ядра не сме проверявали ⚠️ — акоvers=1.0се отхвърля, това може да е причината. В прегледаните източници не е обявено премахване на SMB1, но не разчитай, че ще е там завинаги.bash · монтирай с vers=1.0# Файл с данни за вход, четим само от root; формат по mount.cifs(8): редове username= и password= touch /root/.nas-credentials && chmod 600 /root/.nas-credentials mount -t cifs //<nas-host>/<share> /mnt/target -o credentials=/root/.nas-credentials,vers=1.0 # „Host is down“? Почти сигурно е версията — върни се на vers=1.0Данните за вход са във файл, не в командния ред — така не се виждат в списъка с процеси и в историята на обвивката.
-
Трайна услуга — оцелява спиране на тока
systemd услуга от тип
oneshotсе счита за пуснала, когато главният ѝ процес приключи — подходящо за еднократна задача. Нашата при всяко стартиране пресъздава loop устройството, монтира NAS-а и възобновява rsync (прескача вече копираното). След рестарт просто продължава. Изключи услугата, когато приключиш.systemd · пример (илюстрация, не е пускан тук)[Unit] Description=Data rescue (resumable copy) After=network-online.target Wants=network-online.target [Service] Type=oneshot ExecStart=/usr/local/sbin/rescue.sh [Install] WantedBy=multi-user.targetsh · rescue.sh — идемпотентно (илюстрация)#!/bin/sh set -eu # Име по by-id, не /dev/sdX — след рестарт буквите на дисковете могат да се сменят SRC=/dev/disk/by-id/<disk-id>-part2 mountpoint -q /mnt/old || { LOOP=$(losetup --find --show --read-only --offset $((2048*512)) "$SRC") mount -o ro,noload "$LOOP" /mnt/old } mountpoint -q /mnt/target || mount -t cifs //<nas-host>/<share> /mnt/target -o credentials=/root/.nas-credentials,vers=1.0 rsync -rt --modify-window=2 --inplace --no-perms --no-owner --no-group --omit-dir-times --info=progress2 /mnt/old/ /mnt/target/dest/ℹ️Защо е безопасно да се пуска многократноЛогиката е идемпотентна: ако нещо вече е монтирано, скриптът го пропуска; rsync продължава оттам, докъдето е стигнал. Прекъснатият с--inplaceфайл е в несъгласувано състояние, но следващото пускане го презаписва, защото размерът и времето му не съвпадат. При съмнение, след края пусни проверката от стъпка 3.
04Проверка
1. Ядрото няма linear модул. Как четеш стария том?
2. rsync дава „close failed: Permission denied (13)“ на CIFS целта. Кой флаг помага?
3. df показва фалшив размер, а du се заби. Как следиш прогреса?
4. Защо услугата oneshot оцелява спиране на тока?
5. Защо SMBv1 (vers=1.0) се ползва само временно и в изолирана мрежа?
05Какво следва
06Източници
- losetup(8) —
--read-only,--offset,--find --show. - ext4(5) —
noload/norecoveryи предупреждението за несъгласуваност. - rsync(1) —
--inplace(подразбира--partial),-a = -rlptgoD,--omit-dir-times,--modify-window,--info=progress2. - mount.cifs(8) —
vers=, формат на файлаcredentials=, раздел „Security“,disable_legacy_dialects. - Linux: fs/smb/client/Kconfig —
CIFS_ALLOW_INSECURE_LEGACYи защо старите диалекти се избягват. - Linux 6.8: drivers/md/Kconfig (без
MD_LINEAR) и master (с него). - GNU ddrescue — ръководство — mapfile и примерите за дял.
- smb.conf(5) —
client min protocolиserver min protocol, по подразбиране SMB2_02. - Microsoft: Stop using SMB1.
- systemd.service(5) —
Type=oneshot. - Полеви опит на КАГАМИ: спасяване на данни от стари дискове на NSA325 върху съживен NSA325 (капаните в стъпка 4 са от него).