إشعار
يتطلب الوصول إلى هذه الصفحة تخويلاً. يمكنك محاولة تسجيل الدخول أو تغيير الدلائل.
يتطلب الوصول إلى هذه الصفحة تخويلاً. يمكنك محاولة تغيير الدلائل.
تعد تدقيقات قواعد البيانات جزءا مهما من متطلبات الامتثال لمنظمتك. من خلال مراقبة الأنشطة المستهدفة، يمكنك تحقيق مستوى الأمان الأساسي لديك. في قاعدة بيانات Azure لـ PostgreSQL مرن سيرفر، يمكنك إعداد التدقيقات باستخدام إضافة pgaudit PG، كما هو موضح في تسجيل التدقيق في قاعدة بيانات Azure لـ PostgreSQL.
أحد التحديات هو استخدام ميزة التدقيق إلى جانب مصادقة Microsoft Entra ID عند استخدام مجموعات Microsoft Entra ID وترغب في تدقيق إجراءات أعضاء المجموعة الفردية. يوجد هذا التحدي لأن أعضاء المجموعة يسجلون الدخول باستخدام رموز الوصول الشخصية لكنهم يستخدمون اسم المجموعة كاسم مستخدم.
لغة استعلام كوستو (KQL) هي لغة استعلام قوية تعتمد على خطوط الأنابيب وتقرأ فقط تتيح الاستعلام من سجلات خدمات أزور. يدعم KQL استعلام سجلات Azure لتحليل حجم كبير من البيانات بسرعة. في هذه المقالة، استخدم KQL للاستعلام عن سجلات Azure Postgres واستخراج معلومات مستخدم Microsoft Entra ID من سجلات التدقيق.
Prerequisites
- تمكين تسجيل التدقيق - تسجيل التدقيق في قاعدة بيانات Azure لـ PostgreSQL
- تمكين Azure سجلات Postgres لإرسالها إلى Azure Log Analytics - تكوين السجلات والوصول إليها
- ضبط المعامل
log_line_prefix: من شفرة المعلمات، اضبط لlog_line_prefixلتضمين الهروبuser=%u,db=%d,session=%c,sess_time=%sفي نفس التسلسل للحصول على النتائج المرغوبة.- قبل:
log_line_prefix=%t-%c- - بعد:
log_line_prefix=%t-%c-user=%u,db=%d,session=%c,sess_time=%s
- قبل:
استفسار Kusto
استعلام كوستو التالي يطرح الاستفسار عن AzureDiagnostics المرتين.
يجد الاستعلام الفرعي الأول جميع الأسطر التي تحتوي على السلسلة Microsoft Entra ID connection authorized ويستخرج من PrincipalName هذه الخطوط اللوغاريتية، إلى جانب .SessionId
الاستعلام الفرعي الثاني يجد جميع سجلات التدقيق.
وأخيرا، يتم ربط هاتين الاستعلامات الفرعيتين على .SessionId
let lookbackTime = ago(3d);
let opindex = 3;
let startIndex = toscalar(range thirdIndex from opindex to opindex step 1
| project thirdIndex);
AzureDiagnostics
| where ResourceProvider == 'MICROSOFT.DBFORPOSTGRESQL'
| where TimeGenerated >= lookbackTime
| where Message contains 'Microsoft Entra ID connection authorized'
| extend SessionId = tostring(split(tostring(split(Message, 'session=')[-1]), ',sess_time')[-2])
| extend UPN = iff(Message contains 'UPN',tostring(split(tostring(split(Message, 'UPN=')[-1]), 'oid=')[-2]), '')
| extend appId = iff(Message contains 'appid', tostring(split(tostring(split(Message, 'appid=')[-1]), 'oid=')[-2]), '')
| extend PrincipalName = strcat(UPN, appId)
| project SessionId, PrincipalName
| join kind=leftouter
(
AzureDiagnostics
| where ResourceProvider == 'MICROSOFT.DBFORPOSTGRESQL'
| where TimeGenerated >= lookbackTime
| where Message contains 'AUDIT: SESSION'
| extend RoleName = tostring(split(tostring(split(Message, 'user=')[-1]), ',db')[-2])
| where RoleName !in ('azuresu', '[unknown]', 'postgres', '')
| extend SessionId = tostring(split(tostring(split(Message, 'session=')[-1]), ',sess_time')[-2])
| extend SubMessage = tostring(split(Message, 'SESSION,')[-1])
| extend splitArray = split(SubMessage, ',')
| extend SqlQueryP1 = tostring(split(tostring(split(Message, ',,,')[-1]), ',<')[-2])
| extend SqlQueryP2 = replace_string(tostring(split(SqlQueryP1, ',\"')[-1]), '"', '')
| extend SqlQueryP3 = tostring(split(Message, ',,,')[1])
| extend OperationType = tostring(splitArray[startIndex])
| extend SqlQuery = trim('"', case(OperationType == 'EXECUTE', SqlQueryP2, SqlQueryP1 == '', SqlQueryP3, SqlQueryP1))
)
on $left.SessionId == $right.SessionId
| project TimeGenerated, PrincipalName, RoleName, OperationType, SqlQuery
أمثلة على النتائج
الجدول الناتج يبدو كالتالي:
| TimeGenerated | اسم المدير | RoleName | OperationType | SqlQuery |
|---|---|---|---|---|
| 2025-12-12T16:25:05.104Z | user@example.com | ExampleGroupName | SELECT | اختر * من pg_seclabels؛ |
| 2025-12-12T16:25:04.000Z | user@example.com | user@example.com | SELECT | اختر * من pg_seclabels؛ |
إذا قام المستخدم بتسجيل الدخول كدور جماعي، PrincipalName فإن الأعمدة وتظهر RoleName قيما مختلفة، كما في الصف الأول من المثال.
تحدد القيمة PrincipalName المستخدم الذي سجل الدخول. تحدد القيمة RoleName الدور في PostgreSQL الذي يصل إليه المستخدم بعد تسجيل الدخول.
PrincipalName إما اسم المستخدم الرئيسي (UPN) أو AppId حسب ما إذا كان العميل الرئيسي أو الخدمة يسجل دخول.