Add ability to mass block critical IP addresses from the system
Add a new endpoint to the ML backend to block all critical IPs and an API route to trigger it from the server. Replit-Commit-Author: Agent Replit-Commit-Session-Id: 7a657272-55ba-4a79-9a2e-f1ed9bc7a528 Replit-Commit-Checkpoint-Type: full_checkpoint Replit-Commit-Event-Id: 685ee18c-cd9c-4b9a-8cb1-70c4b25db835 Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/449cf7c4-c97a-45ae-8234-e5c5b8d6a84f/7a657272-55ba-4a79-9a2e-f1ed9bc7a528/18EyBWl
This commit is contained in:
parent
897c9a3d5c
commit
255444d2dd
@ -111,6 +111,10 @@ class UnblockIPRequest(BaseModel):
|
||||
ip_address: str
|
||||
list_name: str = "ddos_blocked"
|
||||
|
||||
class BlockAllCriticalRequest(BaseModel):
|
||||
min_score: float = 80.0
|
||||
list_name: str = "ddos_blocked"
|
||||
|
||||
|
||||
# API Endpoints
|
||||
|
||||
@ -499,6 +503,94 @@ async def block_ip(request: BlockIPRequest):
|
||||
except Exception as e:
|
||||
raise HTTPException(status_code=500, detail=str(e))
|
||||
|
||||
@app.post("/block-all-critical")
|
||||
async def block_all_critical(request: BlockAllCriticalRequest):
|
||||
"""Blocca tutti gli IP critici non ancora bloccati sui router"""
|
||||
try:
|
||||
conn = get_db_connection()
|
||||
cursor = conn.cursor(cursor_factory=RealDictCursor)
|
||||
|
||||
cursor.execute("SELECT * FROM routers WHERE enabled = true")
|
||||
routers = cursor.fetchall()
|
||||
|
||||
if not routers:
|
||||
raise HTTPException(status_code=400, detail="Nessun router configurato")
|
||||
|
||||
cursor.execute("""
|
||||
SELECT DISTINCT source_ip, MAX(CAST(risk_score AS FLOAT)) as max_score,
|
||||
MAX(anomaly_type) as anomaly_type
|
||||
FROM detections
|
||||
WHERE CAST(risk_score AS FLOAT) >= %s
|
||||
AND blocked = false
|
||||
AND source_ip NOT IN (
|
||||
SELECT ip_address FROM whitelist WHERE active = true
|
||||
)
|
||||
GROUP BY source_ip
|
||||
ORDER BY max_score DESC
|
||||
""", (request.min_score,))
|
||||
|
||||
unblocked_ips = cursor.fetchall()
|
||||
|
||||
if not unblocked_ips:
|
||||
cursor.close()
|
||||
conn.close()
|
||||
return {
|
||||
"message": "Nessun IP critico da bloccare",
|
||||
"blocked": 0,
|
||||
"total_critical": 0,
|
||||
"skipped_whitelisted": 0
|
||||
}
|
||||
|
||||
blocked_count = 0
|
||||
failed_count = 0
|
||||
results_detail = []
|
||||
|
||||
for ip_row in unblocked_ips:
|
||||
ip = ip_row['source_ip']
|
||||
score = ip_row['max_score']
|
||||
anomaly = ip_row['anomaly_type']
|
||||
|
||||
try:
|
||||
block_results = await mikrotik_manager.block_ip_on_all_routers(
|
||||
routers,
|
||||
ip,
|
||||
list_name=request.list_name,
|
||||
comment=f"IDS bulk-block: {anomaly} (score: {score:.0f})"
|
||||
)
|
||||
|
||||
if any(block_results.values()):
|
||||
cursor.execute("""
|
||||
UPDATE detections
|
||||
SET blocked = true, blocked_at = NOW()
|
||||
WHERE source_ip = %s AND blocked = false
|
||||
""", (ip,))
|
||||
blocked_count += 1
|
||||
results_detail.append({"ip": ip, "score": score, "status": "blocked"})
|
||||
else:
|
||||
failed_count += 1
|
||||
results_detail.append({"ip": ip, "score": score, "status": "failed"})
|
||||
|
||||
except Exception as e:
|
||||
failed_count += 1
|
||||
results_detail.append({"ip": ip, "score": score, "status": f"error: {str(e)}"})
|
||||
|
||||
conn.commit()
|
||||
cursor.close()
|
||||
conn.close()
|
||||
|
||||
return {
|
||||
"message": f"Blocco massivo completato: {blocked_count} IP bloccati, {failed_count} falliti",
|
||||
"blocked": blocked_count,
|
||||
"failed": failed_count,
|
||||
"total_critical": len(unblocked_ips),
|
||||
"details": results_detail[:50]
|
||||
}
|
||||
|
||||
except HTTPException:
|
||||
raise
|
||||
except Exception as e:
|
||||
raise HTTPException(status_code=500, detail=str(e))
|
||||
|
||||
@app.post("/unblock-ip")
|
||||
async def unblock_ip(request: UnblockIPRequest):
|
||||
"""Sblocca un IP da tutti i router"""
|
||||
|
||||
@ -622,6 +622,42 @@ export async function registerRoutes(app: Express): Promise<Server> {
|
||||
}
|
||||
});
|
||||
|
||||
app.post("/api/ml/block-all-critical", async (req, res) => {
|
||||
try {
|
||||
const { min_score = 80 } = req.body;
|
||||
|
||||
const controller = new AbortController();
|
||||
const timeout = setTimeout(() => controller.abort(), 300000); // 5 min timeout
|
||||
|
||||
const response = await fetch(`${ML_BACKEND_URL}/block-all-critical`, {
|
||||
method: "POST",
|
||||
headers: getMLBackendHeaders(),
|
||||
body: JSON.stringify({ min_score }),
|
||||
signal: controller.signal,
|
||||
});
|
||||
|
||||
clearTimeout(timeout);
|
||||
|
||||
if (!response.ok) {
|
||||
const errorData = await response.json().catch(() => ({}));
|
||||
return res.status(response.status).json({
|
||||
error: errorData.detail || "Block all critical failed",
|
||||
});
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
res.json(data);
|
||||
} catch (error: any) {
|
||||
if (error.name === 'AbortError') {
|
||||
return res.status(504).json({ error: "Timeout - operazione troppo lunga" });
|
||||
}
|
||||
if (error.code === 'ECONNREFUSED') {
|
||||
return res.status(503).json({ error: "ML backend non disponibile" });
|
||||
}
|
||||
res.status(500).json({ error: error.message || "Errore blocco massivo" });
|
||||
}
|
||||
});
|
||||
|
||||
app.get("/api/ml/stats", async (req, res) => {
|
||||
try {
|
||||
const controller = new AbortController();
|
||||
|
||||
Loading…
Reference in New Issue
Block a user