Կոդավորումը MySQL-ում: Keystore

Դասընթացի համար նոր գրանցման մեկնարկի ակնկալիքով «Տվյալների բազա» Մենք ձեզ համար պատրաստել ենք օգտակար հոդվածի թարգմանություն։

Կոդավորումը MySQL-ում: Keystore

Թափանցիկ տվյալների կոդավորումը (TDE) հայտնվել է Percona սերվեր MySQL-ի համար և MySQL-ը բավական ժամանակով: Բայց երբևէ մտածե՞լ եք, թե ինչպես է այն աշխատում գլխարկի տակ և ինչ ազդեցություն կարող է ունենալ TDE-ն ձեր սերվերի վրա: Այս հոդվածների շարքում մենք կանդրադառնանք, թե ինչպես է TDE-ն աշխատում ներսում: Սկսենք բանալիների պահեստից, քանի որ դա անհրաժեշտ է ցանկացած գաղտնագրման աշխատանքի համար: Այնուհետև մենք ավելի մանրամասն կանդրադառնանք, թե ինչպես է աշխատում գաղտնագրումը Percona Server-ում MySQL/MySQL-ի համար և ինչ լրացուցիչ հնարավորություններ ունի Percona Server-ը MySQL-ի համար:

MySQL Keyring

Keyring-ը պլագիններ են, որոնք թույլ են տալիս սերվերին հարցումներ կատարել, ստեղծել և ջնջել բանալիները տեղական ֆայլում (keyring_file) կամ հեռավոր սերվերի վրա (օրինակ՝ HashiCorp Vault): Բանալիները միշտ պահվում են տեղում՝ դրանց որոնումն արագացնելու համար:

Փլագինները կարելի է բաժանել երկու կատեգորիայի.

  • Տեղական պահեստավորում. Օրինակ, տեղական ֆայլ (մենք սա անվանում ենք ֆայլի վրա հիմնված ստեղնաշար):
  • Հեռավոր պահեստավորում: Օրինակ՝ Vault Server (մենք սա անվանում ենք սերվերի վրա հիմնված ստեղնաշար):

Այս տարանջատումը կարևոր է, քանի որ պահեստավորման տարբեր տեսակներ մի փոքր այլ կերպ են վարվում ոչ միայն բանալիները պահելիս և առբերելիս, այլ նաև դրանք գործարկելիս:

Ֆայլի պահեստ օգտագործելիս, գործարկումից հետո, պահեստի ամբողջ բովանդակությունը բեռնվում է քեշում՝ բանալին id, բանալին օգտագործող, բանալի տեսակը և հենց բանալին:

Սերվերի կողմից պահվող խանութի դեպքում (օրինակ՝ Vault Server-ը), գործարկման ժամանակ բեռնվում են միայն բանալու ID-ն և հիմնական օգտվողը, ուստի բոլոր ստեղները ստանալը չի ​​դանդաղեցնում գործարկումը: Ստեղները ծուլորեն բեռնված են: Այսինքն, բանալին ինքնին բեռնվում է Vault-ից միայն այն ժամանակ, երբ այն իրականում անհրաժեշտ է: Ներբեռնվելուց հետո բանալին պահվում է հիշողության մեջ, որպեսզի այն հետագայում կարիք չունենա մուտք գործել Vault Server-ի TLS կապերի միջոցով: Հաջորդը, եկեք տեսնենք, թե ինչ տեղեկատվություն է առկա բանալիների խանութում:

Հիմնական տեղեկատվությունը պարունակում է հետևյալը.

  • բանալին id — բանալին նույնացուցիչ, օրինակ.
    INNODBKey-764d382a-7324-11e9-ad8f-9cb6d0d5dc99-1
  • ստեղնաշարի տեսակը — բանալի տեսակը հիմնված գաղտնագրման ալգորիթմի վրա, հնարավոր արժեքները՝ «AES», «RSA» կամ «DSA»:
  • բանալու երկարությունը — բանալու երկարությունը բայթերով, AES՝ 16, 24 կամ 32, RSA 128, 256, 512 և DSA 128, 256 կամ 384:
  • Տեղ - բանալու սեփականատերը. Եթե ​​բանալին համակարգային է, օրինակ՝ Master Key, ապա այս դաշտը դատարկ է: Եթե ​​բանալին ստեղծվում է keyring_udf-ի միջոցով, ապա այս դաշտը նույնականացնում է բանալու տիրոջը:
  • բանալին ինքնին

Բանալին եզակիորեն նույնականացվում է զույգով՝ key_id, օգտվող:

Տարբերություններ կան նաև բանալիների պահպանման և ջնջման հարցում:

Ֆայլերի պահպանումն ավելի արագ է: Դուք կարող եք մտածել, որ բանալիների խանութը պարզապես մեկ անգամ գրում է ֆայլի բանալին, բայց ոչ, այստեղ ավելին է կատարվում: Ամեն անգամ, երբ ֆայլի պահպանման փոփոխություն է կատարվում, նախ ստեղծվում է ամբողջ բովանդակության կրկնօրինակը: Ենթադրենք ֆայլը կոչվում է my_biggest_secrets, ապա կրկնօրինակը կլինի my_biggest_secrets.backup: Այնուհետև քեշը փոխվում է (ստեղները ավելացվում կամ ջնջվում են) և, եթե ամեն ինչ հաջող է, քեշը վերականգնվում է ֆայլի: Հազվագյուտ դեպքերում, ինչպիսիք են սերվերի ձախողումը, դուք կարող եք տեսնել այս պահուստային ֆայլը: Պահուստային ֆայլը ջնջվում է հաջորդ անգամ, երբ ստեղները բեռնվում են (սովորաբար սերվերի վերագործարկումից հետո):

Սերվերի պահեստում բանալին պահելիս կամ ջնջելիս պահեստը պետք է միանա MySQL սերվերին «ուղարկել բանալին» / «խնդրել բանալին ջնջել» հրամաններով:

Եկեք վերադառնանք սերվերի գործարկման արագությանը: Բացի այն, որ գործարկման արագության վրա ազդում է հենց պահոցը, կա նաև այն հարցը, թե պահոցից քանի բանալի պետք է առբերվի գործարկման ժամանակ: Իհարկե, սա հատկապես կարևոր է սերվերի պահպանման համար: Գործարկման ժամանակ սերվերը ստուգում է, թե որ բանալին է անհրաժեշտ կոդավորված աղյուսակների/սեղանների համար և պահանջում է բանալին պահեստից: Master Key կոդավորումով «մաքուր» սերվերի վրա պետք է լինի մեկ հիմնական բանալի, որը պետք է վերցվի պահեստից: Այնուամենայնիվ, կարող է պահանջվել ավելի մեծ թվով ստեղներ, օրինակ, երբ պահուստային սերվերը վերականգնում է հիմնական սերվերի կրկնօրինակը: Նման դեպքերում պետք է ապահովվի Master Key-ի ռոտացիա: Սա ավելի մանրամասն կքննարկվի ապագա հոդվածներում, չնայած այստեղ ես կցանկանայի նշել, որ մի քանի Master Keys օգտագործող սերվերը կարող է մի փոքր ավելի երկար տևել գործարկելու համար, հատկապես, երբ օգտագործում եք սերվերի կողմից բանալիների պահեստ:

Հիմա եկեք մի փոքր ավելի շատ խոսենք keyring_file-ի մասին: Երբ ես մշակում էի keyring_file-ը, ես նաև մտահոգված էի, թե ինչպես ստուգել keyring_file-ի փոփոխությունները, երբ սերվերն աշխատում է: 5.7-ում ստուգումը կատարվել է ֆայլերի վիճակագրության հիման վրա, որը իդեալական լուծում չէր, իսկ 8.0-ում այն ​​փոխարինվեց SHA256 ստուգաչափով։

Առաջին անգամ, երբ գործարկում եք keyring_file-ը, հաշվարկվում են ֆայլերի վիճակագրությունը և ստուգման գումարը, որոնք հիշվում են սերվերի կողմից, և փոփոխությունները կիրառվում են միայն այն դեպքում, եթե դրանք համընկնում են: Երբ ֆայլը փոխվում է, ստուգման գումարը թարմացվում է:

Մենք արդեն անդրադարձել ենք առանցքային պահոցների վերաբերյալ բազմաթիվ հարցերի: Այնուամենայնիվ, կա ևս մեկ կարևոր թեմա, որը հաճախ մոռացվում կամ սխալ է ընկալվում՝ բանալիների փոխանակում սերվերների միջև:

Թե ինչ նկատի ունեմ? Կլաստերի յուրաքանչյուր սերվեր (օրինակ՝ Percona Server) պետք է առանձին տեղ ունենա Vault Server-ում, որտեղ Percona Server-ը պետք է պահի իր բանալիները: Պահեստում պահվող յուրաքանչյուր հիմնական բանալի պարունակում է Percona սերվերի GUID-ն իր նույնացուցիչում: Ինչու է դա կարևոր: Պատկերացրեք, որ դուք ունեք միայն մեկ Vault սերվեր, և կլաստերի բոլոր Percona սերվերներն օգտագործում են այդ միայնակ Vault սերվերը: Խնդիրն ակնհայտ է թվում. Եթե ​​բոլոր Percona սերվերներն օգտագործեին Master Key առանց եզակի նույնացուցիչների, ինչպիսիք են id = 1, id = 2 և այլն, ապա կլաստերի բոլոր սերվերները կօգտագործեն նույն Master Key-ը: Այն, ինչ տրամադրում է GUID-ը, սերվերների միջև եղած տարբերությունն է: Ինչո՞ւ այդ դեպքում խոսել սերվերների միջև բանալիների փոխանակման մասին, եթե արդեն գոյություն ունի եզակի GUID: Կա ևս մեկ պլագին` keyring_udf: Այս plugin-ի միջոցով ձեր սերվերի օգտվողը կարող է պահել իր բանալիները Vault սերվերում: Խնդիրն առաջանում է, երբ օգտատերը, օրինակ, սերվեր1-ում բանալի է ստեղծում, այնուհետև սերվեր2-ում փորձում է նույն ID-ով բանալի ստեղծել, օրինակ՝

--server1:
select keyring_key_store('ROB_1','AES',"123456789012345");
1
--1 значит успешное завершение
--server2:
select keyring_key_store('ROB_1','AES',"543210987654321");
1

Սպասեք։ Երկու սերվերներն էլ օգտագործում են նույն Vault Server-ը, չպե՞տք է արդյոք keyring_key_store ֆունկցիան ձախողվի server2-ում: Հետաքրքիր է, որ եթե փորձեք նույնն անել մեկ սերվերի վրա, դուք կստանաք սխալ.

--server1:
select keyring_key_store('ROB_1','AES',"123456789012345");
1
select keyring_key_store('ROB_1','AES',"543210987654321");
0

Ճիշտ է, ROB_1-ն արդեն գոյություն ունի:

Նախ քննարկենք երկրորդ օրինակը։ Ինչպես արդեն ասացինք, keyring_vault-ը կամ ցանկացած այլ բանալու պլագին պահում է բոլոր բանալիների ID-ները հիշողության մեջ: Այսպիսով, նոր բանալի ստեղծելուց հետո ROB_1-ը ավելացվում է server1-ին, և բացի այս բանալին Vault-ին ուղարկելուց, բանալին ավելացվում է նաև քեշում։ Այժմ, երբ մենք փորձում ենք երկրորդ անգամ ավելացնել նույն բանալին, keyring_vault ստուգում է, թե արդյոք բանալին կա քեշում և սխալ է թույլ տալիս:

Առաջին դեպքում իրավիճակն այլ է. Server1-ը և server2-ն ունեն առանձին քեշեր: ROB_1-ը սերվերի 1-ի և Vault սերվերի բանալիների քեշին ավելացնելուց հետո, սերվեր 2-ի բանալիների քեշը համաժամեցված չէ: Server2-ի քեշում ROB_1 բանալի չկա: Այսպիսով, ROB_1 բանալին գրված է keyring_key_store-ում և Vault սերվերում, որն իրականում վերագրում է (!) նախորդ արժեքը: Այժմ Vault սերվերի ROB_1 բանալին 543210987654321 է: Հետաքրքիր է, որ Vault սերվերը չի արգելափակում նման գործողությունները և հեշտությամբ վերագրանցում է հին արժեքը:

Այժմ մենք կարող ենք տեսնել, թե ինչու սերվերի բաժանումը Vault-ում կարող է կարևոր լինել, երբ դուք օգտագործում եք keyring_udf և ցանկանում եք բանալիները պահել Vault-ում: Ինչպե՞ս հասնել այս տարանջատմանը Vault սերվերի վրա:

Vault-ին բաժանելու երկու եղանակ կա: Դուք կարող եք ստեղծել տարբեր մոնտաժային կետեր յուրաքանչյուր սերվերի համար կամ օգտագործել տարբեր ուղիներ նույն ամրացման կետում: Սա լավագույնս երևում է օրինակներով: Այսպիսով, եկեք նախ նայենք առանձին ամրացման կետերին.

--server1:
vault_url = http://127.0.0.1:8200
secret_mount_point = server1_mount
token = (...)
vault_ca = (...)

--server2:
vault_url = http://127.0.0.1:8200
secret_mount_point = sever2_mount
token = (...)
vault_ca = (...)

Այստեղ դուք կարող եք տեսնել, որ server1-ը և server2-ը օգտագործում են տարբեր տեղադրման կետեր: Ճանապարհները բաժանելիս կոնֆիգուրացիան այսպիսի տեսք կունենա.

--server1:
vault_url = http://127.0.0.1:8200
secret_mount_point = mount_point/server1
token = (...)
vault_ca = (...)
--server2:
vault_url = http://127.0.0.1:8200
secret_mount_point = mount_point/sever2
token = (...)
vault_ca = (...)

Այս դեպքում երկու սերվերներն էլ օգտագործում են նույն մոնտաժային կետը «mount_point», բայց տարբեր ուղիներ: Երբ դուք ստեղծում եք առաջին գաղտնիքը սերվերի 1-ում՝ օգտագործելով այս ճանապարհը, Vault սերվերն ավտոմատ կերպով ստեղծում է «server1» գրացուցակը: Server2-ի համար ամեն ինչ նման է. Երբ դուք ջնջում եք վերջին գաղտնիքը mount_point/server1 կամ mount_point/server2, Vault սերվերը նույնպես ջնջում է այդ գրացուցակները: Այն դեպքում, երբ դուք օգտագործում եք ուղիների առանձնացում, դուք պետք է ստեղծեք միայն մեկ ամրացման կետ և փոխեք կազմաձևման ֆայլերը, որպեսզի սերվերները օգտագործեն առանձին ուղիներ: Տեղադրման կետը կարող է ստեղծվել HTTP հարցումով: Օգտագործելով CURL դա կարելի է անել այսպես.

curl -L -H "X-Vault-Token: TOKEN" –cacert VAULT_CA
--data '{"type":"generic"}' --request POST VAULT_URL/v1/sys/mounts/SECRET_MOUNT_POINT

Բոլոր դաշտերը (TOKEN, VAULT_CA, VAULT_URL, SECRET_MOUNT_POINT) համապատասխանում են կազմաձևման ֆայլի պարամետրերին: Իհարկե, դուք կարող եք օգտագործել Vault կոմունալ ծառայությունները նույնն անելու համար: Բայց ավելի հեշտ է ավտոմատացնել տեղադրման կետի ստեղծումը: Հուսով եմ, որ այս տեղեկատվությունը ձեզ համար օգտակար կլինի, և մենք ձեզ կտեսնենք այս շարքի հաջորդ հոդվածներում:

Կոդավորումը MySQL-ում: Keystore

Կարդալ ավելին:

Source: www.habr.com

Добавить комментарий