Criptarea copiilor de rezervă: ajungem la acea linie de sosire

Publicat: 2017-09-02

Notă: Acest post de inginerie a fost scris de administratorul bazei de date, Silvia Botros. Consultați câteva dintre celelalte postări ale ei DBA aici.

Acum un an, SendGrid lucra din greu pentru certificarea SOC2. Toată lumea a fost implicată. Au existat povești pe aproape fiecare panou de echipă de livrare cu o etichetă SOC2, deoarece doream cu toții să fim certificați până la sfârșitul celui de-al treilea trimestru. După cum vă puteți imagina, fiind persoana responsabilă cu bazele de date, era cu siguranță ceva de făcut pentru acea parte a stivei.

Pe lista mea de sarcini pentru acest efort la nivel de afaceri era să mă asigur că backup-urile noastre erau criptate. Deoarece domeniul meu de familiaritate sunt instrumentele DBA și știind că xtrabackup-ul Percona are deja suport pentru criptare, era previzibil că voi merge la asta ca primă încercare la această sarcină.

Câteva lucruri importante au fost în vizorul meu în testarea acestei abordări:

  • Evident, copia de rezervă trebuia criptată
  • Suplimentarul pentru crearea copiei de rezervă trebuia să fie cunoscut și acceptabil
  • Suplimentarul pentru decriptarea copiei de rezervă în timpul recuperării trebuia cunoscut și acceptabil

Asta însemna că mai întâi trebuia să pot urmări cât durează backup-urile mele.

Urmărirea timpului de rezervă

SendGrid folosește Graphite pentru valorile sale de infrastructură și, în timp ce marea majoritate sunt trimise prin Sensu, Graphite este suficient de ușor pentru a trimite valori direct prin linii bash – foarte convenabil, deoarece scripturile de rezervă sunt în bash. Rețineți că trimiterea directă a valorilor la Graphite nu este super scalabilă, dar, deoarece aceste copii de siguranță rulează cel mult o dată pe oră, a fost bine pentru nevoile mele.

Acea parte s-a dovedit a fi relativ ușoară.

Pentru a explica ce s-a întâmplat în acea ultimă linie, îi trimit lui Graphite calea metricii pe care o trimit (asigură-te că este unică), valoarea metricii, apoi ora curentă în format epoch. Netcat este ceea ce am decis să folosesc pentru simplitate și îi dau un timeout de 1 secundă pentru că, altfel, nu va ieși niciodată. „Url-ul grafit” este punctul nostru final DNS pentru Graphite în centrul de date.

Acum că aveam o linie de bază cu care să compar, eram gata să începem să testăm metodele de criptare.

Urmând documentația detaliată de la Percona despre cum să fac acest lucru, am început prin a face o cheie. Dacă citiți cu atenție acea pagină de documentație, vă puteți da seama de ceva.

Această cheie trebuie să fie transmisă instrumentului de rezervă direct și este aceeași cheie care poate decripta instantaneul. Aceasta se numește criptare simetrică și este, prin natura aceleiași chei în ambele direcții, mai puțin sigură decât criptarea asimetrică. Am decis să continui testarea pentru a vedea dacă simplitatea face încă o abordare viabilă.

Testele cu DB-uri foarte mici, câteva sute de MB, au avut succes. Instrumentul funcționează conform așteptărilor și documentelor, dar acesta a fost mai degrabă un test funcțional și adevărata întrebare a fost „care este dimensiunea penalizării criptării pe bazele noastre de date mai mari?” Cele mai multe instanțe vechi de la SendGrid crescuseră la dimensiuni de la 1-2 TB la o singură fiară de 18 TB. Ceea ce urma să folosesc pentru instanțele mici trebuia să fie acceptabil din punct de vedere operațional și pentru cele mai mari.

Aici au devenit interesante testele și benchmark-urile

Primul meu subiect de testare de dimensiuni considerabile este o bază de date pe care o avem și care are 1 TB pe disc. Foarte repede am întâlnit o problemă neașteptată. Cu setări minime de criptare (1 fir, dimensiuni implicite ale bucăților), am văzut că backup-urile eșuează cu această eroare:

La acea vreme, aceste baze de date foloseau 512 MB ca dimensiune a fișierului jurnal de tranzacții, iar acesta este un cluster destul de ocupat, așa că acele fișiere se roteau aproape în fiecare minut. În mod normal, acest lucru ar fi vizibil în performanța DB, dar a fost în mare parte mascat de minunea unităților cu stare solidă. Se pare că a nu seta nici un fir de criptare paralel (a se citi: folosește unul) înseamnă că petrecem atât de mult timp criptând fișierele `.ibd`, încât jurnalul de redoare innodb de sub noi facea pauza de rezervă.

Deci, să încercăm din nou acest lucru cu o serie de fire de criptare. Ca prima incercare, am incercat cu 50 de fire. Trucul aici este să găsiți punctul favorabil al criptării rapide fără a concura cu CPU. De asemenea, am mărit dimensiunea `ib_logfiles` la 1 GB fiecare.

Acesta a fost un test mai reușit pe care am fost bucuros să-l las să se infuzeze peste noapte. În primele nopți, lucrurile păreau bune. Era timpul să facem o copie de rezervă care să nu crească prea mult, dar încărcarea medie a casetei în timpul procesului de backup arăta cu siguranță pașii adăugați.

Cu toate acestea, când am trecut la testarea restaurărilor, am constatat că procesul de restaurare a acelorași copii de rezervă, după adăugarea criptării, a crescut de la 60 la 280 de minute, ceea ce înseamnă o penalizare severă pentru timpul de recuperare promis în caz de dezastru.

Trebuia să aducem asta înapoi la un interval de timp mai rezonabil.

Aici a strălucit munca în echipă și soluțiile mai simple la probleme. Unul dintre membrii echipei InfoSec a decis să vadă dacă această soluție poate fi simplificată. Așa că a făcut mai multe teste și a revenit cu ceva mai simplu și mai sigur. Nu învățasem încă despre gpg2 și așadar acesta a devenit un exercițiu de învățare și pentru mine.

Lucrul bun despre gpg2 este că acceptă criptarea asimetrică. Creăm o pereche de chei unde există părți private și publice. Partea publică este folosită pentru a cripta orice flux sau fișier pe care decideți să îl alimentați cu gpg2, iar secretul privat poate fi folosit pentru a decripta.

Modificarea scripturilor noastre de rezervă pentru a adăuga criptare distilată la aceasta. Unele argumente sunt eliminate pentru a face acest lucru mai ușor de citit:

Pe de altă parte, atunci când restaurăm o copie de rezervă, trebuie pur și simplu să ne asigurăm că o cheie secretă care este acceptabilă se află în inelul de chei al gazdei și apoi să folosim această comandă:

Deoarece eram și eu nou la gpg2, aceasta a devenit o oportunitate de învățare pentru mine. Colin, minunatul nostru membru al echipei InfoSec, a continuat să testeze backup-urile și restaurările folosind gpg2 până când a confirmat că utilizarea gpg2 are multiple avantaje în utilizarea compresiei încorporate a xtrabackup, inclusiv:

  • Era asimetric
  • Managementul său secret pentru decriptare este rotit relativ ușor (mai multe despre asta mai jos)
  • Este independent de instrument, ceea ce înseamnă că orice alt tip de backup care nu utilizează xtrabackup ar putea folosi aceeași metodă
  • Foloseau mai multe nuclee la decriptare, ceea ce ne-a oferit timpi de restaurare mai buni

Întotdeauna loc de îmbunătățire

Un loc în care încă văd loc de îmbunătățire este modul în care gestionăm secretul care poate decripta aceste fișiere. Momentan, le avem în soluția noastră de gestionare a parolelor de întreprindere, dar obținerea lor de acolo, apoi folosirea acesteia pentru a testa copiile de siguranță este un proces manual. Următorul în planul nostru este să implementăm Vault de la Hashicorp și să îl folosim pentru a trage fără probleme, iar pe gazdele desemnate, cheia secretă pentru decriptare, apoi o scoatem din inelul local, astfel încât să fie ușor disponibil pentru teste automate și încă protejat.

În cele din urmă, am obținut toate copiile de rezervă ale bazei de date pentru a se conforma nevoilor noastre SOC2 la timp, fără a sacrifica performanța backupului sau SLA de recuperare în caz de dezastru. M-am distrat foarte mult lucrând la această misiune cu echipa noastră InfoSec și am ieșit din ea învățând noi instrumente. În plus, este întotdeauna plăcut când cea mai simplă soluție ajunge să fie cea mai potrivită pentru sarcina cuiva.