Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
As auditorias de banco de dados são um componente importante dos requisitos de conformidade da sua organização. Monitorando atividades direcionadas, você pode obter sua linha de base de segurança. No servidor flexível do Banco de Dados do Azure para PostgreSQL, você pode configurar auditorias usando a extensão pg pgaudit, conforme descrito no log de auditoria no Banco de Dados do Azure para PostgreSQL.
Um desafio é usar o recurso de auditoria ao lado da autenticação da ID do Microsoft Entra quando você estiver usando grupos de ID do Microsoft Entra e quiser auditar as ações de membros individuais do grupo. Esse desafio existe porque os membros do grupo se conectam usando seus tokens de acesso pessoal, mas usam o nome de grupo como nome de usuário.
A KQL (Linguagem de Consulta Kusto) é uma linguagem de consulta baseada em pipeline e somente leitura que permite consultar logs de serviço do Azure. O KQL dá suporte à consulta de logs do Azure para analisar rapidamente um alto volume de dados. Para este artigo, use KQL para consultar os logs do Azure PostgreSQL e extrair informações do usuário do Microsoft Entra ID dos logs de auditoria.
Pré-requisitos
- Habilitar log de auditoria – Log de auditoria no Banco de Dados do Azure para PostgreSQL
- Habilitar o envio dos logs do Azure Postgres para o Azure Log Analytics - Configurar e acessar logs
- Ajuste o parâmetro
log_line_prefix: no painel Parâmetros, definalog_line_prefixpara incluir as sequências de escapeuser=%u,db=%d,session=%c,sess_time=%sna mesma sequência para obter os resultados desejados.- Antes:
log_line_prefix=%t-%c- - Depois:
log_line_prefix=%t-%c-user=%u,db=%d,session=%c,sess_time=%s
- Antes:
Consulta Kusto
A consulta Kusto a seguir consulta as AzureDiagnostics duas vezes.
A primeira subconsulta localiza todas as linhas que contêm a cadeia de caracteres Microsoft Entra ID connection authorized e extrai o PrincipalName destas linhas de log, junto com o SessionId.
A segunda subconsulta localiza todos os logs de auditoria.
Por fim, essas duas subconsultas são unidas no 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
Resultados de exemplo
A tabela resultante tem esta aparência:
| TimeGenerated | Nome principal | Nome da Função | TipoDeOperação | SqlQuery |
|---|---|---|---|---|
| 2025-12-12T16:25:05.104Z | user@example.com | NomeDoGrupoExemplo | SELECT | select * from pg_seclabels; |
| 2025-12-12T16:25:04.000Z | user@example.com | user@example.com | SELECT | select * from pg_seclabels; |
Se o usuário entrar como uma função de grupo, as colunas PrincipalName e RoleName mostrarão valores diferentes, como na primeira linha do exemplo.
O PrincipalName valor identifica o usuário que entrou. O RoleName valor identifica a função no PostgreSQL que o usuário acessa após entrar.
PrincipalName é o UPN (Nome da Entidade de Usuário) ou o AppId, dependendo se a entidade de usuário ou a entidade de serviço for conectada.