לקראת תחילת הרשמה חדשה לקורס הכנו עבורכם תרגום של מאמר שימושי.

הצפנת נתונים שקופה (TDE) הופיעה ב ו-MySQL במשך די הרבה זמן. אבל האם אי פעם חשבת על איך זה עובד מתחת למכסה המנוע ואיזו השפעה יכולה להיות ל-TDE על השרת שלך? בסדרת מאמרים זו נבחן כיצד TDE עובד באופן פנימי. נתחיל עם אחסון מפתחות, מכיוון שזה נדרש כדי שכל הצפנה תעבוד. לאחר מכן נסקור מקרוב כיצד פועלת ההצפנה ב-Percona Server עבור MySQL/MySQL ואיזה תכונות נוספות יש ל-Percona Server for MySQL.
מחזיק מפתחות MySQL
Keyring הם תוספים המאפשרים לשרת לבצע שאילתות, ליצור ולמחוק מפתחות בקובץ מקומי (keyring_file) או בשרת מרוחק (כגון HashiCorp Vault). מפתחות תמיד מאוחסנים במטמון מקומי כדי לזרז את שליפתם.
ניתן לחלק תוספים לשתי קטגוריות:
- אחסון מקומי. לדוגמה, קובץ מקומי (אנחנו קוראים לזה מחזיק מפתחות מבוסס קבצים).
- אחסון מרחוק. לדוגמה, Vault Server (אנחנו קוראים לזה מחזיק מפתחות מבוסס שרת).
הפרדה זו חשובה מכיוון שסוגי אחסון שונים מתנהגים מעט שונה, לא רק בעת אחסון ושליפה של מפתחות, אלא גם בעת הפעלתם.
בעת שימוש באחסון קבצים, בעת ההפעלה, כל תוכן האחסון נטען למטמון: מזהה מפתח, משתמש מפתח, סוג מפתח והמפתח עצמו.
במקרה של חנות בצד השרת (כגון Vault Server), רק מזהה המפתח ומשתמש המפתח נטענים בעת האתחול, כך שקבלת כל המפתחות אינה מאטה את ההפעלה. מפתחות נטענים בעצלתיים. כלומר, המפתח עצמו נטען מ-Vault רק כאשר הוא נחוץ בפועל. לאחר ההורדה, המפתח נשמר בזיכרון כך שאין צורך לגשת אליו דרך חיבורי TLS לשרת הכספת בעתיד. לאחר מכן, הבה נבחן איזה מידע קיים בחנות המפתחות.
המידע המרכזי מכיל את הדברים הבאים:
- מזהה מפתח - מזהה מפתח, לדוגמה:
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, ואז עותק הגיבוי יהיה my_biggest_secrets.backup. לאחר מכן, המטמון משתנה (מפתחות מתווספים או נמחקים) ואם הכל מצליח, המטמון מאופס לקובץ. במקרים נדירים, כגון כשל בשרת, ייתכן שתראה את קובץ הגיבוי הזה. קובץ הגיבוי נמחק בפעם הבאה שהמפתחות נטענים (בדרך כלל לאחר הפעלה מחדש של השרת).
בעת שמירה או מחיקה של מפתח באחסון שרת, האחסון חייב להתחבר לשרת MySQL עם הפקודות "שלח את המפתח" / "בקש מחיקת מפתח".
בואו נחזור למהירות ההפעלה של השרת. בנוסף לעובדה שמהירות ההשקה מושפעת מהכספת עצמה, ישנה גם סוגיה של כמה מפתחות מהכספת צריך לאחזר בהפעלה. כמובן, זה חשוב במיוחד עבור אחסון שרת. בעת ההפעלה, השרת בודק איזה מפתח נדרש לטבלאות/מרחבי טבלאות מוצפנים ומבקש את המפתח מהאחסון. בשרת "נקי" עם הצפנת מפתח ראשי, חייב להיות מפתח ראשי אחד, אותו יש לאחזר מהאחסון. עם זאת, ייתכן שיידרש מספר גדול יותר של מפתחות, לדוגמה, כאשר שרת הגיבוי משחזר גיבוי מהשרת הראשי. במקרים כאלה, יש לספק סיבוב של המפתח הראשי. זה יכוסה ביתר פירוט במאמרים עתידיים, אם כי כאן אני רוצה לציין שלשרת המשתמש במספר מפתחות מאסטר עשוי להימשך מעט יותר זמן להתחיל, במיוחד כאשר משתמשים במאגר מפתחות בצד השרת.
עכשיו בואו נדבר קצת יותר על keyring_file. כשפיתחתי keyring_file, הייתי מודאג גם לגבי איך לבדוק שינויים ב-keyring_file בזמן שהשרת פועל. ב-5.7 הבדיקה בוצעה על סמך סטטיסטיקת קבצים, מה שלא היה פתרון אידיאלי, וב-8.0 הוחלף ב-SHA256 checksum.
בפעם הראשונה שאתה מפעיל keyring_file, מחושבים סטטיסטיקת קבצים וסכום בדיקה, אשר נזכרים על ידי השרת, והשינויים מוחלים רק אם הם תואמים. כאשר הקובץ משתנה, סכום הבדיקה מתעדכן.
כבר כיסינו שאלות רבות על כספות מפתח. עם זאת, ישנו נושא חשוב נוסף שלעיתים קרובות נשכח או לא מובן: שיתוף מפתחות בין שרתים.
מה שאני מתכוון? לכל שרת (לדוגמה, Percona Server) באשכול חייב להיות מיקום נפרד ב-Vault Server שבו Percona Server חייב לאחסן את המפתחות שלו. כל מפתח ראשי שנשמר באחסון מכיל את ה-GUID של שרת Percona בתוך המזהה שלו. למה זה חשוב? תאר לעצמך שיש לך רק שרת כספת אחד וכל שרתי Percona באשכול משתמשים באותו שרת כספת בודד. הבעיה נראית ברורה. אם כל שרתי Percona השתמשו במפתח ראשי ללא מזהים ייחודיים, כגון id = 1, id = 2 וכו', אז כל השרתים באשכול ישתמשו באותו מפתח ראשי. מה שה-GUID מספק הוא ההבחנה בין שרתים. אז למה לדבר על שיתוף מפתחות בין שרתים אם כבר קיים GUID ייחודי? יש תוסף נוסף - keyring_udf. עם תוסף זה, משתמש השרת שלך יכול לאחסן את המפתחות שלו בשרת הכספת. הבעיה מתרחשת כאשר משתמש יוצר מפתח בשרת1, למשל, ולאחר מכן מנסה ליצור מפתח עם אותו מזהה בשרת2, לדוגמה:
--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 לא צריכה להיכשל בשרת2? מעניין שאם תנסה לעשות את אותו הדבר בשרת אחד, תקבל שגיאה:
--server1:
select keyring_key_store('ROB_1','AES',"123456789012345");
1
select keyring_key_store('ROB_1','AES',"543210987654321");
0זה נכון, ROB_1 כבר קיים.
תחילה נדון בדוגמה השנייה. כפי שאמרנו קודם, keyring_vault או כל תוסף מחזיק מפתחות אחר מאחסן את כל מזהי המפתח בזיכרון. לכן, לאחר יצירת מפתח חדש, ROB_1 מתווסף לשרת1, ובנוסף לשליחת מפתח זה לכספת, המפתח מתווסף גם למטמון. כעת, כאשר אנו מנסים להוסיף את אותו מפתח פעם שנייה, keyring_vault בודק האם המפתח קיים במטמון וזורק שגיאה.
במקרה הראשון המצב שונה. לשרת1 ולשרת2 יש מטמונים נפרדים. לאחר הוספת ROB_1 למטמון המפתחות בשרת1 ולשרת הכספת, מטמון המפתחות בשרת2 אינו מסונכרן. אין מפתח ROB_2 במטמון בשרת1. כך, מפתח ROB_1 נכתב ל-keyring_key_store ולשרת Vault, שלמעשה מחליף (!) את הערך הקודם. כעת המפתח ROB_1 בשרת הכספת הוא 543210987654321. מעניין לציין ששרת הכספת אינו חוסם פעולות כאלה ומחליף בקלות את הערך הישן.
כעת אנו יכולים לראות מדוע חלוקת שרת בכספת יכולה להיות חשובה - כאשר אתה משתמש ב-keyring_udf וברצונך לאחסן מפתחות בכספת. כיצד להשיג את ההפרדה הזו בשרת 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 באמצעות נתיב זה, שרת הכספת יוצר אוטומטית ספריית "server1". עבור server2 הכל דומה. כאשר אתה מוחק את הסוד האחרון ב-mount_point/server1 או mount_point/server2, שרת הכספת מוחק גם את הספריות הללו. במקרה שאתה משתמש בהפרדת נתיב, עליך ליצור רק נקודת הרכבה אחת ולשנות את קבצי התצורה כך שהשרתים ישתמשו בנתיבים נפרדים. ניתן ליצור נקודת הרכבה באמצעות בקשת 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 כדי לעשות את אותו הדבר. אבל קל יותר להפוך את יצירת נקודת הרכבה לאוטומטית. אני מקווה שתמצא מידע זה שימושי ונתראה במאמרים הבאים בסדרה זו.
קרא עוד:
מקור: www.habr.com
