MySQL дэх шифрлэлт: Түлхүүр хадгалах газар

Сургалтын шинэ элсэлт эхлэхийг хүлээж байна "Мэдээллийн сан" Бид танд хэрэгтэй нийтлэлийн орчуулгыг бэлдлээ.

MySQL дэх шифрлэлт: Түлхүүр хадгалах газар

Ил тод өгөгдлийн шифрлэлт (TDE) гарч ирэв MySQL-д зориулсан Percona сервер болон MySQL нэлээн удаан. Гэхдээ энэ нь тагны доор хэрхэн ажилладаг, TDE таны серверт ямар нөлөө үзүүлэх талаар бодож үзсэн үү? Энэ цуврал нийтлэлд бид TDE дотооддоо хэрхэн ажилладаг талаар авч үзэх болно. Ямар ч шифрлэлт ажиллахад шаардлагатай тул түлхүүрийн хадгалалтаас эхэлье. Дараа нь бид MySQL/MySQL-д зориулсан Percona серверт шифрлэлт хэрхэн ажилладаг, MySQL-д зориулсан Percona сервер ямар нэмэлт боломжуудтай болохыг нарийвчлан авч үзэх болно.

MySQL Түлхүүр

Түлхүүр нь серверт локал файл (keyring_file) эсвэл алсын сервер (HashiCorp Vault гэх мэт) дээрх түлхүүрүүдийг хайх, үүсгэх, устгах боломжийг олгодог залгаасууд юм. Түлхүүрүүд нь хайлтыг хурдасгахын тулд үргэлж дотооддоо хадгалагддаг.

Plugins-ийг хоёр төрөлд хувааж болно:

  • Орон нутгийн хадгалах сан. Жишээлбэл, локал файл (бид үүнийг файлд суурилсан түлхүүр гэж нэрлэдэг).
  • Алсын хадгалалт. Жишээлбэл, Vault Server (бид үүнийг серверт суурилсан түлхүүрийн бөгж гэж нэрлэдэг).

Өөр өөр төрлийн хадгалалтууд нь зөвхөн түлхүүрүүдийг хадгалах, сэргээхэд төдийгүй тэдгээрийг ажиллуулах үед арай өөрөөр ажилладаг тул энэ тусгаарлалт чухал юм.

Файлын санг ашиглах үед эхлүүлэх үед санах ойн агуулгыг бүхэлд нь кэш рүү ачаалдаг: түлхүүр ID, түлхүүр хэрэглэгч, түлхүүрийн төрөл, түлхүүр өөрөө.

Сервер талын дэлгүүрийн хувьд (Vault Server гэх мэт) эхлүүлэх үед зөвхөн түлхүүр ID болон түлхүүр хэрэглэгчийг ачаалдаг тул бүх түлхүүрүүдийг авах нь эхлүүлэх ажиллагааг удаашруулахгүй. Түлхүүрүүдийг залхуугаар ачаалдаг. Өөрөөр хэлбэл, түлхүүр нь үнэхээр шаардлагатай үед л Vault-аас ачаалагддаг. Татаж авсны дараа түлхүүрийг санах ойд хадгалдаг тул ирээдүйд Vault серверт TLS холболтоор хандах шаардлагагүй болно. Дараа нь гол дэлгүүрт ямар мэдээлэл байгааг харцгаая.

Гол мэдээлэл нь дараахь зүйлийг агуулна.

  • түлхүүр ID - түлхүүр танигч, жишээ нь:
    INNODBKey-764d382a-7324-11e9-ad8f-9cb6d0d5dc99-1
  • түлхүүрийн төрөл - ашигласан шифрлэлтийн алгоритм дээр суурилсан түлхүүрийн төрөл, боломжит утгууд: "AES", "RSA" эсвэл "DSA".
  • түлхүүр урт — байт дахь түлхүүрийн урт, AES: 16, 24 эсвэл 32, RSA 128, 256, 512 ба DSA 128, 256 эсвэл 384.
  • хэрэглэгчийн - түлхүүрийн эзэн. Хэрэв түлхүүр нь систем, жишээлбэл, Мастер түлхүүр бол энэ талбар хоосон байна. Хэрэв keyring_udf ашиглан түлхүүр үүсгэсэн бол энэ талбар нь түлхүүрийн эзэмшигчийг тодорхойлно.
  • түлхүүр нь өөрөө

Түлхүүр нь хосоор тодорхойлогддог: key_id, user.

Түлхүүрийг хадгалах, устгахад ч ялгаа бий.

Файл хадгалах нь илүү хурдан байдаг. Түлхүүр дэлгүүрийг зүгээр л нэг удаа файлын түлхүүр бичиж байна гэж та бодож магадгүй, гэхдээ үгүй, энд өөр зүйл байна. Файлын хадгалалтын өөрчлөлт хийх бүрд эхлээд бүх агуулгын нөөц хуулбар үүсдэг. Файлыг миний_хамгийн_нууц гэж нэрлэе гэж бодъё, тэгвэл нөөц хуулбар нь my_biggest_secrets.backup болно. Дараа нь кэшийг өөрчилнө (түлхүүрүүдийг нэмсэн эсвэл устгасан) бөгөөд хэрэв бүх зүйл амжилттай болбол кэшийг файл болгон дахин тохируулна. Серверийн доголдол гэх мэт ховор тохиолдолд та энэ нөөц файлыг харж болно. Түлхүүрүүдийг дараагийн удаа ачаалах үед нөөц файлыг устгадаг (ихэвчлэн серверийг дахин ачаалсны дараа).

Түлхүүрийг серверийн санд хадгалах эсвэл устгах үед хадгалах сан нь MySQL серверт "түлхүүрийг илгээх" / "түлхүүр устгах хүсэлт" гэсэн командын тусламжтайгаар холбогдох ёстой.

Сервер эхлүүлэх хурд руу буцаж орцгооё. Хөдөлгөөний хурд нь савнаас өөрөөс нь шалтгаалахаас гадна эхлүүлэх үед савнаас хэдэн түлхүүр гаргаж авах шаардлагатай вэ гэдэг асуудал бий. Мэдээжийн хэрэг, энэ нь сервер хадгалахад онцгой ач холбогдолтой юм. Эхлэх үед сервер шифрлэгдсэн хүснэгт/хүснэгтийн зайд ямар түлхүүр шаардлагатайг шалгаж, хадгалах сангаас түлхүүрийг хүсэх болно. Мастер түлхүүрийн шифрлэлттэй "цэвэр" сервер дээр нэг Мастер түлхүүр байх ёстой бөгөөд үүнийг хадгалах сангаас татаж авах шаардлагатай. Гэсэн хэдий ч, жишээлбэл, нөөц сервер үндсэн серверээс нөөц хуулбарыг сэргээх үед илүү олон тооны түлхүүр шаардлагатай байж болно. Ийм тохиолдолд мастер түлхүүрийг эргүүлэх шаардлагатай. Энэ талаар цаашдын нийтлэлүүдэд илүү дэлгэрэнгүй авч үзэх болно, гэхдээ олон Мастер Түлхүүр ашигладаг сервер, ялангуяа сервер талын түлхүүрийн дэлгүүрийг ашиглах үед эхлүүлэхэд бага зэрэг хугацаа шаардагдахыг энд тэмдэглэхийг хүсч байна.

Одоо keyring_file-ийн талаар бага зэрэг яръя. Би keyring_file-г хөгжүүлж байхдаа сервер ажиллаж байх үед түлхүүрийн_файл өөрчлөлтийг хэрхэн шалгах талаар санаа зовж байсан. 5.7-д шалгалтыг файлын статистик дээр үндэслэн хийсэн бөгөөд энэ нь оновчтой шийдэл биш байсан бөгөөд 8.0-д үүнийг SHA256 шалгах нийлбэрээр сольсон.

Таныг keyring_file-г анх удаа ажиллуулах үед файлын статистик болон шалгах нийлбэрийг тооцоолж серверт санах бөгөөд өөрчлөлтүүд нь таарч байвал л хэрэгжинэ. Файл өөрчлөгдөхөд хяналтын нийлбэр шинэчлэгдэнэ.

Түлхүүр савны талаарх олон асуултыг бид аль хэдийн авч үзсэн. Гэсэн хэдий ч ихэвчлэн мартагддаг эсвэл буруу ойлгогддог өөр нэг чухал сэдэв байдаг: түлхүүрүүдийг серверүүдээр хуваалцах.

Би юу гэсэн үг вэ? Кластер дахь сервер бүр (жишээ нь, Percona сервер) Percona сервер түлхүүрээ хадгалах ёстой Vault сервер дээр тусдаа байршилтай байх ёстой. Хадгаламжид хадгалагдсан Мастер түлхүүр бүр өөрийн танигч доторх Percona серверийн GUID-г агуулна. Яагаад чухал вэ? Танд зөвхөн нэг Vault сервер байгаа бөгөөд кластерт байгаа бүх Percona серверүүд тэр нэг Vault серверийг ашигладаг гэж төсөөлөөд үз дээ. Асуудал илт харагдаж байна. Хэрэв бүх Percona серверүүд id = 1, id = 2 гэх мэт өвөрмөц танигчгүй Мастер түлхүүр ашигласан бол кластерийн бүх серверүүд ижил Мастер түлхүүрийг ашиглах болно. GUID нь серверүүдийн хоорондын ялгааг өгдөг. Өвөрмөц GUID аль хэдийн байгаа бол яагаад серверүүд хооронд түлхүүр хуваалцах тухай ярих ёстой гэж? Өөр нэг залгаас байдаг - keyring_udf. Энэ залгаасын тусламжтайгаар таны серверийн хэрэглэгч түлхүүрээ 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 сервер ашиглаж байгаа тул server2 дээр keyring_key_store функц амжилтгүй болох ёстой гэж үү? Сонирхолтой нь, хэрэв та нэг сервер дээр ижил зүйлийг хийхийг оролдвол танд алдаа гарах болно:

--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 нь сервер1-д нэмэгдэх бөгөөд энэ түлхүүрийг Vault руу илгээхээс гадна түлхүүр нь кэшэд нэмэгдэх болно. Одоо бид ижил түлхүүрийг хоёр дахь удаагаа нэмэхийг оролдох үед keyring_vault түлхүүр нь кэшэд байгаа эсэхийг шалгаж, алдаа гаргадаг.

Эхний тохиолдолд нөхцөл байдал өөр байна. Server1 болон server2 нь тусдаа кэштэй. ROB_1-г сервер1 болон Vault сервер дээрх түлхүүр кэшэд нэмсний дараа сервер2 дээрх түлхүүр кэш синк хийгээгүй байна. Сервер2 дээрх кэшэд ROB_1 түлхүүр байхгүй байна. Тиймээс ROB_1 түлхүүр нь keyring_key_store болон Vault серверт бичигдсэн бөгөөд энэ нь үнэндээ өмнөх утгыг (!) дарж бичдэг. Одоо Vault сервер дээрх ROB_1 түлхүүр нь 543210987654321. Сонирхолтой нь Vault сервер ийм үйлдлийг хаадаггүй бөгөөд хуучин утгыг амархан дарж бичдэг.

Та keyring_udf ашиглаж байгаа бөгөөд Vault-д түлхүүрээ хадгалахыг хүсэж байгаа үед 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 = (...)

Эндээс сервер1 болон сервер2 өөр холбох цэгүүдийг ашиглаж байгааг харж болно. Замуудыг хуваах үед тохиргоо нь иймэрхүү харагдах болно.

--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 дэх шифрлэлт: Түлхүүр хадгалах газар

Цааш унших:

Эх сурвалж: www.habr.com

сэтгэгдэл нэмэх