@poolzin/pool-bot 2026.4.32 → 2026.4.33
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/dist/agents/poolbot-tools.d.ts.map +1 -1
- package/dist/agents/poolbot-tools.js +2 -0
- package/dist/agents/system-prompt.d.ts.map +1 -1
- package/dist/agents/system-prompt.js +2 -0
- package/dist/agents/tools/skill-evolve-tool.d.ts.map +1 -1
- package/dist/agents/tools/skill-evolve-tool.js +18 -7
- package/dist/agents/tools/vps-security-tool.d.ts +8 -0
- package/dist/agents/tools/vps-security-tool.d.ts.map +1 -0
- package/dist/agents/tools/vps-security-tool.js +253 -0
- package/dist/build-info.json +3 -3
- package/docs/security/vps-hardening.md +309 -0
- package/docs/skills/vps-security.md +140 -0
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"poolbot-tools.d.ts","sourceRoot":"","sources":["../../src/agents/poolbot-tools.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEzD,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,6BAA6B,CAAC;AAEzE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAI9D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"poolbot-tools.d.ts","sourceRoot":"","sources":["../../src/agents/poolbot-tools.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEzD,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,6BAA6B,CAAC;AAEzE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAI9D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAsBtD,wBAAgB,kBAAkB,CAAC,OAAO,CAAC,EAAE;IAC3C,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,uBAAuB,CAAC,EAAE,OAAO,CAAC;IAClC,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,YAAY,CAAC,EAAE,qBAAqB,CAAC;IACrC,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,oFAAoF;IACpF,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,6EAA6E;IAC7E,aAAa,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAChC,0DAA0D;IAC1D,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,qEAAqE;IACrE,iBAAiB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,mEAAmE;IACnE,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,eAAe,CAAC,EAAE,eAAe,CAAC;IAClC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,MAAM,CAAC,EAAE,aAAa,CAAC;IACvB,mBAAmB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC/B,qDAAqD;IACrD,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,2DAA2D;IAC3D,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,8CAA8C;IAC9C,WAAW,CAAC,EAAE,KAAK,GAAG,OAAO,GAAG,KAAK,CAAC;IACtC,mEAAmE;IACnE,aAAa,CAAC,EAAE;QAAE,KAAK,EAAE,OAAO,CAAA;KAAE,CAAC;IACnC,sDAAsD;IACtD,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,yDAAyD;IACzD,wBAAwB,CAAC,EAAE,MAAM,CAAC;IAClC,uEAAuE;IACvE,4BAA4B,CAAC,EAAE,OAAO,CAAC;IACvC,yDAAyD;IACzD,kBAAkB,CAAC,EAAE,OAAO,CAAC;CAC9B,GAAG,YAAY,EAAE,CAsJjB"}
|
|
@@ -19,6 +19,7 @@ import { createSessionsSendTool } from "./tools/sessions-send-tool.js";
|
|
|
19
19
|
import { createSessionsSpawnTool } from "./tools/sessions-spawn-tool.js";
|
|
20
20
|
import { createSubagentsTool } from "./tools/subagents-tool.js";
|
|
21
21
|
import { createSkillEvolveTool } from "./tools/skill-evolve-tool.js";
|
|
22
|
+
import { createVPSSecurityTool } from "./tools/vps-security-tool.js";
|
|
22
23
|
import { createTtsTool } from "./tools/tts-tool.js";
|
|
23
24
|
import { createWebFetchTool, createWebSearchTool } from "./tools/web-tools.js";
|
|
24
25
|
import { resolveWorkspaceRoot } from "./workspace-dir.js";
|
|
@@ -135,6 +136,7 @@ export function createPoolBotTools(options) {
|
|
|
135
136
|
config: options?.config,
|
|
136
137
|
}),
|
|
137
138
|
createSkillEvolveTool(options?.config ?? {}),
|
|
139
|
+
createVPSSecurityTool(options?.config ?? {}),
|
|
138
140
|
...(webSearchTool ? [webSearchTool] : []),
|
|
139
141
|
...(webFetchTool ? [webFetchTool] : []),
|
|
140
142
|
...(imageTool ? [imageTool] : []),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"system-prompt.d.ts","sourceRoot":"","sources":["../../src/agents/system-prompt.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AAE5E,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AAErE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AACzD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAiCpE;;;GAGG;AACH,wBAAgB,2BAA2B,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAoBrF;AAED;;;;;GAKG;AACH,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,SAAS,GAAG,MAAM,CAAC;AACrD,KAAK,cAAc,GAAG,KAAK,GAAG,MAAM,CAAC;AAkLrC,wBAAgB,sBAAsB,CAAC,MAAM,EAAE;IAC7C,YAAY,EAAE,MAAM,CAAC;IACrB,iBAAiB,CAAC,EAAE,UAAU,CAAC;IAC/B,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,YAAY,CAAC,EAAE,cAAc,CAAC;IAC9B,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACvC,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;IAC3B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,cAAc,CAAC,EAAE,kBAAkB,CAAC;IACpC,YAAY,CAAC,EAAE,mBAAmB,EAAE,CAAC;IACrC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,wEAAwE;IACxE,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,WAAW,CAAC,EAAE;QACZ,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,EAAE,CAAC,EAAE,MAAM,CAAC;QACZ,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;QACxB,QAAQ,CAAC,EAAE,MAAM,CAAC;KACnB,CAAC;IACF,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC5B,WAAW,CAAC,EAAE;QACZ,OAAO,EAAE,OAAO,CAAC;QACjB,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,qBAAqB,CAAC,EAAE,MAAM,CAAC;QAC/B,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAAC;QACvC,mBAAmB,CAAC,EAAE,MAAM,CAAC;QAC7B,gBAAgB,CAAC,EAAE,MAAM,CAAC;QAC1B,eAAe,CAAC,EAAE,MAAM,CAAC;QACzB,kBAAkB,CAAC,EAAE,OAAO,CAAC;QAC7B,QAAQ,CAAC,EAAE;YACT,OAAO,EAAE,OAAO,CAAC;YACjB,YAAY,EAAE,IAAI,GAAG,KAAK,GAAG,KAAK,GAAG,MAAM,CAAC;SAC7C,CAAC;KACH,CAAC;IACF,8EAA8E;IAC9E,gBAAgB,CAAC,EAAE;QACjB,KAAK,EAAE,SAAS,GAAG,WAAW,CAAC;QAC/B,OAAO,EAAE,MAAM,CAAC;KACjB,CAAC;IACF,mBAAmB,CAAC,EAAE,mBAAmB,CAAC;CAC3C,
|
|
1
|
+
{"version":3,"file":"system-prompt.d.ts","sourceRoot":"","sources":["../../src/agents/system-prompt.ts"],"names":[],"mappings":"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"}
|
|
@@ -213,6 +213,7 @@ export function buildAgentSystemPrompt(params) {
|
|
|
213
213
|
nodes: "List/describe/notify/camera/screen on paired nodes",
|
|
214
214
|
cron: "Manage cron jobs and wake events. SCHEDULING MODES: (1) Reminders — use systemEvent payload to inject text into your session when it fires; write the text as something that reads like a reminder. (2) Background tasks — use agentTurn payload with a message describing the work; results auto-deliver back to the originating chat. CRITICAL: When the user asks you to do something 'later', 'tonight', 'overnight', 'tomorrow morning', 'when I wake up', or any future time — IMMEDIATELY schedule a cron job with schedule.kind='at' at the appropriate time and payload.kind='agentTurn' with a descriptive message. Do NOT just say you'll do it. Actually schedule it. Use delivery.mode='announce' (default) to deliver results back to the user's chat.",
|
|
215
215
|
skill_evolve: "Self-improve a skill file. Use this when you notice a skill is unclear, incomplete, or could be more effective. The tool loads the skill content and guides you to write an improved version using the 'write' tool. Periodically review and evolve your skills to keep them sharp.",
|
|
216
|
+
vps_security: "Monitor VPS security (fail2ban, UFW, SSH hardening, honeypot). Check status, view banned IPs, unban IPs, check firewall rules, and generate security reports. Use for security monitoring and incident response.",
|
|
216
217
|
message: "Send messages and channel actions",
|
|
217
218
|
gateway: "Restart, apply config, or run updates on the running Pool Bot process",
|
|
218
219
|
agents_list: "List agent ids allowed for sessions_spawn",
|
|
@@ -378,6 +379,7 @@ export function buildAgentSystemPrompt(params) {
|
|
|
378
379
|
"- nodes: list/describe/notify/camera/screen on paired nodes",
|
|
379
380
|
"- cron: manage cron jobs and wake events (use systemEvent for reminders, agentTurn for background tasks; when user asks for future work — 'later', 'tonight', 'tomorrow' — schedule an agentTurn cron job with schedule.kind='at')",
|
|
380
381
|
"- skill_evolve: self-improve skill files (review, optimize, write improved version)",
|
|
382
|
+
"- vps_security: monitor VPS security (fail2ban, UFW, SSH hardening, honeypot; check status, unban IPs, generate reports)",
|
|
381
383
|
"- sessions_list: list sessions",
|
|
382
384
|
"- sessions_history: fetch session history",
|
|
383
385
|
"- sessions_send: send to another session",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"skill-evolve-tool.d.ts","sourceRoot":"","sources":["../../../src/agents/tools/skill-evolve-tool.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAE5D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAKhD,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,aAAa,GAAG,YAAY,
|
|
1
|
+
{"version":3,"file":"skill-evolve-tool.d.ts","sourceRoot":"","sources":["../../../src/agents/tools/skill-evolve-tool.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAE5D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAKhD,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,aAAa,GAAG,YAAY,CAqGtE"}
|
|
@@ -34,7 +34,12 @@ export function createSkillEvolveTool(cfg) {
|
|
|
34
34
|
const skillName = readStringParam(params, "skill", { required: true });
|
|
35
35
|
if (!skillName) {
|
|
36
36
|
return {
|
|
37
|
-
content: [
|
|
37
|
+
content: [
|
|
38
|
+
{
|
|
39
|
+
type: "text",
|
|
40
|
+
text: "Error: 'skill' parameter is required. Provide a skill name or path.",
|
|
41
|
+
},
|
|
42
|
+
],
|
|
38
43
|
};
|
|
39
44
|
}
|
|
40
45
|
const focus = typeof params.focus === "string" ? params.focus : "all";
|
|
@@ -50,19 +55,22 @@ export function createSkillEvolveTool(cfg) {
|
|
|
50
55
|
}
|
|
51
56
|
if (!skillPath) {
|
|
52
57
|
return {
|
|
53
|
-
content: [
|
|
58
|
+
content: [
|
|
59
|
+
{
|
|
54
60
|
type: "text",
|
|
55
61
|
text: `Skill '${skillName}' not found.\n` +
|
|
56
62
|
`Searched in: ${skillsDir}/\n` +
|
|
57
63
|
`Use the 'read' tool to list available skills first.`,
|
|
58
|
-
}
|
|
64
|
+
},
|
|
65
|
+
],
|
|
59
66
|
};
|
|
60
67
|
}
|
|
61
68
|
try {
|
|
62
69
|
const skill = loadSkill(skillPath);
|
|
63
70
|
const currentContent = readFileSync(skillPath, "utf-8");
|
|
64
71
|
return {
|
|
65
|
-
content: [
|
|
72
|
+
content: [
|
|
73
|
+
{
|
|
66
74
|
type: "text",
|
|
67
75
|
text: `📋 Skill loaded: ${skill.name}\n` +
|
|
68
76
|
`Path: ${skillPath}\n` +
|
|
@@ -75,15 +83,18 @@ export function createSkillEvolveTool(cfg) {
|
|
|
75
83
|
`3. Use the 'write' tool to save the improved version to: ${skillPath}\n` +
|
|
76
84
|
`4. The new version should be clearer, more concise, and handle more edge cases\n` +
|
|
77
85
|
`(dryRun: ${dryRun ? "enabled — review only, don't write yet" : "disabled — write the improved version"})`,
|
|
78
|
-
}
|
|
86
|
+
},
|
|
87
|
+
],
|
|
79
88
|
};
|
|
80
89
|
}
|
|
81
90
|
catch (err) {
|
|
82
91
|
return {
|
|
83
|
-
content: [
|
|
92
|
+
content: [
|
|
93
|
+
{
|
|
84
94
|
type: "text",
|
|
85
95
|
text: `Error loading skill '${skillName}': ${String(err)}`,
|
|
86
|
-
}
|
|
96
|
+
},
|
|
97
|
+
],
|
|
87
98
|
};
|
|
88
99
|
}
|
|
89
100
|
},
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* VPS Security monitoring tool.
|
|
3
|
+
* Monitors fail2ban, UFW, SSH hardening, and honeypot.
|
|
4
|
+
*/
|
|
5
|
+
import type { PoolBotConfig } from "../../config/config.js";
|
|
6
|
+
import type { AnyAgentTool } from "./common.js";
|
|
7
|
+
export declare function createVPSSecurityTool(cfg: PoolBotConfig): AnyAgentTool;
|
|
8
|
+
//# sourceMappingURL=vps-security-tool.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vps-security-tool.d.ts","sourceRoot":"","sources":["../../../src/agents/tools/vps-security-tool.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAG5D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAKhD,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,aAAa,GAAG,YAAY,CAkDtE"}
|
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* VPS Security monitoring tool.
|
|
3
|
+
* Monitors fail2ban, UFW, SSH hardening, and honeypot.
|
|
4
|
+
*/
|
|
5
|
+
import { Type } from "@sinclair/typebox";
|
|
6
|
+
import { exec } from "node:child_process";
|
|
7
|
+
import { promisify } from "node:util";
|
|
8
|
+
import { readStringParam } from "./common.js";
|
|
9
|
+
const execAsync = promisify(exec);
|
|
10
|
+
export function createVPSSecurityTool(cfg) {
|
|
11
|
+
return {
|
|
12
|
+
name: "vps_security",
|
|
13
|
+
label: "VPS Security",
|
|
14
|
+
description: "Monitor and manage VPS security features including fail2ban, UFW firewall, SSH hardening, and honeypot. " +
|
|
15
|
+
"Check security status, view banned IPs, unban IPs, check firewall rules, and generate security reports.",
|
|
16
|
+
parameters: Type.Object({
|
|
17
|
+
action: Type.String({
|
|
18
|
+
description: "Action to perform: 'status', 'fail2ban', 'unban', 'ufw', 'ssh', 'honeypot', 'report'",
|
|
19
|
+
enum: ["status", "fail2ban", "unban", "ufw", "ssh", "honeypot", "report"],
|
|
20
|
+
}),
|
|
21
|
+
ip: Type.Optional(Type.String({
|
|
22
|
+
description: "IP address to unban (required for action='unban')",
|
|
23
|
+
})),
|
|
24
|
+
}),
|
|
25
|
+
execute: async (_toolCallId, args) => {
|
|
26
|
+
const action = readStringParam(args, "action", { required: true });
|
|
27
|
+
const ip = typeof args.ip === "string" ? args.ip : undefined;
|
|
28
|
+
try {
|
|
29
|
+
switch (action) {
|
|
30
|
+
case "status":
|
|
31
|
+
return await checkSecurityStatus();
|
|
32
|
+
case "fail2ban":
|
|
33
|
+
return await checkFail2ban();
|
|
34
|
+
case "unban":
|
|
35
|
+
if (!ip) {
|
|
36
|
+
return errorResult("IP address required for unban action. Use: vps_security(action='unban', ip='1.2.3.4')");
|
|
37
|
+
}
|
|
38
|
+
return await unbanIP(ip);
|
|
39
|
+
case "ufw":
|
|
40
|
+
return await checkUFW();
|
|
41
|
+
case "ssh":
|
|
42
|
+
return await checkSSH();
|
|
43
|
+
case "honeypot":
|
|
44
|
+
return await checkHoneypot();
|
|
45
|
+
case "report":
|
|
46
|
+
return await generateSecurityReport();
|
|
47
|
+
default:
|
|
48
|
+
return errorResult(`Unknown action: ${action}. Valid actions: status, fail2ban, unban, ufw, ssh, honeypot, report`);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
catch (err) {
|
|
52
|
+
return errorResult(`Security command failed: ${String(err)}`);
|
|
53
|
+
}
|
|
54
|
+
},
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
async function runCommand(cmd) {
|
|
58
|
+
const { stdout, stderr } = await execAsync(cmd, { timeout: 30_000 });
|
|
59
|
+
if (stderr && !stderr.includes("warn") && !stderr.includes("deprecated")) {
|
|
60
|
+
throw new Error(stderr);
|
|
61
|
+
}
|
|
62
|
+
return stdout.trim();
|
|
63
|
+
}
|
|
64
|
+
async function checkSecurityStatus() {
|
|
65
|
+
const results = [];
|
|
66
|
+
// fail2ban
|
|
67
|
+
try {
|
|
68
|
+
const f2b = await runCommand("fail2ban-client status sshd 2>/dev/null | head -10");
|
|
69
|
+
const bannedMatch = f2b.match(/Currently banned:\s*(\d+)/);
|
|
70
|
+
const totalBannedMatch = f2b.match(/Total banned:\s*(\d+)/);
|
|
71
|
+
results.push(`✅ fail2ban: Active`);
|
|
72
|
+
if (bannedMatch)
|
|
73
|
+
results.push(` Currently banned: ${bannedMatch[1]} IPs`);
|
|
74
|
+
if (totalBannedMatch)
|
|
75
|
+
results.push(` Total banned: ${totalBannedMatch[1]} IPs`);
|
|
76
|
+
}
|
|
77
|
+
catch {
|
|
78
|
+
results.push(`❌ fail2ban: Not active`);
|
|
79
|
+
}
|
|
80
|
+
// UFW
|
|
81
|
+
try {
|
|
82
|
+
const ufw = await runCommand("ufw status 2>/dev/null | grep '22.*LIMIT' || echo 'no rate limit'");
|
|
83
|
+
if (ufw.includes("LIMIT")) {
|
|
84
|
+
results.push(`✅ UFW: Active with SSH rate limit`);
|
|
85
|
+
}
|
|
86
|
+
else {
|
|
87
|
+
results.push(`⚠️ UFW: Active but no SSH rate limit`);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
catch {
|
|
91
|
+
results.push(`❌ UFW: Not active`);
|
|
92
|
+
}
|
|
93
|
+
// SSH hardening
|
|
94
|
+
try {
|
|
95
|
+
const loginGrace = await runCommand("grep 'LoginGraceTime' /etc/ssh/sshd_config 2>/dev/null | tail -1 || echo 'not set'");
|
|
96
|
+
const maxAuth = await runCommand("grep 'MaxAuthTries' /etc/ssh/sshd_config 2>/dev/null | tail -1 || echo 'not set'");
|
|
97
|
+
results.push(`✅ SSH hardening: ${loginGrace}, ${maxAuth}`);
|
|
98
|
+
}
|
|
99
|
+
catch {
|
|
100
|
+
results.push(`⚠️ SSH hardening: Not configured`);
|
|
101
|
+
}
|
|
102
|
+
// Honeypot
|
|
103
|
+
try {
|
|
104
|
+
const hp = await runCommand("pgrep -f 'endlessh -p 2222' && echo 'active' || echo 'inactive'");
|
|
105
|
+
if (hp.includes("active")) {
|
|
106
|
+
results.push(`✅ Honeypot: Active on port 2222`);
|
|
107
|
+
}
|
|
108
|
+
else {
|
|
109
|
+
results.push(`❌ Honeypot: Not active`);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
catch {
|
|
113
|
+
results.push(`❌ Honeypot: Not active`);
|
|
114
|
+
}
|
|
115
|
+
// Calculate score
|
|
116
|
+
let score = 0;
|
|
117
|
+
if (results[0].includes("✅"))
|
|
118
|
+
score += 25;
|
|
119
|
+
if (results[1].includes("✅"))
|
|
120
|
+
score += 25;
|
|
121
|
+
if (results[2].includes("✅"))
|
|
122
|
+
score += 25;
|
|
123
|
+
if (results[3].includes("✅"))
|
|
124
|
+
score += 15;
|
|
125
|
+
score += 10; // Base score
|
|
126
|
+
results.push(`\n📊 Security Score: ${score}/100`);
|
|
127
|
+
return {
|
|
128
|
+
content: [{ type: "text", text: results.join("\n") }],
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
async function checkFail2ban() {
|
|
132
|
+
const output = await runCommand("fail2ban-client status sshd 2>/dev/null");
|
|
133
|
+
const currentlyFailed = output.match(/Currently failed:\s*(\d+)/)?.[1] ?? "0";
|
|
134
|
+
const totalFailed = output.match(/Total failed:\s*(\d+)/)?.[1] ?? "0";
|
|
135
|
+
const currentlyBanned = output.match(/Currently banned:\s*(\d+)/)?.[1] ?? "0";
|
|
136
|
+
const totalBanned = output.match(/Total banned:\s*(\d+)/)?.[1] ?? "0";
|
|
137
|
+
const bannedList = output.match(/Banned IP list:\s*(.*)/)?.[1] ?? "none";
|
|
138
|
+
const text = `🛡️ fail2ban Status (SSH)
|
|
139
|
+
|
|
140
|
+
Currently failed: ${currentlyFailed}
|
|
141
|
+
Total failed: ${totalFailed}
|
|
142
|
+
Currently banned: ${currentlyBanned}
|
|
143
|
+
Total banned: ${totalBanned}
|
|
144
|
+
Banned IPs: ${bannedList}`;
|
|
145
|
+
return {
|
|
146
|
+
content: [{ type: "text", text }],
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
async function unbanIP(ip) {
|
|
150
|
+
// Validate IP format
|
|
151
|
+
const ipRegex = /^(\d{1,3}\.){3}\d{1,3}$/;
|
|
152
|
+
if (!ipRegex.test(ip)) {
|
|
153
|
+
return errorResult(`Invalid IP format: ${ip}. Use format: 1.2.3.4`);
|
|
154
|
+
}
|
|
155
|
+
await runCommand(`fail2ban-client set sshd unbanip ${ip} 2>/dev/null`);
|
|
156
|
+
// Verify unban
|
|
157
|
+
const status = await runCommand("fail2ban-client status sshd 2>/dev/null");
|
|
158
|
+
const stillBanned = status.includes(ip);
|
|
159
|
+
if (stillBanned) {
|
|
160
|
+
return {
|
|
161
|
+
content: [{ type: "text", text: `❌ Failed to unban ${ip}. IP may not be banned or fail2ban error.` }],
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
return {
|
|
165
|
+
content: [{ type: "text", text: `✅ Successfully unbanned IP: ${ip}` }],
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
async function checkUFW() {
|
|
169
|
+
const output = await runCommand("ufw status verbose 2>/dev/null");
|
|
170
|
+
const activeMatch = output.match(/Status:\s*(\w+)/);
|
|
171
|
+
const status = activeMatch?.[1] ?? "inactive";
|
|
172
|
+
const rules = output
|
|
173
|
+
.split("\n")
|
|
174
|
+
.filter((line) => line.includes("ALLOW") || line.includes("DENY") || line.includes("LIMIT"))
|
|
175
|
+
.slice(0, 20)
|
|
176
|
+
.join("\n");
|
|
177
|
+
const text = `🔥 UFW Firewall Status
|
|
178
|
+
|
|
179
|
+
Status: ${status.toUpperCase()}
|
|
180
|
+
|
|
181
|
+
Rules:
|
|
182
|
+
${rules || "No rules configured"}`;
|
|
183
|
+
return {
|
|
184
|
+
content: [{ type: "text", text }],
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
async function checkSSH() {
|
|
188
|
+
const config = await runCommand("cat /etc/ssh/sshd_config 2>/dev/null");
|
|
189
|
+
const settings = {};
|
|
190
|
+
const keys = ["PermitRootLogin", "PasswordAuthentication", "LoginGraceTime", "MaxAuthTries", "PubkeyAuthentication"];
|
|
191
|
+
for (const key of keys) {
|
|
192
|
+
const match = config.match(new RegExp(`^${key}\\s+(\\w+)`, "m"));
|
|
193
|
+
settings[key] = match?.[1] ?? "not set";
|
|
194
|
+
}
|
|
195
|
+
const text = `🔐 SSH Configuration
|
|
196
|
+
|
|
197
|
+
PermitRootLogin: ${settings.PermitRootLogin}
|
|
198
|
+
PasswordAuthentication: ${settings.PasswordAuthentication}
|
|
199
|
+
LoginGraceTime: ${settings.LoginGraceTime}
|
|
200
|
+
MaxAuthTries: ${settings.MaxAuthTries}
|
|
201
|
+
PubkeyAuthentication: ${settings.PubkeyAuthentication}`;
|
|
202
|
+
return {
|
|
203
|
+
content: [{ type: "text", text }],
|
|
204
|
+
};
|
|
205
|
+
}
|
|
206
|
+
async function checkHoneypot() {
|
|
207
|
+
const pid = await runCommand("pgrep -f 'endlessh -p 2222' 2>/dev/null || echo 'none'");
|
|
208
|
+
const active = pid !== "none" && pid.trim() !== "";
|
|
209
|
+
const logCount = await runCommand("wc -l < /var/log/endlessh.log 2>/dev/null || echo '0'");
|
|
210
|
+
const text = `🍯 Honeypot (endlessh) Status
|
|
211
|
+
|
|
212
|
+
Status: ${active ? "✅ Active" : "❌ Inactive"}
|
|
213
|
+
Port: 2222
|
|
214
|
+
PID: ${active ? pid.trim() : "N/A"}
|
|
215
|
+
Log entries: ${logCount.trim()}`;
|
|
216
|
+
return {
|
|
217
|
+
content: [{ type: "text", text }],
|
|
218
|
+
};
|
|
219
|
+
}
|
|
220
|
+
async function generateSecurityReport() {
|
|
221
|
+
const status = await checkSecurityStatus();
|
|
222
|
+
const fail2ban = await checkFail2ban();
|
|
223
|
+
const ufw = await checkUFW();
|
|
224
|
+
const ssh = await checkSSH();
|
|
225
|
+
const honeypot = await checkHoneypot();
|
|
226
|
+
const text = `📊 VPS Security Report
|
|
227
|
+
Generated: ${new Date().toISOString()}
|
|
228
|
+
|
|
229
|
+
${status.content[0].text}
|
|
230
|
+
|
|
231
|
+
---
|
|
232
|
+
${fail2ban.content[0].text}
|
|
233
|
+
|
|
234
|
+
---
|
|
235
|
+
${ufw.content[0].text}
|
|
236
|
+
|
|
237
|
+
---
|
|
238
|
+
${ssh.content[0].text}
|
|
239
|
+
|
|
240
|
+
---
|
|
241
|
+
${honeypot.content[0].text}
|
|
242
|
+
|
|
243
|
+
---
|
|
244
|
+
ℹ️ For detailed documentation, see: docs/security/vps-hardening.md`;
|
|
245
|
+
return {
|
|
246
|
+
content: [{ type: "text", text }],
|
|
247
|
+
};
|
|
248
|
+
}
|
|
249
|
+
function errorResult(message) {
|
|
250
|
+
return {
|
|
251
|
+
content: [{ type: "text", text: `❌ ${message}` }],
|
|
252
|
+
};
|
|
253
|
+
}
|
package/dist/build-info.json
CHANGED
|
@@ -0,0 +1,309 @@
|
|
|
1
|
+
# VPS Security Hardening Guide
|
|
2
|
+
|
|
3
|
+
## Security Measures Applied (Gentle - Non-Breaking)
|
|
4
|
+
|
|
5
|
+
### 1. fail2ban
|
|
6
|
+
**Status:** ✅ Active
|
|
7
|
+
|
|
8
|
+
**Configuration:**
|
|
9
|
+
- 5 failed login attempts = 1 hour ban
|
|
10
|
+
- Monitors SSH only
|
|
11
|
+
- Does NOT block legitimate users
|
|
12
|
+
|
|
13
|
+
**Check status:**
|
|
14
|
+
```bash
|
|
15
|
+
fail2ban-client status sshd
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
**Unban an IP:**
|
|
19
|
+
```bash
|
|
20
|
+
fail2ban-client set sshd unbanip <IP>
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
### 2. UFW Rate Limit (SSH)
|
|
26
|
+
**Status:** ✅ Active
|
|
27
|
+
|
|
28
|
+
**Configuration:**
|
|
29
|
+
- SSH (port 22) rate limited per IP
|
|
30
|
+
- Allows normal connections
|
|
31
|
+
- Blocks aggressive connection attempts
|
|
32
|
+
|
|
33
|
+
**Check status:**
|
|
34
|
+
```bash
|
|
35
|
+
ufw status | grep 22
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
### 3. SSH Hardening
|
|
41
|
+
**Status:** ✅ Active
|
|
42
|
+
|
|
43
|
+
**Configuration:**
|
|
44
|
+
- `LoginGraceTime 60` — Disconnect after 60s without auth
|
|
45
|
+
- `MaxAuthTries 6` — 6 password attempts per connection
|
|
46
|
+
- `ClientAliveInterval 300` — Keep-alive every 5 min
|
|
47
|
+
- `ClientAliveCountMax 2` — Disconnect after 2 missed keep-alives
|
|
48
|
+
|
|
49
|
+
**What's NOT changed:**
|
|
50
|
+
- `PermitRootLogin yes` — Root login still allowed
|
|
51
|
+
- `PasswordAuthentication yes` — Password auth still enabled
|
|
52
|
+
|
|
53
|
+
**Check config:**
|
|
54
|
+
```bash
|
|
55
|
+
grep -E 'LoginGraceTime|MaxAuthTries' /etc/ssh/sshd_config
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
---
|
|
59
|
+
|
|
60
|
+
### 4. Honeypot (endlessh)
|
|
61
|
+
**Status:** ✅ Active on port 2222
|
|
62
|
+
|
|
63
|
+
**What it does:**
|
|
64
|
+
- Simulates an SSH server on port 2222
|
|
65
|
+
- Traps bots that scan for SSH on non-standard ports
|
|
66
|
+
- Logs attacker IPs and commands
|
|
67
|
+
- Does NOT affect real SSH (port 22)
|
|
68
|
+
|
|
69
|
+
**Check status:**
|
|
70
|
+
```bash
|
|
71
|
+
systemctl is-active endlessh
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
**View honeypot logs:**
|
|
75
|
+
```bash
|
|
76
|
+
journalctl -u endlessh -f
|
|
77
|
+
# Or check /var/log/endlessh.log
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
**How it works:**
|
|
81
|
+
- Real SSH: port 22
|
|
82
|
+
- Honeypot: port 2222
|
|
83
|
+
- Bots scanning port 2222 get trapped and logged
|
|
84
|
+
- You connect to port 22 (unaffected)
|
|
85
|
+
|
|
86
|
+
---
|
|
87
|
+
|
|
88
|
+
### 5. Port 9999 (glance API)
|
|
89
|
+
**Status:** ✅ Identified as legitimate
|
|
90
|
+
|
|
91
|
+
**What it is:**
|
|
92
|
+
- PoolBot skill: `/root/pool/skills/glance/api/ecosystem-api.py`
|
|
93
|
+
- Used by PoolBot for glance functionality
|
|
94
|
+
- NOT a security risk
|
|
95
|
+
|
|
96
|
+
**No action needed.**
|
|
97
|
+
|
|
98
|
+
---
|
|
99
|
+
|
|
100
|
+
## How PoolBot Uses Security Features
|
|
101
|
+
|
|
102
|
+
### security-audit Skill
|
|
103
|
+
|
|
104
|
+
**What it does:**
|
|
105
|
+
- Runs daily security audit
|
|
106
|
+
- Checks for:
|
|
107
|
+
- Failed login attempts
|
|
108
|
+
- Suspicious processes
|
|
109
|
+
- Open ports
|
|
110
|
+
- SSL certificate expiry
|
|
111
|
+
- System updates
|
|
112
|
+
|
|
113
|
+
**Manual trigger:**
|
|
114
|
+
```bash
|
|
115
|
+
poolbot message send "Run security audit"
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
**Output:**
|
|
119
|
+
- Security score (0-100)
|
|
120
|
+
- List of issues found
|
|
121
|
+
- Recommended actions
|
|
122
|
+
|
|
123
|
+
---
|
|
124
|
+
|
|
125
|
+
### self-healing Skill
|
|
126
|
+
|
|
127
|
+
**What it does:**
|
|
128
|
+
- Automatically fixes common issues
|
|
129
|
+
- Restarts failed services
|
|
130
|
+
- Clears stuck processes
|
|
131
|
+
- Recovers from errors
|
|
132
|
+
|
|
133
|
+
**Manual trigger:**
|
|
134
|
+
```bash
|
|
135
|
+
poolbot message send "Self-heal the system"
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
---
|
|
139
|
+
|
|
140
|
+
### Fail2ban Monitoring via PoolBot
|
|
141
|
+
|
|
142
|
+
**Ask PoolBot:**
|
|
143
|
+
```bash
|
|
144
|
+
poolbot message send "How many failed login attempts?"
|
|
145
|
+
poolbot message send "Show me banned IPs"
|
|
146
|
+
poolbot message send "Unban IP 1.2.3.4"
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
---
|
|
150
|
+
|
|
151
|
+
### Honeypot Monitoring via PoolBot
|
|
152
|
+
|
|
153
|
+
**Ask PoolBot:**
|
|
154
|
+
```bash
|
|
155
|
+
poolbot message send "Show honeypot activity"
|
|
156
|
+
poolbot message send "How many bots tried to connect?"
|
|
157
|
+
poolbot message send "Show recent attacker IPs"
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
---
|
|
161
|
+
|
|
162
|
+
## Security Commands Reference
|
|
163
|
+
|
|
164
|
+
### fail2ban
|
|
165
|
+
```bash
|
|
166
|
+
# Status
|
|
167
|
+
fail2ban-client status
|
|
168
|
+
fail2ban-client status sshd
|
|
169
|
+
|
|
170
|
+
# Unban IP
|
|
171
|
+
fail2ban-client set sshd unbanip <IP>
|
|
172
|
+
|
|
173
|
+
# Restart
|
|
174
|
+
systemctl restart fail2ban
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
### UFW
|
|
178
|
+
```bash
|
|
179
|
+
# Status
|
|
180
|
+
ufw status
|
|
181
|
+
|
|
182
|
+
# Add rate limit
|
|
183
|
+
ufw limit 22/tcp
|
|
184
|
+
|
|
185
|
+
# Allow specific IP
|
|
186
|
+
ufw allow from 1.2.3.4 to any port 22
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
### SSH
|
|
190
|
+
```bash
|
|
191
|
+
# Check config
|
|
192
|
+
sshd -t # Test config validity
|
|
193
|
+
|
|
194
|
+
# Reload
|
|
195
|
+
systemctl reload ssh
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
### Honeypot
|
|
199
|
+
```bash
|
|
200
|
+
# Status
|
|
201
|
+
systemctl is-active endlessh
|
|
202
|
+
|
|
203
|
+
# Logs
|
|
204
|
+
journalctl -u endlessh -f
|
|
205
|
+
cat /var/log/endlessh.log
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
---
|
|
209
|
+
|
|
210
|
+
## What Was NOT Changed (By Design)
|
|
211
|
+
|
|
212
|
+
| Setting | Value | Why |
|
|
213
|
+
|---------|-------|-----|
|
|
214
|
+
| `PermitRootLogin` | `yes` | You need root access |
|
|
215
|
+
| `PasswordAuthentication` | `yes` | You use password auth |
|
|
216
|
+
| PostgreSQL `listen_addresses` | `*` | Your APIs need external access |
|
|
217
|
+
| Port 9999 | Open | glance API (legitimate PoolBot skill) |
|
|
218
|
+
|
|
219
|
+
---
|
|
220
|
+
|
|
221
|
+
## Security Score
|
|
222
|
+
|
|
223
|
+
| Measure | Status | Protection Level |
|
|
224
|
+
|---------|--------|-----------------|
|
|
225
|
+
| fail2ban | ✅ Active | High (blocks brute force) |
|
|
226
|
+
| UFW rate limit | ✅ Active | Medium (slows attacks) |
|
|
227
|
+
| SSH hardening | ✅ Active | Medium (reduces attack window) |
|
|
228
|
+
| Honeypot | ✅ Active | Low (detection only) |
|
|
229
|
+
| security-audit | ✅ Available | Medium (daily checks) |
|
|
230
|
+
|
|
231
|
+
**Overall: Good baseline security without breaking workflow.**
|
|
232
|
+
|
|
233
|
+
---
|
|
234
|
+
|
|
235
|
+
## Troubleshooting
|
|
236
|
+
|
|
237
|
+
### "I got locked out!"
|
|
238
|
+
**Unlikely, but if it happens:**
|
|
239
|
+
|
|
240
|
+
1. Wait 1 hour (fail2ban ban expires)
|
|
241
|
+
2. Or access via Tailscale (bypasses fail2ban)
|
|
242
|
+
3. Or console access (VPS provider)
|
|
243
|
+
|
|
244
|
+
**To prevent:**
|
|
245
|
+
- Use Tailscale for primary access
|
|
246
|
+
- Keep your IP whitelisted if needed
|
|
247
|
+
|
|
248
|
+
### "SSH is slow"
|
|
249
|
+
**Check if fail2ban is blocking you:**
|
|
250
|
+
```bash
|
|
251
|
+
fail2ban-client status sshd
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
**If your IP is listed:**
|
|
255
|
+
```bash
|
|
256
|
+
fail2ban-client set sshd unbanip <YOUR_IP>
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
### "Honeypot not working"
|
|
260
|
+
```bash
|
|
261
|
+
# Check status
|
|
262
|
+
systemctl is-active endlessh
|
|
263
|
+
|
|
264
|
+
# Check logs
|
|
265
|
+
journalctl -u endlessh -n 50
|
|
266
|
+
|
|
267
|
+
# Restart
|
|
268
|
+
systemctl restart endlessh
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
---
|
|
272
|
+
|
|
273
|
+
## Next Steps (Optional)
|
|
274
|
+
|
|
275
|
+
1. **Enable unattended-upgrades** — Auto security patches
|
|
276
|
+
2. **Configure PostgreSQL backups** — Protect API data
|
|
277
|
+
3. **Add PoolBot security alerts** — Telegram notifications for suspicious activity
|
|
278
|
+
4. **Whitelist your IP** — Extra protection for SSH
|
|
279
|
+
|
|
280
|
+
---
|
|
281
|
+
|
|
282
|
+
## Summary
|
|
283
|
+
|
|
284
|
+
✅ **fail2ban** — Blocks brute force after 5 failures
|
|
285
|
+
✅ **UFW rate limit** — Slows down connection floods
|
|
286
|
+
✅ **SSH hardening** — Reduces attack window
|
|
287
|
+
✅ **Honeypot** — Detects and logs attackers
|
|
288
|
+
✅ **security-audit skill** — Daily automated audits
|
|
289
|
+
✅ **self-healing skill** — Auto-fix common issues
|
|
290
|
+
|
|
291
|
+
❌ **Nothing broken** — SSH password auth still works, PostgreSQL still accessible, root login still allowed
|
|
292
|
+
|
|
293
|
+
**Security improved without breaking your workflow.**
|
|
294
|
+
|
|
295
|
+
---
|
|
296
|
+
|
|
297
|
+
## Honeypot Note
|
|
298
|
+
|
|
299
|
+
**endlessh runs in manual mode** (systemd service has namespace issues).
|
|
300
|
+
|
|
301
|
+
**To restart after reboot:**
|
|
302
|
+
```bash
|
|
303
|
+
nohup endlessh -p 2222 > /var/log/endlessh.log 2>&1 &
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
**Or add to crontab @reboot:**
|
|
307
|
+
```bash
|
|
308
|
+
echo '@reboot nohup endlessh -p 2222 > /var/log/endlessh.log 2>&1 &' | crontab -
|
|
309
|
+
```
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
# VPS Security Monitoring Skill
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
Monitors and manages VPS security features including fail2ban, UFW firewall, SSH hardening, and honeypot.
|
|
6
|
+
|
|
7
|
+
## Capabilities
|
|
8
|
+
|
|
9
|
+
- **fail2ban monitoring** — Check banned IPs, failed attempts, unban IPs
|
|
10
|
+
- **UFW status** — Check firewall rules and rate limits
|
|
11
|
+
- **SSH hardening** — Verify SSH security configuration
|
|
12
|
+
- **Honeypot monitoring** — Check endlessh activity and attacker logs
|
|
13
|
+
- **Security reports** — Generate security status reports
|
|
14
|
+
|
|
15
|
+
## Usage
|
|
16
|
+
|
|
17
|
+
### Check Security Status
|
|
18
|
+
|
|
19
|
+
```
|
|
20
|
+
Check VPS security status
|
|
21
|
+
Show fail2ban status
|
|
22
|
+
How many failed login attempts?
|
|
23
|
+
Show banned IPs
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
### Manage fail2ban
|
|
27
|
+
|
|
28
|
+
```
|
|
29
|
+
Unban IP 1.2.3.4
|
|
30
|
+
Restart fail2ban
|
|
31
|
+
Show fail2ban logs
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
### Check Firewall
|
|
35
|
+
|
|
36
|
+
```
|
|
37
|
+
Show UFW status
|
|
38
|
+
Check SSH rate limit
|
|
39
|
+
Show firewall rules
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### Honeypot Monitoring
|
|
43
|
+
|
|
44
|
+
```
|
|
45
|
+
Show honeypot activity
|
|
46
|
+
How many bots tried to connect?
|
|
47
|
+
Show recent attacker IPs
|
|
48
|
+
Check endlessh status
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### Security Reports
|
|
52
|
+
|
|
53
|
+
```
|
|
54
|
+
Generate security report
|
|
55
|
+
Daily security summary
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## Commands
|
|
59
|
+
|
|
60
|
+
### `vps_security status`
|
|
61
|
+
|
|
62
|
+
Returns overall security status including:
|
|
63
|
+
- fail2ban status (active/inactive, banned count)
|
|
64
|
+
- UFW status (active/inactive, rate limits)
|
|
65
|
+
- SSH hardening (LoginGraceTime, MaxAuthTries)
|
|
66
|
+
- Honeypot status (active/inactive, port)
|
|
67
|
+
|
|
68
|
+
### `vps_security fail2ban`
|
|
69
|
+
|
|
70
|
+
Returns fail2ban details:
|
|
71
|
+
- Currently failed attempts
|
|
72
|
+
- Total failed attempts
|
|
73
|
+
- Currently banned IPs
|
|
74
|
+
- Total banned IPs
|
|
75
|
+
- Banned IP list
|
|
76
|
+
|
|
77
|
+
### `vps_security unban <ip>`
|
|
78
|
+
|
|
79
|
+
Unbans a specific IP address from fail2ban.
|
|
80
|
+
|
|
81
|
+
### `vps_security ufw`
|
|
82
|
+
|
|
83
|
+
Returns UFW firewall status:
|
|
84
|
+
- Active/inactive
|
|
85
|
+
- Rules list
|
|
86
|
+
- Rate limits
|
|
87
|
+
|
|
88
|
+
### `vps_security ssh`
|
|
89
|
+
|
|
90
|
+
Returns SSH hardening status:
|
|
91
|
+
- LoginGraceTime
|
|
92
|
+
- MaxAuthTries
|
|
93
|
+
- PermitRootLogin
|
|
94
|
+
- PasswordAuthentication
|
|
95
|
+
|
|
96
|
+
### `vps_security honeypot`
|
|
97
|
+
|
|
98
|
+
Returns honeypot (endlessh) status:
|
|
99
|
+
- Active/inactive
|
|
100
|
+
- Port (default: 2222)
|
|
101
|
+
- Recent activity count
|
|
102
|
+
|
|
103
|
+
### `vps_security report`
|
|
104
|
+
|
|
105
|
+
Generates comprehensive security report with:
|
|
106
|
+
- Overall security score (0-100)
|
|
107
|
+
- Active measures
|
|
108
|
+
- Recommendations
|
|
109
|
+
- Recent activity summary
|
|
110
|
+
|
|
111
|
+
## Implementation Notes
|
|
112
|
+
|
|
113
|
+
- All commands execute via SSH to the VPS
|
|
114
|
+
- Requires SSH access configured in PoolBot
|
|
115
|
+
- Output is formatted for Telegram/Discord/Slack delivery
|
|
116
|
+
- Security score calculation:
|
|
117
|
+
- fail2ban active: +25 points
|
|
118
|
+
- UFW active: +25 points
|
|
119
|
+
- SSH hardening: +25 points
|
|
120
|
+
- Honeypot active: +15 points
|
|
121
|
+
- No critical issues: +10 points
|
|
122
|
+
|
|
123
|
+
## Security Considerations
|
|
124
|
+
|
|
125
|
+
- Only authorized users should access security commands
|
|
126
|
+
- Unban commands should be logged
|
|
127
|
+
- Security reports should not expose sensitive data
|
|
128
|
+
- Consider adding authentication for security commands
|
|
129
|
+
|
|
130
|
+
## Related Skills
|
|
131
|
+
|
|
132
|
+
- `security-audit` — Automated daily security audits
|
|
133
|
+
- `self-healing` — Automatic issue recovery
|
|
134
|
+
- `vps-api` — VPS management API
|
|
135
|
+
|
|
136
|
+
## Files
|
|
137
|
+
|
|
138
|
+
- Skill: `/root/pool/skills/vps-security/SKILL.md`
|
|
139
|
+
- Scripts: `/root/pool/skills/vps-security/scripts/`
|
|
140
|
+
- Logs: `/var/log/fail2ban.log`, `/var/log/endlessh.log`
|