Compare commits
18 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f6d656ce14 | ||
|
|
17dc79372e | ||
|
|
4118d60d6d | ||
|
|
6ce60ed5d3 | ||
|
|
fe113d5518 | ||
|
|
9104c67f97 | ||
|
|
d01eca2cf0 | ||
|
|
b7abd340bc | ||
|
|
0bd84ed2ed | ||
|
|
74eb423a92 | ||
|
|
3c8c03bb98 | ||
|
|
2f76875f2b | ||
|
|
f9e0e1a98e | ||
|
|
544b7cfa49 | ||
|
|
1fc63c657a | ||
|
|
b45b810eb9 | ||
|
|
64c491f245 | ||
|
|
88b0dd7472 |
@ -0,0 +1,57 @@
|
||||
echo "=== TEST PORTA 5000 ===" && curl -s -o /dev/null -w "HTTP %{http_code}\n" http://localhost:5000/api/health && echo "=== TEST AUTO-BLOCK MANUALE ===" && sudo -u ids /opt/ids/python_ml/venv/bin/python3 /opt/ids/python_ml/auto_block.py 2>&1 && echo "=== STATO TUTTI I SERVIZI ===" && systemctl status ids-backend ids-ml-backend ids-syslog-parser ids-auto-block.timer --no-pager -l
|
||||
=== TEST PORTA 5000 ===
|
||||
HTTP 200
|
||||
=== TEST AUTO-BLOCK MANUALE ===
|
||||
[2026-02-17 08:51:22] Starting auto-block cycle...
|
||||
[2026-02-17 08:51:22] Step 1: Detection ML...
|
||||
[2026-02-17 08:51:22] Detection completata: 0 anomalie rilevate
|
||||
[2026-02-17 08:51:22] Step 2: Blocco IP critici sui router...
|
||||
[2026-02-17 08:51:22] 24 IP bloccati sui router, 0 falliti, 0 gia' bloccati
|
||||
=== STATO TUTTI I SERVIZI ===
|
||||
● ids-backend.service - IDS Node.js Backend (Express API + Frontend)
|
||||
Loaded: loaded (/etc/systemd/system/ids-backend.service; enabled; preset: disabled)
|
||||
Active: active (running) since Tue 2026-02-17 08:51:09 CET; 57s ago
|
||||
Process: 31307 ExecStartPre=/bin/bash -c test -f /opt/ids/dist/index.js || (echo "ERRORE: dist/index.js non trovato - eseguire npm run build" && exit 1) (code=exited, status=0/SUCCESS)
|
||||
Main PID: 31308 (node)
|
||||
Tasks: 11 (limit: 100409)
|
||||
Memory: 59.1M (max: 1.0G available: 964.8M)
|
||||
CPU: 1.669s
|
||||
CGroup: /system.slice/ids-backend.service
|
||||
└─31308 node dist/index.js
|
||||
|
||||
Feb 17 08:51:09 ids.alfacom.it systemd[1]: Starting IDS Node.js Backend (Express API + Frontend)...
|
||||
Feb 17 08:51:09 ids.alfacom.it systemd[1]: Started IDS Node.js Backend (Express API + Frontend).
|
||||
|
||||
● ids-ml-backend.service - IDS ML Backend (FastAPI)
|
||||
Loaded: loaded (/etc/systemd/system/ids-ml-backend.service; enabled; preset: disabled)
|
||||
Active: active (running) since Tue 2026-02-17 08:50:14 CET; 1min 51s ago
|
||||
Main PID: 31127 (python3)
|
||||
Tasks: 26 (limit: 100409)
|
||||
Memory: 256.8M (max: 2.0G available: 1.7G)
|
||||
CPU: 4.073s
|
||||
CGroup: /system.slice/ids-ml-backend.service
|
||||
└─31127 /opt/ids/python_ml/venv/bin/python3 main.py
|
||||
|
||||
Feb 17 08:50:14 ids.alfacom.it systemd[1]: Started IDS ML Backend (FastAPI).
|
||||
|
||||
● ids-syslog-parser.service - IDS Syslog Parser (Network Logs Processor)
|
||||
Loaded: loaded (/etc/systemd/system/ids-syslog-parser.service; enabled; preset: disabled)
|
||||
Active: active (running) since Mon 2026-02-16 12:18:52 CET; 20h ago
|
||||
Main PID: 1069 (python3)
|
||||
Tasks: 1 (limit: 100409)
|
||||
Memory: 9.7M (max: 1.0G available: 1014.2M)
|
||||
CPU: 1h 59min 34.854s
|
||||
CGroup: /system.slice/ids-syslog-parser.service
|
||||
└─1069 /opt/ids/python_ml/venv/bin/python3 syslog_parser.py
|
||||
|
||||
Feb 16 12:18:52 ids.alfacom.it systemd[1]: Started IDS Syslog Parser (Network Logs Processor).
|
||||
|
||||
● ids-auto-block.timer - IDS Auto-Blocking Timer - Run every 5 minutes
|
||||
Loaded: loaded (/etc/systemd/system/ids-auto-block.timer; enabled; preset: disabled)
|
||||
Active: active (running) since Mon 2026-02-16 19:24:04 CET; 13h ago
|
||||
Until: Mon 2026-02-16 19:24:04 CET; 13h ago
|
||||
Trigger: n/a
|
||||
Triggers: ● ids-auto-block.service
|
||||
Docs: https://github.com/yourusername/ids
|
||||
|
||||
Feb 16 19:24:04 ids.alfacom.it systemd[1]: Started IDS Auto-Blocking Timer - Run every 5 minutes.
|
||||
@ -0,0 +1,85 @@
|
||||
tail -f /var/log/ids/backend.log
|
||||
9:21:00 AM [express] GET /api/detections 304 in 19ms :: {"detections":[{"id":"fcde52d3-0ae4-4904-a7c…
|
||||
9:21:01 AM [express] GET /api/services/status 200 in 29ms :: {"services":{"mlBackend":{"name":"ML Ba…
|
||||
9:21:02 AM [express] GET /api/routers 200 in 3ms :: [{"id":"c6904896-59dc-4060-952f-0e55df7dee4a","n…
|
||||
9:21:12 AM [express] PUT /api/routers/c6904896-59dc-4060-952f-0e55df7dee4a 200 in 8ms :: {"id":"c690…
|
||||
9:21:12 AM [express] GET /api/routers 304 in 2ms :: [{"id":"c6904896-59dc-4060-952f-0e55df7dee4a","n…
|
||||
9:22:16 AM [express] POST /api/ml/block-all-critical 200 in 99ms :: {"message":"Nessun IP critico da…
|
||||
9:24:17 AM [express] POST /api/ml/block-all-critical 200 in 75ms :: {"message":"Nessun IP critico da…
|
||||
Using standard PostgreSQL database
|
||||
9:26:18 AM [express] serving on port 5000
|
||||
✅ Database connection successful
|
||||
9:28:19 AM [express] POST /api/ml/block-all-critical 200 in 93ms :: {"message":"Nessun IP critico da…
|
||||
9:30:19 AM [express] POST /api/ml/block-all-critical 200 in 82ms :: {"message":"Nessun IP critico da…
|
||||
9:30:25 AM [express] GET /api/training-history 200 in 6ms :: [{"id":"7570df54-8169-4fb2-abdc-e9c1bfa…
|
||||
9:30:29 AM [express] GET /api/detections 200 in 24ms :: {"detections":[{"id":"fcde52d3-0ae4-4904-a7c…
|
||||
9:30:29 AM [express] GET /api/whitelist 200 in 259ms :: {"items":[{"id":"49b5b9a9-4683-452c-a784-fc5…
|
||||
9:30:37 AM [express] GET /api/services/status 200 in 22ms :: {"services":{"mlBackend":{"name":"ML Ba…
|
||||
9:30:39 AM [express] POST /api/services/ids-syslog-parser/start 500 in 22ms :: {"error":"Service con…
|
||||
9:30:42 AM [express] GET /api/services/status 200 in 21ms :: {"services":{"mlBackend":{"name":"ML Ba…
|
||||
9:30:47 AM [express] GET /api/services/status 200 in 18ms :: {"services":{"mlBackend":{"name":"ML Ba…
|
||||
9:30:52 AM [express] GET /api/services/status 200 in 17ms :: {"services":{"mlBackend":{"name":"ML Ba…
|
||||
9:30:57 AM [express] GET /api/services/status 200 in 17ms :: {"services":{"mlBackend":{"name":"ML Ba…
|
||||
9:31:02 AM [express] GET /api/services/status 200 in 17ms :: {"services":{"mlBackend":{"name":"ML Ba…
|
||||
9:31:07 AM [express] GET /api/services/status 200 in 23ms :: {"services":{"mlBackend":{"name":"ML Ba…
|
||||
9:31:12 AM [express] GET /api/services/status 200 in 18ms :: {"services":{"mlBackend":{"name":"ML Ba…
|
||||
9:31:16 AM [express] GET /api/services/status 200 in 18ms :: {"services":{"mlBackend":{"name":"ML Ba…
|
||||
9:31:21 AM [express] GET /api/services/status 200 in 17ms :: {"services":{"mlBackend":{"name":"ML Ba…
|
||||
9:31:26 AM [express] GET /api/services/status 200 in 17ms :: {"services":{"mlBackend":{"name":"ML Ba…
|
||||
9:31:27 AM [express] GET /api/detections 304 in 11ms :: {"detections":[{"id":"fcde52d3-0ae4-4904-a7c…
|
||||
9:31:27 AM [express] GET /api/whitelist 200 in 229ms :: {"items":[{"id":"91108765-7ef6-4e49-87d8-319…
|
||||
9:31:30 AM [express] GET /api/public-lists 200 in 5ms :: [{"id":"2a835798-02a7-4129-a528-d39a026ad15…
|
||||
9:31:32 AM [express] GET /api/services/status 200 in 19ms :: {"services":{"mlBackend":{"name":"ML Ba…
|
||||
9:31:37 AM [express] GET /api/services/status 200 in 20ms :: {"services":{"mlBackend":{"name":"ML Ba…
|
||||
9:31:42 AM [express] GET /api/services/status 200 in 19ms :: {"services":{"mlBackend":{"name":"ML Ba…
|
||||
9:31:47 AM [express] GET /api/services/status 200 in 18ms :: {"services":{"mlBackend":{"name":"ML Ba…
|
||||
9:31:52 AM [express] GET /api/services/status 200 in 17ms :: {"services":{"mlBackend":{"name":"ML Ba…
|
||||
9:31:57 AM [express] GET /api/services/status 200 in 21ms :: {"services":{"mlBackend":{"name":"ML Ba…
|
||||
9:32:02 AM [express] GET /api/services/status 200 in 18ms :: {"services":{"mlBackend":{"name":"ML Ba…
|
||||
9:32:07 AM [express] GET /api/services/status 200 in 24ms :: {"services":{"mlBackend":{"name":"ML Ba…
|
||||
9:32:12 AM [express] GET /api/services/status 200 in 24ms :: {"services":{"mlBackend":{"name":"ML Ba…
|
||||
9:32:17 AM [express] GET /api/services/status 200 in 23ms :: {"services":{"mlBackend":{"name":"ML Ba…
|
||||
9:32:25 AM [express] GET /api/services/status 200 in 2875ms :: {"services":{"mlBackend":{"name":"ML …
|
||||
[BLOCK-ALL] Avvio blocco massivo: 11/11 IP con score >= 80 su 2 router
|
||||
[BULK-BLOCK] Starting: 11 IPs on 2 routers (10.20.30.100, 185.203.24.2)
|
||||
[BULK-BLOCK] Router 185.203.24.2: 124 IPs already in list (50ms)
|
||||
9:32:30 AM [express] GET /api/services/status 200 in 31ms :: {"services":{"mlBackend":{"name":"ML Ba…
|
||||
9:32:35 AM [express] GET /api/services/status 200 in 31ms :: {"services":{"mlBackend":{"name":"ML Ba…
|
||||
9:32:40 AM [express] GET /api/services/status 200 in 46ms :: {"services":{"mlBackend":{"name":"ML Ba…
|
||||
9:32:46 AM [express] GET /api/services/status 200 in 75ms :: {"services":{"mlBackend":{"name":"ML Ba…
|
||||
[MIKROTIK] Failed to get address-list from 10.20.30.100: This operation was aborted
|
||||
[BULK-BLOCK] Router 10.20.30.100: 0 IPs already in list (20004ms)
|
||||
[BULK-BLOCK] 0 already blocked, 11 new to block
|
||||
9:32:51 AM [express] GET /api/services/status 200 in 40ms :: {"services":{"mlBackend":{"name":"ML Ba…
|
||||
[BULK-BLOCK] SLOW: Router 10.20.30.100 took 8002ms for IP 87.17.182.32: This operation was aborted
|
||||
[BULK-BLOCK] SLOW: Router 10.20.30.100 took 8001ms for IP 185.98.164.31: This operation was aborted
|
||||
[BULK-BLOCK] SLOW: Router 10.20.30.100 took 8001ms for IP 109.115.163.146: This operation was aborted
|
||||
[BULK-BLOCK] SLOW: Router 10.20.30.100 took 8002ms for IP 2.118.225.238: This operation was aborted
|
||||
[BULK-BLOCK] SLOW: Router 10.20.30.100 took 8001ms for IP 74.125.99.38: This operation was aborted
|
||||
[BULK-BLOCK] SLOW: Router 10.20.30.100 took 8001ms for IP 192.178.112.96: This operation was aborted
|
||||
[BULK-BLOCK] SLOW: Router 10.20.30.100 took 8001ms for IP 74.125.111.102: This operation was aborted
|
||||
[BULK-BLOCK] SLOW: Router 10.20.30.100 took 8001ms for IP 212.14.142.214: This operation was aborted
|
||||
[BULK-BLOCK] SLOW: Router 10.20.30.100 took 8000ms for IP 89.96.215.146: This operation was aborted
|
||||
[BULK-BLOCK] SLOW: Router 10.20.30.100 took 8001ms for IP 172.217.39.230: This operation was aborted
|
||||
9:32:56 AM [express] GET /api/services/status 200 in 44ms :: {"services":{"mlBackend":{"name":"ML Ba…
|
||||
9:33:01 AM [express] GET /api/services/status 200 in 46ms :: {"services":{"mlBackend":{"name":"ML Ba…
|
||||
[BULK-BLOCK] SLOW: Router 10.20.30.100 took 8002ms for IP 104.19.148.8: This operation was aborted
|
||||
[BULK-BLOCK] Progress: 11/11
|
||||
[BULK-BLOCK] Router 10.20.30.100: 0 blocked, 11 failed, 0 skipped
|
||||
[BULK-BLOCK] Router 185.203.24.2: 11 blocked, 0 failed, 0 skipped
|
||||
[BULK-BLOCK] Done: 11 blocked, 0 failed, 0 skipped
|
||||
[BLOCK-ALL] Database aggiornato: 11 IP marcati come bloccati
|
||||
9:33:03 AM [express] POST /api/ml/block-all-critical 200 in 36137ms :: {"message":"Blocco massivo co…
|
||||
9:33:07 AM [express] GET /api/services/status 200 in 1125ms :: {"services":{"mlBackend":{"name":"ML …
|
||||
9:33:12 AM [express] GET /api/services/status 200 in 40ms :: {"services":{"mlBackend":{"name":"ML Ba…
|
||||
9:33:17 AM [express] GET /api/services/status 200 in 56ms :: {"services":{"mlBackend":{"name":"ML Ba…
|
||||
9:33:22 AM [express] GET /api/services/status 200 in 58ms :: {"services":{"mlBackend":{"name":"ML Ba…
|
||||
9:33:27 AM [express] GET /api/services/status 200 in 57ms :: {"services":{"mlBackend":{"name":"ML Ba…
|
||||
9:33:32 AM [express] GET /api/services/status 200 in 57ms :: {"services":{"mlBackend":{"name":"ML Ba…
|
||||
9:33:37 AM [express] GET /api/services/status 200 in 52ms :: {"services":{"mlBackend":{"name":"ML Ba…
|
||||
9:33:42 AM [express] GET /api/services/status 200 in 77ms :: {"services":{"mlBackend":{"name":"ML Ba…
|
||||
9:33:48 AM [express] GET /api/services/status 200 in 50ms :: {"services":{"mlBackend":{"name":"ML Ba…
|
||||
9:33:53 AM [express] GET /api/services/status 200 in 72ms :: {"services":{"mlBackend":{"name":"ML Ba…
|
||||
9:33:58 AM [express] GET /api/services/status 200 in 69ms :: {"services":{"mlBackend":{"name":"ML Ba…
|
||||
9:34:03 AM [express] GET /api/services/status 200 in 64ms :: {"services":{"mlBackend":{"name":"ML Ba…
|
||||
9:34:08 AM [express] GET /api/services/status 200 in 79ms :: {"services":{"mlBackend":{"name":"ML Ba…
|
||||
@ -0,0 +1,224 @@
|
||||
tail -f /var/log/ids/backend.log
|
||||
[BULK-BLOCK] SLOW: Router 10.20.30.100 took 8000ms for IP 188.8.66.34: This operation was aborted
|
||||
[BULK-BLOCK] SLOW: Router 10.20.30.100 took 8001ms for IP 151.101.193.229: This operation was aborted
|
||||
[BULK-BLOCK] SLOW: Router 10.20.30.100 took 8001ms for IP 109.205.211.40: This operation was aborted
|
||||
[BULK-BLOCK] SLOW: Router 10.20.30.100 took 8001ms for IP 151.59.33.110: This operation was aborted
|
||||
[BULK-BLOCK] SLOW: Router 10.20.30.100 took 8002ms for IP 151.73.209.26: This operation was aborted
|
||||
[BULK-BLOCK] SLOW: Router 10.20.30.100 took 8001ms for IP 79.8.248.29: This operation was aborted
|
||||
[BULK-BLOCK] SLOW: Router 10.20.30.100 took 8001ms for IP 217.202.28.18: This operation was aborted
|
||||
Using standard PostgreSQL database
|
||||
9:13:09 AM [express] serving on port 5000
|
||||
✅ Database connection successful
|
||||
[BLOCK-ALL] Avvio blocco massivo: 100/100 IP con score >= 80 su 2 router
|
||||
[BULK-BLOCK] Starting: 100 IPs on 2 routers (10.20.30.100, 185.203.24.2)
|
||||
[BULK-BLOCK] Router 185.203.24.2: 74 IPs already in list (38ms)
|
||||
9:14:15 AM [express] GET /api/detections 200 in 17ms :: {"detections":[{"id":"fcde52d3-0ae4-4904-a7c…
|
||||
9:14:15 AM [express] GET /api/services/status 200 in 42ms :: {"services":{"mlBackend":{"name":"ML Ba…
|
||||
9:14:20 AM [express] GET /api/detections 200 in 19ms :: {"detections":[{"id":"fcde52d3-0ae4-4904-a7c…
|
||||
9:14:20 AM [express] GET /api/services/status 200 in 20ms :: {"services":{"mlBackend":{"name":"ML Ba…
|
||||
9:14:25 AM [express] GET /api/detections 200 in 7ms :: {"detections":[{"id":"fcde52d3-0ae4-4904-a7cf…
|
||||
9:14:25 AM [express] GET /api/whitelist 200 in 222ms :: {"items":[{"id":"4b7a60b4-b47c-431e-8efa-864…
|
||||
[MIKROTIK] Failed to get address-list from 10.20.30.100: This operation was aborted
|
||||
[BULK-BLOCK] Router 10.20.30.100: 0 IPs already in list (20004ms)
|
||||
[BULK-BLOCK] 0 already blocked, 100 new to block
|
||||
9:14:35 AM [express] GET /api/detections 200 in 8ms :: {"detections":[{"id":"fcde52d3-0ae4-4904-a7cf…
|
||||
9:14:39 AM [express] GET /api/training-history 200 in 5ms :: [{"id":"4306f5a1-b30b-4241-97d9-6b6a1e2…
|
||||
[BULK-BLOCK] SLOW: Router 10.20.30.100 took 8003ms for IP 151.73.24.49: This operation was aborted
|
||||
[BULK-BLOCK] SLOW: Router 10.20.30.100 took 8001ms for IP 104.16.248.249: This operation was aborted
|
||||
[BULK-BLOCK] SLOW: Router 10.20.30.100 took 8001ms for IP 77.39.130.185: This operation was aborted
|
||||
[BULK-BLOCK] SLOW: Router 10.20.30.100 took 8002ms for IP 104.16.249.249: This operation was aborted
|
||||
[BULK-BLOCK] SLOW: Router 10.20.30.100 took 8002ms for IP 104.18.36.146: This operation was aborted
|
||||
[BULK-BLOCK] SLOW: Router 10.20.30.100 took 8003ms for IP 193.205.185.20: This operation was aborted
|
||||
[BULK-BLOCK] SLOW: Router 10.20.30.100 took 8003ms for IP 50.93.53.165: This operation was aborted
|
||||
[BULK-BLOCK] SLOW: Router 10.20.30.100 took 8004ms for IP 91.208.175.82: This operation was aborted
|
||||
[BULK-BLOCK] SLOW: Router 10.20.30.100 took 8004ms for IP 74.0.42.209: This operation was aborted
|
||||
[BULK-BLOCK] SLOW: Router 10.20.30.100 took 8005ms for IP 79.6.115.203: This operation was aborted
|
||||
9:14:50 AM [express] GET /api/detections 200 in 31ms :: {"detections":[{"id":"fcde52d3-0ae4-4904-a7c…
|
||||
9:14:50 AM [express] GET /api/whitelist 200 in 246ms :: {"items":[{"id":"49b5b9a9-4683-452c-a784-fc5…
|
||||
[BULK-BLOCK] SLOW: Router 10.20.30.100 took 8002ms for IP 142.250.181.168: This operation was aborted
|
||||
[BULK-BLOCK] SLOW: Router 10.20.30.100 took 8002ms for IP 195.32.127.72: This operation was aborted
|
||||
[BULK-BLOCK] SLOW: Router 10.20.30.100 took 8002ms for IP 93.150.41.42: This operation was aborted
|
||||
[BULK-BLOCK] SLOW: Router 10.20.30.100 took 8001ms for IP 212.183.171.12: This operation was aborted
|
||||
[BULK-BLOCK] SLOW: Router 10.20.30.100 took 8003ms for IP 78.134.17.204: This operation was aborted
|
||||
[BULK-BLOCK] SLOW: Router 10.20.30.100 took 8002ms for IP 62.94.77.251: This operation was aborted
|
||||
[BULK-BLOCK] SLOW: Router 10.20.30.100 took 8003ms for IP 151.73.24.107: This operation was aborted
|
||||
[BULK-BLOCK] SLOW: Router 10.20.30.100 took 8003ms for IP 74.125.45.108: This operation was aborted
|
||||
[BULK-BLOCK] SLOW: Router 10.20.30.100 took 8003ms for IP 2.42.47.211: This operation was aborted
|
||||
[BULK-BLOCK] SLOW: Router 10.20.30.100 took 8004ms for IP 89.97.31.234: This operation was aborted
|
||||
9:14:52 AM [express] GET /api/dashboard/live 200 in 12ms :: {"totalPackets":75520962,"attackPackets"…
|
||||
[BULK-BLOCK] SLOW: Router 10.20.30.100 took 8002ms for IP 31.197.212.130: This operation was aborted
|
||||
[BULK-BLOCK] SLOW: Router 10.20.30.100 took 8002ms for IP 44.197.141.31: This operation was aborted
|
||||
[BULK-BLOCK] SLOW: Router 10.20.30.100 took 8002ms for IP 146.75.61.140: This operation was aborted
|
||||
[BULK-BLOCK] SLOW: Router 10.20.30.100 took 8002ms for IP 93.150.200.81: This operation was aborted
|
||||
[BULK-BLOCK] SLOW: Router 10.20.30.100 took 8002ms for IP 101.56.92.15: This operation was aborted
|
||||
[BULK-BLOCK] SLOW: Router 10.20.30.100 took 8003ms for IP 2.33.192.82: This operation was aborted
|
||||
[BULK-BLOCK] SLOW: Router 10.20.30.100 took 8003ms for IP 151.41.104.237: This operation was aborted
|
||||
[BULK-BLOCK] SLOW: Router 10.20.30.100 took 8003ms for IP 77.39.220.111: This operation was aborted
|
||||
[BULK-BLOCK] SLOW: Router 10.20.30.100 took 8003ms for IP 185.96.131.245: This operation was aborted
|
||||
[BULK-BLOCK] SLOW: Router 10.20.30.100 took 8004ms for IP 142.250.181.164: This operation was aborted
|
||||
9:15:00 AM [express] GET /api/routers 200 in 16ms :: [{"id":"c6904896-59dc-4060-952f-0e55df7dee4a","…
|
||||
9:15:00 AM [express] GET /api/detections 200 in 24ms :: {"detections":[{"id":"fcde52d3-0ae4-4904-a7c…
|
||||
9:15:00 AM [express] GET /api/services/status 200 in 28ms :: {"services":{"mlBackend":{"name":"ML Ba…
|
||||
9:15:05 AM [express] GET /api/detections 200 in 11ms :: {"detections":[{"id":"fcde52d3-0ae4-4904-a7c…
|
||||
9:15:05 AM [express] GET /api/services/status 200 in 18ms :: {"services":{"mlBackend":{"name":"ML Ba…
|
||||
9:15:06 AM [express] GET /api/stats 200 in 5385ms :: {"routers":{"total":2,"enabled":2},"detections"…
|
||||
[BULK-BLOCK] SLOW: Router 10.20.30.100 took 8001ms for IP 45.146.216.240: This operation was aborted
|
||||
[BULK-BLOCK] SLOW: Router 10.20.30.100 took 8001ms for IP 62.112.11.234: This operation was aborted
|
||||
[BULK-BLOCK] SLOW: Router 10.20.30.100 took 8002ms for IP 51.159.85.76: This operation was aborted
|
||||
[BULK-BLOCK] SLOW: Router 10.20.30.100 took 8001ms for IP 188.8.66.34: This operation was aborted
|
||||
[BULK-BLOCK] SLOW: Router 10.20.30.100 took 8002ms for IP 151.101.193.229: This operation was aborted
|
||||
[BULK-BLOCK] SLOW: Router 10.20.30.100 took 8001ms for IP 109.205.211.40: This operation was aborted
|
||||
[BULK-BLOCK] SLOW: Router 10.20.30.100 took 8003ms for IP 151.59.33.110: This operation was aborted
|
||||
[BULK-BLOCK] SLOW: Router 10.20.30.100 took 8003ms for IP 151.73.209.26: This operation was aborted
|
||||
[BULK-BLOCK] SLOW: Router 10.20.30.100 took 8003ms for IP 79.8.248.29: This operation was aborted
|
||||
[BULK-BLOCK] SLOW: Router 10.20.30.100 took 8003ms for IP 217.202.28.18: This operation was aborted
|
||||
[ANALYTICS QUERY] {
|
||||
startDate: '2026-01-18T08:15:10.899Z',
|
||||
endDate: '2026-02-17T08:15:10.899Z',
|
||||
hourly: true,
|
||||
hourCondition: 'NOT NULL'
|
||||
}
|
||||
[ANALYTICS RESULTS] 41 records found
|
||||
[ANALYTICS SAMPLE] {
|
||||
id: 'b3216c05-7f95-4ba9-a5fb-b37461441401',
|
||||
date: 2026-02-16T00:00:00.000Z,
|
||||
hour: 23,
|
||||
totalPackets: 10463767,
|
||||
totalBytes: 13102201398,
|
||||
uniqueIps: 25472,
|
||||
normalPackets: 10463767,
|
||||
normalBytes: 13102201398,
|
||||
normalUniqueIps: 25472,
|
||||
topNormalIps: '[{"ip": "88.39.149.52", "packets": 3744014, "bytes": 5747025096, "country": null}, {"ip": "79.11.175.156", "packets": 1279527, "bytes": 1892212998, "country": null}, {"ip": "95.229.133.69", "packets": 1188856, "bytes": 1758976078, "country": null}, {"ip": "188.12.75.242", "packets": 1168922, "bytes": 1729133469, "country": null}, {"ip": "95.229.85.134", "packets": 1151191, "bytes": 1703382127, "country": null}, {"ip": "74.125.45.108", "packets": 108382, "bytes": 13501983, "country": "United States"}, {"ip": "185.243.5.22", "packets": 87376, "bytes": 38384352, "country": null}, {"ip": "104.16.248.249", "packets": 72117, "bytes": 40864635, "country": "Canada"}, {"ip": "8.8.8.8", "packets": 66005, "bytes": 18862021, "country": "United States"}, {"ip": "95.110.183.67", "packets": 51456, "bytes": 2281666, "country": "Italy"}]',
|
||||
attackPackets: 0,
|
||||
attackBytes: 0,
|
||||
attackUniqueIps: 0,
|
||||
attacksByCountry: '{}',
|
||||
attacksByType: '{}',
|
||||
topAttackers: '[]',
|
||||
trafficByCountry: '{"Canada": {"normal": 81941, "attacks": 0}, "The Netherlands": {"normal": 49409, "attacks": 0}, "Singapore": {"normal": 61, "attacks": 0}, "Germany": {"normal": 339, "attacks": 0}, "United States":
|
||||
{"normal": 385230, "attacks": 0}, "Italy": {"normal": 73801, "attacks": 0}, "Netherlands": {"normal": 19928, "attacks": 0}}',
|
||||
createdAt: 2026-02-17T00:05:00.185Z
|
||||
}
|
||||
9:15:10 AM [express] GET /api/analytics/recent 200 in 16ms :: [{"id":"b3216c05-7f95-4ba9-a5fb-b37461…
|
||||
9:15:12 AM [express] GET /api/training-history 200 in 3ms :: [{"id":"4306f5a1-b30b-4241-97d9-6b6a1e2…
|
||||
[BULK-BLOCK] SLOW: Router 10.20.30.100 took 7968ms for IP 151.73.139.162: HTTP 401: {"error":401,"message":"Unauthorized"}
|
||||
[BULK-BLOCK] SLOW: Router 10.20.30.100 took 7969ms for IP 217.28.70.122: HTTP 401: {"error":401,"message":"Unauthorized"}
|
||||
[BULK-BLOCK] SLOW: Router 10.20.30.100 took 7971ms for IP 79.9.120.141: HTTP 401: {"error":401,"message":"Unauthorized"}
|
||||
[BULK-BLOCK] SLOW: Router 10.20.30.100 took 7971ms for IP 52.123.129.14: HTTP 401: {"error":401,"message":"Unauthorized"}
|
||||
[BULK-BLOCK] SLOW: Router 10.20.30.100 took 7970ms for IP 157.240.231.35: HTTP 401: {"error":401,"message":"Unauthorized"}
|
||||
[BULK-BLOCK] SLOW: Router 10.20.30.100 took 7975ms for IP 46.229.84.162: HTTP 401: {"error":401,"message":"Unauthorized"}
|
||||
[BULK-BLOCK] SLOW: Router 10.20.30.100 took 7973ms for IP 178.248.182.171: HTTP 401: {"error":401,"message":"Unauthorized"}
|
||||
[BULK-BLOCK] SLOW: Router 10.20.30.100 took 7974ms for IP 93.43.107.86: HTTP 401: {"error":401,"message":"Unauthorized"}
|
||||
[BULK-BLOCK] SLOW: Router 10.20.30.100 took 7974ms for IP 178.248.51.104: HTTP 401: {"error":401,"message":"Unauthorized"}
|
||||
[BULK-BLOCK] SLOW: Router 10.20.30.100 took 7977ms for IP 93.51.52.251: HTTP 401: {"error":401,"message":"Unauthorized"}
|
||||
[BULK-BLOCK] Progress: 50/100
|
||||
9:15:19 AM [express] GET /api/ml/stats 200 in 6466ms :: {"logs":{"total":126216346,"last_hour":0},"d…
|
||||
9:15:22 AM [express] POST /api/ml/train 200 in 10ms :: {"message":"Training avviato in background","…
|
||||
9:15:22 AM [express] GET /api/training-history 304 in 3ms :: [{"id":"4306f5a1-b30b-4241-97d9-6b6a1e2…
|
||||
[BULK-BLOCK] SLOW: Router 10.20.30.100 took 8001ms for IP 85.44.118.45: This operation was aborted
|
||||
[BULK-BLOCK] SLOW: Router 10.20.30.100 took 8001ms for IP 2.228.8.122: This operation was aborted
|
||||
[BULK-BLOCK] SLOW: Router 10.20.30.100 took 8000ms for IP 188.217.110.96: This operation was aborted
|
||||
[BULK-BLOCK] SLOW: Router 10.20.30.100 took 8001ms for IP 151.84.198.239: This operation was aborted
|
||||
[BULK-BLOCK] SLOW: Router 10.20.30.100 took 8002ms for IP 93.54.65.87: This operation was aborted
|
||||
[BULK-BLOCK] SLOW: Router 10.20.30.100 took 8002ms for IP 213.82.166.186: This operation was aborted
|
||||
[BULK-BLOCK] SLOW: Router 10.20.30.100 took 8002ms for IP 23.216.150.137: This operation was aborted
|
||||
[BULK-BLOCK] SLOW: Router 10.20.30.100 took 8002ms for IP 185.110.20.185: This operation was aborted
|
||||
[BULK-BLOCK] SLOW: Router 10.20.30.100 took 8002ms for IP 95.100.171.8: This operation was aborted
|
||||
[BULK-BLOCK] SLOW: Router 10.20.30.100 took 8002ms for IP 79.11.222.236: This operation was aborted
|
||||
9:15:28 AM [express] GET /api/ml/stats 304 in 6490ms :: {"logs":{"total":126216346,"last_hour":0},"d…
|
||||
[BULK-BLOCK] SLOW: Router 10.20.30.100 took 8001ms for IP 85.35.59.252: This operation was aborted
|
||||
[BULK-BLOCK] SLOW: Router 10.20.30.100 took 8001ms for IP 79.10.32.9: This operation was aborted
|
||||
[BULK-BLOCK] SLOW: Router 10.20.30.100 took 8001ms for IP 79.13.197.84: This operation was aborted
|
||||
[BULK-BLOCK] SLOW: Router 10.20.30.100 took 8001ms for IP 94.85.21.211: This operation was aborted
|
||||
[BULK-BLOCK] SLOW: Router 10.20.30.100 took 8001ms for IP 213.215.214.82: This operation was aborted
|
||||
[BULK-BLOCK] SLOW: Router 10.20.30.100 took 8001ms for IP 185.82.114.4: This operation was aborted
|
||||
[BULK-BLOCK] SLOW: Router 10.20.30.100 took 8001ms for IP 5.158.71.206: This operation was aborted
|
||||
[BULK-BLOCK] SLOW: Router 10.20.30.100 took 8001ms for IP 94.34.87.184: This operation was aborted
|
||||
[BULK-BLOCK] SLOW: Router 10.20.30.100 took 8001ms for IP 93.67.251.46: This operation was aborted
|
||||
[BULK-BLOCK] SLOW: Router 10.20.30.100 took 8001ms for IP 31.7.147.21: This operation was aborted
|
||||
9:15:32 AM [express] GET /api/training-history 304 in 15ms :: [{"id":"4306f5a1-b30b-4241-97d9-6b6a1e…
|
||||
[BULK-BLOCK] SLOW: Router 10.20.30.100 took 8001ms for IP 91.187.197.104: This operation was aborted
|
||||
[BULK-BLOCK] SLOW: Router 10.20.30.100 took 8001ms for IP 172.217.38.150: This operation was aborted
|
||||
[BULK-BLOCK] SLOW: Router 10.20.30.100 took 8001ms for IP 217.141.0.110: This operation was aborted
|
||||
[BULK-BLOCK] SLOW: Router 10.20.30.100 took 8001ms for IP 172.217.38.157: This operation was aborted
|
||||
[BULK-BLOCK] SLOW: Router 10.20.30.100 took 8001ms for IP 140.82.121.3: This operation was aborted
|
||||
[BULK-BLOCK] SLOW: Router 10.20.30.100 took 8001ms for IP 95.255.202.79: This operation was aborted
|
||||
[BULK-BLOCK] SLOW: Router 10.20.30.100 took 8001ms for IP 151.58.132.84: This operation was aborted
|
||||
[BULK-BLOCK] SLOW: Router 10.20.30.100 took 8001ms for IP 82.55.154.58: This operation was aborted
|
||||
[BULK-BLOCK] SLOW: Router 10.20.30.100 took 8001ms for IP 62.98.165.6: This operation was aborted
|
||||
[BULK-BLOCK] SLOW: Router 10.20.30.100 took 8001ms for IP 95.110.183.67: This operation was aborted
|
||||
9:15:42 AM [express] GET /api/training-history 304 in 16ms :: [{"id":"4306f5a1-b30b-4241-97d9-6b6a1e…
|
||||
9:15:45 AM [express] GET /api/ml/stats 304 in 7198ms :: {"logs":{"total":126216346,"last_hour":0},"d…
|
||||
[BULK-BLOCK] SLOW: Router 10.20.30.100 took 8001ms for IP 93.40.225.146: This operation was aborted
|
||||
[BULK-BLOCK] SLOW: Router 10.20.30.100 took 8001ms for IP 216.128.11.53: This operation was aborted
|
||||
[BULK-BLOCK] SLOW: Router 10.20.30.100 took 8001ms for IP 95.230.242.4: This operation was aborted
|
||||
[BULK-BLOCK] SLOW: Router 10.20.30.100 took 8001ms for IP 2.118.179.69: This operation was aborted
|
||||
[BULK-BLOCK] SLOW: Router 10.20.30.100 took 8002ms for IP 188.8.204.7: This operation was aborted
|
||||
[BULK-BLOCK] SLOW: Router 10.20.30.100 took 8001ms for IP 185.168.176.197: This operation was aborted
|
||||
[BULK-BLOCK] SLOW: Router 10.20.30.100 took 8002ms for IP 93.64.198.214: This operation was aborted
|
||||
[BULK-BLOCK] SLOW: Router 10.20.30.100 took 8001ms for IP 217.202.56.187: This operation was aborted
|
||||
[BULK-BLOCK] SLOW: Router 10.20.30.100 took 8002ms for IP 5.63.174.25: This operation was aborted
|
||||
[BULK-BLOCK] SLOW: Router 10.20.30.100 took 8001ms for IP 151.64.151.157: This operation was aborted
|
||||
9:15:52 AM [express] GET /api/training-history 304 in 17ms :: [{"id":"4306f5a1-b30b-4241-97d9-6b6a1e…
|
||||
[BULK-BLOCK] SLOW: Router 10.20.30.100 took 8001ms for IP 79.2.176.5: This operation was aborted
|
||||
[BULK-BLOCK] SLOW: Router 10.20.30.100 took 8001ms for IP 82.192.139.100: This operation was aborted
|
||||
[BULK-BLOCK] SLOW: Router 10.20.30.100 took 8001ms for IP 93.40.226.33: This operation was aborted
|
||||
[BULK-BLOCK] SLOW: Router 10.20.30.100 took 8001ms for IP 93.146.168.160: This operation was aborted
|
||||
[BULK-BLOCK] SLOW: Router 10.20.30.100 took 8001ms for IP 94.101.59.182: This operation was aborted
|
||||
[BULK-BLOCK] SLOW: Router 10.20.30.100 took 8001ms for IP 185.104.127.31: This operation was aborted
|
||||
[BULK-BLOCK] SLOW: Router 10.20.30.100 took 8001ms for IP 31.197.212.236: This operation was aborted
|
||||
[BULK-BLOCK] SLOW: Router 10.20.30.100 took 8000ms for IP 79.3.132.252: This operation was aborted
|
||||
[BULK-BLOCK] SLOW: Router 10.20.30.100 took 8001ms for IP 172.217.38.148: This operation was aborted
|
||||
[BULK-BLOCK] SLOW: Router 10.20.30.100 took 8001ms for IP 172.217.38.151: This operation was aborted
|
||||
[BULK-BLOCK] Progress: 100/100
|
||||
[BULK-BLOCK] Router 10.20.30.100: 0 blocked, 100 failed, 0 skipped
|
||||
[BULK-BLOCK] Router 185.203.24.2: 50 blocked, 0 failed, 50 skipped
|
||||
[BULK-BLOCK] Done: 100 blocked, 0 failed, 0 skipped
|
||||
[BLOCK-ALL] Database aggiornato: 100 IP marcati come bloccati
|
||||
9:15:55 AM [express] POST /api/ml/block-all-critical 200 in 100172ms :: {"message":"Blocco massivo c…
|
||||
9:16:02 AM [express] GET /api/training-history 304 in 2ms :: [{"id":"4306f5a1-b30b-4241-97d9-6b6a1e2…
|
||||
9:16:02 AM [express] GET /api/ml/stats 200 in 6527ms :: {"logs":{"total":126216346,"last_hour":0},"d…
|
||||
9:16:12 AM [express] GET /api/training-history 304 in 13ms :: [{"id":"4306f5a1-b30b-4241-97d9-6b6a1e…
|
||||
9:16:19 AM [express] GET /api/ml/stats 304 in 6558ms :: {"logs":{"total":126216346,"last_hour":0},"d…
|
||||
9:16:19 AM [express] POST /api/ml/block-all-critical 200 in 76ms :: {"message":"Nessun IP critico da…
|
||||
9:16:22 AM [express] GET /api/training-history 304 in 3ms :: [{"id":"4306f5a1-b30b-4241-97d9-6b6a1e2…
|
||||
9:16:29 AM [express] GET /api/training-history 304 in 3ms :: [{"id":"4306f5a1-b30b-4241-97d9-6b6a1e2…
|
||||
9:16:35 AM [express] GET /api/ml/stats 304 in 6623ms :: {"logs":{"total":126216346,"last_hour":0},"d…
|
||||
9:16:39 AM [express] GET /api/training-history 304 in 13ms :: [{"id":"4306f5a1-b30b-4241-97d9-6b6a1e…
|
||||
9:16:49 AM [express] GET /api/training-history 304 in 14ms :: [{"id":"4306f5a1-b30b-4241-97d9-6b6a1e…
|
||||
9:16:59 AM [express] GET /api/training-history 304 in 15ms :: [{"id":"4306f5a1-b30b-4241-97d9-6b6a1e…
|
||||
[ML Stats] Fallback to database - ML Backend error: This operation was aborted
|
||||
9:17:06 AM [express] GET /api/ml/stats 200 in 20345ms :: {"source":"database_fallback","ml_backend_s…
|
||||
9:17:08 AM [express] GET /api/detections 200 in 21ms :: {"detections":[{"id":"fcde52d3-0ae4-4904-a7c…
|
||||
9:17:08 AM [express] GET /api/routers 200 in 21ms :: [{"id":"c6904896-59dc-4060-952f-0e55df7dee4a","…
|
||||
9:17:13 AM [express] GET /api/services/status 200 in 5007ms :: {"services":{"mlBackend":{"name":"ML …
|
||||
9:17:13 AM [express] GET /api/detections 304 in 8ms :: {"detections":[{"id":"fcde52d3-0ae4-4904-a7cf…
|
||||
9:17:14 AM [express] GET /api/stats 200 in 5393ms :: {"routers":{"total":2,"enabled":2},"detections"…
|
||||
9:17:18 AM [express] GET /api/detections 304 in 7ms :: {"detections":[{"id":"fcde52d3-0ae4-4904-a7cf…
|
||||
9:17:23 AM [express] GET /api/services/status 304 in 5006ms :: {"services":{"mlBackend":{"name":"ML …
|
||||
9:17:23 AM [express] GET /api/detections 304 in 7ms :: {"detections":[{"id":"fcde52d3-0ae4-4904-a7cf…
|
||||
9:17:28 AM [express] GET /api/services/status 200 in 85ms :: {"services":{"mlBackend":{"name":"ML Ba…
|
||||
9:17:28 AM [express] GET /api/detections 304 in 8ms :: {"detections":[{"id":"fcde52d3-0ae4-4904-a7cf…
|
||||
9:17:29 AM [express] GET /api/stats 304 in 5314ms :: {"routers":{"total":2,"enabled":2},"detections"…
|
||||
9:17:33 AM [express] GET /api/services/status 200 in 29ms :: {"services":{"mlBackend":{"name":"ML Ba…
|
||||
9:17:33 AM [express] GET /api/detections 304 in 7ms :: {"detections":[{"id":"fcde52d3-0ae4-4904-a7cf…
|
||||
9:17:38 AM [express] GET /api/services/status 200 in 53ms :: {"services":{"mlBackend":{"name":"ML Ba…
|
||||
9:17:39 AM [express] GET /api/detections 304 in 7ms :: {"detections":[{"id":"fcde52d3-0ae4-4904-a7cf…
|
||||
9:17:43 AM [express] GET /api/services/status 200 in 70ms :: {"services":{"mlBackend":{"name":"ML Ba…
|
||||
9:17:44 AM [express] GET /api/detections 304 in 8ms :: {"detections":[{"id":"fcde52d3-0ae4-4904-a7cf…
|
||||
9:17:44 AM [express] GET /api/stats 304 in 5395ms :: {"routers":{"total":2,"enabled":2},"detections"…
|
||||
9:17:49 AM [express] GET /api/services/status 200 in 47ms :: {"services":{"mlBackend":{"name":"ML Ba…
|
||||
9:17:49 AM [express] GET /api/detections 304 in 7ms :: {"detections":[{"id":"fcde52d3-0ae4-4904-a7cf…
|
||||
9:17:54 AM [express] GET /api/detections 304 in 12ms :: {"detections":[{"id":"fcde52d3-0ae4-4904-a7c…
|
||||
9:17:54 AM [express] GET /api/services/status 200 in 61ms :: {"services":{"mlBackend":{"name":"ML Ba…
|
||||
9:17:59 AM [express] GET /api/detections 304 in 11ms :: {"detections":[{"id":"fcde52d3-0ae4-4904-a7c…
|
||||
9:17:59 AM [express] GET /api/services/status 200 in 30ms :: {"services":{"mlBackend":{"name":"ML Ba…
|
||||
9:18:00 AM [express] GET /api/stats 304 in 5405ms :: {"routers":{"total":2,"enabled":2},"detections"…
|
||||
9:18:04 AM [express] GET /api/detections 304 in 7ms :: {"detections":[{"id":"fcde52d3-0ae4-4904-a7cf…
|
||||
9:18:04 AM [express] GET /api/services/status 200 in 64ms :: {"services":{"mlBackend":{"name":"ML Ba…
|
||||
9:18:09 AM [express] GET /api/detections 304 in 8ms :: {"detections":[{"id":"fcde52d3-0ae4-4904-a7cf…
|
||||
9:18:09 AM [express] GET /api/services/status 200 in 21ms :: {"services":{"mlBackend":{"name":"ML Ba…
|
||||
9:18:14 AM [express] GET /api/detections 304 in 21ms :: {"detections":[{"id":"fcde52d3-0ae4-4904-a7c…
|
||||
9:18:15 AM [express] GET /api/stats 304 in 5344ms :: {"routers":{"total":2,"enabled":2},"detections"…
|
||||
|
||||
@ -0,0 +1,158 @@
|
||||
echo "=== 1. STATO SERVIZI ===" && systemctl status ids-backend ids-ml-backend ids-syslog-parser ids-analytics ids-auto-block.timer ids-auto-block.service --no-pager -l 2>&1 | tail -80 && echo "=== 2. LOG
|
||||
NODE.JS ===" && journalctl -u ids-backend --no-pager -n 50 && echo "=== 3. LOG ML ===" && journalctl -u ids-ml-backend --no-pager -n 50 && echo "=== 4. LOG AUTO-BLOCK ===" && journalctl -u ids-auto-block --no-pager -n 50 && echo "=== 5. LOG SYSLOG ===" && journalctl -u ids-syslog-parser --no-pager -n 30 && echo "=== 6. PORTE ===" && ss -tlnp | grep -E '3001|5001|514' && echo "=== 7. PROCESSI ===" && ps aux | grep -E 'node|python|uvicorn' | grep -v grep && echo "=== 8. DISCO/MEMORIA ===" && df -h / && free -h && echo "=== 9. TEST CONNESSIONE ===" && curl -s -o /dev/null -w "%{http_code} - Node.js backend\n" http://localhost:3001/api/health && curl -s -o /dev/null -w "%{http_code} - ML backend\n" http://localhost:5001/health && echo "=== 10. LOG DB ===" && sudo -u ids psql -d ids_db -c "SELECT COUNT(*) as logs_last_30min FROM network_logs WHERE timestamp > NOW() - INTERVAL '30 minutes';"
|
||||
=== 1. STATO SERVIZI ===
|
||||
Unit ids-backend.service could not be found.
|
||||
Unit ids-analytics.service could not be found.
|
||||
● ids-ml-backend.service - IDS ML Backend (FastAPI)
|
||||
Loaded: loaded (/etc/systemd/system/ids-ml-backend.service; enabled; preset: disabled)
|
||||
Active: active (running) since Mon 2026-02-16 19:29:06 CET; 13h ago
|
||||
Main PID: 17629 (python3)
|
||||
Tasks: 26 (limit: 100409)
|
||||
Memory: 75.8M (max: 2.0G available: 1.9G)
|
||||
CPU: 40.396s
|
||||
CGroup: /system.slice/ids-ml-backend.service
|
||||
└─17629 /opt/ids/python_ml/venv/bin/python3 main.py
|
||||
|
||||
Feb 16 19:29:06 ids.alfacom.it systemd[1]: Started IDS ML Backend (FastAPI).
|
||||
|
||||
● ids-syslog-parser.service - IDS Syslog Parser (Network Logs Processor)
|
||||
Loaded: loaded (/etc/systemd/system/ids-syslog-parser.service; enabled; preset: disabled)
|
||||
Active: active (running) since Mon 2026-02-16 12:18:52 CET; 20h ago
|
||||
Main PID: 1069 (python3)
|
||||
Tasks: 1 (limit: 100409)
|
||||
Memory: 9.7M (max: 1.0G available: 1014.2M)
|
||||
CPU: 1h 59min 34.173s
|
||||
CGroup: /system.slice/ids-syslog-parser.service
|
||||
└─1069 /opt/ids/python_ml/venv/bin/python3 syslog_parser.py
|
||||
|
||||
Feb 16 12:18:52 ids.alfacom.it systemd[1]: Started IDS Syslog Parser (Network Logs Processor).
|
||||
|
||||
● ids-auto-block.timer - IDS Auto-Blocking Timer - Run every 5 minutes
|
||||
Loaded: loaded (/etc/systemd/system/ids-auto-block.timer; enabled; preset: disabled)
|
||||
Active: active (running) since Mon 2026-02-16 19:24:04 CET; 13h ago
|
||||
Until: Mon 2026-02-16 19:24:04 CET; 13h ago
|
||||
Trigger: n/a
|
||||
Triggers: ● ids-auto-block.service
|
||||
Docs: https://github.com/yourusername/ids
|
||||
|
||||
Feb 16 19:24:04 ids.alfacom.it systemd[1]: Started IDS Auto-Blocking Timer - Run every 5 minutes.
|
||||
|
||||
● ids-auto-block.service - IDS Auto-Blocking Service - Detect and Block Malicious IPs
|
||||
Loaded: loaded (/etc/systemd/system/ids-auto-block.service; disabled; preset: disabled)
|
||||
Active: activating (start) since Tue 2026-02-17 08:33:33 CET; 3min 14s ago
|
||||
TriggeredBy: ● ids-auto-block.timer
|
||||
Main PID: 30644 (python3)
|
||||
Tasks: 1 (limit: 100409)
|
||||
Memory: 14.7M
|
||||
CPU: 148ms
|
||||
CGroup: /system.slice/ids-auto-block.service
|
||||
└─30644 /opt/ids/python_ml/venv/bin/python3 /opt/ids/python_ml/auto_block.py
|
||||
|
||||
Feb 17 08:33:33 ids.alfacom.it systemd[1]: Starting IDS Auto-Blocking Service - Detect and Block Malicious IPs...
|
||||
=== 2. LOG NODE.JS ===
|
||||
-- No entries --
|
||||
=== 3. LOG ML ===
|
||||
Feb 16 15:51:21 ids.alfacom.it systemd[1]: ids-ml-backend.service: Killing process 12676 (n/a) with signal SIGKILL.
|
||||
Feb 16 15:51:21 ids.alfacom.it systemd[1]: ids-ml-backend.service: Killing process 12677 (n/a) with signal SIGKILL.
|
||||
Feb 16 15:51:21 ids.alfacom.it systemd[1]: ids-ml-backend.service: Killing process 12681 (n/a) with signal SIGKILL.
|
||||
Feb 16 15:51:21 ids.alfacom.it systemd[1]: ids-ml-backend.service: Killing process 12682 (n/a) with signal SIGKILL.
|
||||
Feb 16 15:51:21 ids.alfacom.it systemd[1]: ids-ml-backend.service: Killing process 12684 (python3) with signal SIGKILL.
|
||||
Feb 16 15:51:21 ids.alfacom.it systemd[1]: ids-ml-backend.service: Main process exited, code=killed, status=9/KILL
|
||||
Feb 16 15:51:21 ids.alfacom.it systemd[1]: ids-ml-backend.service: Failed with result 'timeout'.
|
||||
Feb 16 15:51:21 ids.alfacom.it systemd[1]: Stopped IDS ML Backend (FastAPI).
|
||||
Feb 16 15:51:21 ids.alfacom.it systemd[1]: ids-ml-backend.service: Consumed 9.526s CPU time.
|
||||
Feb 16 15:51:26 ids.alfacom.it systemd[1]: Started IDS ML Backend (FastAPI).
|
||||
Feb 16 16:50:11 ids.alfacom.it systemd[1]: Stopping IDS ML Backend (FastAPI)...
|
||||
Feb 16 16:51:41 ids.alfacom.it systemd[1]: ids-ml-backend.service: State 'stop-sigterm' timed out. Killing.
|
||||
Feb 16 16:51:41 ids.alfacom.it systemd[1]: ids-ml-backend.service: Killing process 13099 (python3) with signal SIGKILL.
|
||||
Feb 16 16:51:41 ids.alfacom.it systemd[1]: ids-ml-backend.service: Killing process 13102 (python3) with signal SIGKILL.
|
||||
Feb 16 16:51:41 ids.alfacom.it systemd[1]: ids-ml-backend.service: Killing process 13103 (n/a) with signal SIGKILL.
|
||||
Feb 16 16:51:41 ids.alfacom.it systemd[1]: ids-ml-backend.service: Killing process 13110 (n/a) with signal SIGKILL.
|
||||
Feb 16 16:51:41 ids.alfacom.it systemd[1]: ids-ml-backend.service: Killing process 13112 (n/a) with signal SIGKILL.
|
||||
Feb 16 16:51:41 ids.alfacom.it systemd[1]: ids-ml-backend.service: Killing process 13116 (n/a) with signal SIGKILL.
|
||||
Feb 16 16:51:41 ids.alfacom.it systemd[1]: ids-ml-backend.service: Killing process 13117 (python3) with signal SIGKILL.
|
||||
Feb 16 16:51:41 ids.alfacom.it systemd[1]: ids-ml-backend.service: Killing process 13122 (python3) with signal SIGKILL.
|
||||
Feb 16 16:51:41 ids.alfacom.it systemd[1]: ids-ml-backend.service: Killing process 13125 (n/a) with signal SIGKILL.
|
||||
Feb 16 16:51:41 ids.alfacom.it systemd[1]: ids-ml-backend.service: Main process exited, code=killed, status=9/KILL
|
||||
Feb 16 16:51:41 ids.alfacom.it systemd[1]: ids-ml-backend.service: Failed with result 'timeout'.
|
||||
Feb 16 16:51:41 ids.alfacom.it systemd[1]: Stopped IDS ML Backend (FastAPI).
|
||||
Feb 16 16:51:41 ids.alfacom.it systemd[1]: ids-ml-backend.service: Consumed 15.919s CPU time.
|
||||
Feb 16 16:51:46 ids.alfacom.it systemd[1]: Started IDS ML Backend (FastAPI).
|
||||
Feb 16 19:27:20 ids.alfacom.it systemd[1]: Stopping IDS ML Backend (FastAPI)...
|
||||
Feb 16 19:28:50 ids.alfacom.it systemd[1]: ids-ml-backend.service: State 'stop-sigterm' timed out. Killing.
|
||||
Feb 16 19:28:50 ids.alfacom.it systemd[1]: ids-ml-backend.service: Killing process 14614 (python3) with signal SIGKILL.
|
||||
Feb 16 19:28:50 ids.alfacom.it systemd[1]: ids-ml-backend.service: Killing process 14619 (python3) with signal SIGKILL.
|
||||
Feb 16 19:28:50 ids.alfacom.it systemd[1]: ids-ml-backend.service: Killing process 14626 (python3) with signal SIGKILL.
|
||||
Feb 16 19:28:50 ids.alfacom.it systemd[1]: ids-ml-backend.service: Killing process 14675 (n/a) with signal SIGKILL.
|
||||
Feb 16 19:28:50 ids.alfacom.it systemd[1]: ids-ml-backend.service: Killing process 14676 (python3) with signal SIGKILL.
|
||||
Feb 16 19:28:50 ids.alfacom.it systemd[1]: ids-ml-backend.service: Killing process 14677 (python3) with signal SIGKILL.
|
||||
Feb 16 19:28:50 ids.alfacom.it systemd[1]: ids-ml-backend.service: Killing process 14678 (python3) with signal SIGKILL.
|
||||
Feb 16 19:28:50 ids.alfacom.it systemd[1]: ids-ml-backend.service: Killing process 14679 (python3) with signal SIGKILL.
|
||||
Feb 16 19:28:50 ids.alfacom.it systemd[1]: ids-ml-backend.service: Killing process 14680 (python3) with signal SIGKILL.
|
||||
Feb 16 19:28:50 ids.alfacom.it systemd[1]: ids-ml-backend.service: Killing process 14681 (python3) with signal SIGKILL.
|
||||
Feb 16 19:28:50 ids.alfacom.it systemd[1]: ids-ml-backend.service: Killing process 14682 (python3) with signal SIGKILL.
|
||||
Feb 16 19:28:50 ids.alfacom.it systemd[1]: ids-ml-backend.service: Killing process 14683 (python3) with signal SIGKILL.
|
||||
Feb 16 19:28:50 ids.alfacom.it systemd[1]: ids-ml-backend.service: Main process exited, code=killed, status=9/KILL
|
||||
Feb 16 19:28:50 ids.alfacom.it systemd[1]: ids-ml-backend.service: Failed with result 'timeout'.
|
||||
Feb 16 19:28:50 ids.alfacom.it systemd[1]: Stopped IDS ML Backend (FastAPI).
|
||||
Feb 16 19:28:50 ids.alfacom.it systemd[1]: ids-ml-backend.service: Consumed 15.247s CPU time.
|
||||
Feb 16 19:28:50 ids.alfacom.it systemd[1]: Started IDS ML Backend (FastAPI).
|
||||
Feb 16 19:29:00 ids.alfacom.it systemd[1]: Stopping IDS ML Backend (FastAPI)...
|
||||
Feb 16 19:29:01 ids.alfacom.it systemd[1]: ids-ml-backend.service: Deactivated successfully.
|
||||
Feb 16 19:29:01 ids.alfacom.it systemd[1]: Stopped IDS ML Backend (FastAPI).
|
||||
Feb 16 19:29:01 ids.alfacom.it systemd[1]: ids-ml-backend.service: Consumed 4.113s CPU time.
|
||||
Feb 16 19:29:06 ids.alfacom.it systemd[1]: Started IDS ML Backend (FastAPI).
|
||||
=== 4. LOG AUTO-BLOCK ===
|
||||
Feb 17 07:45:29 ids.alfacom.it systemd[1]: Failed to start IDS Auto-Blocking Service - Detect and Block Malicious IPs.
|
||||
Feb 17 07:45:29 ids.alfacom.it systemd[1]: Starting IDS Auto-Blocking Service - Detect and Block Malicious IPs...
|
||||
Feb 17 07:49:30 ids.alfacom.it systemd[1]: ids-auto-block.service: Main process exited, code=exited, status=1/FAILURE
|
||||
Feb 17 07:49:30 ids.alfacom.it systemd[1]: ids-auto-block.service: Failed with result 'exit-code'.
|
||||
Feb 17 07:49:30 ids.alfacom.it systemd[1]: Failed to start IDS Auto-Blocking Service - Detect and Block Malicious IPs.
|
||||
Feb 17 07:49:30 ids.alfacom.it systemd[1]: Starting IDS Auto-Blocking Service - Detect and Block Malicious IPs...
|
||||
Feb 17 07:53:30 ids.alfacom.it systemd[1]: ids-auto-block.service: Main process exited, code=exited, status=1/FAILURE
|
||||
Feb 17 07:53:30 ids.alfacom.it systemd[1]: ids-auto-block.service: Failed with result 'exit-code'.
|
||||
Feb 17 07:53:30 ids.alfacom.it systemd[1]: Failed to start IDS Auto-Blocking Service - Detect and Block Malicious IPs.
|
||||
Feb 17 07:53:30 ids.alfacom.it systemd[1]: Starting IDS Auto-Blocking Service - Detect and Block Malicious IPs...
|
||||
Feb 17 07:57:30 ids.alfacom.it systemd[1]: ids-auto-block.service: Main process exited, code=exited, status=1/FAILURE
|
||||
Feb 17 07:57:30 ids.alfacom.it systemd[1]: ids-auto-block.service: Failed with result 'exit-code'.
|
||||
Feb 17 07:57:30 ids.alfacom.it systemd[1]: Failed to start IDS Auto-Blocking Service - Detect and Block Malicious IPs.
|
||||
Feb 17 07:57:30 ids.alfacom.it systemd[1]: Starting IDS Auto-Blocking Service - Detect and Block Malicious IPs...
|
||||
Feb 17 08:01:31 ids.alfacom.it systemd[1]: ids-auto-block.service: Main process exited, code=exited, status=1/FAILURE
|
||||
Feb 17 08:01:31 ids.alfacom.it systemd[1]: ids-auto-block.service: Failed with result 'exit-code'.
|
||||
Feb 17 08:01:31 ids.alfacom.it systemd[1]: Failed to start IDS Auto-Blocking Service - Detect and Block Malicious IPs.
|
||||
Feb 17 08:01:31 ids.alfacom.it systemd[1]: Starting IDS Auto-Blocking Service - Detect and Block Malicious IPs...
|
||||
Feb 17 08:05:31 ids.alfacom.it systemd[1]: ids-auto-block.service: Main process exited, code=exited, status=1/FAILURE
|
||||
Feb 17 08:05:31 ids.alfacom.it systemd[1]: ids-auto-block.service: Failed with result 'exit-code'.
|
||||
Feb 17 08:05:31 ids.alfacom.it systemd[1]: Failed to start IDS Auto-Blocking Service - Detect and Block Malicious IPs.
|
||||
Feb 17 08:05:31 ids.alfacom.it systemd[1]: Starting IDS Auto-Blocking Service - Detect and Block Malicious IPs...
|
||||
Feb 17 08:09:31 ids.alfacom.it systemd[1]: ids-auto-block.service: Main process exited, code=exited, status=1/FAILURE
|
||||
Feb 17 08:09:31 ids.alfacom.it systemd[1]: ids-auto-block.service: Failed with result 'exit-code'.
|
||||
Feb 17 08:09:31 ids.alfacom.it systemd[1]: Failed to start IDS Auto-Blocking Service - Detect and Block Malicious IPs.
|
||||
Feb 17 08:09:31 ids.alfacom.it systemd[1]: Starting IDS Auto-Blocking Service - Detect and Block Malicious IPs...
|
||||
Feb 17 08:13:32 ids.alfacom.it systemd[1]: ids-auto-block.service: Main process exited, code=exited, status=1/FAILURE
|
||||
Feb 17 08:13:32 ids.alfacom.it systemd[1]: ids-auto-block.service: Failed with result 'exit-code'.
|
||||
Feb 17 08:13:32 ids.alfacom.it systemd[1]: Failed to start IDS Auto-Blocking Service - Detect and Block Malicious IPs.
|
||||
Feb 17 08:13:32 ids.alfacom.it systemd[1]: Starting IDS Auto-Blocking Service - Detect and Block Malicious IPs...
|
||||
Feb 17 08:17:32 ids.alfacom.it systemd[1]: ids-auto-block.service: Main process exited, code=exited, status=1/FAILURE
|
||||
Feb 17 08:17:32 ids.alfacom.it systemd[1]: ids-auto-block.service: Failed with result 'exit-code'.
|
||||
Feb 17 08:17:32 ids.alfacom.it systemd[1]: Failed to start IDS Auto-Blocking Service - Detect and Block Malicious IPs.
|
||||
Feb 17 08:17:32 ids.alfacom.it systemd[1]: Starting IDS Auto-Blocking Service - Detect and Block Malicious IPs...
|
||||
Feb 17 08:21:32 ids.alfacom.it systemd[1]: ids-auto-block.service: Main process exited, code=exited, status=1/FAILURE
|
||||
Feb 17 08:21:32 ids.alfacom.it systemd[1]: ids-auto-block.service: Failed with result 'exit-code'.
|
||||
Feb 17 08:21:32 ids.alfacom.it systemd[1]: Failed to start IDS Auto-Blocking Service - Detect and Block Malicious IPs.
|
||||
Feb 17 08:21:32 ids.alfacom.it systemd[1]: Starting IDS Auto-Blocking Service - Detect and Block Malicious IPs...
|
||||
Feb 17 08:25:33 ids.alfacom.it systemd[1]: ids-auto-block.service: Main process exited, code=exited, status=1/FAILURE
|
||||
Feb 17 08:25:33 ids.alfacom.it systemd[1]: ids-auto-block.service: Failed with result 'exit-code'.
|
||||
Feb 17 08:25:33 ids.alfacom.it systemd[1]: Failed to start IDS Auto-Blocking Service - Detect and Block Malicious IPs.
|
||||
Feb 17 08:25:33 ids.alfacom.it systemd[1]: Starting IDS Auto-Blocking Service - Detect and Block Malicious IPs...
|
||||
Feb 17 08:29:33 ids.alfacom.it systemd[1]: ids-auto-block.service: Main process exited, code=exited, status=1/FAILURE
|
||||
Feb 17 08:29:33 ids.alfacom.it systemd[1]: ids-auto-block.service: Failed with result 'exit-code'.
|
||||
Feb 17 08:29:33 ids.alfacom.it systemd[1]: Failed to start IDS Auto-Blocking Service - Detect and Block Malicious IPs.
|
||||
Feb 17 08:29:33 ids.alfacom.it systemd[1]: Starting IDS Auto-Blocking Service - Detect and Block Malicious IPs...
|
||||
Feb 17 08:33:33 ids.alfacom.it systemd[1]: ids-auto-block.service: Main process exited, code=exited, status=1/FAILURE
|
||||
Feb 17 08:33:33 ids.alfacom.it systemd[1]: ids-auto-block.service: Failed with result 'exit-code'.
|
||||
Feb 17 08:33:33 ids.alfacom.it systemd[1]: Failed to start IDS Auto-Blocking Service - Detect and Block Malicious IPs.
|
||||
Feb 17 08:33:33 ids.alfacom.it systemd[1]: Starting IDS Auto-Blocking Service - Detect and Block Malicious IPs...
|
||||
=== 5. LOG SYSLOG ===
|
||||
Feb 16 12:18:52 ids.alfacom.it systemd[1]: Started IDS Syslog Parser (Network Logs Processor).
|
||||
=== 6. PORTE ===
|
||||
@ -0,0 +1,110 @@
|
||||
echo "=== VERIFICA BACKEND NODE.JS ===" && ls -la /etc/systemd/system/ids-*.service /etc/systemd/system/ids-*.timer && echo "=== FILE SERVICE DISPONIBILI ===" && cat /etc/systemd/system/ids-backend.service 2>&1 || echo "FILE NON TROVATO" && echo "=== NGINX/REVERSE PROXY ===" && ss -tlnp | grep -E '80|443|3001|5001' && echo "=== TEST PORTA 3001 ===" && curl -v --connect-timeout 5 http://localhost:3001/api/health 2>&1 && echo "=== COME VIENE AVVIATO NODE.JS ===" && ps aux | grep -i node | grep -v grep && echo "=== PM2 STATUS ===" && pm2 list 2>&1 || echo "PM2 non installato" && echo "=== CONTENUTO /opt/ids/ ===" && ls -la /opt/ids/ && echo "=== PACKAGE.JSON ===" && cat /opt/ids/package.json 2>&1 | head -30 && echo "=== AUTO_BLOCK OUTPUT DETTAGLIATO ===" && sudo -u ids /opt/ids/python_ml/venv/bin/python3 /opt/ids/python_ml/auto_block.py 2>&1
|
||||
=== VERIFICA BACKEND NODE.JS ===
|
||||
-rw-r--r--. 1 root root 473 Feb 16 15:52 /etc/systemd/system/ids-analytics-aggregator.service
|
||||
-rw-r--r--. 1 root root 339 Feb 16 15:52 /etc/systemd/system/ids-analytics-aggregator.timer
|
||||
-rw-r--r--. 1 root root 674 Feb 16 19:23 /etc/systemd/system/ids-auto-block.service
|
||||
-rw-r--r--. 1 root root 457 Feb 14 11:42 /etc/systemd/system/ids-auto-block.timer
|
||||
-rw-r--r--. 1 root root 550 Nov 25 11:47 /etc/systemd/system/ids-cleanup.service
|
||||
-rw-r--r--. 1 root root 440 Nov 25 11:47 /etc/systemd/system/ids-cleanup.timer
|
||||
-rw-r--r--. 1 root root 623 Nov 27 19:29 /etc/systemd/system/ids-list-fetcher.service
|
||||
-rw-r--r--. 1 root root 246 Nov 27 19:29 /etc/systemd/system/ids-list-fetcher.timer
|
||||
-rw-r--r--. 1 root root 675 Nov 24 12:12 /etc/systemd/system/ids-ml-backend.service
|
||||
-rw-r--r--. 1 root root 620 Nov 24 19:19 /etc/systemd/system/ids-ml-training.service
|
||||
-rw-r--r--. 1 root root 398 Nov 24 19:19 /etc/systemd/system/ids-ml-training.timer
|
||||
-rw-r--r--. 1 root root 727 Nov 24 12:12 /etc/systemd/system/ids-syslog-parser.service
|
||||
=== FILE SERVICE DISPONIBILI ===
|
||||
cat: /etc/systemd/system/ids-backend.service: No such file or directory
|
||||
FILE NON TROVATO
|
||||
=== NGINX/REVERSE PROXY ===
|
||||
LISTEN 1107 2048 0.0.0.0:8000 0.0.0.0:* users:(("python3",pid=17629,fd=12))
|
||||
=== TEST PORTA 3001 ===
|
||||
* Trying ::1:3001...
|
||||
* connect to ::1 port 3001 failed: Connection refused
|
||||
* Trying 127.0.0.1:3001...
|
||||
* connect to 127.0.0.1 port 3001 failed: Connection refused
|
||||
* Failed to connect to localhost port 3001: Connection refused
|
||||
* Closing connection 0
|
||||
curl: (7) Failed to connect to localhost port 3001: Connection refused
|
||||
PM2 non installato
|
||||
=== CONTENUTO /opt/ids/ ===
|
||||
total 608
|
||||
drwxr-xr-x. 14 ids ids 4096 Feb 16 19:28 .
|
||||
drwxr-xr-x. 3 root root 43 Nov 17 18:20 ..
|
||||
-rw-------. 1 ids ids 508 Feb 16 19:28 .env
|
||||
-rw-r-----. 1 root root 508 Feb 16 19:28 .env.backup
|
||||
-rw-r--r--. 1 ids ids 446 Nov 17 18:23 .env.example
|
||||
drwxr-xr-x. 8 ids ids 4096 Feb 16 19:28 .git
|
||||
-rw-r--r--. 1 ids ids 686 Nov 17 18:23 .gitignore
|
||||
-rw-r--r--. 1 ids ids 801 Jan 2 12:50 .replit
|
||||
-rw-r--r--. 1 ids ids 6264 Nov 17 17:08 GUIDA_INSTALLAZIONE.md
|
||||
-rw-r--r--. 1 ids ids 44765 Feb 16 08:50 IDS_Conformita_ISO27001.docx
|
||||
-rw-r--r--. 1 ids ids 7595 Nov 25 19:14 MIKROTIK_API_FIX.md
|
||||
-rw-r--r--. 1 ids ids 8452 Nov 17 16:40 README.md
|
||||
-rw-r--r--. 1 ids ids 9092 Nov 17 16:40 RISPOSTA_DEPLOYMENT.md
|
||||
drwxr-xr-x. 2 ids ids 12288 Feb 16 16:49 attached_assets
|
||||
drwxr-xr-x. 2 ids ids 4096 Feb 17 04:00 backups
|
||||
drwxr-xr-x. 4 ids ids 49 Nov 17 16:40 client
|
||||
-rw-r--r--. 1 ids ids 459 Nov 17 16:40 components.json
|
||||
drwxr-xr-x. 3 ids ids 4096 Feb 16 19:28 database-schema
|
||||
-rwxr-xr-x. 1 ids ids 10264 Nov 17 18:23 deploy-to-gitlab.sh
|
||||
drwxr-xr-x. 7 ids ids 4096 Feb 16 19:28 deployment
|
||||
-rw-r--r--. 1 ids ids 3165 Nov 17 16:40 design_guidelines.md
|
||||
drwxr-xr-x. 3 root root 36 Nov 24 11:05 dist
|
||||
-rw-r--r--. 1 ids ids 325 Nov 17 16:40 drizzle.config.ts
|
||||
drwxr-xr-x. 4 ids ids 4096 Nov 17 16:40 extracted_idf
|
||||
-rw-r--r--. 1 ids ids 28609 Feb 16 08:50 generate_iso27001_doc.py
|
||||
-rw-r--r--. 1 ids ids 1033 Nov 17 17:08 git.env.example
|
||||
-rw-r--r--. 1 ids ids 96 Nov 26 11:14 main.py
|
||||
drwxr-xr-x. 328 ids ids 12288 Feb 16 19:28 node_modules
|
||||
-rw-r--r--. 1 ids ids 299523 Feb 16 19:28 package-lock.json
|
||||
-rw-r--r--. 1 ids ids 3696 Nov 17 16:40 package.json
|
||||
-rw-r--r--. 1 ids ids 80 Nov 17 16:40 postcss.config.js
|
||||
-rwxr-xr-x. 1 ids ids 2496 Nov 17 16:40 push-gitlab.sh
|
||||
-rw-r--r--. 1 ids ids 191 Feb 16 08:50 pyproject.toml
|
||||
drwxr-xr-x. 7 ids ids 4096 Feb 16 16:49 python_ml
|
||||
-rw-r--r--. 1 ids ids 5796 Feb 16 12:33 replit.md
|
||||
drwxr-xr-x. 2 ids ids 104 Feb 16 12:55 server
|
||||
drwxr-xr-x. 2 ids ids 23 Jan 2 15:50 shared
|
||||
-rw-r--r--. 1 ids ids 4050 Nov 17 16:40 tailwind.config.ts
|
||||
-rw-r--r--. 1 ids ids 657 Nov 17 16:40 tsconfig.json
|
||||
-rw-r--r--. 1 ids ids 37505 Feb 16 08:50 uv.lock
|
||||
-rw-r--r--. 1 ids ids 7329 Feb 16 19:28 version.json
|
||||
-rw-r--r--. 1 ids ids 1080 Nov 17 16:40 vite.config.ts
|
||||
=== PACKAGE.JSON ===
|
||||
{
|
||||
"name": "rest-express",
|
||||
"version": "1.0.0",
|
||||
"type": "module",
|
||||
"license": "MIT",
|
||||
"scripts": {
|
||||
"dev": "NODE_ENV=development tsx server/index.ts",
|
||||
"build": "vite build && esbuild server/index.ts --platform=node --packages=external --bundle --format=esm --outdir=dist",
|
||||
"start": "NODE_ENV=production node dist/index.js",
|
||||
"check": "tsc",
|
||||
"db:push": "drizzle-kit push"
|
||||
},
|
||||
"dependencies": {
|
||||
"@hookform/resolvers": "^3.10.0",
|
||||
"@jridgewell/trace-mapping": "^0.3.25",
|
||||
"@neondatabase/serverless": "^0.10.4",
|
||||
"@radix-ui/react-accordion": "^1.2.4",
|
||||
"@radix-ui/react-alert-dialog": "^1.1.7",
|
||||
"@radix-ui/react-aspect-ratio": "^1.1.3",
|
||||
"@radix-ui/react-avatar": "^1.1.4",
|
||||
"@radix-ui/react-checkbox": "^1.1.5",
|
||||
"@radix-ui/react-collapsible": "^1.1.4",
|
||||
"@radix-ui/react-context-menu": "^2.2.7",
|
||||
"@radix-ui/react-dialog": "^1.1.7",
|
||||
"@radix-ui/react-dropdown-menu": "^2.1.7",
|
||||
"@radix-ui/react-hover-card": "^1.1.7",
|
||||
"@radix-ui/react-label": "^2.1.3",
|
||||
"@radix-ui/react-menubar": "^1.1.7",
|
||||
"@radix-ui/react-navigation-menu": "^1.2.6",
|
||||
"@radix-ui/react-popover": "^1.1.7",
|
||||
=== AUTO_BLOCK OUTPUT DETTAGLIATO ===
|
||||
[2026-02-17 08:38:05] Starting auto-block cycle...
|
||||
[2026-02-17 08:38:05] Step 1: Detection ML...
|
||||
[2026-02-17 08:38:05] ML Detection timeout, skip (blocco IP esistenti continua)
|
||||
[2026-02-17 08:38:05] Step 2: Blocco IP critici sui router...
|
||||
[2026-02-17 08:38:05] ERRORE: Timeout blocco IP (120s)
|
||||
[root@ids ~]#
|
||||
@ -2,25 +2,21 @@ import { useQuery, useMutation } from "@tanstack/react-query";
|
||||
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
|
||||
import { Badge } from "@/components/ui/badge";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Activity, Brain, Database, FileText, Terminal, RefreshCw, AlertCircle, Play, Square, RotateCw } from "lucide-react";
|
||||
import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert";
|
||||
import { Activity, Brain, Database, FileText, Terminal, RefreshCw, Play, Square, RotateCw, Shield, Trash2, ListChecks, GraduationCap, Server, Clock, Timer } from "lucide-react";
|
||||
import { useToast } from "@/hooks/use-toast";
|
||||
import { queryClient, apiRequest } from "@/lib/queryClient";
|
||||
|
||||
interface ServiceStatus {
|
||||
name: string;
|
||||
status: "running" | "idle" | "offline" | "error" | "unknown";
|
||||
status: string;
|
||||
healthy: boolean;
|
||||
details: any;
|
||||
systemdUnit: string;
|
||||
type: string;
|
||||
}
|
||||
|
||||
interface ServicesStatusResponse {
|
||||
services: {
|
||||
mlBackend: ServiceStatus;
|
||||
database: ServiceStatus;
|
||||
syslogParser: ServiceStatus;
|
||||
analyticsAggregator: ServiceStatus;
|
||||
};
|
||||
services: Record<string, ServiceStatus>;
|
||||
}
|
||||
|
||||
export default function ServicesPage() {
|
||||
@ -28,10 +24,9 @@ export default function ServicesPage() {
|
||||
|
||||
const { data: servicesStatus, isLoading, refetch } = useQuery<ServicesStatusResponse>({
|
||||
queryKey: ["/api/services/status"],
|
||||
refetchInterval: 5000, // Refresh every 5s
|
||||
refetchInterval: 5000,
|
||||
});
|
||||
|
||||
// Mutation for service control
|
||||
const serviceControlMutation = useMutation({
|
||||
mutationFn: async ({ service, action }: { service: string; action: string }) => {
|
||||
return apiRequest("POST", `/api/services/${service}/${action}`);
|
||||
@ -39,9 +34,8 @@ export default function ServicesPage() {
|
||||
onSuccess: (data, variables) => {
|
||||
toast({
|
||||
title: "Operazione completata",
|
||||
description: `Servizio ${variables.service}: ${variables.action} eseguito con successo`,
|
||||
description: `Servizio ${variables.service}: ${variables.action} eseguito`,
|
||||
});
|
||||
// Refresh status after 2 seconds
|
||||
setTimeout(() => {
|
||||
queryClient.invalidateQueries({ queryKey: ["/api/services/status"] });
|
||||
}, 2000);
|
||||
@ -59,39 +53,260 @@ export default function ServicesPage() {
|
||||
serviceControlMutation.mutate({ service, action });
|
||||
};
|
||||
|
||||
const getStatusBadge = (service: ServiceStatus) => {
|
||||
const getStatusBadge = (service: ServiceStatus, key: string) => {
|
||||
if (service.healthy) {
|
||||
return <Badge variant="default" className="bg-green-600" data-testid={`badge-status-healthy`}>Online</Badge>;
|
||||
return <Badge variant="default" className="bg-green-600" data-testid={`badge-status-${key}-healthy`}>Online</Badge>;
|
||||
}
|
||||
if (service.status === 'idle') {
|
||||
return <Badge variant="secondary" data-testid={`badge-status-idle`}>In Attesa</Badge>;
|
||||
return <Badge variant="secondary" data-testid={`badge-status-${key}-idle`}>In Attesa</Badge>;
|
||||
}
|
||||
if (service.status === 'offline') {
|
||||
return <Badge variant="destructive" data-testid={`badge-status-offline`}>Offline</Badge>;
|
||||
return <Badge variant="destructive" data-testid={`badge-status-${key}-offline`}>Offline</Badge>;
|
||||
}
|
||||
if (service.status === 'error') {
|
||||
return <Badge variant="destructive" data-testid={`badge-status-error`}>Errore</Badge>;
|
||||
return <Badge variant="destructive" data-testid={`badge-status-${key}-error`}>Errore</Badge>;
|
||||
}
|
||||
return <Badge variant="outline" data-testid={`badge-status-unknown`}>Sconosciuto</Badge>;
|
||||
return <Badge variant="outline" data-testid={`badge-status-${key}-unknown`}>Sconosciuto</Badge>;
|
||||
};
|
||||
|
||||
const getStatusIndicator = (service: ServiceStatus) => {
|
||||
if (service.healthy) {
|
||||
return <div className="h-3 w-3 rounded-full bg-green-500" />;
|
||||
return <div className="h-3 w-3 rounded-full bg-green-500 shrink-0" />;
|
||||
}
|
||||
if (service.status === 'idle') {
|
||||
return <div className="h-3 w-3 rounded-full bg-yellow-500" />;
|
||||
return <div className="h-3 w-3 rounded-full bg-yellow-500 shrink-0" />;
|
||||
}
|
||||
return <div className="h-3 w-3 rounded-full bg-red-500" />;
|
||||
return <div className="h-3 w-3 rounded-full bg-red-500 shrink-0" />;
|
||||
};
|
||||
|
||||
const getServiceIcon = (key: string) => {
|
||||
const icons: Record<string, any> = {
|
||||
nodeBackend: Server,
|
||||
mlBackend: Brain,
|
||||
database: Database,
|
||||
syslogParser: FileText,
|
||||
analyticsAggregator: Activity,
|
||||
autoBlock: Shield,
|
||||
cleanup: Trash2,
|
||||
listFetcher: ListChecks,
|
||||
mlTraining: GraduationCap,
|
||||
};
|
||||
const Icon = icons[key] || Activity;
|
||||
return <Icon className="h-5 w-5" />;
|
||||
};
|
||||
|
||||
const controllableServices = [
|
||||
"ids-ml-backend", "ids-syslog-parser", "ids-backend",
|
||||
"ids-analytics-aggregator", "ids-auto-block", "ids-cleanup",
|
||||
"ids-list-fetcher", "ids-ml-training"
|
||||
];
|
||||
|
||||
const getLogCommand = (key: string): string | null => {
|
||||
const logs: Record<string, string> = {
|
||||
nodeBackend: "tail -f /var/log/ids/backend.log",
|
||||
mlBackend: "journalctl -u ids-ml-backend -f",
|
||||
database: "sudo journalctl -u postgresql-16 -f",
|
||||
syslogParser: "tail -f /var/log/ids/syslog_parser.log",
|
||||
analyticsAggregator: "journalctl -u ids-analytics-aggregator -f",
|
||||
autoBlock: "journalctl -u ids-auto-block -f",
|
||||
cleanup: "journalctl -u ids-cleanup -f",
|
||||
listFetcher: "journalctl -u ids-list-fetcher -f",
|
||||
mlTraining: "journalctl -u ids-ml-training -f",
|
||||
};
|
||||
return logs[key] || null;
|
||||
};
|
||||
|
||||
const renderDetailRow = (label: string, value: any, variant?: "default" | "destructive" | "secondary" | "outline") => {
|
||||
if (value === undefined || value === null) return null;
|
||||
return (
|
||||
<div className="flex items-center justify-between gap-2 flex-wrap">
|
||||
<span className="text-sm text-muted-foreground">{label}:</span>
|
||||
{variant ? (
|
||||
<Badge variant={variant} className="text-xs">{String(value)}</Badge>
|
||||
) : (
|
||||
<span className="text-sm font-mono">{String(value)}</span>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const renderServiceDetails = (key: string, service: ServiceStatus) => {
|
||||
const d = service.details;
|
||||
if (!d) return null;
|
||||
|
||||
switch (key) {
|
||||
case "nodeBackend":
|
||||
return (
|
||||
<>
|
||||
{renderDetailRow("Porta", d.port)}
|
||||
{renderDetailRow("Uptime", d.uptime)}
|
||||
</>
|
||||
);
|
||||
case "mlBackend":
|
||||
return (
|
||||
<>
|
||||
{d.modelLoaded !== undefined && renderDetailRow("Modello ML", d.modelLoaded ? "Caricato" : "Non Caricato", d.modelLoaded ? "default" : "secondary")}
|
||||
{d.error && renderDetailRow("Errore", d.error, "destructive")}
|
||||
</>
|
||||
);
|
||||
case "database":
|
||||
return (
|
||||
<>
|
||||
{d.connected && renderDetailRow("Connessione", "Attiva", "default")}
|
||||
{d.error && renderDetailRow("Errore", d.error, "destructive")}
|
||||
</>
|
||||
);
|
||||
case "syslogParser":
|
||||
return (
|
||||
<>
|
||||
{d.recentLogs30min !== undefined && renderDetailRow("Log ultimi 30min", d.recentLogs30min.toLocaleString())}
|
||||
{d.lastLog && renderDetailRow("Ultimo log", typeof d.lastLog === 'string' ? d.lastLog : new Date(d.lastLog).toLocaleString('it-IT'))}
|
||||
{d.warning && renderDetailRow("Avviso", d.warning, "destructive")}
|
||||
</>
|
||||
);
|
||||
case "analyticsAggregator":
|
||||
return (
|
||||
<>
|
||||
{d.lastRun && renderDetailRow("Ultima esecuzione", new Date(d.lastRun).toLocaleString('it-IT'))}
|
||||
{d.hoursSinceLastRun && renderDetailRow("Ore dall'ultimo run", d.hoursSinceLastRun + "h", parseFloat(d.hoursSinceLastRun) < 2 ? "default" : "destructive")}
|
||||
{d.warning && renderDetailRow("Avviso", d.warning, "destructive")}
|
||||
</>
|
||||
);
|
||||
case "autoBlock":
|
||||
return (
|
||||
<>
|
||||
{renderDetailRow("Blocchi ultimi 10min", d.recentBlocks10min)}
|
||||
{renderDetailRow("Totale bloccati", d.totalBlocked)}
|
||||
{d.lastBlock && renderDetailRow("Ultimo blocco", typeof d.lastBlock === 'string' && d.lastBlock !== 'Mai' ? new Date(d.lastBlock).toLocaleString('it-IT') : d.lastBlock)}
|
||||
{renderDetailRow("Intervallo", d.interval)}
|
||||
</>
|
||||
);
|
||||
case "cleanup":
|
||||
return (
|
||||
<>
|
||||
{renderDetailRow("Detection vecchie (>48h)", d.oldDetections48h, d.oldDetections48h > 0 ? "destructive" : "default")}
|
||||
{renderDetailRow("Detection totali", d.totalDetections)}
|
||||
{renderDetailRow("Intervallo", d.interval)}
|
||||
{d.warning && renderDetailRow("Avviso", d.warning, "destructive")}
|
||||
</>
|
||||
);
|
||||
case "listFetcher":
|
||||
return (
|
||||
<>
|
||||
{renderDetailRow("Liste totali", d.totalLists)}
|
||||
{renderDetailRow("Liste attive", d.enabledLists)}
|
||||
{d.lastFetched && renderDetailRow("Ultimo fetch", typeof d.lastFetched === 'string' && d.lastFetched !== 'Mai' ? new Date(d.lastFetched).toLocaleString('it-IT') : d.lastFetched)}
|
||||
{d.hoursSinceLastFetch && renderDetailRow("Ore dall'ultimo fetch", d.hoursSinceLastFetch + "h", parseFloat(d.hoursSinceLastFetch) < 1 ? "default" : "destructive")}
|
||||
{renderDetailRow("Intervallo", d.interval)}
|
||||
</>
|
||||
);
|
||||
case "mlTraining":
|
||||
return (
|
||||
<>
|
||||
{d.lastTraining && renderDetailRow("Ultimo training", typeof d.lastTraining === 'string' && d.lastTraining !== 'Mai' ? new Date(d.lastTraining).toLocaleString('it-IT') : d.lastTraining)}
|
||||
{d.daysSinceLastTraining && renderDetailRow("Giorni dall'ultimo", d.daysSinceLastTraining, parseFloat(d.daysSinceLastTraining) < 8 ? "default" : "destructive")}
|
||||
{d.lastStatus && renderDetailRow("Stato ultimo training", d.lastStatus, d.lastStatus === 'completed' ? "default" : "destructive")}
|
||||
{d.lastModel && renderDetailRow("Modello", d.lastModel)}
|
||||
{d.recordsProcessed && renderDetailRow("Record processati", d.recordsProcessed.toLocaleString())}
|
||||
{renderDetailRow("Intervallo", d.interval)}
|
||||
</>
|
||||
);
|
||||
default:
|
||||
return d.error ? renderDetailRow("Errore", d.error, "destructive") : null;
|
||||
}
|
||||
};
|
||||
|
||||
const coreServices = ["nodeBackend", "mlBackend", "database", "syslogParser"];
|
||||
const timerServices = ["autoBlock", "analyticsAggregator", "cleanup", "listFetcher", "mlTraining"];
|
||||
|
||||
const renderServiceCard = (key: string, service: ServiceStatus) => {
|
||||
const isControllable = controllableServices.includes(service.systemdUnit);
|
||||
const isTimer = service.type === "timer";
|
||||
const logCmd = getLogCommand(key);
|
||||
|
||||
return (
|
||||
<Card key={key} data-testid={`card-service-${key}`}>
|
||||
<CardHeader className="flex flex-row items-center justify-between gap-2 space-y-0 pb-2">
|
||||
<CardTitle className="flex items-center gap-2 text-base">
|
||||
{getServiceIcon(key)}
|
||||
<span className="truncate">{service.name}</span>
|
||||
</CardTitle>
|
||||
<div className="flex items-center gap-2 shrink-0">
|
||||
{isTimer && <Timer className="h-4 w-4 text-muted-foreground" />}
|
||||
{getStatusIndicator(service)}
|
||||
</div>
|
||||
</CardHeader>
|
||||
<CardContent className="space-y-3">
|
||||
<div className="flex items-center justify-between gap-2">
|
||||
<span className="text-sm text-muted-foreground">Stato:</span>
|
||||
{getStatusBadge(service, key)}
|
||||
</div>
|
||||
|
||||
<div className="flex items-center justify-between gap-2">
|
||||
<span className="text-sm text-muted-foreground">Systemd:</span>
|
||||
<Badge variant="outline" className="text-xs font-mono">
|
||||
{service.systemdUnit}{isTimer ? '.timer' : '.service'}
|
||||
</Badge>
|
||||
</div>
|
||||
|
||||
{renderServiceDetails(key, service)}
|
||||
|
||||
{isControllable && (
|
||||
<div className="space-y-2 pt-2 border-t">
|
||||
<p className="text-xs font-medium text-muted-foreground">Controlli:</p>
|
||||
<div className="flex gap-2 flex-wrap">
|
||||
<Button
|
||||
size="sm"
|
||||
variant="outline"
|
||||
onClick={() => handleServiceAction(service.systemdUnit, "restart")}
|
||||
disabled={serviceControlMutation.isPending}
|
||||
data-testid={`button-restart-${key}`}
|
||||
>
|
||||
<RotateCw className="h-3 w-3 mr-1" />
|
||||
Restart
|
||||
</Button>
|
||||
<Button
|
||||
size="sm"
|
||||
variant="outline"
|
||||
onClick={() => handleServiceAction(service.systemdUnit, "start")}
|
||||
disabled={serviceControlMutation.isPending || service.status === 'running'}
|
||||
data-testid={`button-start-${key}`}
|
||||
>
|
||||
<Play className="h-3 w-3 mr-1" />
|
||||
Start
|
||||
</Button>
|
||||
<Button
|
||||
size="sm"
|
||||
variant="outline"
|
||||
onClick={() => handleServiceAction(service.systemdUnit, "stop")}
|
||||
disabled={serviceControlMutation.isPending || service.status === 'offline'}
|
||||
data-testid={`button-stop-${key}`}
|
||||
>
|
||||
<Square className="h-3 w-3 mr-1" />
|
||||
Stop
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{logCmd && (
|
||||
<div className="p-2 bg-muted rounded-md">
|
||||
<p className="text-xs font-medium text-muted-foreground mb-1">Log:</p>
|
||||
<code className="text-xs font-mono break-all" data-testid={`code-log-${key}`}>{logCmd}</code>
|
||||
</div>
|
||||
)}
|
||||
</CardContent>
|
||||
</Card>
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="flex flex-col gap-6 p-6" data-testid="page-services">
|
||||
<div className="flex items-center justify-between">
|
||||
<div className="flex items-center justify-between gap-4 flex-wrap">
|
||||
<div>
|
||||
<h1 className="text-3xl font-semibold" data-testid="text-services-title">Gestione Servizi</h1>
|
||||
<p className="text-muted-foreground" data-testid="text-services-subtitle">
|
||||
Monitoraggio e controllo dei servizi IDS
|
||||
Monitoraggio e controllo di tutti i servizi IDS
|
||||
</p>
|
||||
</div>
|
||||
<Button onClick={() => refetch()} variant="outline" data-testid="button-refresh">
|
||||
@ -100,303 +315,40 @@ export default function ServicesPage() {
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
<Alert data-testid="alert-server-instructions">
|
||||
<AlertCircle className="h-4 w-4" />
|
||||
<AlertTitle>Gestione Servizi Systemd</AlertTitle>
|
||||
<AlertDescription>
|
||||
I servizi IDS sono gestiti da systemd sul server AlmaLinux.
|
||||
Usa i pulsanti qui sotto per controllarli oppure esegui i comandi systemctl direttamente sul server.
|
||||
</AlertDescription>
|
||||
</Alert>
|
||||
|
||||
{/* Services Grid */}
|
||||
<div className="grid grid-cols-1 lg:grid-cols-3 gap-6">
|
||||
{/* ML Backend Service */}
|
||||
<Card data-testid="card-ml-backend-service">
|
||||
<CardHeader>
|
||||
<CardTitle className="flex items-center gap-2 text-lg">
|
||||
<Brain className="h-5 w-5" />
|
||||
ML Backend Python
|
||||
{servicesStatus && getStatusIndicator(servicesStatus.services.mlBackend)}
|
||||
</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent className="space-y-4">
|
||||
<div className="flex items-center justify-between">
|
||||
<span className="text-sm text-muted-foreground">Stato:</span>
|
||||
{servicesStatus && getStatusBadge(servicesStatus.services.mlBackend)}
|
||||
</div>
|
||||
|
||||
{servicesStatus?.services.mlBackend.details?.modelLoaded !== undefined && (
|
||||
<div className="flex items-center justify-between">
|
||||
<span className="text-sm text-muted-foreground">Modello ML:</span>
|
||||
<Badge variant={servicesStatus.services.mlBackend.details.modelLoaded ? "default" : "secondary"}>
|
||||
{servicesStatus.services.mlBackend.details.modelLoaded ? "Caricato" : "Non Caricato"}
|
||||
</Badge>
|
||||
</div>
|
||||
{isLoading && (
|
||||
<div className="text-center py-8 text-muted-foreground">Caricamento stato servizi...</div>
|
||||
)}
|
||||
|
||||
{/* Service Controls */}
|
||||
<div className="mt-4 space-y-2">
|
||||
<p className="text-xs font-medium mb-2">Controlli Servizio:</p>
|
||||
<div className="flex gap-2 flex-wrap">
|
||||
<Button
|
||||
size="sm"
|
||||
variant="outline"
|
||||
onClick={() => handleServiceAction("ids-ml-backend", "start")}
|
||||
disabled={serviceControlMutation.isPending || servicesStatus?.services.mlBackend.status === 'running'}
|
||||
data-testid="button-start-ml"
|
||||
>
|
||||
<Play className="h-3 w-3 mr-1" />
|
||||
Start
|
||||
</Button>
|
||||
<Button
|
||||
size="sm"
|
||||
variant="outline"
|
||||
onClick={() => handleServiceAction("ids-ml-backend", "stop")}
|
||||
disabled={serviceControlMutation.isPending || servicesStatus?.services.mlBackend.status === 'offline'}
|
||||
data-testid="button-stop-ml"
|
||||
>
|
||||
<Square className="h-3 w-3 mr-1" />
|
||||
Stop
|
||||
</Button>
|
||||
<Button
|
||||
size="sm"
|
||||
variant="outline"
|
||||
onClick={() => handleServiceAction("ids-ml-backend", "restart")}
|
||||
disabled={serviceControlMutation.isPending}
|
||||
data-testid="button-restart-ml"
|
||||
>
|
||||
<RotateCw className="h-3 w-3 mr-1" />
|
||||
Restart
|
||||
</Button>
|
||||
{servicesStatus && (
|
||||
<>
|
||||
<div>
|
||||
<h2 className="text-lg font-semibold mb-3 flex items-center gap-2">
|
||||
<Server className="h-5 w-5" />
|
||||
Servizi Core
|
||||
</h2>
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 xl:grid-cols-4 gap-4">
|
||||
{coreServices.map((key) => {
|
||||
const service = (servicesStatus.services as any)[key];
|
||||
return service ? renderServiceCard(key, service) : null;
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Manual Commands (fallback) */}
|
||||
<div className="mt-4 p-3 bg-muted rounded-lg">
|
||||
<p className="text-xs font-medium mb-2">Comando systemctl (sul server):</p>
|
||||
<code className="text-xs bg-background p-2 rounded block font-mono" data-testid="code-systemctl-ml">
|
||||
sudo systemctl {servicesStatus?.services.mlBackend.status === 'offline' ? 'start' : 'restart'} ids-ml-backend
|
||||
</code>
|
||||
<div>
|
||||
<h2 className="text-lg font-semibold mb-3 flex items-center gap-2">
|
||||
<Clock className="h-5 w-5" />
|
||||
Timer Systemd (Attivita Periodiche)
|
||||
</h2>
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 xl:grid-cols-3 gap-4">
|
||||
{timerServices.map((key) => {
|
||||
const service = (servicesStatus.services as any)[key];
|
||||
return service ? renderServiceCard(key, service) : null;
|
||||
})}
|
||||
</div>
|
||||
|
||||
<div className="mt-4 p-3 bg-muted rounded-lg">
|
||||
<p className="text-xs font-medium mb-2">Log:</p>
|
||||
<code className="text-xs bg-background p-2 rounded block font-mono" data-testid="code-log-ml">
|
||||
tail -f /var/log/ids/backend.log
|
||||
</code>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
{/* Database Service */}
|
||||
<Card data-testid="card-database-service">
|
||||
<CardHeader>
|
||||
<CardTitle className="flex items-center gap-2 text-lg">
|
||||
<Database className="h-5 w-5" />
|
||||
PostgreSQL Database
|
||||
{servicesStatus && getStatusIndicator(servicesStatus.services.database)}
|
||||
</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent className="space-y-4">
|
||||
<div className="flex items-center justify-between">
|
||||
<span className="text-sm text-muted-foreground">Stato:</span>
|
||||
{servicesStatus && getStatusBadge(servicesStatus.services.database)}
|
||||
</div>
|
||||
|
||||
{servicesStatus?.services.database.status === 'running' && (
|
||||
<div className="flex items-center justify-between">
|
||||
<span className="text-sm text-muted-foreground">Connessione:</span>
|
||||
<Badge variant="default" className="bg-green-600">Connesso</Badge>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
|
||||
<div className="mt-4 p-3 bg-muted rounded-lg">
|
||||
<p className="text-xs font-medium mb-2">Verifica status:</p>
|
||||
<code className="text-xs bg-background p-2 rounded block font-mono" data-testid="code-status-db">
|
||||
systemctl status postgresql-16
|
||||
</code>
|
||||
</div>
|
||||
|
||||
{servicesStatus?.services.database.status === 'error' && (
|
||||
<div className="mt-4 p-3 bg-muted rounded-lg">
|
||||
<p className="text-xs font-medium mb-2">Riavvia database:</p>
|
||||
<code className="text-xs bg-background p-2 rounded block font-mono" data-testid="code-restart-db">
|
||||
sudo systemctl restart postgresql-16
|
||||
</code>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className="mt-4 p-3 bg-muted rounded-lg">
|
||||
<p className="text-xs font-medium mb-2">Log:</p>
|
||||
<code className="text-xs bg-background p-2 rounded block font-mono" data-testid="code-log-db">
|
||||
sudo journalctl -u postgresql-16 -f
|
||||
</code>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
{/* Syslog Parser Service */}
|
||||
<Card data-testid="card-syslog-parser-service">
|
||||
<CardHeader>
|
||||
<CardTitle className="flex items-center gap-2 text-lg">
|
||||
<FileText className="h-5 w-5" />
|
||||
Syslog Parser
|
||||
{servicesStatus && getStatusIndicator(servicesStatus.services.syslogParser)}
|
||||
</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent className="space-y-4">
|
||||
<div className="flex items-center justify-between">
|
||||
<span className="text-sm text-muted-foreground">Stato:</span>
|
||||
{servicesStatus && getStatusBadge(servicesStatus.services.syslogParser)}
|
||||
</div>
|
||||
|
||||
{servicesStatus?.services.syslogParser.details?.pid && (
|
||||
<div className="flex items-center justify-between">
|
||||
<span className="text-sm text-muted-foreground">PID Processo:</span>
|
||||
<Badge variant="outline" className="font-mono">
|
||||
{servicesStatus.services.syslogParser.details.pid}
|
||||
</Badge>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{servicesStatus?.services.syslogParser.details?.systemd_unit && (
|
||||
<div className="flex items-center justify-between">
|
||||
<span className="text-sm text-muted-foreground">Systemd Unit:</span>
|
||||
<Badge variant="outline" className="font-mono text-xs">
|
||||
{servicesStatus.services.syslogParser.details.systemd_unit}
|
||||
</Badge>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Service Controls */}
|
||||
<div className="mt-4 space-y-2">
|
||||
<p className="text-xs font-medium mb-2">Controlli Servizio:</p>
|
||||
<div className="flex gap-2 flex-wrap">
|
||||
<Button
|
||||
size="sm"
|
||||
variant="outline"
|
||||
onClick={() => handleServiceAction("ids-syslog-parser", "start")}
|
||||
disabled={serviceControlMutation.isPending || servicesStatus?.services.syslogParser.status === 'running'}
|
||||
data-testid="button-start-parser"
|
||||
>
|
||||
<Play className="h-3 w-3 mr-1" />
|
||||
Start
|
||||
</Button>
|
||||
<Button
|
||||
size="sm"
|
||||
variant="outline"
|
||||
onClick={() => handleServiceAction("ids-syslog-parser", "stop")}
|
||||
disabled={serviceControlMutation.isPending || servicesStatus?.services.syslogParser.status === 'offline'}
|
||||
data-testid="button-stop-parser"
|
||||
>
|
||||
<Square className="h-3 w-3 mr-1" />
|
||||
Stop
|
||||
</Button>
|
||||
<Button
|
||||
size="sm"
|
||||
variant="outline"
|
||||
onClick={() => handleServiceAction("ids-syslog-parser", "restart")}
|
||||
disabled={serviceControlMutation.isPending}
|
||||
data-testid="button-restart-parser"
|
||||
>
|
||||
<RotateCw className="h-3 w-3 mr-1" />
|
||||
Restart
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Manual Commands (fallback) */}
|
||||
<div className="mt-4 p-3 bg-muted rounded-lg">
|
||||
<p className="text-xs font-medium mb-2">Comando systemctl (sul server):</p>
|
||||
<code className="text-xs bg-background p-2 rounded block font-mono" data-testid="code-systemctl-parser">
|
||||
sudo systemctl {servicesStatus?.services.syslogParser.status === 'offline' ? 'start' : 'restart'} ids-syslog-parser
|
||||
</code>
|
||||
</div>
|
||||
|
||||
<div className="mt-4 p-3 bg-muted rounded-lg">
|
||||
<p className="text-xs font-medium mb-2">Log:</p>
|
||||
<code className="text-xs bg-background p-2 rounded block font-mono" data-testid="code-log-parser">
|
||||
tail -f /var/log/ids/syslog_parser.log
|
||||
</code>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
{/* Analytics Aggregator Service */}
|
||||
<Card data-testid="card-analytics-aggregator-service">
|
||||
<CardHeader>
|
||||
<CardTitle className="flex items-center gap-2 text-lg">
|
||||
<Activity className="h-5 w-5" />
|
||||
Analytics Aggregator
|
||||
{servicesStatus && getStatusIndicator(servicesStatus.services.analyticsAggregator)}
|
||||
</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent className="space-y-4">
|
||||
<div className="flex items-center justify-between">
|
||||
<span className="text-sm text-muted-foreground">Stato:</span>
|
||||
{servicesStatus && getStatusBadge(servicesStatus.services.analyticsAggregator)}
|
||||
</div>
|
||||
|
||||
{servicesStatus?.services.analyticsAggregator.details?.lastRun && (
|
||||
<div className="flex items-center justify-between">
|
||||
<span className="text-sm text-muted-foreground">Ultima Aggregazione:</span>
|
||||
<Badge variant="outline" className="text-xs">
|
||||
{new Date(servicesStatus.services.analyticsAggregator.details.lastRun).toLocaleString('it-IT')}
|
||||
</Badge>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{servicesStatus?.services.analyticsAggregator.details?.hoursSinceLastRun && (
|
||||
<div className="flex items-center justify-between">
|
||||
<span className="text-sm text-muted-foreground">Ore dall'ultimo run:</span>
|
||||
<Badge variant={parseFloat(servicesStatus.services.analyticsAggregator.details.hoursSinceLastRun) < 2 ? "default" : "destructive"}>
|
||||
{servicesStatus.services.analyticsAggregator.details.hoursSinceLastRun}h
|
||||
</Badge>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* CRITICAL ALERT: Aggregator idle for too long */}
|
||||
{servicesStatus?.services.analyticsAggregator.details?.hoursSinceLastRun &&
|
||||
parseFloat(servicesStatus.services.analyticsAggregator.details.hoursSinceLastRun) > 2 && (
|
||||
<Alert variant="destructive" className="mt-2" data-testid="alert-aggregator-idle">
|
||||
<AlertCircle className="h-4 w-4" />
|
||||
<AlertTitle className="text-sm font-semibold">⚠️ Timer Systemd Non Attivo</AlertTitle>
|
||||
<AlertDescription className="text-xs mt-1">
|
||||
<p className="mb-2">L'aggregatore non esegue da {servicesStatus.services.analyticsAggregator.details.hoursSinceLastRun}h! Dashboard e Analytics bloccati.</p>
|
||||
<p className="font-semibold">Soluzione Immediata (sul server):</p>
|
||||
<code className="block bg-destructive-foreground/10 p-2 rounded mt-1 font-mono text-xs">
|
||||
sudo /opt/ids/deployment/setup_analytics_timer.sh
|
||||
</code>
|
||||
</AlertDescription>
|
||||
</Alert>
|
||||
)}
|
||||
|
||||
<div className="mt-4 p-3 bg-muted rounded-lg">
|
||||
<p className="text-xs font-medium mb-2">Verifica timer:</p>
|
||||
<code className="text-xs bg-background p-2 rounded block font-mono" data-testid="code-status-aggregator">
|
||||
systemctl status ids-analytics-aggregator.timer
|
||||
</code>
|
||||
</div>
|
||||
|
||||
<div className="mt-4 p-3 bg-muted rounded-lg">
|
||||
<p className="text-xs font-medium mb-2">Avvia aggregazione manualmente:</p>
|
||||
<code className="text-xs bg-background p-2 rounded block font-mono" data-testid="code-run-aggregator">
|
||||
cd /opt/ids && ./deployment/run_analytics.sh
|
||||
</code>
|
||||
</div>
|
||||
|
||||
<div className="mt-4 p-3 bg-muted rounded-lg">
|
||||
<p className="text-xs font-medium mb-2">Log:</p>
|
||||
<code className="text-xs bg-background p-2 rounded block font-mono" data-testid="code-log-aggregator">
|
||||
journalctl -u ids-analytics-aggregator.timer -f
|
||||
</code>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
|
||||
{/* Additional Commands */}
|
||||
<Card data-testid="card-additional-commands">
|
||||
<CardHeader>
|
||||
<CardTitle className="flex items-center gap-2">
|
||||
@ -406,30 +358,27 @@ export default function ServicesPage() {
|
||||
</CardHeader>
|
||||
<CardContent className="space-y-4">
|
||||
<div>
|
||||
<p className="text-sm font-medium mb-2">Verifica tutti i processi IDS attivi:</p>
|
||||
<code className="text-xs bg-muted p-2 rounded block font-mono" data-testid="code-check-processes">
|
||||
ps aux | grep -E "python.*(main|syslog_parser)" | grep -v grep
|
||||
<p className="text-sm font-medium mb-2">Stato di tutti i servizi IDS:</p>
|
||||
<code className="text-xs bg-muted p-2 rounded-md block font-mono" data-testid="code-all-services">
|
||||
systemctl list-units 'ids-*' --all
|
||||
</code>
|
||||
</div>
|
||||
<div>
|
||||
<p className="text-sm font-medium mb-2">Stato di tutti i timer IDS:</p>
|
||||
<code className="text-xs bg-muted p-2 rounded-md block font-mono" data-testid="code-all-timers">
|
||||
systemctl list-timers 'ids-*' --all
|
||||
</code>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<p className="text-sm font-medium mb-2">Verifica log RSyslog (ricezione log MikroTik):</p>
|
||||
<code className="text-xs bg-muted p-2 rounded block font-mono" data-testid="code-check-rsyslog">
|
||||
<code className="text-xs bg-muted p-2 rounded-md block font-mono" data-testid="code-check-rsyslog">
|
||||
tail -f /var/log/mikrotik/raw.log
|
||||
</code>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<p className="text-sm font-medium mb-2">Esegui training manuale ML:</p>
|
||||
<code className="text-xs bg-muted p-2 rounded block font-mono" data-testid="code-manual-training">
|
||||
curl -X POST http://localhost:8000/train -H "Content-Type: application/json" -d '{"max_records": 10000, "hours_back": 24}'
|
||||
</code>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<p className="text-sm font-medium mb-2">Verifica storico training nel database:</p>
|
||||
<code className="text-xs bg-muted p-2 rounded block font-mono" data-testid="code-check-training">
|
||||
psql $DATABASE_URL -c "SELECT * FROM training_history ORDER BY trained_at DESC LIMIT 5;"
|
||||
<p className="text-sm font-medium mb-2">Verifica processi IDS attivi:</p>
|
||||
<code className="text-xs bg-muted p-2 rounded-md block font-mono" data-testid="code-check-processes">
|
||||
ps aux | grep -E "python.*(main|syslog_parser)" | grep -v grep
|
||||
</code>
|
||||
</div>
|
||||
</CardContent>
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
-- PostgreSQL database dump
|
||||
--
|
||||
|
||||
\restrict zKJmTXfD2mDCILkBGmMKFqMblgFsSpKpVUZfa2oGLibXRmd9rKoFVgOjrXmJtIh
|
||||
\restrict QQPZgpukcxzRMKOdS5xNsXDiphiHLW5uAuhQxN7luRJ2u8BkVkDOz1h9Un2BrJ0
|
||||
|
||||
-- Dumped from database version 16.11 (df20cf9)
|
||||
-- Dumped by pg_dump version 16.10
|
||||
@ -387,5 +387,5 @@ ALTER TABLE ONLY public.public_blacklist_ips
|
||||
-- PostgreSQL database dump complete
|
||||
--
|
||||
|
||||
\unrestrict zKJmTXfD2mDCILkBGmMKFqMblgFsSpKpVUZfa2oGLibXRmd9rKoFVgOjrXmJtIh
|
||||
\unrestrict QQPZgpukcxzRMKOdS5xNsXDiphiHLW5uAuhQxN7luRJ2u8BkVkDOz1h9Un2BrJ0
|
||||
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
# =========================================================
|
||||
# CHECK BACKEND - Verifica e riavvia backend Python se necessario
|
||||
# Usa systemctl per gestire il servizio (con virtual environment)
|
||||
# Nota: questo script può girare come root o come user ids
|
||||
# =========================================================
|
||||
|
||||
LOG_FILE="/var/log/ids/backend.log"
|
||||
@ -11,18 +12,28 @@ mkdir -p /var/log/ids
|
||||
# Check if systemd service is active
|
||||
if systemctl is-active --quiet ids-ml-backend; then
|
||||
exit 0
|
||||
else
|
||||
echo "[$(date)] Backend Python NON attivo, riavvio via systemctl..." >> "$LOG_FILE"
|
||||
|
||||
# Restart via systemctl (usa il venv configurato nel service)
|
||||
systemctl restart ids-ml-backend
|
||||
|
||||
# Wait for startup
|
||||
sleep 3
|
||||
|
||||
if systemctl is-active --quiet ids-ml-backend; then
|
||||
echo "[$(date)] Backend riavviato con successo via systemctl" >> "$LOG_FILE"
|
||||
else
|
||||
echo "[$(date)] ERRORE: Backend non si è avviato. Controlla: journalctl -u ids-ml-backend" >> "$LOG_FILE"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Verifica anche se il processo Python è attivo (fallback)
|
||||
if pgrep -f "python.*main.py" > /dev/null; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "[$(date)] Backend Python NON attivo, riavvio..." >> "$LOG_FILE"
|
||||
|
||||
# Prova prima con systemctl (funziona se eseguito come root o con sudo configurato)
|
||||
if [ "$(id -u)" -eq 0 ]; then
|
||||
systemctl restart ids-ml-backend
|
||||
else
|
||||
# Se non siamo root, prova con sudo (richiede sudoers configurato)
|
||||
sudo systemctl restart ids-ml-backend 2>/dev/null
|
||||
fi
|
||||
|
||||
# Wait for startup
|
||||
sleep 5
|
||||
|
||||
if systemctl is-active --quiet ids-ml-backend || pgrep -f "python.*main.py" > /dev/null; then
|
||||
echo "[$(date)] Backend riavviato con successo" >> "$LOG_FILE"
|
||||
else
|
||||
echo "[$(date)] ERRORE: Backend non si è avviato. Controlla: journalctl -u ids-ml-backend" >> "$LOG_FILE"
|
||||
fi
|
||||
|
||||
@ -1,33 +1,23 @@
|
||||
#!/bin/bash
|
||||
# =========================================================
|
||||
# CHECK FRONTEND - Verifica e riavvia frontend Node.js se necessario
|
||||
# CHECK FRONTEND - Verifica se backend Node.js e' attivo
|
||||
# =========================================================
|
||||
|
||||
LOG_FILE="/var/log/ids/frontend.log"
|
||||
WORK_DIR="/opt/ids"
|
||||
LOG_FILE="/var/log/ids/backend.log"
|
||||
|
||||
mkdir -p /var/log/ids
|
||||
|
||||
# Check if frontend (vite/node) is running
|
||||
if pgrep -f "vite" > /dev/null || pgrep -f "node.*server" > /dev/null; then
|
||||
if systemctl is-active --quiet ids-backend.service 2>/dev/null; then
|
||||
exit 0
|
||||
else
|
||||
echo "[$(date)] Frontend Node NON attivo, riavvio..." >> "$LOG_FILE"
|
||||
|
||||
# Start frontend with environment variables from .env
|
||||
cd "$WORK_DIR"
|
||||
if [ -f "$WORK_DIR/.env" ]; then
|
||||
nohup env $(cat "$WORK_DIR/.env" | grep -v '^#' | xargs) npm run dev >> "$LOG_FILE" 2>&1 &
|
||||
else
|
||||
nohup npm run dev >> "$LOG_FILE" 2>&1 &
|
||||
fi
|
||||
NEW_PID=$!
|
||||
echo "[$(date)] Backend Node.js NON attivo" >> "$LOG_FILE"
|
||||
systemctl start ids-backend.service 2>> "$LOG_FILE" || true
|
||||
|
||||
sleep 3
|
||||
|
||||
if pgrep -f "vite" > /dev/null; then
|
||||
echo "[$(date)] Frontend riavviato con successo (PID: $NEW_PID)" >> "$LOG_FILE"
|
||||
if systemctl is-active --quiet ids-backend.service 2>/dev/null; then
|
||||
echo "[$(date)] Backend riavviato con successo via systemd" >> "$LOG_FILE"
|
||||
else
|
||||
echo "[$(date)] ERRORE: Frontend non si è avviato" >> "$LOG_FILE"
|
||||
echo "[$(date)] ERRORE: Backend non si e' avviato - verificare con: journalctl -u ids-backend -n 20" >> "$LOG_FILE"
|
||||
fi
|
||||
fi
|
||||
|
||||
@ -18,43 +18,49 @@ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
PROJECT_ROOT="$(dirname "$SCRIPT_DIR")"
|
||||
|
||||
echo ""
|
||||
echo "📋 Installing systemd service files..."
|
||||
echo "Installing systemd service files..."
|
||||
|
||||
# Copy service files
|
||||
cp "$PROJECT_ROOT/deployment/systemd/ids-backend.service" /etc/systemd/system/
|
||||
cp "$PROJECT_ROOT/deployment/systemd/ids-ml-backend.service" /etc/systemd/system/
|
||||
cp "$PROJECT_ROOT/deployment/systemd/ids-syslog-parser.service" /etc/systemd/system/
|
||||
cp "$PROJECT_ROOT/deployment/systemd/ids-auto-block.service" /etc/systemd/system/
|
||||
|
||||
# Ensure correct permissions
|
||||
chmod 644 /etc/systemd/system/ids-backend.service
|
||||
chmod 644 /etc/systemd/system/ids-ml-backend.service
|
||||
chmod 644 /etc/systemd/system/ids-syslog-parser.service
|
||||
chmod 644 /etc/systemd/system/ids-auto-block.service
|
||||
|
||||
echo "✅ Service files copied to /etc/systemd/system/"
|
||||
echo "Service files copied to /etc/systemd/system/"
|
||||
|
||||
echo ""
|
||||
echo "🔄 Reloading systemd daemon..."
|
||||
echo "Reloading systemd daemon..."
|
||||
systemctl daemon-reload
|
||||
|
||||
echo ""
|
||||
echo "🔧 Enabling services to start on boot..."
|
||||
echo "Enabling services to start on boot..."
|
||||
systemctl enable ids-backend.service
|
||||
systemctl enable ids-ml-backend.service
|
||||
systemctl enable ids-syslog-parser.service
|
||||
|
||||
echo ""
|
||||
echo "========================================="
|
||||
echo "✅ Installation Complete!"
|
||||
echo "Installation Complete!"
|
||||
echo "========================================="
|
||||
echo ""
|
||||
echo "Next steps:"
|
||||
echo ""
|
||||
echo "1. Start the services:"
|
||||
echo " sudo systemctl start ids-backend"
|
||||
echo " sudo systemctl start ids-ml-backend"
|
||||
echo " sudo systemctl start ids-syslog-parser"
|
||||
echo ""
|
||||
echo "2. Check status:"
|
||||
echo " sudo systemctl status ids-ml-backend"
|
||||
echo " sudo systemctl status ids-syslog-parser"
|
||||
echo " sudo systemctl status ids-backend ids-ml-backend ids-syslog-parser"
|
||||
echo ""
|
||||
echo "3. View logs:"
|
||||
echo " tail -f /var/log/ids/backend.log"
|
||||
echo " tail -f /var/log/ids/ml_backend.log"
|
||||
echo " tail -f /var/log/ids/syslog_parser.log"
|
||||
echo ""
|
||||
|
||||
@ -1,58 +1,56 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Restart IDS Frontend (Node.js/Express/Vite)
|
||||
# Utility per restart manuale del server frontend
|
||||
# Restart IDS Frontend (Node.js/Express)
|
||||
# Utility per restart manuale del server frontend via systemd
|
||||
#
|
||||
|
||||
set -e
|
||||
|
||||
echo "🔄 Restart Frontend Node.js..."
|
||||
echo "Restart Backend Node.js via systemd..."
|
||||
|
||||
# Kill AGGRESSIVO di tutti i processi Node/Vite
|
||||
echo "⏸️ Stopping all Node/Vite processes..."
|
||||
pkill -9 -f "node.*tsx" 2>/dev/null || true
|
||||
pkill -9 -f "vite" 2>/dev/null || true
|
||||
pkill -9 -f "npm run dev" 2>/dev/null || true
|
||||
# Stop servizio
|
||||
echo "Stopping ids-backend..."
|
||||
sudo systemctl stop ids-backend.service 2>/dev/null || true
|
||||
sleep 2
|
||||
|
||||
# Kill processo sulla porta 5000 (se esiste)
|
||||
echo "🔍 Liberando porta 5000..."
|
||||
# Kill eventuali processi orfani sulla porta 5000
|
||||
echo "Liberando porta 5000..."
|
||||
lsof -ti:5000 | xargs kill -9 2>/dev/null || true
|
||||
sleep 1
|
||||
|
||||
# Verifica porta LIBERA
|
||||
# Verifica porta libera
|
||||
if lsof -Pi :5000 -sTCP:LISTEN -t >/dev/null 2>&1; then
|
||||
echo "❌ ERRORE: Porta 5000 ancora occupata!"
|
||||
echo "ERRORE: Porta 5000 ancora occupata!"
|
||||
echo "Processi sulla porta:"
|
||||
lsof -i:5000
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "✅ Porta 5000 libera"
|
||||
echo "Porta 5000 libera"
|
||||
|
||||
# Restart usando check_frontend.sh
|
||||
echo "🚀 Starting frontend..."
|
||||
/opt/ids/deployment/check_frontend.sh
|
||||
# Start servizio
|
||||
echo "Starting ids-backend..."
|
||||
sudo systemctl start ids-backend.service
|
||||
|
||||
# Attendi avvio completo
|
||||
sleep 5
|
||||
|
||||
# Verifica avvio
|
||||
if pgrep -f "vite" > /dev/null; then
|
||||
PID=$(pgrep -f "vite")
|
||||
echo "✅ Frontend avviato con PID: $PID"
|
||||
echo "📡 Server disponibile su: http://localhost:5000"
|
||||
if systemctl is-active --quiet ids-backend.service; then
|
||||
echo "Backend avviato con successo"
|
||||
echo "Server disponibile su: http://localhost:5000"
|
||||
|
||||
# Test rapido
|
||||
sleep 2
|
||||
HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" http://localhost:5000/ 2>/dev/null || echo "000")
|
||||
if [ "$HTTP_CODE" = "200" ]; then
|
||||
echo "✅ HTTP test OK (200)"
|
||||
echo "HTTP test OK (200)"
|
||||
else
|
||||
echo "⚠️ HTTP test: $HTTP_CODE"
|
||||
echo "HTTP test: $HTTP_CODE (potrebbe essere in fase di avvio)"
|
||||
fi
|
||||
else
|
||||
echo "❌ Errore: Frontend non avviato!"
|
||||
echo "📋 Controlla log: tail -f /var/log/ids/frontend.log"
|
||||
echo "ERRORE: Backend non avviato!"
|
||||
echo "Controlla log: journalctl -u ids-backend -n 20"
|
||||
sudo journalctl -u ids-backend -n 20 --no-pager
|
||||
exit 1
|
||||
fi
|
||||
|
||||
@ -22,8 +22,8 @@ SyslogIdentifier=ids-auto-block
|
||||
NoNewPrivileges=true
|
||||
PrivateTmp=true
|
||||
|
||||
# Timeout: max 5 minuti per detection+blocking
|
||||
TimeoutStartSec=300
|
||||
# Timeout: max 8 minuti per detection+blocking
|
||||
TimeoutStartSec=480
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
|
||||
32
deployment/systemd/ids-backend.service
Normal file
32
deployment/systemd/ids-backend.service
Normal file
@ -0,0 +1,32 @@
|
||||
[Unit]
|
||||
Description=IDS Node.js Backend (Express API + Frontend)
|
||||
After=network.target postgresql-16.service
|
||||
Wants=postgresql-16.service
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=ids
|
||||
Group=ids
|
||||
WorkingDirectory=/opt/ids
|
||||
EnvironmentFile=/opt/ids/.env
|
||||
Environment=NODE_ENV=production
|
||||
Environment=PORT=5000
|
||||
Environment=PATH=/usr/local/bin:/usr/bin:/bin
|
||||
|
||||
ExecStartPre=/bin/bash -c 'test -f /opt/ids/dist/index.js || (echo "ERRORE: dist/index.js non trovato - eseguire npm run build" && exit 1)'
|
||||
ExecStart=/usr/bin/env node dist/index.js
|
||||
|
||||
Restart=always
|
||||
RestartSec=5
|
||||
StartLimitInterval=300
|
||||
StartLimitBurst=10
|
||||
|
||||
LimitNOFILE=65536
|
||||
MemoryMax=1G
|
||||
|
||||
StandardOutput=append:/var/log/ids/backend.log
|
||||
StandardError=append:/var/log/ids/backend.log
|
||||
SyslogIdentifier=ids-backend
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
@ -58,7 +58,7 @@ def auto_block():
|
||||
"limit": 200,
|
||||
"list_name": "ddos_blocked"
|
||||
},
|
||||
timeout=120
|
||||
timeout=300
|
||||
)
|
||||
|
||||
if response.status_code == 200:
|
||||
@ -85,7 +85,7 @@ def auto_block():
|
||||
print(f"[{timestamp}] ERRORE: Node.js backend non raggiungibile su {NODE_API_URL}")
|
||||
return 1
|
||||
except requests.exceptions.Timeout:
|
||||
print(f"[{timestamp}] ERRORE: Timeout blocco IP (120s)")
|
||||
print(f"[{timestamp}] ERRORE: Timeout blocco IP (300s)")
|
||||
return 1
|
||||
except Exception as e:
|
||||
print(f"[{timestamp}] ERRORE imprevisto: {type(e).__name__}: {e}")
|
||||
|
||||
@ -1,3 +1,5 @@
|
||||
const VERBOSE = process.env.MIKROTIK_DEBUG === '1' || process.env.MIKROTIK_DEBUG === 'true';
|
||||
|
||||
interface RouterConfig {
|
||||
id: string;
|
||||
ipAddress: string;
|
||||
@ -20,12 +22,13 @@ async function mikrotikRequest(
|
||||
method: string,
|
||||
path: string,
|
||||
body?: any,
|
||||
timeoutMs: number = 10000
|
||||
timeoutMs: number = 8000
|
||||
): Promise<{ status: number; data: any }> {
|
||||
const useHttps = router.apiPort === 443;
|
||||
const protocol = useHttps ? "https" : "http";
|
||||
const url = `${protocol}://${router.ipAddress}:${router.apiPort}${path}`;
|
||||
const auth = Buffer.from(`${router.username}:${router.password}`).toString("base64");
|
||||
const startTime = Date.now();
|
||||
|
||||
const origTlsReject = process.env.NODE_TLS_REJECT_UNAUTHORIZED;
|
||||
if (useHttps) {
|
||||
@ -60,9 +63,24 @@ async function mikrotikRequest(
|
||||
data = text;
|
||||
}
|
||||
|
||||
const elapsed = Date.now() - startTime;
|
||||
if (VERBOSE) {
|
||||
const bodyStr = body ? ` body=${JSON.stringify(body)}` : '';
|
||||
const dataPreview = typeof data === 'string' ? data.substring(0, 200) : JSON.stringify(data).substring(0, 200);
|
||||
console.log(`[MIKROTIK] ${method} ${url} => HTTP ${response.status} (${elapsed}ms)${bodyStr} response=${dataPreview}`);
|
||||
} else if (response.status >= 400) {
|
||||
const dataPreview = typeof data === 'string' ? data.substring(0, 100) : JSON.stringify(data).substring(0, 100);
|
||||
console.warn(`[MIKROTIK] ${method} ${router.ipAddress}${path} => HTTP ${response.status} (${elapsed}ms) err=${dataPreview}`);
|
||||
} else if (elapsed > 5000) {
|
||||
console.warn(`[MIKROTIK] SLOW: ${method} ${router.ipAddress}${path} => HTTP ${response.status} (${elapsed}ms)`);
|
||||
}
|
||||
|
||||
return { status: response.status, data };
|
||||
} catch (error: any) {
|
||||
clearTimeout(timeout);
|
||||
const elapsed = Date.now() - startTime;
|
||||
const errMsg = error.name === 'AbortError' ? `TIMEOUT after ${timeoutMs}ms` : error.message;
|
||||
console.error(`[MIKROTIK] ${method} ${url} => ERRORE: ${errMsg} (${elapsed}ms)`);
|
||||
if (useHttps && origTlsReject !== undefined) {
|
||||
process.env.NODE_TLS_REJECT_UNAUTHORIZED = origTlsReject;
|
||||
} else if (useHttps) {
|
||||
@ -94,19 +112,26 @@ export async function getExistingBlockedIps(
|
||||
listName: string = "ddos_blocked"
|
||||
): Promise<Set<string>> {
|
||||
try {
|
||||
if (VERBOSE) console.log(`[MIKROTIK] Fetching address-list da router ${router.ipAddress} (list=${listName}, timeout=20s)...`);
|
||||
const { status, data } = await mikrotikRequest(router, "GET", "/rest/ip/firewall/address-list", undefined, 20000);
|
||||
if (status === 200 && Array.isArray(data)) {
|
||||
const ips = new Set<string>();
|
||||
const allLists = new Map<string, number>();
|
||||
for (const entry of data) {
|
||||
const count = allLists.get(entry.list) || 0;
|
||||
allLists.set(entry.list, count + 1);
|
||||
if (entry.list === listName) {
|
||||
ips.add(entry.address);
|
||||
}
|
||||
}
|
||||
const listsInfo = Array.from(allLists.entries()).map(([name, count]) => `${name}:${count}`).join(', ');
|
||||
console.log(`[MIKROTIK] Router ${router.ipAddress}: ${data.length} entries totali (${listsInfo}), ${ips.size} in list "${listName}"`);
|
||||
return ips;
|
||||
}
|
||||
console.warn(`[MIKROTIK] Router ${router.ipAddress}: risposta inattesa status=${status}, data non e' array`);
|
||||
return new Set();
|
||||
} catch (e: any) {
|
||||
console.error(`[MIKROTIK] Failed to get address-list from ${router.ipAddress}: ${e.message}`);
|
||||
console.error(`[MIKROTIK] Router ${router.ipAddress}: ERRORE fetch address-list: ${e.message}`);
|
||||
return new Set();
|
||||
}
|
||||
}
|
||||
@ -127,41 +152,53 @@ export async function addToAddressList(
|
||||
});
|
||||
|
||||
if (status === 200 || status === 201) {
|
||||
if (VERBOSE) console.log(`[BLOCK] OK: ${ipAddress} aggiunto su router ${router.ipAddress} (HTTP ${status})`);
|
||||
return { routerIp: router.ipAddress, success: true };
|
||||
}
|
||||
|
||||
if (status === 400 || status === 409) {
|
||||
const text = typeof data === "string" ? data.toLowerCase() : JSON.stringify(data).toLowerCase();
|
||||
if (text.includes("already") || text.includes("exists") || text.includes("duplicate") || text.includes("failure: already")) {
|
||||
if (VERBOSE) console.log(`[BLOCK] SKIP: ${ipAddress} gia' presente su router ${router.ipAddress} (HTTP ${status})`);
|
||||
return { routerIp: router.ipAddress, success: true, alreadyExists: true };
|
||||
}
|
||||
console.warn(`[BLOCK] VERIFICA: ${ipAddress} su router ${router.ipAddress} HTTP ${status} risposta="${text.substring(0, 150)}", verifico lista...`);
|
||||
try {
|
||||
const verifyResult = await mikrotikRequest(router, "GET", "/rest/ip/firewall/address-list");
|
||||
if (verifyResult.status === 200 && Array.isArray(verifyResult.data)) {
|
||||
for (const entry of verifyResult.data) {
|
||||
if (entry.address === ipAddress && entry.list === listName) {
|
||||
console.log(`[BLOCK] CONFERMATO: ${ipAddress} trovato nella lista di router ${router.ipAddress} dopo verifica`);
|
||||
return { routerIp: router.ipAddress, success: true, alreadyExists: true };
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch {}
|
||||
} catch (verifyErr: any) {
|
||||
console.error(`[BLOCK] ERRORE verifica: ${ipAddress} su router ${router.ipAddress}: ${verifyErr.message}`);
|
||||
}
|
||||
const errMsg = `HTTP ${status}: ${typeof data === "string" ? data : JSON.stringify(data)}`;
|
||||
console.error(`[BLOCK] FALLITO: ${ipAddress} su router ${router.ipAddress}: ${errMsg}`);
|
||||
return {
|
||||
routerIp: router.ipAddress,
|
||||
success: false,
|
||||
error: `HTTP ${status}: ${typeof data === "string" ? data : JSON.stringify(data)}`,
|
||||
error: errMsg,
|
||||
};
|
||||
}
|
||||
|
||||
const errMsg = `HTTP ${status}: ${typeof data === "string" ? data : JSON.stringify(data)}`;
|
||||
console.error(`[BLOCK] FALLITO: ${ipAddress} su router ${router.ipAddress}: ${errMsg}`);
|
||||
return {
|
||||
routerIp: router.ipAddress,
|
||||
success: false,
|
||||
error: `HTTP ${status}: ${typeof data === "string" ? data : JSON.stringify(data)}`,
|
||||
error: errMsg,
|
||||
};
|
||||
} catch (error: any) {
|
||||
const errMsg = error.name === 'AbortError' ? `TIMEOUT (8s)` : (error.message || "Connection failed");
|
||||
console.error(`[BLOCK] ERRORE: ${ipAddress} su router ${router.ipAddress}: ${errMsg}`);
|
||||
return {
|
||||
routerIp: router.ipAddress,
|
||||
success: false,
|
||||
error: error.message || "Connection failed",
|
||||
error: errMsg,
|
||||
};
|
||||
}
|
||||
}
|
||||
@ -172,8 +209,10 @@ export async function removeFromAddressList(
|
||||
listName: string = "ddos_blocked"
|
||||
): Promise<BlockResult> {
|
||||
try {
|
||||
if (VERBOSE) console.log(`[UNBLOCK] Rimozione ${ipAddress} da router ${router.ipAddress} (list=${listName})...`);
|
||||
const { status, data } = await mikrotikRequest(router, "GET", "/rest/ip/firewall/address-list");
|
||||
if (status !== 200 || !Array.isArray(data)) {
|
||||
console.error(`[UNBLOCK] ERRORE: impossibile leggere address-list da router ${router.ipAddress}: HTTP ${status}`);
|
||||
return { routerIp: router.ipAddress, success: false, error: "Failed to read address list" };
|
||||
}
|
||||
|
||||
@ -182,14 +221,18 @@ export async function removeFromAddressList(
|
||||
const entryId = entry[".id"];
|
||||
const delResult = await mikrotikRequest(router, "DELETE", `/rest/ip/firewall/address-list/${entryId}`);
|
||||
if (delResult.status === 200 || delResult.status === 204) {
|
||||
console.log(`[UNBLOCK] OK: ${ipAddress} rimosso da router ${router.ipAddress}`);
|
||||
return { routerIp: router.ipAddress, success: true };
|
||||
}
|
||||
console.error(`[UNBLOCK] FALLITO: eliminazione ${ipAddress} da router ${router.ipAddress}: HTTP ${delResult.status}`);
|
||||
return { routerIp: router.ipAddress, success: false, error: `Delete failed: ${delResult.status}` };
|
||||
}
|
||||
}
|
||||
|
||||
if (VERBOSE) console.log(`[UNBLOCK] ${ipAddress} non trovato su router ${router.ipAddress} (gia' assente)`);
|
||||
return { routerIp: router.ipAddress, success: true };
|
||||
} catch (error: any) {
|
||||
console.error(`[UNBLOCK] ERRORE: ${ipAddress} su router ${router.ipAddress}: ${error.message}`);
|
||||
return { routerIp: router.ipAddress, success: false, error: error.message };
|
||||
}
|
||||
}
|
||||
@ -239,14 +282,21 @@ export async function bulkBlockIps(
|
||||
return { blocked: 0, failed: 0, skipped: 0, details: [] };
|
||||
}
|
||||
|
||||
console.log(`[BULK-BLOCK] Starting: ${ipList.length} IPs on ${enabled.length} routers`);
|
||||
console.log(`[BULK-BLOCK] Starting: ${ipList.length} IPs on ${enabled.length} routers (${enabled.map(r => r.ipAddress).join(', ')})`);
|
||||
|
||||
const routerStatus = new Map<string, { ok: number; fail: number; skip: number }>();
|
||||
for (const r of enabled) {
|
||||
routerStatus.set(r.ipAddress, { ok: 0, fail: 0, skip: 0 });
|
||||
}
|
||||
|
||||
const existingCache = new Map<string, Set<string>>();
|
||||
await Promise.allSettled(
|
||||
enabled.map(async (router) => {
|
||||
const start = Date.now();
|
||||
const existing = await getExistingBlockedIps(router, listName);
|
||||
const elapsed = Date.now() - start;
|
||||
existingCache.set(router.ipAddress, existing);
|
||||
console.log(`[BULK-BLOCK] Router ${router.ipAddress}: ${existing.size} IPs already in list`);
|
||||
console.log(`[BULK-BLOCK] Router ${router.ipAddress}: ${existing.size} IPs already in list (${elapsed}ms)`);
|
||||
})
|
||||
);
|
||||
|
||||
@ -274,36 +324,72 @@ export async function bulkBlockIps(
|
||||
let blocked = 0;
|
||||
let failed = 0;
|
||||
const details: Array<{ ip: string; status: string }> = [];
|
||||
const partialIps: string[] = [];
|
||||
const failedIps: string[] = [];
|
||||
|
||||
async function processIp(ip: string) {
|
||||
const routerResults = await Promise.allSettled(
|
||||
enabled.map(async (router) => {
|
||||
const existing = existingCache.get(router.ipAddress) || new Set();
|
||||
if (existing.has(ip)) return true;
|
||||
if (existing.has(ip)) {
|
||||
const st = routerStatus.get(router.ipAddress);
|
||||
if (st) st.skip++;
|
||||
return { success: true, skipped: true, routerIp: router.ipAddress };
|
||||
}
|
||||
const start = Date.now();
|
||||
const result = await addToAddressList(router, ip, listName, `${commentPrefix} ${ip}`, timeoutDuration);
|
||||
return result.success;
|
||||
const elapsed = Date.now() - start;
|
||||
const st = routerStatus.get(router.ipAddress);
|
||||
if (result.success) {
|
||||
if (st) st.ok++;
|
||||
} else {
|
||||
if (st) st.fail++;
|
||||
}
|
||||
return { success: result.success, skipped: false, routerIp: router.ipAddress, elapsed, error: result.error };
|
||||
})
|
||||
);
|
||||
|
||||
const perRouterDetail = routerResults.map((r) => {
|
||||
if (r.status === 'fulfilled') {
|
||||
const v = r.value;
|
||||
if (v.skipped) return `${v.routerIp}:SKIP`;
|
||||
if (v.success) return `${v.routerIp}:OK(${v.elapsed}ms)`;
|
||||
return `${v.routerIp}:FAIL(${v.elapsed}ms,${v.error})`;
|
||||
}
|
||||
return 'REJECTED';
|
||||
}).join(' | ');
|
||||
|
||||
const anySuccess = routerResults.some(
|
||||
(r) => r.status === "fulfilled" && r.value === true
|
||||
(r) => r.status === "fulfilled" && r.value.success
|
||||
);
|
||||
const allSuccess = routerResults.every(
|
||||
(r) => r.status === "fulfilled" && r.value.success
|
||||
);
|
||||
|
||||
if (anySuccess) {
|
||||
blocked++;
|
||||
details.push({ ip, status: "blocked" });
|
||||
if (!allSuccess) {
|
||||
partialIps.push(ip);
|
||||
if (VERBOSE) console.warn(`[BULK-BLOCK] PARZIALE: IP ${ip}: ${perRouterDetail}`);
|
||||
}
|
||||
} else {
|
||||
failed++;
|
||||
failedIps.push(ip);
|
||||
details.push({ ip, status: "failed" });
|
||||
if (VERBOSE) console.error(`[BULK-BLOCK] FALLITO: IP ${ip}: ${perRouterDetail}`);
|
||||
}
|
||||
}
|
||||
|
||||
const bulkStart = Date.now();
|
||||
for (let i = 0; i < newIps.length; i += concurrency) {
|
||||
const batch = newIps.slice(i, i + concurrency);
|
||||
await Promise.allSettled(batch.map((ip) => processIp(ip)));
|
||||
|
||||
if ((i + concurrency) % 50 === 0 || i + concurrency >= newIps.length) {
|
||||
console.log(`[BULK-BLOCK] Progress: ${Math.min(i + concurrency, newIps.length)}/${newIps.length}`);
|
||||
const progress = Math.min(i + concurrency, newIps.length);
|
||||
if (progress === newIps.length || progress % 50 === 0) {
|
||||
const elapsed = ((Date.now() - bulkStart) / 1000).toFixed(1);
|
||||
console.log(`[BULK-BLOCK] Progress: ${progress}/${newIps.length} (${elapsed}s, ${blocked} ok, ${failed} fail)`);
|
||||
}
|
||||
}
|
||||
|
||||
@ -311,7 +397,17 @@ export async function bulkBlockIps(
|
||||
details.push({ ip, status: "already_blocked" });
|
||||
}
|
||||
|
||||
console.log(`[BULK-BLOCK] Done: ${blocked} blocked, ${failed} failed, ${skippedIps.length} skipped`);
|
||||
const totalElapsed = ((Date.now() - bulkStart) / 1000).toFixed(1);
|
||||
routerStatus.forEach((st, routerIp) => {
|
||||
console.log(`[BULK-BLOCK] Router ${routerIp}: ${st.ok} blocked, ${st.fail} failed, ${st.skip} skipped`);
|
||||
});
|
||||
console.log(`[BULK-BLOCK] Completato in ${totalElapsed}s: ${blocked} blocked, ${failed} failed, ${skippedIps.length} already_blocked, ${partialIps.length} parziali`);
|
||||
if (failedIps.length > 0) {
|
||||
console.error(`[BULK-BLOCK] IP non bloccati su nessun router (${failedIps.length}): ${failedIps.slice(0, 20).join(', ')}${failedIps.length > 20 ? '...' : ''}`);
|
||||
}
|
||||
if (partialIps.length > 0) {
|
||||
console.warn(`[BULK-BLOCK] IP bloccati solo parzialmente (${partialIps.length}): ${partialIps.slice(0, 20).join(', ')}${partialIps.length > 20 ? '...' : ''}`);
|
||||
}
|
||||
|
||||
return { blocked, failed, skipped: skippedIps.length, details };
|
||||
}
|
||||
|
||||
202
server/routes.ts
202
server/routes.ts
@ -672,7 +672,8 @@ export async function registerRoutes(app: Express): Promise<Server> {
|
||||
}
|
||||
|
||||
const ipList = rows.map((r: any) => r.source_ip);
|
||||
console.log(`[BLOCK-ALL] Avvio blocco massivo: ${ipList.length}/${totalUnblocked} IP con score >= ${min_score} su ${enabledRouters.length} router`);
|
||||
const routerInfo = enabledRouters.map((r: any) => `${r.name || r.ipAddress}(${r.ipAddress}:${r.apiPort})`).join(', ');
|
||||
console.log(`[BLOCK-ALL] Avvio blocco massivo: ${ipList.length}/${totalUnblocked} IP con score >= ${min_score} su ${enabledRouters.length} router: ${routerInfo}`);
|
||||
|
||||
const result = await bulkBlockIps(
|
||||
enabledRouters as any,
|
||||
@ -779,39 +780,43 @@ export async function registerRoutes(app: Express): Promise<Server> {
|
||||
// Services monitoring
|
||||
app.get("/api/services/status", async (req, res) => {
|
||||
try {
|
||||
const mkService = (name: string) => ({ name, status: "unknown" as string, healthy: false, details: null as any, systemdUnit: "" as string, type: "service" as string });
|
||||
|
||||
const services = {
|
||||
mlBackend: { name: "ML Backend Python", status: "unknown", healthy: false, details: null as any },
|
||||
database: { name: "PostgreSQL Database", status: "unknown", healthy: false, details: null as any },
|
||||
syslogParser: { name: "Syslog Parser", status: "unknown", healthy: false, details: null as any },
|
||||
analyticsAggregator: { name: "Analytics Aggregator Timer", status: "unknown", healthy: false, details: null as any },
|
||||
nodeBackend: { ...mkService("Node.js Backend"), systemdUnit: "ids-backend", type: "service" },
|
||||
mlBackend: { ...mkService("ML Backend Python"), systemdUnit: "ids-ml-backend", type: "service" },
|
||||
database: { ...mkService("PostgreSQL Database"), systemdUnit: "postgresql-16", type: "service" },
|
||||
syslogParser: { ...mkService("Syslog Parser"), systemdUnit: "ids-syslog-parser", type: "service" },
|
||||
analyticsAggregator: { ...mkService("Analytics Aggregator"), systemdUnit: "ids-analytics-aggregator", type: "timer" },
|
||||
autoBlock: { ...mkService("Auto Block"), systemdUnit: "ids-auto-block", type: "timer" },
|
||||
cleanup: { ...mkService("Cleanup Detections"), systemdUnit: "ids-cleanup", type: "timer" },
|
||||
listFetcher: { ...mkService("Public Lists Fetcher"), systemdUnit: "ids-list-fetcher", type: "timer" },
|
||||
mlTraining: { ...mkService("ML Training Settimanale"), systemdUnit: "ids-ml-training", type: "timer" },
|
||||
};
|
||||
|
||||
// Node.js Backend - always running if this endpoint responds
|
||||
services.nodeBackend.status = "running";
|
||||
services.nodeBackend.healthy = true;
|
||||
services.nodeBackend.details = { port: 5000, uptime: process.uptime().toFixed(0) + "s" };
|
||||
|
||||
// Check ML Backend Python
|
||||
try {
|
||||
const controller = new AbortController();
|
||||
const timeout = setTimeout(() => controller.abort(), 5000);
|
||||
|
||||
const response = await fetch(`${ML_BACKEND_URL}/health`, {
|
||||
signal: controller.signal,
|
||||
});
|
||||
|
||||
const response = await fetch(`${ML_BACKEND_URL}/health`, { signal: controller.signal });
|
||||
clearTimeout(timeout);
|
||||
|
||||
if (response.ok) {
|
||||
const data = await response.json();
|
||||
services.mlBackend.status = "running";
|
||||
services.mlBackend.healthy = true;
|
||||
services.mlBackend.details = {
|
||||
modelLoaded: data.ml_model === "loaded",
|
||||
timestamp: data.timestamp,
|
||||
};
|
||||
services.mlBackend.details = { modelLoaded: data.ml_model === "loaded", timestamp: data.timestamp };
|
||||
} else {
|
||||
services.mlBackend.status = "error";
|
||||
services.mlBackend.details = { error: `HTTP ${response.status}` };
|
||||
}
|
||||
} catch (error: any) {
|
||||
services.mlBackend.status = "offline";
|
||||
services.mlBackend.details = { error: error.code === 'ECONNREFUSED' ? "Connection refused" : error.message };
|
||||
services.mlBackend.details = { error: error.code === 'ECONNREFUSED' ? "Connessione rifiutata" : error.message };
|
||||
}
|
||||
|
||||
// Check Database
|
||||
@ -827,87 +832,156 @@ export async function registerRoutes(app: Express): Promise<Server> {
|
||||
services.database.details = { error: error.message };
|
||||
}
|
||||
|
||||
// Check Syslog Parser via database (independent of ML Backend)
|
||||
// Check Syslog Parser via database
|
||||
try {
|
||||
const recentLogsResult = await db.execute(
|
||||
sql`SELECT COUNT(*) as count, MAX(timestamp) as last_log
|
||||
FROM network_logs
|
||||
WHERE timestamp > NOW() - INTERVAL '30 minutes'`
|
||||
sql`SELECT COUNT(*) as count, MAX(timestamp) as last_log FROM network_logs WHERE timestamp > NOW() - INTERVAL '30 minutes'`
|
||||
);
|
||||
const logRows = (recentLogsResult as any).rows || recentLogsResult;
|
||||
const recentLogCount = parseInt(logRows[0]?.count || "0");
|
||||
const lastLogTime = logRows[0]?.last_log;
|
||||
|
||||
if (recentLogCount > 0) {
|
||||
services.syslogParser.status = "running";
|
||||
services.syslogParser.healthy = true;
|
||||
services.syslogParser.details = {
|
||||
recentLogs30min: recentLogCount,
|
||||
lastLog: lastLogTime,
|
||||
};
|
||||
services.syslogParser.details = { recentLogs30min: recentLogCount, lastLog: lastLogTime };
|
||||
} else {
|
||||
const lastLogEverResult = await db.execute(
|
||||
sql`SELECT MAX(timestamp) as last_log FROM network_logs`
|
||||
);
|
||||
const lastLogEverResult = await db.execute(sql`SELECT MAX(timestamp) as last_log FROM network_logs`);
|
||||
const lastLogEverRows = (lastLogEverResult as any).rows || lastLogEverResult;
|
||||
const lastLogEver = lastLogEverRows[0]?.last_log;
|
||||
|
||||
services.syslogParser.status = "offline";
|
||||
services.syslogParser.healthy = false;
|
||||
services.syslogParser.details = {
|
||||
recentLogs30min: 0,
|
||||
lastLog: lastLogEver || "Never",
|
||||
warning: "No logs received in last 30 minutes",
|
||||
};
|
||||
services.syslogParser.details = { recentLogs30min: 0, lastLog: lastLogEverRows[0]?.last_log || "Mai", warning: "Nessun log negli ultimi 30 minuti" };
|
||||
}
|
||||
} catch (error: any) {
|
||||
services.syslogParser.status = "error";
|
||||
services.syslogParser.healthy = false;
|
||||
services.syslogParser.details = { error: error.message };
|
||||
}
|
||||
|
||||
// Check Analytics Aggregator (via last record timestamp)
|
||||
try {
|
||||
const latestAnalytics = await db
|
||||
.select()
|
||||
.from(networkAnalytics)
|
||||
.orderBy(desc(networkAnalytics.date), desc(networkAnalytics.hour))
|
||||
.limit(1);
|
||||
|
||||
const latestAnalytics = await db.select().from(networkAnalytics).orderBy(desc(networkAnalytics.date), desc(networkAnalytics.hour)).limit(1);
|
||||
if (latestAnalytics.length > 0) {
|
||||
const lastRun = new Date(latestAnalytics[0].date);
|
||||
const lastTimestamp = lastRun.toISOString();
|
||||
const hoursSinceLastRun = (Date.now() - lastRun.getTime()) / (1000 * 60 * 60);
|
||||
|
||||
if (hoursSinceLastRun < 2) {
|
||||
const hoursSince = (Date.now() - lastRun.getTime()) / (1000 * 60 * 60);
|
||||
if (hoursSince < 2) {
|
||||
services.analyticsAggregator.status = "running";
|
||||
services.analyticsAggregator.healthy = true;
|
||||
services.analyticsAggregator.details = {
|
||||
lastRun: latestAnalytics[0].date,
|
||||
lastTimestamp,
|
||||
hoursSinceLastRun: hoursSinceLastRun.toFixed(1),
|
||||
};
|
||||
services.analyticsAggregator.details = { lastRun: latestAnalytics[0].date, hoursSinceLastRun: hoursSince.toFixed(1) };
|
||||
} else {
|
||||
services.analyticsAggregator.status = "idle";
|
||||
services.analyticsAggregator.healthy = false;
|
||||
services.analyticsAggregator.details = {
|
||||
lastRun: latestAnalytics[0].date,
|
||||
lastTimestamp,
|
||||
hoursSinceLastRun: hoursSinceLastRun.toFixed(1),
|
||||
warning: "No aggregation in last 2 hours",
|
||||
};
|
||||
services.analyticsAggregator.details = { lastRun: latestAnalytics[0].date, hoursSinceLastRun: hoursSince.toFixed(1), warning: "Nessuna aggregazione nelle ultime 2 ore" };
|
||||
}
|
||||
} else {
|
||||
services.analyticsAggregator.status = "idle";
|
||||
services.analyticsAggregator.healthy = false;
|
||||
services.analyticsAggregator.details = { error: "No analytics data found" };
|
||||
services.analyticsAggregator.details = { error: "Nessun dato analytics trovato" };
|
||||
}
|
||||
} catch (error: any) {
|
||||
services.analyticsAggregator.status = "error";
|
||||
services.analyticsAggregator.healthy = false;
|
||||
services.analyticsAggregator.details = { error: error.message };
|
||||
}
|
||||
|
||||
// Check Auto Block (via recent blocked detections)
|
||||
try {
|
||||
const recentBlockResult = await db.execute(
|
||||
sql`SELECT COUNT(*) as count, MAX(detected_at) as last_block FROM detections WHERE blocked = true AND detected_at > NOW() - INTERVAL '10 minutes'`
|
||||
);
|
||||
const blockRows = (recentBlockResult as any).rows || recentBlockResult;
|
||||
const recentBlocks = parseInt(blockRows[0]?.count || "0");
|
||||
const lastBlock = blockRows[0]?.last_block;
|
||||
|
||||
const totalBlockedResult = await db.execute(sql`SELECT COUNT(*) as count FROM detections WHERE blocked = true`);
|
||||
const totalBlockedRows = (totalBlockedResult as any).rows || totalBlockedResult;
|
||||
const totalBlocked = parseInt(totalBlockedRows[0]?.count || "0");
|
||||
|
||||
services.autoBlock.status = recentBlocks > 0 ? "running" : "idle";
|
||||
services.autoBlock.healthy = true;
|
||||
services.autoBlock.details = {
|
||||
recentBlocks10min: recentBlocks,
|
||||
totalBlocked,
|
||||
lastBlock: lastBlock || "Mai",
|
||||
interval: "ogni 5 minuti"
|
||||
};
|
||||
} catch (error: any) {
|
||||
services.autoBlock.status = "error";
|
||||
services.autoBlock.details = { error: error.message };
|
||||
}
|
||||
|
||||
// Check Cleanup (via absence of old detections)
|
||||
try {
|
||||
const oldDetResult = await db.execute(
|
||||
sql`SELECT COUNT(*) as count FROM detections WHERE detected_at < NOW() - INTERVAL '48 hours'`
|
||||
);
|
||||
const oldRows = (oldDetResult as any).rows || oldDetResult;
|
||||
const oldDetections = parseInt(oldRows[0]?.count || "0");
|
||||
|
||||
const totalDetResult = await db.execute(sql`SELECT COUNT(*) as count FROM detections`);
|
||||
const totalRows = (totalDetResult as any).rows || totalDetResult;
|
||||
const totalDetections = parseInt(totalRows[0]?.count || "0");
|
||||
|
||||
services.cleanup.status = oldDetections === 0 ? "running" : "idle";
|
||||
services.cleanup.healthy = oldDetections === 0;
|
||||
services.cleanup.details = {
|
||||
oldDetections48h: oldDetections,
|
||||
totalDetections,
|
||||
interval: "ogni ora",
|
||||
warning: oldDetections > 0 ? `${oldDetections} detection vecchie non ancora pulite` : undefined
|
||||
};
|
||||
} catch (error: any) {
|
||||
services.cleanup.status = "error";
|
||||
services.cleanup.details = { error: error.message };
|
||||
}
|
||||
|
||||
// Check List Fetcher (via public lists last_updated)
|
||||
try {
|
||||
const listsResult = await db.execute(
|
||||
sql`SELECT COUNT(*) as total,
|
||||
COUNT(*) FILTER (WHERE enabled = true) as enabled,
|
||||
MAX(last_fetch) as last_fetch
|
||||
FROM public_lists`
|
||||
);
|
||||
const listRows = (listsResult as any).rows || listsResult;
|
||||
const totalLists = parseInt(listRows[0]?.total || "0");
|
||||
const enabledLists = parseInt(listRows[0]?.enabled || "0");
|
||||
const lastFetched = listRows[0]?.last_fetch;
|
||||
|
||||
if (lastFetched) {
|
||||
const hoursSince = (Date.now() - new Date(lastFetched).getTime()) / (1000 * 60 * 60);
|
||||
services.listFetcher.status = hoursSince < 1 ? "running" : "idle";
|
||||
services.listFetcher.healthy = hoursSince < 1;
|
||||
services.listFetcher.details = { totalLists, enabledLists, lastFetched, hoursSinceLastFetch: hoursSince.toFixed(1), interval: "ogni 10 minuti" };
|
||||
} else {
|
||||
services.listFetcher.status = "idle";
|
||||
services.listFetcher.details = { totalLists, enabledLists, lastFetched: "Mai", interval: "ogni 10 minuti" };
|
||||
}
|
||||
} catch (error: any) {
|
||||
services.listFetcher.status = "error";
|
||||
services.listFetcher.details = { error: error.message };
|
||||
}
|
||||
|
||||
// Check ML Training (via training history)
|
||||
try {
|
||||
const latestTraining = await db.select().from(trainingHistory).orderBy(desc(trainingHistory.trainedAt)).limit(1);
|
||||
if (latestTraining.length > 0) {
|
||||
const lastTrainDate = new Date(latestTraining[0].trainedAt);
|
||||
const daysSince = (Date.now() - lastTrainDate.getTime()) / (1000 * 60 * 60 * 24);
|
||||
services.mlTraining.status = daysSince < 8 ? "running" : "idle";
|
||||
services.mlTraining.healthy = daysSince < 8;
|
||||
services.mlTraining.details = {
|
||||
lastTraining: latestTraining[0].trainedAt,
|
||||
daysSinceLastTraining: daysSince.toFixed(1),
|
||||
lastStatus: latestTraining[0].status,
|
||||
lastModel: latestTraining[0].modelVersion,
|
||||
recordsProcessed: latestTraining[0].recordsProcessed,
|
||||
interval: "settimanale"
|
||||
};
|
||||
} else {
|
||||
services.mlTraining.status = "idle";
|
||||
services.mlTraining.details = { lastTraining: "Mai", interval: "settimanale" };
|
||||
}
|
||||
} catch (error: any) {
|
||||
services.mlTraining.status = "error";
|
||||
services.mlTraining.details = { error: error.message };
|
||||
}
|
||||
|
||||
res.json({ services });
|
||||
} catch (error: any) {
|
||||
res.status(500).json({ error: "Failed to check services status" });
|
||||
@ -915,7 +989,11 @@ export async function registerRoutes(app: Express): Promise<Server> {
|
||||
});
|
||||
|
||||
// Service Control Endpoints (Secured - only allow specific systemd operations)
|
||||
const ALLOWED_SERVICES = ["ids-ml-backend", "ids-syslog-parser"];
|
||||
const ALLOWED_SERVICES = [
|
||||
"ids-ml-backend", "ids-syslog-parser", "ids-backend",
|
||||
"ids-analytics-aggregator", "ids-auto-block", "ids-cleanup",
|
||||
"ids-list-fetcher", "ids-ml-training"
|
||||
];
|
||||
const ALLOWED_ACTIONS = ["start", "stop", "restart", "status"];
|
||||
|
||||
app.post("/api/services/:service/:action", async (req, res) => {
|
||||
|
||||
64
version.json
64
version.json
@ -1,7 +1,37 @@
|
||||
{
|
||||
"version": "1.0.117",
|
||||
"lastUpdate": "2026-02-16T15:49:34.102Z",
|
||||
"version": "1.0.122",
|
||||
"lastUpdate": "2026-02-17T09:13:40.571Z",
|
||||
"changelog": [
|
||||
{
|
||||
"version": "1.0.122",
|
||||
"date": "2026-02-17",
|
||||
"type": "patch",
|
||||
"description": "Deployment automatico v1.0.122"
|
||||
},
|
||||
{
|
||||
"version": "1.0.121",
|
||||
"date": "2026-02-17",
|
||||
"type": "patch",
|
||||
"description": "Deployment automatico v1.0.121"
|
||||
},
|
||||
{
|
||||
"version": "1.0.120",
|
||||
"date": "2026-02-17",
|
||||
"type": "patch",
|
||||
"description": "Deployment automatico v1.0.120"
|
||||
},
|
||||
{
|
||||
"version": "1.0.119",
|
||||
"date": "2026-02-17",
|
||||
"type": "patch",
|
||||
"description": "Deployment automatico v1.0.119"
|
||||
},
|
||||
{
|
||||
"version": "1.0.118",
|
||||
"date": "2026-02-16",
|
||||
"type": "patch",
|
||||
"description": "Deployment automatico v1.0.118"
|
||||
},
|
||||
{
|
||||
"version": "1.0.117",
|
||||
"date": "2026-02-16",
|
||||
@ -271,36 +301,6 @@
|
||||
"date": "2025-11-25",
|
||||
"type": "patch",
|
||||
"description": "Deployment automatico v1.0.73"
|
||||
},
|
||||
{
|
||||
"version": "1.0.72",
|
||||
"date": "2025-11-25",
|
||||
"type": "patch",
|
||||
"description": "Deployment automatico v1.0.72"
|
||||
},
|
||||
{
|
||||
"version": "1.0.71",
|
||||
"date": "2025-11-25",
|
||||
"type": "patch",
|
||||
"description": "Deployment automatico v1.0.71"
|
||||
},
|
||||
{
|
||||
"version": "1.0.70",
|
||||
"date": "2025-11-25",
|
||||
"type": "patch",
|
||||
"description": "Deployment automatico v1.0.70"
|
||||
},
|
||||
{
|
||||
"version": "1.0.69",
|
||||
"date": "2025-11-25",
|
||||
"type": "patch",
|
||||
"description": "Deployment automatico v1.0.69"
|
||||
},
|
||||
{
|
||||
"version": "1.0.68",
|
||||
"date": "2025-11-24",
|
||||
"type": "patch",
|
||||
"description": "Deployment automatico v1.0.68"
|
||||
}
|
||||
]
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user