mirror of
https://github.com/myronblair/jarvis
synced 2026-06-30 17:50:23 -05:00
Add netscan push endpoint: PVE1 nmap scan every 3min populates network devices
This commit is contained in:
@@ -312,60 +312,9 @@ function collect_all(): array {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ── Network Device Scan (nmap via PVE1) ───────────────────────────────
|
// Network device scan is handled by PVE1 cron (/usr/local/bin/jarvis-netscan.sh)
|
||||||
try {
|
// which POSTs nmap results to /api/netscan every 3 minutes.
|
||||||
$nmapRaw = shell_exec(
|
$results['nmap_scan'] = 'handled by PVE1 push (jarvis-netscan.sh)';
|
||||||
"sshpass -p 'Joker1974!!!' ssh -o StrictHostKeyChecking=no -o ConnectTimeout=10 " .
|
|
||||||
"root@10.48.200.90 'nmap -sn --send-ip 10.48.200.0/24 2>/dev/null' 2>/dev/null"
|
|
||||||
);
|
|
||||||
if ($nmapRaw) {
|
|
||||||
$discovered = [];
|
|
||||||
$cur = null;
|
|
||||||
foreach (explode("\n", $nmapRaw) as $line) {
|
|
||||||
$line = trim($line);
|
|
||||||
if (preg_match('/Nmap scan report for (?:(\S+) \()?(\d+\.\d+\.\d+\.\d+)\)?/', $line, $m)) {
|
|
||||||
if ($cur) $discovered[] = $cur;
|
|
||||||
$cur = ['hostname' => ($m[1] && $m[1] !== $m[2]) ? $m[1] : null, 'ip' => $m[2], 'mac' => null, 'vendor' => null];
|
|
||||||
} elseif ($cur && preg_match('/MAC Address: ([0-9A-Fa-f:]{17}) \(([^)]+)\)/i', $line, $m)) {
|
|
||||||
$cur['mac'] = strtolower($m[1]);
|
|
||||||
$cur['vendor'] = $m[2] !== 'Unknown' ? $m[2] : null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ($cur) $discovered[] = $cur;
|
|
||||||
|
|
||||||
$discoveredIPs = [];
|
|
||||||
foreach ($discovered as $d) {
|
|
||||||
$discoveredIPs[] = $d['ip'];
|
|
||||||
JarvisDB::execute(
|
|
||||||
'INSERT INTO network_devices (ip, mac, hostname, status, last_seen)
|
|
||||||
VALUES (?,?,?,"online",NOW())
|
|
||||||
ON DUPLICATE KEY UPDATE mac=VALUES(mac), hostname=COALESCE(VALUES(hostname),hostname),
|
|
||||||
status="online", last_seen=NOW()',
|
|
||||||
[$d['ip'], $d['mac'], $d['hostname'] ?? $d['vendor']]
|
|
||||||
);
|
|
||||||
if ($d['vendor']) {
|
|
||||||
JarvisDB::execute(
|
|
||||||
'UPDATE network_devices SET device_type=? WHERE ip=? AND (device_type IS NULL OR device_type="")',
|
|
||||||
[$d['vendor'], $d['ip']]
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!empty($discoveredIPs)) {
|
|
||||||
$ph = implode(',', array_fill(0, count($discoveredIPs), '?'));
|
|
||||||
JarvisDB::execute(
|
|
||||||
"UPDATE network_devices SET status='offline'
|
|
||||||
WHERE ip NOT IN ($ph) AND last_seen < DATE_SUB(NOW(), INTERVAL 10 MINUTE)",
|
|
||||||
$discoveredIPs
|
|
||||||
);
|
|
||||||
}
|
|
||||||
$results['nmap_scan'] = 'ok (' . count($discovered) . ' devices found)';
|
|
||||||
} else {
|
|
||||||
$results['nmap_scan'] = 'skipped (PVE1 unreachable)';
|
|
||||||
}
|
|
||||||
} catch (Exception $e) {
|
|
||||||
$results['nmap_scan'] = 'error: ' . $e->getMessage();
|
|
||||||
}
|
|
||||||
|
|
||||||
return $results;
|
return $results;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,64 @@
|
|||||||
|
<?php
|
||||||
|
// Network scan push endpoint — called by PVE1 cron with nmap results
|
||||||
|
// Authenticates via X-Registration-Key header (same key as agent installer)
|
||||||
|
|
||||||
|
define('NETSCAN_KEY', 'f846a9aaf7ce9a61742c63c87c4186052a71d2a580c65518');
|
||||||
|
|
||||||
|
if ($method !== 'POST') {
|
||||||
|
echo json_encode(['error' => 'POST only']); exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
$reqKey = $_SERVER['HTTP_X_REGISTRATION_KEY'] ?? '';
|
||||||
|
if ($reqKey !== NETSCAN_KEY) {
|
||||||
|
http_response_code(401);
|
||||||
|
echo json_encode(['error' => 'Unauthorized']); exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
$body = file_get_contents('php://input');
|
||||||
|
$payload = json_decode($body, true);
|
||||||
|
$devices = $payload['devices'] ?? [];
|
||||||
|
|
||||||
|
if (empty($devices)) {
|
||||||
|
echo json_encode(['error' => 'No devices in payload']); exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
$discoveredIPs = [];
|
||||||
|
$upserted = 0;
|
||||||
|
foreach ($devices as $d) {
|
||||||
|
$ip = trim($d['ip'] ?? '');
|
||||||
|
$mac = trim($d['mac'] ?? '');
|
||||||
|
$hostname = trim($d['hostname'] ?? '');
|
||||||
|
$vendor = trim($d['vendor'] ?? '');
|
||||||
|
if (!$ip) continue;
|
||||||
|
|
||||||
|
$discoveredIPs[] = $ip;
|
||||||
|
JarvisDB::execute(
|
||||||
|
'INSERT INTO network_devices (ip, mac, hostname, status, last_seen)
|
||||||
|
VALUES (?,?,?,"online",NOW())
|
||||||
|
ON DUPLICATE KEY UPDATE
|
||||||
|
mac = COALESCE(NULLIF(VALUES(mac),""), mac),
|
||||||
|
hostname = COALESCE(NULLIF(VALUES(hostname),""), hostname),
|
||||||
|
status = "online",
|
||||||
|
last_seen = NOW()',
|
||||||
|
[$ip, $mac ?: null, $hostname ?: $vendor ?: null]
|
||||||
|
);
|
||||||
|
if ($vendor) {
|
||||||
|
JarvisDB::execute(
|
||||||
|
'UPDATE network_devices SET device_type=? WHERE ip=? AND (device_type IS NULL OR device_type="")',
|
||||||
|
[$vendor, $ip]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
$upserted++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mark anything NOT in this scan as offline if stale > 10 min
|
||||||
|
if (!empty($discoveredIPs)) {
|
||||||
|
$ph = implode(',', array_fill(0, count($discoveredIPs), '?'));
|
||||||
|
JarvisDB::execute(
|
||||||
|
"UPDATE network_devices SET status='offline'
|
||||||
|
WHERE ip NOT IN ($ph) AND last_seen < DATE_SUB(NOW(), INTERVAL 10 MINUTE)",
|
||||||
|
$discoveredIPs
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
echo json_encode(['ok' => true, 'upserted' => $upserted, 'total_discovered' => count($discoveredIPs)]);
|
||||||
+4
-1
@@ -26,7 +26,7 @@ $endpoint = $parts[0] ?? '';
|
|||||||
$action = $parts[1] ?? '';
|
$action = $parts[1] ?? '';
|
||||||
|
|
||||||
// Auth check (except login and ping)
|
// Auth check (except login and ping)
|
||||||
if ($endpoint !== 'auth' && $endpoint !== 'agent') {
|
if ($endpoint !== 'auth' && $endpoint !== 'agent' && $endpoint !== 'netscan') {
|
||||||
$token = $_SESSION['jarvis_token'] ?? ($_SERVER['HTTP_X_SESSION_TOKEN'] ?? '');
|
$token = $_SESSION['jarvis_token'] ?? ($_SERVER['HTTP_X_SESSION_TOKEN'] ?? '');
|
||||||
if (empty($token) || $token !== ($_SESSION['jarvis_token'] ?? '')) {
|
if (empty($token) || $token !== ($_SESSION['jarvis_token'] ?? '')) {
|
||||||
$localIP = $_SERVER['REMOTE_ADDR'] ?? '';
|
$localIP = $_SERVER['REMOTE_ADDR'] ?? '';
|
||||||
@@ -57,6 +57,9 @@ switch ($endpoint) {
|
|||||||
case 'system':
|
case 'system':
|
||||||
require __DIR__ . '/../api/endpoints/system.php';
|
require __DIR__ . '/../api/endpoints/system.php';
|
||||||
break;
|
break;
|
||||||
|
case 'netscan':
|
||||||
|
require __DIR__ . '/../api/endpoints/netscan.php';
|
||||||
|
break;
|
||||||
case 'network':
|
case 'network':
|
||||||
require __DIR__ . '/../api/endpoints/network.php';
|
require __DIR__ . '/../api/endpoints/network.php';
|
||||||
break;
|
break;
|
||||||
|
|||||||
Reference in New Issue
Block a user