Coletar registros de auditoria da Oracle Cloud Infrastructure
Este documento explica como ingerir registros de auditoria do Oracle Cloud Infrastructure no Google Security Operations usando o Amazon S3.
Antes de começar
Verifique se você atende os seguintes pré-requisitos:
- Instância do Google SecOps.
- Uma conta da Oracle Cloud Infrastructure com permissões para criar e gerenciar:
- Hub de conectores de serviço
- Oracle Functions
- Vaults e secrets
- Grupos dinâmicos e políticas do IAM
- Logging
- Conta da AWS com permissões para criar e gerenciar:
- Buckets do S3
- Usuários e políticas do IAM
Criar um bucket do Amazon S3
- Faça login no Console de Gerenciamento da AWS.
- Acesse S3 > Criar bucket.
- Informe os seguintes detalhes de configuração:
- Nome do bucket: insira um nome exclusivo, por exemplo,
oci-audit-logs-bucket. - Região da AWS: selecione uma região (por exemplo,
us-east-1). - Mantenha as configurações padrão para as outras opções.
- Nome do bucket: insira um nome exclusivo, por exemplo,
- Clique em Criar bucket.
- Salve o Nome e a Região do bucket para uso posterior.
Criar um usuário do IAM na AWS para o OCI Functions
- Faça login no Console de Gerenciamento da AWS.
- Acesse IAM > Usuários > Adicionar usuários.
- Informe os seguintes detalhes de configuração:
- Nome de usuário: insira um nome de usuário (por exemplo,
oci-functions-s3-user). - Tipo de acesso: selecione Chave de acesso - Acesso programático.
- Nome de usuário: insira um nome de usuário (por exemplo,
- Clique em Next: Permissions.
- Clique em Anexar políticas atuais diretamente.
- Pesquise e selecione a política AmazonS3FullAccess.
- Clique em Avançar: tags.
- Clique em PRÓXIMO: REVISAR.
- Clique em Criar usuário.
- Importante: na página de sucesso, copie e salve as seguintes credenciais:
- ID da chave de acesso
- Chave de acesso secreta
Armazenar credenciais da AWS no OCI Vault
Para armazenar credenciais da AWS com segurança, use o Oracle Cloud Infrastructure Vault em vez de codificá-las no código da função.
Criar um cofre e uma chave de criptografia principal
- Faça login no console do Oracle Cloud.
- Acesse Identidade e segurança > Vault.
- Se você não tiver um Vault, clique em Criar Vault.
- Informe os seguintes detalhes de configuração:
- Criar no compartimento: selecione seu compartimento.
- Nome: insira um nome (por exemplo,
oci-functions-vault).
- Clique em Criar cofre.
- Depois que o Vault for criado, clique no nome dele para abrir.
- Em Chaves de criptografia principais, clique em Criar chave.
- Informe os seguintes detalhes de configuração:
- Modo de proteção: software
- Nome: insira um nome (por exemplo,
oci-functions-key). - Formato da chave: algoritmo: AES
- Formato da chave: comprimento: 256 bits
- Clique em Criar chave.
Criar secrets para credenciais da AWS
- No Vault, em Secrets, clique em Criar secret.
- Informe os seguintes detalhes de configuração para a chave de acesso da AWS:
- Criar no compartimento: selecione seu compartimento.
- Nome:
aws-access-key - Descrição: chave de acesso da AWS para S3
- Chave de criptografia: selecione a chave de criptografia principal que você criou.
- Conteúdo do tipo de secret: texto simples
- Conteúdo secreto: cole o ID da chave de acesso da AWS.
- Clique em Criar secret.
- Copie e salve o OCID desse segredo (parece
ocid1.vaultsecret.oc1...). - Clique em Criar secret novamente para criar o segundo secret.
- Informe os seguintes detalhes de configuração para a chave secreta da AWS:
- Criar no compartimento: selecione seu compartimento.
- Nome:
aws-secret-key - Descrição: chave secreta da AWS para o S3
- Chave de criptografia: selecione a mesma chave de criptografia principal.
- Conteúdo do tipo de secret: texto simples
- Conteúdo secreto: cole sua chave de acesso secreta da AWS.
- Clique em Criar secret.
- Copie e salve o OCID desse secret.
Criar um grupo dinâmico para funções do OCI
- Faça login no console do Oracle Cloud.
- Acesse Identidade e segurança > Identidade > Grupos dinâmicos.
- Clique em Criar grupo dinâmico.
Informe os seguintes detalhes de configuração:
- Nome:
oci-functions-dynamic-group - Descrição: grupo dinâmico para funções do OCI acessar segredos do Vault
Regras de correspondência: insira a seguinte regra (substitua
<your_compartment_ocid>pelo OCID do seu compartimento):ALL {resource.type = 'fnfunc', resource.compartment.id = '<your_compartment_ocid>'}
- Nome:
Clique em Criar.
Criar uma política do IAM para acesso ao Vault
- Faça login no console do Oracle Cloud.
- Acesse Identidade e segurança > Identidade > Políticas.
- Selecione o compartimento em que você quer criar a política.
- Clique em Criar política.
Informe os seguintes detalhes de configuração:
- Nome:
oci-functions-vault-access-policy - Descrição: permite que as funções do OCI leiam secrets do Vault.
- Criador de políticas: ative a opção Mostrar editor manual.
Instruções da política: insira o seguinte (substitua
<compartment_name>pelo nome do compartimento):allow dynamic-group oci-functions-dynamic-group to manage secret-family in compartment <compartment_name>
- Nome:
Clique em Criar.
Criar um aplicativo de função do OCI
- Faça login no console do Oracle Cloud.
- Acesse Serviços para desenvolvedores > Aplicativos (em "Funções").
- Clique em Criar aplicativo.
- Informe os seguintes detalhes de configuração:
- Nome: insira um nome (por exemplo,
oci-logs-to-s3-app). - VCN: selecione uma VCN no seu compartimento.
- Sub-redes: selecione uma ou mais sub-redes.
- Nome: insira um nome (por exemplo,
- Clique em Criar.
Criar e implantar a função do OCI
Configurar o Cloud Shell (recomendado)
- No Oracle Cloud Console, clique no ícone do Cloud Shell no canto superior direito.
- Aguarde a inicialização do Cloud Shell.
Criar a função
No Cloud Shell, crie um diretório para sua função:
mkdir pushlogs cd pushlogsInicialize uma nova função do Python:
fn init --runtime pythonIsso cria três arquivos:
func.py,func.yamlerequirements.txt.
Atualizar func.py
Substitua o conteúdo de
func.pypelo seguinte código:import io import json import logging import boto3 import oci import base64 import os from fdk import response def handler(ctx, data: io.BytesIO = None): """ OCI Function to push audit logs from OCI Logging to AWS S3 """ try: # Parse incoming log data from Service Connector funDataStr = data.read().decode('utf-8') funData = json.loads(funDataStr) logging.getLogger().info(f"Received {len(funData)} log entries") # Replace these with your actual OCI Vault secret OCIDs secret_key_id = "ocid1.vaultsecret.oc1..<your_secret_key_ocid>" access_key_id = "ocid1.vaultsecret.oc1..<your_access_key_ocid>" # Replace with your S3 bucket name s3_bucket_name = "oci-audit-logs-bucket" # Use Resource Principals for OCI authentication signer = oci.auth.signers.get_resource_principals_signer() secret_client = oci.secrets.SecretsClient({}, signer=signer) def read_secret_value(secret_client, secret_id): """Retrieve and decode secret value from OCI Vault""" response = secret_client.get_secret_bundle(secret_id) base64_secret_content = response.data.secret_bundle_content.content base64_secret_bytes = base64_secret_content.encode('ascii') base64_message_bytes = base64.b64decode(base64_secret_bytes) secret_content = base64_message_bytes.decode('ascii') return secret_content # Retrieve AWS credentials from OCI Vault awsaccesskey = read_secret_value(secret_client, access_key_id) awssecretkey = read_secret_value(secret_client, secret_key_id) # Initialize boto3 session with AWS credentials session = boto3.Session( aws_access_key_id=awsaccesskey, aws_secret_access_key=awssecretkey ) s3 = session.resource('s3') # Process each log entry for i in range(0, len(funData)): # Use timestamp as filename filename = funData[i].get('time', f'log_{i}') # Remove special characters from filename filename = filename.replace(':', '-').replace('.', '-') logging.getLogger().info(f"Processing log entry: {filename}") # Write log entry to temporary file temp_file = f'/tmp/{filename}.json' with open(temp_file, 'w', encoding='utf-8') as f: json.dump(funData[i], f, ensure_ascii=False, indent=4) # Upload to S3 s3_key = f'{filename}.json' s3.meta.client.upload_file( Filename=temp_file, Bucket=s3_bucket_name, Key=s3_key ) logging.getLogger().info(f"Uploaded {s3_key} to S3 bucket {s3_bucket_name}") # Clean up temporary file os.remove(temp_file) return response.Response( ctx, response_data=json.dumps({ "status": "success", "processed_logs": len(funData) }), headers={"Content-Type": "application/json"} ) except Exception as e: logging.getLogger().error(f"Error processing logs: {str(e)}") return response.Response( ctx, response_data=json.dumps({ "status": "error", "message": str(e) }), headers={"Content-Type": "application/json"}, status_code=500 )- Substitua
secret_key_idpelo OCID secreto do cofre para a chave secreta da AWS. - Substitua
access_key_idpelo OCID secreto do cofre real para a chave de acesso da AWS. - Substitua
s3_bucket_namepelo nome real do bucket do S3.
- Substitua
Atualizar func.yaml
Substitua o conteúdo de func.yaml por:
schema_version: 20180708
name: pushlogs
version: 0.0.1
runtime: python
build_image: fnproject/python:3.9-dev
run_image: fnproject/python:3.9
entrypoint: /python/bin/fdk /function/func.py handler
memory: 256
Atualizar requirements.txt
Substitua o conteúdo de
requirements.txtpor:fdk>=0.1.56 boto3 oci
Implantar a função
Defina o contexto da função para usar seu aplicativo:
fn use context <region-context> fn update context oracle.compartment-id <compartment-ocid>Implante a função:
fn -v deploy --app oci-logs-to-s3-appAguarde até que a implantação seja concluída. Você vai ver uma saída indicando que a função foi implantada com sucesso.
Verifique se a função foi criada:
fn list functions oci-logs-to-s3-app
Criar um conector de serviço para enviar registros de auditoria do OCI à função
- Faça login no console do Oracle Cloud.
- Acesse Analytics e IA > Mensagens > Service Connector Hub.
- Selecione o compartimento em que você quer criar o conector de serviço.
- Clique em Criar conector de serviço.
Configurar detalhes do conector de serviço
- Informe os seguintes detalhes de configuração:
Informações do conector de serviço:
* Nome do conector: insira um nome descritivo (por exemplo, audit-logs-to-s3-connector).
* Descrição: descrição opcional (por exemplo, "Encaminhar registros de auditoria do OCI para o AWS S3").
* Compartimento de recursos: selecione o compartimento.
Configurar origem
- Em Configurar origem:
- Origem: selecione Logging.
- Compartimento: selecione o compartimento que contém os registros de auditoria.
- Grupo de registros: selecione
_Audit(esse é o grupo de registros padrão para registros de auditoria). - Registros: clique em + Outro registro.
- Selecione o registro de auditoria do seu compartimento (por exemplo,
_Audit_Include_Subcompartment).
Configurar destino
- Em Configurar destino:
- Destino: selecione Funções.
- Compartimento: selecione o compartimento que contém o aplicativo de função.
- Aplicativo de função: selecione
oci-logs-to-s3-app(o aplicativo que você criou anteriormente). - Função: selecione
pushlogs(a função que você implantou).
Configurar política
Em Configurar política:
- Revise as instruções de política do IAM necessárias que aparecem.
- Clique em Criar para criar as políticas necessárias automaticamente.
Clique em Criar para criar o conector de serviço.
Aguarde a criação e ativação do conector de serviço. O status muda para Ativo.
Verificar se os registros estão sendo enviados para o AWS S3
- Faça login no console do Oracle Cloud.
- Realize algumas ações que gerem registros de auditoria (por exemplo, crie ou modifique um recurso).
- Aguarde de 2 a 5 minutos para que os registros sejam processados.
- Faça login no Console de Gerenciamento da AWS.
- Acesse S3 > Buckets.
- Clique no seu bucket (por exemplo,
oci-audit-logs-bucket). - Verifique se os arquivos de registro JSON estão aparecendo no bucket.
Configurar o bucket do AWS S3 e o IAM para o Google SecOps
Criar um usuário do IAM para o Chronicle
- Faça login no Console de Gerenciamento da AWS.
- Acesse IAM > Usuários > Adicionar usuários.
- Informe os seguintes detalhes de configuração:
- Nome de usuário: insira
chronicle-s3-reader. - Tipo de acesso: selecione Chave de acesso - Acesso programático.
- Nome de usuário: insira
- Clique em Next: Permissions.
- Clique em Anexar políticas atuais diretamente.
- Pesquise e selecione a política AmazonS3ReadOnlyAccess.
- Clique em Avançar: tags.
- Clique em PRÓXIMO: REVISAR.
- Clique em Criar usuário.
- Clique em Fazer o download do arquivo CSV para salvar o ID da chave de acesso e a chave de acesso secreta.
- Clique em Fechar.
Opcional: crie uma política personalizada do IAM para acesso com privilégio mínimo
Se você quiser restringir o acesso apenas ao bucket específico:
- Acesse IAM > Políticas > Criar política.
- Clique na guia JSON.
Insira a seguinte política:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "s3:GetObject", "s3:ListBucket" ], "Resource": [ "arn:aws:s3:::oci-audit-logs-bucket", "arn:aws:s3:::oci-audit-logs-bucket/*" ] } ] }- Substitua
oci-audit-logs-bucketpelo nome do seu bucket.
- Substitua
Clique em Avançar: tags.
Clique em PRÓXIMO: REVISAR.
Informe os seguintes detalhes de configuração:
- Nome:
chronicle-s3-read-policy - Descrição: acesso somente leitura ao bucket de registros de auditoria do OCI
- Nome:
Clique em Criar política.
Volte para IAM > Usuários e selecione o usuário
chronicle-s3-reader.Clique em Adicionar permissões > Anexar políticas diretamente.
Pesquise e selecione
chronicle-s3-read-policy.Remova a política AmazonS3ReadOnlyAccess se você a adicionou antes.
Clique em Adicionar permissões
Configurar um feed no Google SecOps para ingerir registros de auditoria do Oracle Cloud
- Acesse Configurações do SIEM > Feeds.
- Clique em Adicionar novo feed.
- Na próxima página, clique em Configurar um único feed.
- No campo Nome do feed, insira um nome para o feed (por exemplo,
Oracle Cloud Audit Logs). - Selecione Amazon S3 V2 como o Tipo de origem.
- Selecione Oracle Cloud Infrastructure como o Tipo de registro.
- Clique em Próxima.
- Especifique valores para os seguintes parâmetros de entrada:
- URI do S3: insira o URI do bucket do S3 (por exemplo,
s3://oci-audit-logs-bucket/). - Opção de exclusão da fonte: selecione a opção de exclusão de acordo com sua preferência:
- Nunca: recomendado para testes e configuração inicial.
- Excluir arquivos transferidos: exclui arquivos após a ingestão bem-sucedida. Use essa opção em produção para gerenciar os custos de armazenamento.
- Idade máxima do arquivo: inclui arquivos modificados no último número de dias. O padrão é de 180 dias.
- ID da chave de acesso: insira o ID da chave de acesso do usuário do IAM do Chronicle que você criou.
- Chave de acesso secreta: insira a chave de acesso secreta do usuário do IAM do Chronicle que você criou.
- Namespace do recurso: o namespace do recurso.
- Rótulos de ingestão: o rótulo a ser aplicado aos eventos deste feed.
- URI do S3: insira o URI do bucket do S3 (por exemplo,
- Clique em Próxima.
- Revise a nova configuração do feed na tela Finalizar e clique em Enviar.
Tabela de mapeamento do UDM
| Campo de registro | Mapeamento do UDM | Lógica |
|---|---|---|
data.request.headers.authorization.0 |
event.idm.read_only_udm.additional.fields |
Valor extraído de data.request.headers.authorization.0 e adicionado como um par de chave-valor em que a chave é "Request Headers Authorization". |
data.compartmentId |
event.idm.read_only_udm.additional.fields |
Valor extraído de data.compartmentId e adicionado como um par de chave-valor em que a chave é "compartmentId". |
data.compartmentName |
event.idm.read_only_udm.additional.fields |
Valor extraído de data.compartmentName e adicionado como um par de chave-valor em que a chave é "compartmentName". |
data.response.headers.Content-Length.0 |
event.idm.read_only_udm.additional.fields |
Valor extraído de data.response.headers.Content-Length.0 e adicionado como um par de chave-valor em que a chave é "Response Headers Content-Length". |
data.response.headers.Content-Type.0 |
event.idm.read_only_udm.additional.fields |
Valor extraído de data.response.headers.Content-Type.0 e adicionado como um par de chave-valor em que a chave é "Content-Type dos cabeçalhos de resposta". |
data.eventGroupingId |
event.idm.read_only_udm.additional.fields |
Valor extraído de data.eventGroupingId e adicionado como um par de chave-valor em que a chave é "eventGroupingId". |
oracle.tenantid, data.identity.tenantId |
event.idm.read_only_udm.additional.fields |
O valor é extraído de oracle.tenantid, se presente, ou de data.identity.tenantId. Ele é adicionado como um par de chave-valor em que a chave é "tenantId". |
data.message |
event.idm.read_only_udm.metadata.description |
Valor extraído de data.message. |
time |
event.idm.read_only_udm.metadata.event_timestamp |
Valor extraído de time e analisado como um carimbo de data/hora ISO8601. |
event.idm.read_only_udm.metadata.event_type |
Definido como GENERIC_EVENT por padrão. Definido como NETWORK_CONNECTION se um principal (IP ou nome do host) e um IP de destino estiverem presentes. Definido como STATUS_UPDATE se apenas um principal estiver presente. |
|
time |
event.idm.read_only_udm.metadata.ingested_timestamp |
Se oracle.ingestedtime não estiver vazio, o valor será extraído do campo time e analisado como um carimbo de data/hora ISO8601. |
oracle.tenantid |
event.idm.read_only_udm.metadata.product_deployment_id |
Valor extraído de oracle.tenantid. |
type |
event.idm.read_only_udm.metadata.product_event_type |
Valor extraído de type. |
oracle.logid |
event.idm.read_only_udm.metadata.product_log_id |
Valor extraído de oracle.logid. |
specversion |
event.idm.read_only_udm.metadata.product_version |
Valor extraído de specversion. |
data.request.action |
event.idm.read_only_udm.network.http.method |
Valor extraído de data.request.action. |
data.identity.userAgent |
event.idm.read_only_udm.network.http.parsed_user_agent |
Valor extraído de data.identity.userAgent e analisado. |
data.response.status |
event.idm.read_only_udm.network.http.response_code |
Valor extraído de data.response.status e convertido em um número inteiro. |
data.protocol |
event.idm.read_only_udm.network.ip_protocol |
O valor numérico de data.protocol é convertido na representação de string dele (por exemplo, 6 se torna "TCP", 17 se torna "UDP"). |
data.bytesOut |
event.idm.read_only_udm.network.sent_bytes |
Valor extraído de data.bytesOut e convertido em um número inteiro sem sinal. |
data.packets |
event.idm.read_only_udm.network.sent_packets |
Valor extraído de data.packets e convertido em um número inteiro. |
data.identity.consoleSessionId |
event.idm.read_only_udm.network.session_id |
Valor extraído de data.identity.consoleSessionId. |
id |
event.idm.read_only_udm.principal.asset.product_object_id |
Valor extraído de id. |
source |
event.idm.read_only_udm.principal.hostname |
Valor extraído de source. |
data.sourceAddress, data.identity.ipAddress |
event.idm.read_only_udm.principal.ip |
Os valores de data.sourceAddress e data.identity.ipAddress são mesclados nesse campo. |
data.sourcePort |
event.idm.read_only_udm.principal.port |
Valor extraído de data.sourcePort e convertido em um número inteiro. |
data.request.headers.X-Forwarded-For.0 |
event.idm.read_only_udm.principal.resource.attribute.labels |
Valor extraído de data.request.headers.X-Forwarded-For.0 e adicionado como um par de chave-valor em que a chave é "x forward". |
oracle.compartmentid |
event.idm.read_only_udm.principal.resource.attribute.labels |
Valor extraído de oracle.compartmentid e adicionado como um par de chave-valor em que a chave é "compartmentid". |
oracle.loggroupid |
event.idm.read_only_udm.principal.resource.attribute.labels |
Valor extraído de oracle.loggroupid e adicionado como um par de chave-valor em que a chave é "loggroupid". |
oracle.vniccompartmentocid |
event.idm.read_only_udm.principal.resource.attribute.labels |
Valor extraído de oracle.vniccompartmentocid e adicionado como um par de chave-valor em que a chave é "vniccompartmentocid". |
oracle.vnicocid |
event.idm.read_only_udm.principal.resource.attribute.labels |
Valor extraído de oracle.vnicocid e adicionado como um par de chave-valor em que a chave é "vnicocid". |
oracle.vnicsubnetocid |
event.idm.read_only_udm.principal.resource.attribute.labels |
Valor extraído de oracle.vnicsubnetocid e adicionado como um par de chave-valor em que a chave é "vnicsubnetocid". |
data.flowid |
event.idm.read_only_udm.principal.resource.product_object_id |
Valor extraído de data.flowid. |
data.identity.credentials |
event.idm.read_only_udm.principal.user.attribute.labels |
Valor extraído de data.identity.credentials e adicionado como um par de chave-valor em que a chave é "credentials". |
data.identity.principalName |
event.idm.read_only_udm.principal.user.user_display_name |
Valor extraído de data.identity.principalName. |
data.identity.principalId |
event.idm.read_only_udm.principal.user.userid |
Valor extraído de data.identity.principalId. |
data.action |
event.idm.read_only_udm.security_result.action |
Definido como UNKNOWN_ACTION por padrão. Se data.action for "REJECT", o valor será definido como BLOCK. Se data.action for "ACCEPT", isso será definido como ALLOW. |
data.endTime |
event.idm.read_only_udm.security_result.detection_fields |
Valor extraído de data.endTime e adicionado como um par de chave-valor em que a chave é "endTime". |
data.startTime |
event.idm.read_only_udm.security_result.detection_fields |
Valor extraído de data.startTime e adicionado como um par de chave-valor em que a chave é "startTime". |
data.status |
event.idm.read_only_udm.security_result.detection_fields |
Valor extraído de data.status e adicionado como um par de chave-valor em que a chave é "status". |
data.version |
event.idm.read_only_udm.security_result.detection_fields |
Valor extraído de data.version e adicionado como um par de chave-valor em que a chave é "version". |
data.destinationAddress |
event.idm.read_only_udm.target.ip |
Valor extraído de data.destinationAddress. |
data.destinationPort |
event.idm.read_only_udm.target.port |
Valor extraído de data.destinationPort e convertido em um número inteiro. |
data.request.path |
event.idm.read_only_udm.target.url |
Valor extraído de data.request.path. |
event.idm.read_only_udm.metadata.product_name |
Defina como "ORACLE CLOUD AUDIT". | |
event.idm.read_only_udm.metadata.vendor_name |
Defina como "ORACLE". |
Precisa de mais ajuda? Receba respostas de membros da comunidade e profissionais do Google SecOps.