Esse código do analisador do Logstash primeiro extrai campos como IP de origem, usuário, método e protocolo de aplicativo de mensagens de registro brutas usando padrões grok. Em seguida, ele mapeia campos específicos dos dados de registro brutos para os campos correspondentes no Modelo de Dados Unificado (UDM, na sigla em inglês), realiza conversões de tipo de dados e enriquece os dados com rótulos e metadados adicionais antes de estruturar a saída no formato UDM desejado.
Antes de começar
Verifique se você atende aos seguintes pré-requisitos:
Instância do Google Security Operations.
Acesso privilegiado ao Google Cloud.
Acesso privilegiado ao Qualys.
Ative as APIs obrigatórias:
Faça login no console do Google Cloud .
Acesse APIs e serviços>Biblioteca.
Procure e ative as seguintes APIs:
API Cloud Functions
API Cloud Scheduler
Cloud Pub/Sub (necessário para o Cloud Scheduler invocar funções)
Nome: insira um nome exclusivo que atenda aos requisitos de nome de bucket (por exemplo, qualys-asset-bucket).
Escolha onde armazenar seus dados: selecione um local.
Escolha uma classe de armazenamento para seus dados: selecione uma classe de armazenamento padrão para o bucket ou escolha Classe automática para gerenciamento automático da classe de armazenamento.
Escolha como controlar o acesso a objetos: selecione não para aplicar a prevenção de acesso público e escolha um modelo de controle de acesso para os objetos do bucket.
Classe de armazenamento: escolha com base nas suas necessidades (por exemplo, Padrão).
Clique em Criar.
Criar uma conta de serviço do Google Cloud
Faça login no console do Google Cloud .
Acesse IAM e administrador>Contas de serviço.
Crie uma nova conta de serviço.
Dê um nome descritivo a ele (por exemplo, qualys-user).
Conceda à conta de serviço o papel Administrador de objetos do Storage no bucket do GCS criado na etapa anterior.
Conceda à conta de serviço o papel Invocador do Cloud Functions.
Role a tela para ver essas informações em "Central de operações de segurança (SOC)".
Copie o URL da API do Qualys.
Configurar a função do Cloud
Acesse Cloud Functions no console Google Cloud .
Clique em Criar função.
Configure a função:
Nome: insira um nome para sua função (por exemplo, fetch-qualys-cm-alerts).
Região: selecione uma região próxima ao seu bucket.
Ambiente de execução: Python 3.10 (ou o ambiente de execução de sua preferência).
Gatilho: escolha o gatilho HTTP, se necessário, ou o Cloud Pub/Sub para execução programada.
Autenticação: proteja com autenticação.
Escreva o código com um editor in-line:
```pythonfromgoogle.cloudimportstorageimportrequestsimportbase64importjson# Google Cloud Storage ConfigurationBUCKET_NAME="<bucket-name>"FILE_NAME="qualys_cm_alerts.json"# Qualys API CredentialsQUALYS_USERNAME="<qualys-username>"QUALYS_PASSWORD="<qualys-password>"QUALYS_BASE_URL="https://<qualys_base_url>"deffetch_cm_alerts():"""Fetch alerts from Qualys Continuous Monitoring."""auth=base64.b64encode(f"{QUALYS_USERNAME}:{QUALYS_PASSWORD}".encode()).decode()headers={"Authorization":f"Basic {auth}","Content-Type":"application/xml"}payload=""" <ServiceRequest> <filters> <Criteria field="alert.date" operator="GREATER">2024-01-01</Criteria> </filters> </ServiceRequest> """response=requests.post(f"{QUALYS_BASE_URL}/qps/rest/2.0/search/cm/alert",headers=headers,data=payload)response.raise_for_status()returnresponse.json()defupload_to_gcs(data):"""Upload data to Google Cloud Storage."""client=storage.Client()bucket=client.get_bucket(BUCKET_NAME)blob=bucket.blob(FILE_NAME)blob.upload_from_string(json.dumps(data,indent=2),content_type="application/json")defmain(request):"""Cloud Function entry point."""try:alerts=fetch_cm_alerts()upload_to_gcs(alerts)return"Qualys CM alerts uploaded to Cloud Storage successfully!"exceptExceptionase:returnf"An error occurred: {e}",500```
Clique em Implantar depois de concluir a configuração.
Configurar o Cloud Scheduler
Acesse o Cloud Scheduler no console Google Cloud .
Clique em Criar job.
Configure o job:
Nome: insira um nome para o trabalho (por exemplo, trigger-fetch-qualys-cm-alerts).
Frequência: use a sintaxe cron para especificar a programação (por exemplo, 0 * * * * para executar a cada hora).
Fuso horário: defina seu fuso horário preferido.
Tipo de gatilho: escolha HTTP.
URL do gatilho: insira o URL da função do Cloud, que pode ser encontrado nos detalhes da função após a implantação.
Método: escolha POST.
Crie o job.
Configurar feeds
Há dois pontos de entrada diferentes para configurar feeds na plataforma do Google SecOps:
Configurações do SIEM > Feeds
Central de conteúdo > Pacotes de conteúdo
Configure feeds em "Configurações do SIEM" > "Feeds".
Para configurar um feed, siga estas etapas:
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, Registros de monitoramento contínuo da Qualys.
Selecione Google Cloud Storage como o Tipo de origem.
Selecione Monitoramento contínuo da Qualys como o Tipo de registro.
Clique em Próxima.
Especifique valores para os seguintes parâmetros de entrada:
URI do bucket de armazenamento: o URI de origem do bucket de armazenamento Google Cloud .
URI é um: selecione Arquivo único.
Opções de exclusão de fontes: selecione a opção de exclusão de acordo com sua preferência.
Clique em Próxima.
Revise a nova configuração do feed na tela Finalizar e clique em Enviar.
Configurar feeds na Central de conteúdo
Especifique valores para os seguintes campos:
URI do bucket de armazenamento: o URI de origem do bucket de armazenamento Google Cloud .
URI é um: selecione Arquivo único.
Opções de exclusão de fontes: selecione a opção de exclusão de acordo com sua preferência.
Opções avançadas
Nome do feed:um valor pré-preenchido que identifica o feed.
Tipo de origem:método usado para coletar registros no Google SecOps.
Namespace do recurso:namespace associado ao feed.
Rótulos de ingestão:rótulos aplicados a todos os eventos deste feed.
Tabela de mapeamento do UDM
Campo de registro
Mapeamento do UDM
Lógica
Alert.alertInfo.appVersion
metadata.product_version
Mapeado diretamente de Alert.alertInfo.appVersion
Alert.alertInfo.operatingSystem
principal.platform_version
Mapeado diretamente de Alert.alertInfo.operatingSystem
Alert.alertInfo.port
additional.fields.value.string_value
Mapeado diretamente de Alert.alertInfo.port e adicionado como um par de chave-valor em additional.fields com a chave "Alert port"
Alert.alertInfo.protocol
network.ip_protocol
Mapeado diretamente de Alert.alertInfo.protocol
Alert.alertInfo.sslIssuer
network.tls.client.certificate.issuer
Mapeado diretamente de Alert.alertInfo.sslIssuer
Alert.alertInfo.sslName
additional.fields.value.string_value
Mapeado diretamente de Alert.alertInfo.sslName e adicionado como um par de chave-valor em additional.fields com a chave "Nome SSL"
Alert.alertInfo.sslOrg
additional.fields.value.string_value
Mapeado diretamente de Alert.alertInfo.sslOrg e adicionado como um par de chave-valor em additional.fields com a chave "SSL Org"
Alert.alertInfo.ticketId
additional.fields.value.string_value
Mapeado diretamente de Alert.alertInfo.ticketId e adicionado como um par de chave-valor em additional.fields com a chave "Ticket Id"
Alert.alertInfo.vpeConfidence
additional.fields.value.string_value
Mapeado diretamente de Alert.alertInfo.vpeConfidence e adicionado como um par de chave-valor em additional.fields com a chave "VPE Confidence"
Alert.alertInfo.vpeStatus
additional.fields.value.string_value
Mapeado diretamente de Alert.alertInfo.vpeStatus e adicionado como um par de chave-valor em additional.fields com a chave "VPE Confidence"
Alert.eventType
additional.fields.value.string_value
Mapeado diretamente de Alert.eventType e adicionado como um par de chave-valor em additional.fields com a chave "Tipo de evento".
Alert.hostname
principal.hostname
Mapeado diretamente de Alert.hostname
Alert.id
security_result.threat_id
Mapeado diretamente de Alert.id
Alert.ipAddress
principal.ip
Mapeado diretamente de Alert.ipAddress
Alert.profile.id
additional.fields.value.string_value
Mapeado diretamente de Alert.profile.id e adicionado como um par de chave-valor em additional.fields com a chave "ID do perfil"
Alert.profile.title
additional.fields.value.string_value
Mapeado diretamente de Alert.profile.title e adicionado como um par de chave-valor em additional.fields com a chave "Título do perfil"
Alert.qid
vulnerability.name
Mapeado como "QID: " de Alert.qid
Alert.source
additional.fields.value.string_value
Mapeado diretamente de Alert.source e adicionado como um par de chave-valor em additional.fields com a chave "Alert Source"
Alert.triggerUuid
metadata.product_log_id
Mapeado diretamente de Alert.triggerUuid
Alert.vulnCategory
additional.fields.value.string_value
Mapeado diretamente de Alert.vulnCategory e adicionado como um par de chave-valor em additional.fields com a chave "Categoria de vulnerabilidade"
Alert.vulnSeverity
vulnerability.severity
Mapeado com base no valor de Alert.vulnSeverity: 1 a 3: BAIXO, 4 a 6: MÉDIO, 7 a 8: ALTO
Alert.vulnTitle
vulnerability.description
Mapeado diretamente de Alert.vulnTitle
Alert.vulnType
additional.fields.value.string_value
Mapeado diretamente de Alert.vulnType e adicionado como um par de chave-valor em additional.fields com a chave "Vulnerability Type"
Host
principal.ip
Analisado da linha de registro "Host: "
edr.client.ip_addresses
Copiados do principal.ip
edr.client.hostname
Copiados do principal.hostname
edr.raw_event_name
Definido como "STATUS_UPDATE" se Alert.ipAddress, Alert.hostname ou src_ip estiverem presentes. Caso contrário, definido como "GENERIC_EVENT".
metadata.event_timestamp
Extraído dos campos Alert.eventDate ou timestamp. Alert.eventDate tem prioridade se existir. Caso contrário, timestamp será usado. O carimbo de data/hora é convertido para UTC.
metadata.event_type
Mesma lógica de edr.raw_event_name
metadata.log_type
Definido como "QUALYS_CONTINUOUS_MONITORING"
metadata.product_name
Definido como "QUALYS_CONTINUOUS_MONITORING"
metadata.vendor_name
Definido como "QUALYS_CONTINUOUS_MONITORING"
network.application_protocol
Analisado da linha de registro " /user HTTP"
network.http.method
Analisado da linha de registro " /user HTTP"
timestamp
event.timestamp
Extraído dos campos Alert.eventDate ou timestamp. Alert.eventDate tem prioridade se existir. Caso contrário, timestamp será usado. O carimbo de data/hora é convertido para UTC.
[[["Fácil de entender","easyToUnderstand","thumb-up"],["Meu problema foi resolvido","solvedMyProblem","thumb-up"],["Outro","otherUp","thumb-up"]],[["Difícil de entender","hardToUnderstand","thumb-down"],["Informações incorretas ou exemplo de código","incorrectInformationOrSampleCode","thumb-down"],["Não contém as informações/amostras de que eu preciso","missingTheInformationSamplesINeed","thumb-down"],["Problema na tradução","translationIssue","thumb-down"],["Outro","otherDown","thumb-down"]],["Última atualização 2025-08-21 UTC."],[[["\u003cp\u003eThis guide details how to collect and ingest Qualys Continuous Monitoring logs into Google Security Operations (SecOps), including the necessary steps for setup, configuration, and UDM mapping.\u003c/p\u003e\n"],["\u003cp\u003eThe process involves enabling specific APIs in Google Cloud, creating a storage bucket, setting up a service account with proper permissions, and optionally creating a dedicated Qualys API user.\u003c/p\u003e\n"],["\u003cp\u003eA Google Cloud Function is used to fetch alerts from Qualys, and then store them in a GCS Bucket, while Cloud Scheduler is employed to automate the triggering of the function on a set schedule.\u003c/p\u003e\n"],["\u003cp\u003eThe UDM mapping table explains how Qualys log fields are transformed and mapped to their corresponding fields within the Unified Data Model, ensuring proper data normalization.\u003c/p\u003e\n"],["\u003cp\u003eOnce the data is present in the GCS bucket, a new feed must be created in the Google SecOps platform to ingest the information, setting the appropriate source type, log type and storage location, and selecting the appropriate ingestion labels.\u003c/p\u003e\n"]]],[],null,["# Collect Qualys Continuous Monitoring logs\n=========================================\n\nSupported in: \nGoogle secops [SIEM](/chronicle/docs/secops/google-secops-siem-toc)\n| **Note:** This feature is covered by [Pre-GA Offerings Terms](https://chronicle.security/legal/service-terms/) of the Google Security Operations Service Specific Terms. Pre-GA features might have limited support, and changes to pre-GA features might not be compatible with other pre-GA versions. For more information, see the [Google SecOps Technical Support Service guidelines](https://chronicle.security/legal/technical-support-services-guidelines/) and the [Google SecOps Service Specific Terms](https://chronicle.security/legal/service-terms/).\n\nThis Logstash parser code first extracts fields such as source IP, user, method, and application protocol from raw log messages using grok patterns. It thenmaps specific fields from the raw log data to their corresponding fields in the Unified Data Model (UDM), performs data type conversions, and enriches the data with additional labels and metadata before finally structuring the output in the desired UDM format.\n\nBefore you begin\n----------------\n\nEnsure that you have the following prerequisites:\n\n- Google Security Operations instance.\n- Privileged access to Google Cloud.\n- Privileged access to Qualys.\n\nEnable Required APIs:\n---------------------\n\n1. Sign in to the Google Cloud console.\n2. Go to **APIs \\& Services** \\\u003e **Library**.\n3. Search for the following APIs and enable them:\n - Cloud Functions API\n - Cloud Scheduler API\n - Cloud Pub/Sub (required for Cloud Scheduler to invoke functions)\n\nCreate a Google Cloud Storage Bucket\n------------------------------------\n\n1. Sign in to the Google Cloud console.\n2. Go to the **Cloud Storage Buckets** page.\n\n [Go to Buckets](https://console.cloud.google.com/storage/browser)\n3. Click **Create**.\n\n4. Configure the bucket:\n\n - **Name** : enter a unique name that meets the bucket name requirements (for example, **qualys-asset-bucket**).\n - **Choose where to store your data**: select a location.\n - **Choose a storage class for your data** : either select a **default storage class** for the bucket, or select **Autoclass** for automatic storage class management.\n - **Choose how to control access to objects** : select **not** to enforce **public access prevention** , and select an **access control model** for your bucket's objects.\n\n | **Note:** If public access prevention is already enforced by your project's organization policy, the **Prevent public access** checkbox is locked.\n - **Storage class** : choose based on your needs (for example, **Standard**).\n5. Click **Create**.\n\n| **Note:** Do not set a retention policy, as the last data entry may need to be overwritten in case of a timeout.\n\nCreate a Google Cloud Service Account\n-------------------------------------\n\n1. Sign in to the Google Cloud console.\n2. Go to to **IAM \\& Admin** \\\u003e **Service Accounts**.\n3. Create a new service account.\n4. Give it a descriptive name (for example, **qualys-user**).\n5. Grant the service account with **Storage Object Admin** role on the GCS bucket you created in the previous step.\n6. Grant the service account with **Cloud Functions Invoker** role.\n7. Create an [**SSH key**](/iam/docs/keys-create-delete) for the service account.\n8. Download a JSON key file for the service account. Keep this file secure.\n\nOptional: Create a dedicated API User in Qualys\n-----------------------------------------------\n\n1. Sign in to the Qualys console.\n2. Go to **Users**.\n3. Click **New** \\\u003e **User**.\n4. Enter the **General Information** required for the user.\n5. Select the **User Role** tab.\n6. Make sure the role has the **API Access** checkbox selected.\n7. Click **Save**.\n\nIdentify your specific Qualys API URL\n-------------------------------------\n\n### Option 1\n\nIdentify your URLs as mentioned in the [platform identification](https://www.qualys.com/platform-identification).\n\n### Option 2\n\n1. Sign in to the Qualys console.\n2. Go to **Help** \\\u003e **About**.\n3. Scroll to see this information under Security Operations Center (SOC).\n4. Copy the Qualys API URL.\n\nConfigure the Cloud Function\n----------------------------\n\n1. Go to **Cloud Functions** in the Google Cloud console.\n2. Click **Create Function**.\n3. Configure the Function:\n\n - **Name** : enter a name for your function (for example, **fetch-qualys-cm-alerts**).\n - **Region**: select a region close to your Bucket.\n - **Runtime**: Python 3.10 (or your preferred runtime).\n - **Trigger**: choose HTTP trigger if needed or Cloud Pub/Sub for scheduled execution.\n - **Authentication**: secure with authentication.\n - **Write the Code** with an inline editor:\n\n **Note:** Make sure to replace the following with your data: `\u003cbucket-name\u003e`, `\u003cqualys-username\u003e`, `\u003cqualys-password\u003e`, `\u003cqualys_base_url\u003e`. \n\n ```python\n from google.cloud import storage\n import requests\n import base64\n import json\n\n # Google Cloud Storage Configuration\n BUCKET_NAME = \"\u003cbucket-name\u003e\"\n FILE_NAME = \"qualys_cm_alerts.json\"\n\n # Qualys API Credentials\n QUALYS_USERNAME = \"\u003cqualys-username\u003e\"\n QUALYS_PASSWORD = \"\u003cqualys-password\u003e\"\n QUALYS_BASE_URL = \"https://\u003cqualys_base_url\u003e\"\n\n def fetch_cm_alerts():\n \"\"\"Fetch alerts from Qualys Continuous Monitoring.\"\"\"\n auth = base64.b64encode(f\"{QUALYS_USERNAME}:{QUALYS_PASSWORD}\".encode()).decode()\n headers = {\n \"Authorization\": f\"Basic {auth}\",\n \"Content-Type\": \"application/xml\"\n }\n payload = \"\"\"\n \u003cServiceRequest\u003e\n \u003cfilters\u003e\n \u003cCriteria field=\"alert.date\" operator=\"GREATER\"\u003e2024-01-01\u003c/Criteria\u003e\n \u003c/filters\u003e\n \u003c/ServiceRequest\u003e\n \"\"\"\n response = requests.post(f\"{QUALYS_BASE_URL}/qps/rest/2.0/search/cm/alert\", headers=headers, data=payload)\n response.raise_for_status()\n return response.json()\n\n def upload_to_gcs(data):\n \"\"\"Upload data to Google Cloud Storage.\"\"\"\n client = storage.Client()\n bucket = client.get_bucket(BUCKET_NAME)\n blob = bucket.blob(FILE_NAME)\n blob.upload_from_string(json.dumps(data, indent=2), content_type=\"application/json\")\n\n def main(request):\n \"\"\"Cloud Function entry point.\"\"\"\n try:\n alerts = fetch_cm_alerts()\n upload_to_gcs(alerts)\n return \"Qualys CM alerts uploaded to Cloud Storage successfully!\"\n except Exception as e:\n return f\"An error occurred: {e}\", 500\n ```\n\n4. Click **Deploy** after completing the configuration.\n\nConfigure Cloud Scheduler\n-------------------------\n\n1. Go to **Cloud Scheduler** in the Google Cloud console.\n2. Click **Create Job**.\n3. Configure the Job:\n\n - **Name** : enter a name for your job (for example, **trigger-fetch-qualys-cm-alerts**).\n - **Frequency** : use **cron** syntax to specify the schedule (for example, `0 * * * *` to run every hour).\n - **Time Zone**: set your preferred time zone.\n - **Trigger Type** : choose **HTTP**.\n - **Trigger URL**: Enter the Cloud Function's URL (found in the function details after deployment).\n - **Method** : Choose **POST**.\n\n | **Note:** If authentication is enabled for the function, select **Service Account** and ensure the account has the **Cloud Functions Invoker** role.\n4. Create the job.\n\nSet up feeds\n------------\n\nTo configure a feed, follow these steps:\n\n1. Go to **SIEM Settings** \\\u003e **Feeds**.\n2. Click **Add New Feed**.\n3. On the next page, click **Configure a single feed**.\n4. In the **Feed name** field, enter a name for the feed; for example, **Qualys Continuous Monitoring Logs**.\n5. Select **Google Cloud Storage V2** as the **Source type**.\n6. Select **Qualys Continuous Monitoring** as the **Log type**.\n7. Click **Next**.\n8. Specify values for the following input parameters:\n\n - **Storage Bucket URI**: the Google Cloud storage bucket source URI.\n - **Source deletion options**: select the deletion option according to your preference.\n\n | **Note:** If you select the `Delete transferred files` or `Delete transferred files and empty directories` option, make sure that you granted appropriate permissions to the service account. \\* **Maximum File Age**: Includes files modified in the last number of days. Default is 180 days.\n9. Click **Next**.\n\n10. Review your new feed configuration in the **Finalize** screen, and then click **Submit**.\n\nUDM Mapping Table\n-----------------\n\n**Need more help?** [Get answers from Community members and Google SecOps professionals.](https://security.googlecloudcommunity.com/google-security-operations-2)"]]