Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
I controlli del database sono un componente importante dei requisiti di conformità dell'organizzazione. Monitorando le attività mirate, è possibile ottenere la baseline di sicurezza. Nel servizio flessibile di Azure Database per PostgreSQL, è possibile configurare la registrazione degli audit usando l'estensione pgaudit, come descritto in Audit logging in Database di Azure per PostgreSQL.
Una sfida consiste nell'usare la funzionalità di controllo insieme all'autenticazione microsoft Entra ID quando si usano i gruppi di ID Microsoft Entra e si vogliono controllare le azioni dei singoli membri del gruppo. Questo problema si verifica perché i membri del gruppo accedono tramite i loro token di accesso personali, ma usano il nome del gruppo come nome utente.
Il linguaggio di query Kusto (KQL) è un potente linguaggio di query basato su pipeline e di sola lettura che consente di eseguire query sui log del servizio di Azure. KQL supporta l'esecuzione di query sui log di Azure per analizzare rapidamente un volume elevato di dati. Per questo articolo, usare KQL per eseguire query sui log di Azure Postgres ed estrarre le informazioni utente dell'ID Entra di Microsoft dai log di controllo.
Prerequisiti
- Abilitare la registrazione di controllo - Registrazione di controllo in Database di Azure per PostgreSQL
- Abilitare l'invio dei log di Azure Postgres ad Log Analytics di Azure - Configurare e accedere ai log
- Modificare il parametro
log_line_prefix: dal pannello Parametri, impostarelog_line_prefixin modo da includere i caratteri di escapeuser=%u,db=%d,session=%c,sess_time=%snella stessa sequenza per ottenere i risultati desiderati.- Prima:
log_line_prefix=%t-%c- - Dopo:
log_line_prefix=%t-%c-user=%u,db=%d,session=%c,sess_time=%s
- Prima:
Query Kusto
La query seguente in Kusto esegue due volte una query su AzureDiagnostics.
La prima sottoquery trova tutte le righe che contengono la stringa Microsoft Entra ID connection authorized ed estrae il PrincipalName da queste righe di log, insieme a SessionId.
La seconda sottoquery trova tutti i log di controllo.
Infine, queste due sottoquery vengono unite tramite il join su 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
Risultati di esempio
La tabella risultante è simile alla seguente:
| TimeGenerated | Nome principale | NomeRuolo | Tipo di Operazione | SqlQuery |
|---|---|---|---|---|
| 2025-12-12T16:25:05.104Z | user@example.com | NomeGruppoEsempio | SELECT | selezionare * da pg_seclabels; |
| 2025-12-12T16:25:04.000Z | user@example.com | user@example.com | SELECT | selezionare * da pg_seclabels; |
Se l'utente accede come ruolo di gruppo, le PrincipalName colonne e RoleName mostrano valori diversi, ad esempio nella prima riga dell'esempio.
Il PrincipalName valore identifica l'utente che ha eseguito l'accesso. Il RoleName valore identifica il ruolo in PostgreSQL a cui l'utente accede dopo l'accesso.
PrincipalName è il Nome dell'entità utente (UPN) o AppId a seconda che l'entità utente o l'entità servizio siano state registrate.