Szyfrowanie naszych kopii zapasowych: dotarcie do mety
Opublikowany: 2017-09-02Uwaga: ten post inżynierski został napisany przez naszego administratora bazy danych, Silvię Botros. Sprawdź niektóre z jej innych postów DBA tutaj.
Rok temu SendGrid ciężko pracował nad certyfikacją SOC2. Wszyscy byli zaangażowani. Na prawie każdej tablicy zespołu dostawczego pojawiły się historie z tagiem SOC2, ponieważ wszyscy chcieliśmy uzyskać certyfikat do końca trzeciego kwartału. Jak możesz sobie wyobrazić, będąc osobą odpowiedzialną za bazy danych, zdecydowanie trzeba było wykonać trochę pracy dla tej części stosu.
Na mojej liście zadań dla tego przedsięwzięcia biznesowego było upewnienie się, że nasze kopie zapasowe są szyfrowane. Ponieważ moim obszarem znajomości są narzędzia DBA i wiedząc, że xtrabackup Percony ma już obsługę szyfrowania, było do przewidzenia, że pójdę do tego jako pierwsza próba tego zadania.
Podczas testowania tego podejścia miałem na uwadze kilka ważnych rzeczy:
- Oczywiście kopia zapasowa musiała być zaszyfrowana
- Koszty związane z tworzeniem kopii zapasowej musiały być znane i akceptowalne
- Koszt odszyfrowania kopii zapasowej w czasie odzyskiwania musiał być znany i akceptowalny
Oznaczało to, że najpierw musiałem być w stanie śledzić, jak długo trwa tworzenie kopii zapasowych.
Śledzenie czasu kopii zapasowej
SendGrid używa Graphite do metryk infrastruktury i chociaż zdecydowana większość jest wysyłana przez Sensu, Graphite jest wystarczająco łatwy do wysyłania metryk bezpośrednio przez linie bash - bardzo wygodne, ponieważ skrypty kopii zapasowych są w bash. Zwróć uwagę, że wysyłanie metryk bezpośrednio do Graphite nie jest super skalowalne, ale ponieważ te kopie zapasowe są uruchamiane co najwyżej raz na godzinę, to było w porządku dla moich potrzeb.
Ta część okazała się stosunkowo łatwa.
Aby wyjaśnić, co się stało w ostatniej linii, wysyłam Graphite ścieżkę metryki, którą wysyłam (upewnij się, że jest unikalna), wartość metryki, a następnie aktualny czas w formacie epoki. Netcat jest tym, co postanowiłem użyć dla uproszczenia i daję mu czas oczekiwania na 1 sekundę, ponieważ w przeciwnym razie nigdy się nie wyłączy. `Graphite url` to nasz punkt końcowy DNS dla Graphite w centrum danych.
Teraz, gdy miałem podstawę do porównania, byliśmy gotowi do rozpoczęcia testowania metod szyfrowania.
Postępując zgodnie ze szczegółową dokumentacją Percony, jak to zrobić, zacząłem od zrobienia klucza. Jeśli uważnie przeczytasz tę stronę z dokumentacją, możesz coś sobie uświadomić.
Ten klucz należy przekazać bezpośrednio do narzędzia do tworzenia kopii zapasowych i jest to ten sam klucz, który może odszyfrować migawkę. Nazywa się to szyfrowaniem symetrycznym i ze względu na ten sam klucz w obu kierunkach jest mniej bezpieczne niż szyfrowanie asymetryczne. Postanowiłem kontynuować testowanie, aby sprawdzić, czy prostota nadal sprawia, że jest to opłacalne podejście.
Testy z bardzo małymi bazami danych, kilkuset MB, zakończyły się sukcesem. Narzędzie działa zgodnie z oczekiwaniami i dokumentacją, ale był to bardziej test funkcjonalny, a prawdziwe pytanie brzmiało „jaka jest kara za szyfrowanie naszych większych baz danych?” Bardziej starsze wystąpienia w SendGrid urosły do rozmiarów od 1-2 TB do jednej bestii 18 TB. To, czego zamierzałem użyć w małych instancjach, musiało być również operacyjnie akceptowalne w przypadku większych.
W tym miejscu testy i benchmarki stały się interesujące
Moim pierwszym obiektem testowym o sporych rozmiarach jest baza danych, którą posiadamy o pojemności 1 TB na dysku. Bardzo szybko natknąłem się na nieoczekiwany problem. Przy minimalnych ustawieniach szyfrowania (1 wątek, domyślne rozmiary fragmentów), zauważyłem, że tworzenie kopii zapasowych kończy się niepowodzeniem z tym błędem:
W tym czasie te bazy danych wykorzystywały 512 MB jako rozmiar pliku dziennika transakcji, a jest to dość obciążony klaster, więc pliki te zmieniały się prawie co minutę. Normalnie byłoby to zauważalne w wydajności DB, ale w większości było to maskowane przez cudowne dyski półprzewodnikowe. Wygląda na to, że nie ustawianie żadnych równoległych wątków szyfrowania (czytaj: użyj jednego) oznacza, że spędzamy tak dużo czasu na szyfrowaniu plików `.ibd`, że innodb redo log rolls spod nas robił przerwę w kopii zapasowej.
Spróbujmy więc ponownie z kilkoma wątkami szyfrowania. W pierwszej próbie próbowałem z 50 wątkami. Sztuczka polega na znalezieniu najlepszego punktu szybkiego szyfrowania bez konkurowania o procesor. Zwiększyłem również rozmiar `ib_logfiles` do 1 GB każdy.
To był bardziej udany test, który z radością pozwoliłem uwarzyć przez noc. Przez kilka pierwszych nocy wszystko wyglądało dobrze. Nadszedł czas, aby wykonać kopię zapasową, która nie rozrasta się zbytnio, ale średnia obciążenia pudełka podczas procesu tworzenia kopii zapasowej zdecydowanie pokazywała dodane kroki.
Jednak kiedy przeszedłem do przywracania testowego, stwierdziłem, że proces przywracania tych samych kopii zapasowych po dodaniu szyfrowania wzrósł z 60 do 280 minut, co oznacza poważną karę w stosunku do obiecanego czasu odzyskiwania w przypadku awarii.
Musieliśmy sprowadzić to z powrotem do bardziej rozsądnych ram czasowych.
Tutaj zabłysnęła praca zespołowa i prostsze rozwiązania problemów. Jeden z członków naszego zespołu InfoSec postanowił sprawdzić, czy można uprościć to rozwiązanie. Zrobił więc więcej testów i wrócił z czymś prostszym i bezpieczniejszym. Nie dowiedziałem się jeszcze o gpg2, więc stało się to również dla mnie ćwiczeniem edukacyjnym.
Dobrą rzeczą w gpg2 jest to, że obsługuje szyfrowanie asymetryczne. Tworzymy parę kluczy, w której znajdują się części prywatne i publiczne. Część publiczna służy do szyfrowania dowolnego strumienia lub pliku, który zdecydujesz się nakarmić gpg2, a prywatny sekret może zostać użyty do odszyfrowania.
Zmiana w naszych skryptach tworzenia kopii zapasowych, aby dodać szyfrowanie, sprowadzała się do tego. Niektóre argumenty zostały usunięte, aby ułatwić czytanie:
Z drugiej strony, podczas przywracania kopii zapasowej, musimy po prostu upewnić się, że akceptowalny tajny klucz znajduje się w pęku kluczy hosta, a następnie użyć tego polecenia:
Ponieważ byłem również nowy w gpg2, stało się to dla mnie okazją do nauki. Colin, nasz niesamowity członek zespołu InfoSec, kontynuował testowanie kopii zapasowych i przywracania za pomocą gpg2, dopóki nie potwierdził, że korzystanie z gpg2 ma wiele zalet w porównaniu z wbudowaną kompresją xtrabackup, w tym:
- Był asymetryczny
- Jego tajne zarządzanie w celu odszyfrowania jest stosunkowo łatwe do rotacji (więcej na ten temat poniżej)
- Jest niezależny od narzędzi, co oznacza, że każdy inny rodzaj kopii zapasowej, który nie używa xtrabackup, może korzystać z tej samej metody
- Używał wielu rdzeni do deszyfrowania, co dało nam lepsze czasy przywracania
Zawsze miejsce na ulepszenia
Jednym z miejsc, w którym wciąż widzę pole do ulepszeń, jest to, jak radzimy sobie z sekretem, który może odszyfrować te pliki. W tej chwili mamy je w naszym korporacyjnym rozwiązaniu do zarządzania hasłami, ale pobieranie ich stamtąd, a następnie używanie ich do testowania kopii zapasowych to proces ręczny. Następnym w naszym planie jest wdrożenie Vault przez Hashicorp i wykorzystanie go do bezproblemowego, i na wyznaczonych hostach, pobrania tajnego klucza do odszyfrowania, a następnie usunięcia go z lokalnego pierścienia, aby był łatwo dostępny do automatycznych testów i nadal chroniony.
Ostatecznie wszystkie nasze kopie zapasowe baz danych były zgodne z naszymi potrzebami SOC2 na czas, bez poświęcania wydajności tworzenia kopii zapasowych lub umowy SLA dotyczącej odzyskiwania po awarii. Świetnie się bawiłem pracując nad tym zadaniem z naszym zespołem InfoSec i wyszedłem z tego, ucząc się nowych narzędzi. Poza tym zawsze miło jest, gdy najprostsze rozwiązanie okazuje się najbardziej odpowiednie dla danego zadania.