Coletar registros de auditoria da Oracle Cloud Infrastructure

Compatível com:

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

  1. Faça login no Console de Gerenciamento da AWS.
  2. Acesse S3 > Criar bucket.
  3. 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.
  4. Clique em Criar bucket.
  5. Salve o Nome e a Região do bucket para uso posterior.

Criar um usuário do IAM na AWS para o OCI Functions

  1. Faça login no Console de Gerenciamento da AWS.
  2. Acesse IAM > Usuários > Adicionar usuários.
  3. 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.
  4. Clique em Next: Permissions.
  5. Clique em Anexar políticas atuais diretamente.
  6. Pesquise e selecione a política AmazonS3FullAccess.
  7. Clique em Avançar: tags.
  8. Clique em PRÓXIMO: REVISAR.
  9. Clique em Criar usuário.
  10. 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

  1. Faça login no console do Oracle Cloud.
  2. Acesse Identidade e segurança > Vault.
  3. Se você não tiver um Vault, clique em Criar Vault.
  4. Informe os seguintes detalhes de configuração:
    • Criar no compartimento: selecione seu compartimento.
    • Nome: insira um nome (por exemplo, oci-functions-vault).
  5. Clique em Criar cofre.
  6. Depois que o Vault for criado, clique no nome dele para abrir.
  7. Em Chaves de criptografia principais, clique em Criar chave.
  8. 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
  9. Clique em Criar chave.

Criar secrets para credenciais da AWS

  1. No Vault, em Secrets, clique em Criar secret.
  2. 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.
  3. Clique em Criar secret.
  4. Copie e salve o OCID desse segredo (parece ocid1.vaultsecret.oc1...).
  5. Clique em Criar secret novamente para criar o segundo secret.
  6. 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.
  7. Clique em Criar secret.
  8. Copie e salve o OCID desse secret.

Criar um grupo dinâmico para funções do OCI

  1. Faça login no console do Oracle Cloud.
  2. Acesse Identidade e segurança > Identidade > Grupos dinâmicos.
  3. Clique em Criar grupo dinâmico.
  4. 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>'}
      
  5. Clique em Criar.

Criar uma política do IAM para acesso ao Vault

  1. Faça login no console do Oracle Cloud.
  2. Acesse Identidade e segurança > Identidade > Políticas.
  3. Selecione o compartimento em que você quer criar a política.
  4. Clique em Criar política.
  5. 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>
      
  6. Clique em Criar.

Criar um aplicativo de função do OCI

  1. Faça login no console do Oracle Cloud.
  2. Acesse Serviços para desenvolvedores > Aplicativos (em "Funções").
  3. Clique em Criar aplicativo.
  4. 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.
  5. Clique em Criar.

Criar e implantar a função do OCI

  1. No Oracle Cloud Console, clique no ícone do Cloud Shell no canto superior direito.
  2. Aguarde a inicialização do Cloud Shell.

Criar a função

  1. No Cloud Shell, crie um diretório para sua função:

    mkdir pushlogs
    cd pushlogs
    
  2. Inicialize uma nova função do Python:

    fn init --runtime python
    
  3. Isso cria três arquivos: func.py, func.yaml e requirements.txt.

Atualizar func.py

  • Substitua o conteúdo de func.py pelo 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_id pelo OCID secreto do cofre para a chave secreta da AWS.
    • Substitua access_key_id pelo OCID secreto do cofre real para a chave de acesso da AWS.
    • Substitua s3_bucket_name pelo nome real do bucket do S3.

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.txt por:

    fdk>=0.1.56
    boto3
    oci
    

Implantar a função

  1. Defina o contexto da função para usar seu aplicativo:

    fn use context <region-context>
    fn update context oracle.compartment-id <compartment-ocid>
    
  2. Implante a função:

    fn -v deploy --app oci-logs-to-s3-app
    
  3. Aguarde até que a implantação seja concluída. Você vai ver uma saída indicando que a função foi implantada com sucesso.

  4. 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

  1. Faça login no console do Oracle Cloud.
  2. Acesse Analytics e IA > Mensagens > Service Connector Hub.
  3. Selecione o compartimento em que você quer criar o conector de serviço.
  4. Clique em Criar conector de serviço.

Configurar detalhes do conector de serviço

  1. 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

  1. 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

  1. 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

  1. 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.
  2. Clique em Criar para criar o conector de serviço.

  3. 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

  1. Faça login no console do Oracle Cloud.
  2. Realize algumas ações que gerem registros de auditoria (por exemplo, crie ou modifique um recurso).
  3. Aguarde de 2 a 5 minutos para que os registros sejam processados.
  4. Faça login no Console de Gerenciamento da AWS.
  5. Acesse S3 > Buckets.
  6. Clique no seu bucket (por exemplo, oci-audit-logs-bucket).
  7. 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

  1. Faça login no Console de Gerenciamento da AWS.
  2. Acesse IAM > Usuários > Adicionar usuários.
  3. 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.
  4. Clique em Next: Permissions.
  5. Clique em Anexar políticas atuais diretamente.
  6. Pesquise e selecione a política AmazonS3ReadOnlyAccess.
  7. Clique em Avançar: tags.
  8. Clique em PRÓXIMO: REVISAR.
  9. Clique em Criar usuário.
  10. Clique em Fazer o download do arquivo CSV para salvar o ID da chave de acesso e a chave de acesso secreta.
  11. 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:

  1. Acesse IAM > Políticas > Criar política.
  2. Clique na guia JSON.
  3. 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-bucket pelo nome do seu bucket.
  4. Clique em Avançar: tags.

  5. Clique em PRÓXIMO: REVISAR.

  6. 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
  7. Clique em Criar política.

  8. Volte para IAM > Usuários e selecione o usuário chronicle-s3-reader.

  9. Clique em Adicionar permissões > Anexar políticas diretamente.

  10. Pesquise e selecione chronicle-s3-read-policy.

  11. Remova a política AmazonS3ReadOnlyAccess se você a adicionou antes.

  12. Clique em Adicionar permissões

Configurar um feed no Google SecOps para ingerir registros de auditoria do Oracle Cloud

  1. Acesse Configurações do SIEM > Feeds.
  2. Clique em Adicionar novo feed.
  3. Na próxima página, clique em Configurar um único feed.
  4. No campo Nome do feed, insira um nome para o feed (por exemplo, Oracle Cloud Audit Logs).
  5. Selecione Amazon S3 V2 como o Tipo de origem.
  6. Selecione Oracle Cloud Infrastructure como o Tipo de registro.
  7. Clique em Próxima.
  8. 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.
  9. Clique em Próxima.
  10. 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.