@usex/mikrotik-mcp 4.10.0 → 4.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -0
- package/dist/cli.js +47 -1
- package/dist/index.js +1 -1
- package/dist/shared/{cli-vfm5c52q.js → cli-07emrpkr.js} +3450 -3082
- package/dist/shared/{cli-56bsncg6.js → cli-p6yc41tg.js} +1 -1
- package/dist/shared/{library-vpg7d53z.js → library-pczgrhdt.js} +3450 -3082
- package/dist/shared/{library-1775m2yr.js → library-txj981yv.js} +1 -1
- package/dist/ui/observability.html +3 -3
- package/package.json +2 -2
- package/prompts/setup-port-scan-detection.md +109 -0
- package/schemas/README.md +1 -1
- package/schemas/tool-catalog.json +89 -2
- package/schemas/tools/add_port_scan_detection_rules.json +57 -0
- package/schemas/tools/create_filter_rule.json +2 -0
- package/schemas/tools/list_port_scan_detection_signatures.json +7 -0
- package/schemas/tools/update_filter_rule.json +2 -0
package/README.md
CHANGED
|
@@ -349,6 +349,10 @@ On top of the per-scope tools, the server ships higher-level workflows:
|
|
|
349
349
|
CRL, segmentation, DNS) plus an orchestrator. Every audit is read-only; every
|
|
350
350
|
fix defaults to dry-run and snapshots + Safe-Modes before writing, remediating
|
|
351
351
|
by explicit `finding_id`.
|
|
352
|
+
- **[Port-Scan Detection](docs/port-scan-detection.md)** — detect (never block) six
|
|
353
|
+
port-scan signatures (psd, Nmap FIN/NULL/Xmas, SYN/FIN, SYN/RST) by tagging the
|
|
354
|
+
source, inside a trust-excluding `detect-portscan` jump-gate; explicit signature
|
|
355
|
+
selection, trust-list pre-flight, snapshot + Safe-Mode apply.
|
|
352
356
|
- **[Packet Capture Studio](docs/packet-capture.md)** — stream mirrored packets to
|
|
353
357
|
the host as TZSP, decode them live in the dashboard, and export `.pcap`.
|
|
354
358
|
- **[Discovery](docs/discovery.md)** — `bun run discover` lists MikroTik devices on
|
|
@@ -380,6 +384,7 @@ source** (`bun run gen:schemas`) so they can never drift:
|
|
|
380
384
|
| **[Config Snapshots](docs/config-snapshots.md)** | `/export` snapshots + time-travel diff |
|
|
381
385
|
| **[Firewall Audit](docs/firewall-audit.md)** | Shadowed/broad/dead rules, risk-scored |
|
|
382
386
|
| **[Security Hardening](docs/security-hardening.md)** | Per-category audit+remediate, fix by finding_id, snapshot + Safe-Mode |
|
|
387
|
+
| **[Port-Scan Detection](docs/port-scan-detection.md)** | Detect+tag six scan signatures behind a trust-excluding jump-gate |
|
|
383
388
|
| **[Packet Capture Studio](docs/packet-capture.md)** | Live TZSP capture + pcap export |
|
|
384
389
|
| **[Discovery](docs/discovery.md)** | `bun run discover`, MNDP neighbours, topology map |
|
|
385
390
|
| **[Config Studio](docs/config-studio.md)** | Edit config in the dashboard with autocomplete |
|
package/dist/cli.js
CHANGED
|
@@ -106,12 +106,13 @@ import {
|
|
|
106
106
|
updateAaaEntity,
|
|
107
107
|
updateSummaryLine,
|
|
108
108
|
writeBackup
|
|
109
|
-
} from "./shared/cli-
|
|
109
|
+
} from "./shared/cli-07emrpkr.js";
|
|
110
110
|
|
|
111
111
|
// src/cli.ts
|
|
112
112
|
import { existsSync as existsSync2 } from "fs";
|
|
113
113
|
|
|
114
114
|
// src/observability/dashboard.ts
|
|
115
|
+
import { spawn } from "child_process";
|
|
115
116
|
import { readFileSync as readFileSync2 } from "fs";
|
|
116
117
|
import { homedir, networkInterfaces } from "os";
|
|
117
118
|
import { dirname as dirname4, join as join2 } from "path";
|
|
@@ -1473,6 +1474,24 @@ var JSON_HEADERS3 = { "content-type": "application/json; charset=utf-8" };
|
|
|
1473
1474
|
function json3(body, status = 200) {
|
|
1474
1475
|
return new Response(JSON.stringify(body), { status, headers: JSON_HEADERS3 });
|
|
1475
1476
|
}
|
|
1477
|
+
function restartProcess() {
|
|
1478
|
+
let ok = false;
|
|
1479
|
+
try {
|
|
1480
|
+
const child = spawn(process.execPath, process.argv.slice(1), {
|
|
1481
|
+
cwd: process.cwd(),
|
|
1482
|
+
env: { ...process.env, MIKROTIK_RESTART_DELAY_MS: "1500" },
|
|
1483
|
+
detached: true,
|
|
1484
|
+
stdio: "inherit"
|
|
1485
|
+
});
|
|
1486
|
+
child.unref();
|
|
1487
|
+
ok = true;
|
|
1488
|
+
logger.warn("Dashboard requested a restart \u2014 relaunched a fresh server process; this one is exiting.");
|
|
1489
|
+
} catch (e) {
|
|
1490
|
+
logger.error(`Restart relaunch failed: ${e instanceof Error ? e.message : String(e)}. Exiting anyway.`);
|
|
1491
|
+
}
|
|
1492
|
+
setTimeout(() => process.exit(0), 500);
|
|
1493
|
+
return ok;
|
|
1494
|
+
}
|
|
1476
1495
|
function dashboardHtml() {
|
|
1477
1496
|
try {
|
|
1478
1497
|
return readFileSync2(join2(UI_DIST_DIR, "observability.html"), "utf8");
|
|
@@ -1771,6 +1790,28 @@ async function configRoutes(req, url, admin) {
|
|
|
1771
1790
|
const rolledBack = admin.rollback(String(body?.pendingId ?? ""));
|
|
1772
1791
|
return json3({ rolledBack, config: redact(getConfig()) });
|
|
1773
1792
|
}
|
|
1793
|
+
if (p === "/api/reload" && req.method === "POST") {
|
|
1794
|
+
const body = await readJson(req);
|
|
1795
|
+
if (body?.hard === true) {
|
|
1796
|
+
const relaunched = restartProcess();
|
|
1797
|
+
return json3({
|
|
1798
|
+
ok: true,
|
|
1799
|
+
mode: "restart",
|
|
1800
|
+
note: relaunched ? "Restarting now \u2014 a fresh server process was launched and will bind the same port(s) in ~1.5s. Reconnect shortly." : "Could not self-relaunch; the process is exiting. It only comes back if a supervisor respawns it."
|
|
1801
|
+
});
|
|
1802
|
+
}
|
|
1803
|
+
try {
|
|
1804
|
+
const cfg = loadConfig();
|
|
1805
|
+
setConfig(cfg);
|
|
1806
|
+
const devices = Object.keys(cfg.devices);
|
|
1807
|
+
logger.info(`Config reloaded from source \u2014 ${devices.length} device(s): ${devices.join(", ")}`);
|
|
1808
|
+
return json3({ ok: true, mode: "config", count: devices.length, devices });
|
|
1809
|
+
} catch (e) {
|
|
1810
|
+
const error = e instanceof Error ? e.message : String(e);
|
|
1811
|
+
logger.error(`Config reload failed: ${error}`);
|
|
1812
|
+
return json3({ ok: false, error }, 500);
|
|
1813
|
+
}
|
|
1814
|
+
}
|
|
1774
1815
|
if (p === "/api/config/history" && req.method === "GET") {
|
|
1775
1816
|
const current = JSON.stringify(redact(getConfig()), null, 2);
|
|
1776
1817
|
const versions = listVersions().map((v) => {
|
|
@@ -3236,6 +3277,11 @@ async function main() {
|
|
|
3236
3277
|
if (command === "auth-check") {
|
|
3237
3278
|
process.exit(await authCheck());
|
|
3238
3279
|
}
|
|
3280
|
+
const restartDelayMs = Number.parseInt(process.env.MIKROTIK_RESTART_DELAY_MS ?? "", 10);
|
|
3281
|
+
if (Number.isFinite(restartDelayMs) && restartDelayMs > 0) {
|
|
3282
|
+
logger.info(`Restart: waiting ${restartDelayMs}ms for the previous process to release its ports\u2026`);
|
|
3283
|
+
await new Promise((resolve) => setTimeout(resolve, restartDelayMs));
|
|
3284
|
+
}
|
|
3239
3285
|
const cfg = loadConfig();
|
|
3240
3286
|
setConfig(cfg);
|
|
3241
3287
|
await printBanner();
|
package/dist/index.js
CHANGED
|
@@ -29,7 +29,7 @@ import {
|
|
|
29
29
|
selectToolModules,
|
|
30
30
|
setConfig,
|
|
31
31
|
updateSummaryLine
|
|
32
|
-
} from "./shared/library-
|
|
32
|
+
} from "./shared/library-pczgrhdt.js";
|
|
33
33
|
// src/server.ts
|
|
34
34
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
35
35
|
import { ListToolsRequestSchema } from "@modelcontextprotocol/sdk/types.js";
|