5.7 KiB
Threat Log Analysis Reference
Use Firewall Threat Logs and Cloud IDS logs to identify, analyze, and troubleshoot security incidents in your VPC network.
🤖 Agent / Gemini CLI Instructions (MCP)
Agents should use Cloud Logging MCP for quick identification of recent alerts or BigQuery MCP for analyzing trends and identifying top attackers. Fallback to the CLI if the MCP tools are not available.
1. View Threat Alerts (Cloud Logging MCP)
Tool: list_log_entries
Filter: Search for both Cloud Firewall Plus and Cloud IDS threat log sources:
logName:(
"projects/{project_id}/logs/networksecurity.googleapis.com%2Ffirewall_threat" OR
"projects/{project_id}/logs/ids.googleapis.com%2Fthreat")
To filter for high-severity blocked threats: `
logName:(
"projects/{project_id}/logs/networksecurity.googleapis.com%2Ffirewall_threat" OR
"projects/{project_id}/logs/ids.googleapis.com%2Fthreat")
jsonPayload.threatDetails.severity=("HIGH" OR "CRITICAL")
jsonPayload.action="DENY"
2. Aggregate Threat Trends (BigQuery MCP)
Tool: execute_sql_readonly
SQL Pattern: Note: In BigQuery, the top-level column name is
json_payload (snake_case). However, fields extracted from inside the JSON
payload are case-sensitive and retain the camelCase format of the original log
(for example, threatDetails, clientIp). Do not use snake_case for nested
fields.
SELECT
timestamp,
JSON_VALUE(json_payload.threatDetails.threat) AS threat_name,
JSON_VALUE(json_payload.threatDetails.severity) AS severity,
JSON_VALUE(json_payload.threatDetails.category) AS category,
JSON_VALUE(json_payload.action) AS action,
JSON_VALUE(json_payload.connection.clientIp) AS src_ip,
JSON_VALUE(json_payload.connection.serverIp) AS dest_ip,
JSON_VALUE(json_payload.connection.serverPort) AS dest_port,
JSON_VALUE(json_payload.threatDetails.description) AS description
FROM `{project_id}.{dataset_id}._AllLogs`
WHERE
log_id IN ('networksecurity.googleapis.com/firewall_threat',
'ids.googleapis.com/threat')
AND JSON_VALUE(json_payload.threatDetails.severity) IN ('HIGH', 'CRITICAL')
AND timestamp >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 24 HOUR)
ORDER BY timestamp DESC
LIMIT 20
To find top sources of attacks:
SELECT
JSON_VALUE(json_payload.connection.clientIp) AS attacker_ip, COUNT(*) AS
attack_count, ARRAY_AGG(DISTINCT JSON_VALUE(json_payload.threatDetails.threat)
LIMIT 5) AS sample_threats FROM `{project_id}.{dataset_id}._AllLogs` WHERE
log_id IN ('networksecurity.googleapis.com/firewall_threat',
'ids.googleapis.com/threat') AND timestamp >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(),
INTERVAL 7 DAY) GROUP BY 1 ORDER BY attack_count DESC LIMIT 10
3. CLI Fallback
If MCP tools are unavailable, use the following gcloud and bq commands:
View Threat Alerts (gcloud)
gcloud logging read 'logName:("projects/{project_id}/logs/networksecurity.googleapis.com%2Ffirewall_threat" OR "projects/{project_id}/logs/ids.googleapis.com%2Fthreat")' --project {project_id} --limit 10 --format json --quiet
To filter for high-severity blocked threats:
gcloud logging read 'logName:("projects/{project_id}/logs/networksecurity.googleapis.com%2Ffirewall_threat" OR "projects/{project_id}/logs/ids.googleapis.com%2Fthreat") AND jsonPayload.threatDetails.severity=("HIGH" OR "CRITICAL") AND jsonPayload.action="DENY"' --project {project_id} --limit 10 --format json --quiet
Aggregate Threat Trends (bq)
bq query --use_legacy_sql=false --project_id {project_id} '
SELECT
timestamp,
JSON_VALUE(json_payload.threatDetails.threat) AS threat_name,
JSON_VALUE(json_payload.threatDetails.severity) AS severity,
JSON_VALUE(json_payload.threatDetails.category) AS category,
JSON_VALUE(json_payload.action) AS action,
JSON_VALUE(json_payload.connection.clientIp) AS src_ip,
JSON_VALUE(json_payload.connection.serverIp) AS dest_ip,
JSON_VALUE(json_payload.connection.serverPort) AS dest_port,
JSON_VALUE(json_payload.threatDetails.description) AS description
FROM `{project_id}.{dataset_id}._AllLogs`
WHERE
log_id IN ("networksecurity.googleapis.com/firewall_threat",
"ids.googleapis.com/threat")
AND JSON_VALUE(json_payload.threatDetails.severity) IN ("HIGH", "CRITICAL")
AND timestamp >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 24 HOUR)
ORDER BY timestamp DESC
LIMIT 20
'
To find top sources of attacks:
bq query --use_legacy_sql=false --project_id {project_id} '
SELECT
JSON_VALUE(json_payload.connection.clientIp) AS attacker_ip,
COUNT(*) AS attack_count,
ARRAY_AGG(DISTINCT JSON_VALUE(json_payload.threatDetails.threat)
LIMIT 5) AS sample_threats
FROM `{project_id}.{dataset_id}._AllLogs`
WHERE
log_id IN ("networksecurity.googleapis.com/firewall_threat",
"ids.googleapis.com/threat")
AND timestamp >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 7 DAY)
GROUP BY 1
ORDER BY attack_count DESC
LIMIT 10
'
Key Fields (Cloud Logging Filter Names)
- jsonPayload.threatDetails.threat: Human-readable name of the threat.
- jsonPayload.threatDetails.severity: Severity level (CRITICAL, HIGH, MEDIUM, LOW, INFORMATIONAL).
- jsonPayload.threatDetails.category: The category of threat.
- jsonPayload.action: Action taken (for example, "ALLOW", "DENY", "ALERT").
- jsonPayload.connection.clientIp: The true source IP.
- jsonPayload.connection.serverIp: The destination IP.
- jsonPayload.threatDetails.cves: List of CVE IDs.
- jsonPayload.threatDetails.description: Attack payload details.