Back to Tech Blog
ArchitekturaRustZero-KnowledgeiSCSI

Dlaczego zbudowaliśmy natywny cel iSCSI dla Windows w języku Rust na potrzeby odzyskiwania zero-knowledge

Inżynieria StateWarden
5 min read
Share:

W przestrzeni disaster recovery (DR), funkcja "Instant Mount" jest absolutnym standardem. Możliwość pobrania zdalnego strumienia kopii zapasowej i natychmiastowego wystawienia go jako lokalnej litery dysku w systemie Windows jest krytyczna dla przywrócenia biznesu do działania i zminimalizowania wskaźnika RTO (Recovery Time Objective).

Większość dostawców rozwiązań backupowych radzi sobie z tym poprzez dołączanie do swoich agentów sterowników wirtualnych dysków firm trzecich – takich jak ImDisk czy WNBD. Są to sterowniki działające w trybie jądra (pliki .sys), które głęboko integrują się ze stosem pamięci masowej Windows.

W StateWarden® nasza architektura podlega rygorystycznemu mandatowi: Zero Zewnętrznych Zależności. Odmawiamy zaśmiecania jądra systemu hosta sterownikami firm trzecich. Instalacja zewnętrznych modułów jądra wprowadza znaczne ryzyko bezpieczeństwa, tarcia wdrożeniowe i potencjalną niestabilność systemu (BSOD).

Co ważniejsze, StateWarden to system w 100% zero-knowledge. Kopie zapasowe są poddawane silnej deduplikacji i szyfrowaniu (AES-256-GCM) na poziomie bloków, zanim w ogóle opuszczą klienta. Klucze deszyfrujące nigdy nie opuszczają maszyny hosta. Jeśli chcemy natychmiast zamontować zdalną kopię zapasową o rozmiarze 2 TB, nie możemy jej pobrać i odszyfrować do pliku tymczasowego – to przeczyłoby idei zero-knowledge i zniszczyłoby wydajność.

Dane w postaci jawnej (plaintext) muszą istnieć tylko w pamięci RAM, dokładnie w momencie, gdy system operacyjny żąda konkretnego sektora.

Aby to osiągnąć bez niestandardowych sterowników, wybraliśmy najtrudniejszą, ale najczystszą architektonicznie ścieżkę: Zbudowaliśmy w pełni zgodny serwer iSCSI Target od podstaw, napisany w całości w języku Rust, osadzony bezpośrednio w Agencie StateWarden.

Windows posiada natywny, wbudowany Inicjator iSCSI. Mówiąc jego językiem przez lokalny interfejs loopback, mogliśmy strumieniować bloki z naszych własnych centrów danych, deszyfrować je w pamięci RAM w locie i serwować je bezpośrednio do natywnego stosu pamięci masowej Windows.

Oto czego wymaga zbudowanie celu pamięci blokowej od zera i okiełznanie notorycznie bezlitosnego stosu pamięci masowej Windows.

Nawigowanie po rygorystycznych zasadach Windows iSCSI

Protokół iSCSI (RFC 3720) enkapsuluje złożone komendy SCSI wewnątrz jednostek PDU (Protocol Data Units) przesyłanych przez TCP. Inicjator iSCSI w Windows świetnie wykonuje swoje zadanie, ale jest niewiarygodnie restrykcyjny. Pojedynczy błędnie umieszczony bajt lub najmniejsze odstępstwo od maszyny stanów skutkuje cichą awarią: inicjator po prostu zrywa połączenie TCP (os error 10054) bez żadnego wyjaśnienia.

Podczas naszych wczesnych wdrożeń, inicjator Windows pomyślnie kończył złożony handshake logowania i odkrywał nasz wirtualny cel. Ale w momencie, gdy próbował odpytać dysk, połączenie gwałtownie umierało.

Analiza pakietów ujawniła dokładny moment awarii: Windows wysyłał komendę REPORT LUNS (0xA0). Nasz serwer w Rust przetwarzał ją idealnie i dołączał dane payloadu bezpośrednio do PDU SCSI Response (0x21).

Zgodnie z RFC, PDU SCSI Response musi zawierać wyłącznie kody statusu (takie jak SUCCESS lub CHECK CONDITION). Nie może przenosić odczytanych danych. Wszelkie rzeczywiste dane muszą być wysyłane przez dedykowane PDU SCSI Data-In (0x25). Inicjator Windows zobaczył bajty payloadu dołączone do ramki statusu, sklasyfikował to jako fatalne uszkodzenie protokołu i natychmiast wystrzelił flagę TCP RST (Reset).

Refaktoryzacja naszego budowniczego pakietów w celu oddzielenia strumienia danych i poprawnego ustawienia flag F (Final) oraz S (Status present) na ramce Data-In ustabilizowała połączenie.

Obsługa fragmentacji PDU

Nawet przy zgodnym protokole głębokie skany systemu plików powodowały sporadyczne zrywanie połączeń. Przełom nastąpił podczas analizy parametrów logowania iSCSI.

Podczas handshake'u Windows negocjuje parametr MaxRecvDataSegmentLength (zazwyczaj 256 KB). Jednak podczas odczytywania dużych struktur Master File Table (MFT), Windows wydaje żądania odczytu SCSI na 512 KB lub więcej. Nasza początkowa implementacja próbowała wysłać cały 512-kilobajtowy payload w pojedynczym PDU Data-In. Windows widział przewymiarowany pakiet, zdawał sobie sprawę, że przekracza on wynegocjowane limity i natychmiast zamykał socket.

Musieliśmy napisać od nowa naszą logikę strumieniowania Data-In, aby automatycznie fragmentować ogromne żądania odczytu SCSI na sekwencję mniejszych, w pełni zgodnych PDU, pociętych precyzyjnie do limitów wynegocjowanych przez inicjatora, wykonując deszyfrowanie i mapowanie deduplikacji w locie przez wiele pakietów.

Fałszowanie geometrii NTFS w pamięci

Po ustabilizowaniu protokołu sieciowego, Inicjator Windows w końcu połączył się bez problemów. W Zarządzaniu Dyskami pojawił się nowy dysk. Jednak Eksplorator Windows odmówił jego otwarcia, oznaczając system plików jako "RAW".

Nasz cel (target) serwował dokładnie zdeszyfrowane bajty skopiowanej partycji NTFS. Dlaczego Windows nie mógł jej odczytać?

Problem leżał w fizycznej geometrii oryginalnej kopii zapasowej. Gdy Agent StateWarden wykonuje kopię działającego dysku Windows, odpytuje API FSCTL_GET_NTFS_VOLUME_DATA w celu określenia dokładnego rozmiaru systemu plików.

Jednak to API Windows raportuje rozmiar woluminu z pominięciem ostatniego sektora. Ten ostatni sektor zawiera zapasowy rekord rozruchowy woluminu (Backup VBR). Działający na żywo system Windows nie przejmuje się tym ucięciem, ale sterownik ntfs.sys walidujący nowo zamontowany dysk absolutnie wymaga, aby Główny VBR (na LBA 0) i Zapasowy VBR (na końcu dysku) pasowały do siebie idealnie. Ponieważ naszemu strumieniowi backupu brakowało tego ostatniego sektora, Windows odrzucał cały system plików jako uszkodzony.

Skonstruowaliśmy poprawkę w czasie rzeczywistym w naszym backendzie strumieniującym. Nasz MbrWrapperBackend teraz buforuje Główny VBR w locie, oblicza prawdziwe granice fizyczne partycji i dynamicznie wstrzykuje syntetyczny Backup VBR dokładnie na samym końcu strumienia w pamięci. Skutecznie dopełniamy (padujemy) geometrię idealnie przed zaprezentowaniem jej inicjatorowi iSCSI.

Architektoniczny zysk

Z odtworzoną dokładną geometrią NTFS i perfekcyjnie sfragmentowanymi payloadami sieciowymi, wirtualny dysk montuje się natychmiastowo. Błąd "RAW" znika, a gigabajty silnie zaszyfrowanych, zdeduplikowanych danych z naszych centrów danych są natychmiast gotowe do przeglądania w Eksploratorze Windows.

Za każdym razem, gdy klikasz dwukrotnie plik, Agent StateWarden pobiera dokładnie zdeduplikowane bloki ze zdalnego węzła magazynującego, deszyfruje je w pamięci RAM za pomocą lokalnie przechowywanych kluczy i przepycha je przez połączenie loopback iSCSI do systemu operacyjnego.

Budowa celu pamięci blokowej od zera jest bolesna, ale zysk architektoniczny jest ogromny. Dostarczamy możliwości "Instant Mount" klasy enterprise natywnie, z absolutnym bezpieczeństwem zero-knowledge i bez zaśmiecania jądra systemu użytkownika sterownikami firm trzecich. Nie chodzimy na skróty, jeśli chodzi o integralność systemu hosta.

Spodziewamy się, że po przeczytaniu tego tekstu, tradycyjni dostawcy spróbują zrekonstruować i skopiować tę bezsterownikową architekturę. Zapraszamy. Ale natywna implementacja iSCSI to tylko jeden z elementów silnika StateWarden. To zaledwie jedna z dziesiątek autorskich decyzji inżynieryjnych – od naszej kryptografii cebulowej PrimeKEM po heurystyki aktywnej obrony Vigil – które fundamentalnie deklasują obecne oferty rynkowe. Nie budujemy po prostu narzędzia do backupu; inżynieryjnie tworzymy nowy standard odporności danych.

Prywatność z Założenia

Ta strona używa wyłącznie własnych plików cookies, ściśle niezbędnych do jej działania. Zero zewnętrznych trackerów, zero zewnętrznych platform analitycznych.

Szczegóły znajdziesz w naszej Polityce Prywatności.