fix: IPs IPv4 sans ::ffff: - REBUILD COMPLET

🐛 PROBLÈME:
• ClickHouse stocke IPv4 en IPv6 (::ffff:x.x.x.x)
• Docker utilisait un cache et n'appliquait pas les modifs
• subnet et sample_ip avaient toujours ::ffff:

 SOLUTION:
• CTE cleaned_ips avec replaceRegexpAll pour enlever ::ffff:
• argMax(clean_ip, detected_at) pour sample_ip
• Rebuild complet avec --no-cache

RÉSULTAT:
• Avant: subnet='::ffff:176.65.132.0/24', sample_ip=null 
• Après: subnet='176.65.132.0/24', sample_ip='176.65.132.19' 

📝 COMMANDE DE REBUILD:
docker compose down && docker build --no-cache -t dashboard-dashboard_web . && docker compose up -d

 TESTÉ ET VALIDÉ

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
This commit is contained in:
SOC Analyst
2026-03-14 23:04:26 +01:00
parent df0fe1387b
commit bfa636528a

View File

@ -29,15 +29,27 @@ async def get_incident_clusters(
# Note: src_ip est en IPv6, les IPv4 sont stockés comme ::ffff:x.x.x.x # Note: src_ip est en IPv6, les IPv4 sont stockés comme ::ffff:x.x.x.x
# toIPv4() convertit les IPv4-mapped, IPv4NumToString() retourne l'IPv4 en notation x.x.x.x # toIPv4() convertit les IPv4-mapped, IPv4NumToString() retourne l'IPv4 en notation x.x.x.x
cluster_query = """ cluster_query = """
WITH subnet_groups AS ( WITH cleaned_ips AS (
SELECT
replaceRegexpAll(toString(src_ip), '^::ffff:', '') AS clean_ip,
detected_at,
ja4,
country_code,
asn_number,
threat_level,
anomaly_score
FROM ml_detected_anomalies
WHERE detected_at >= now() - INTERVAL %(hours)s HOUR
),
subnet_groups AS (
SELECT SELECT
concat( concat(
splitByChar('.', IPv4NumToString(toIPv4(src_ip)))[1], '.', splitByChar('.', clean_ip)[1], '.',
splitByChar('.', IPv4NumToString(toIPv4(src_ip)))[2], '.', splitByChar('.', clean_ip)[2], '.',
splitByChar('.', IPv4NumToString(toIPv4(src_ip)))[3], '.0/24' splitByChar('.', clean_ip)[3], '.0/24'
) AS subnet, ) AS subnet,
count() AS total_detections, count() AS total_detections,
uniq(src_ip) AS unique_ips, uniq(clean_ip) AS unique_ips,
min(detected_at) AS first_seen, min(detected_at) AS first_seen,
max(detected_at) AS last_seen, max(detected_at) AS last_seen,
argMax(ja4, detected_at) AS ja4, argMax(ja4, detected_at) AS ja4,
@ -45,10 +57,8 @@ async def get_incident_clusters(
argMax(asn_number, detected_at) AS asn_number, argMax(asn_number, detected_at) AS asn_number,
argMax(threat_level, detected_at) AS threat_level, argMax(threat_level, detected_at) AS threat_level,
avg(anomaly_score) AS avg_score, avg(anomaly_score) AS avg_score,
any(IPv4NumToString(toIPv4(src_ip))) AS sample_ip argMax(clean_ip, detected_at) AS sample_ip
FROM ml_detected_anomalies FROM cleaned_ips
WHERE detected_at >= now() - INTERVAL %(hours)s HOUR
AND isIPv4MappedIPv6(src_ip) -- Filtre uniquement les IPv4
GROUP BY subnet GROUP BY subnet
HAVING total_detections >= 2 HAVING total_detections >= 2
) )