@panguard-ai/panguard-guard 0.1.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.
Files changed (130) hide show
  1. package/dist/agent/analyze-agent.d.ts +62 -0
  2. package/dist/agent/analyze-agent.d.ts.map +1 -0
  3. package/dist/agent/analyze-agent.js +327 -0
  4. package/dist/agent/analyze-agent.js.map +1 -0
  5. package/dist/agent/detect-agent.d.ts +59 -0
  6. package/dist/agent/detect-agent.d.ts.map +1 -0
  7. package/dist/agent/detect-agent.js +214 -0
  8. package/dist/agent/detect-agent.js.map +1 -0
  9. package/dist/agent/index.d.ts +15 -0
  10. package/dist/agent/index.d.ts.map +1 -0
  11. package/dist/agent/index.js +14 -0
  12. package/dist/agent/index.js.map +1 -0
  13. package/dist/agent/report-agent.d.ts +122 -0
  14. package/dist/agent/report-agent.d.ts.map +1 -0
  15. package/dist/agent/report-agent.js +468 -0
  16. package/dist/agent/report-agent.js.map +1 -0
  17. package/dist/agent/respond-agent.d.ts +113 -0
  18. package/dist/agent/respond-agent.d.ts.map +1 -0
  19. package/dist/agent/respond-agent.js +749 -0
  20. package/dist/agent/respond-agent.js.map +1 -0
  21. package/dist/agent-client/index.d.ts +81 -0
  22. package/dist/agent-client/index.d.ts.map +1 -0
  23. package/dist/agent-client/index.js +170 -0
  24. package/dist/agent-client/index.js.map +1 -0
  25. package/dist/cli/index.d.ts +17 -0
  26. package/dist/cli/index.d.ts.map +1 -0
  27. package/dist/cli/index.js +295 -0
  28. package/dist/cli/index.js.map +1 -0
  29. package/dist/config.d.ts +23 -0
  30. package/dist/config.d.ts.map +1 -0
  31. package/dist/config.js +108 -0
  32. package/dist/config.js.map +1 -0
  33. package/dist/daemon/index.d.ts +66 -0
  34. package/dist/daemon/index.d.ts.map +1 -0
  35. package/dist/daemon/index.js +284 -0
  36. package/dist/daemon/index.js.map +1 -0
  37. package/dist/dashboard/index.d.ts +78 -0
  38. package/dist/dashboard/index.d.ts.map +1 -0
  39. package/dist/dashboard/index.js +455 -0
  40. package/dist/dashboard/index.js.map +1 -0
  41. package/dist/guard-engine.d.ts +108 -0
  42. package/dist/guard-engine.d.ts.map +1 -0
  43. package/dist/guard-engine.js +740 -0
  44. package/dist/guard-engine.js.map +1 -0
  45. package/dist/index.d.ts +29 -0
  46. package/dist/index.d.ts.map +1 -0
  47. package/dist/index.js +39 -0
  48. package/dist/index.js.map +1 -0
  49. package/dist/install/index.d.ts +23 -0
  50. package/dist/install/index.d.ts.map +1 -0
  51. package/dist/install/index.js +216 -0
  52. package/dist/install/index.js.map +1 -0
  53. package/dist/investigation/index.d.ts +80 -0
  54. package/dist/investigation/index.d.ts.map +1 -0
  55. package/dist/investigation/index.js +570 -0
  56. package/dist/investigation/index.js.map +1 -0
  57. package/dist/license/index.d.ts +46 -0
  58. package/dist/license/index.d.ts.map +1 -0
  59. package/dist/license/index.js +145 -0
  60. package/dist/license/index.js.map +1 -0
  61. package/dist/memory/baseline.d.ts +34 -0
  62. package/dist/memory/baseline.d.ts.map +1 -0
  63. package/dist/memory/baseline.js +224 -0
  64. package/dist/memory/baseline.js.map +1 -0
  65. package/dist/memory/index.d.ts +32 -0
  66. package/dist/memory/index.d.ts.map +1 -0
  67. package/dist/memory/index.js +58 -0
  68. package/dist/memory/index.js.map +1 -0
  69. package/dist/memory/learning.d.ts +35 -0
  70. package/dist/memory/learning.d.ts.map +1 -0
  71. package/dist/memory/learning.js +60 -0
  72. package/dist/memory/learning.js.map +1 -0
  73. package/dist/monitors/falco-monitor.d.ts +62 -0
  74. package/dist/monitors/falco-monitor.d.ts.map +1 -0
  75. package/dist/monitors/falco-monitor.js +226 -0
  76. package/dist/monitors/falco-monitor.js.map +1 -0
  77. package/dist/monitors/suricata-monitor.d.ts +80 -0
  78. package/dist/monitors/suricata-monitor.d.ts.map +1 -0
  79. package/dist/monitors/suricata-monitor.js +227 -0
  80. package/dist/monitors/suricata-monitor.js.map +1 -0
  81. package/dist/notify/email.d.ts +23 -0
  82. package/dist/notify/email.d.ts.map +1 -0
  83. package/dist/notify/email.js +124 -0
  84. package/dist/notify/email.js.map +1 -0
  85. package/dist/notify/index.d.ts +31 -0
  86. package/dist/notify/index.d.ts.map +1 -0
  87. package/dist/notify/index.js +70 -0
  88. package/dist/notify/index.js.map +1 -0
  89. package/dist/notify/line-notify.d.ts.map +1 -0
  90. package/dist/notify/slack.d.ts +21 -0
  91. package/dist/notify/slack.d.ts.map +1 -0
  92. package/dist/notify/slack.js +92 -0
  93. package/dist/notify/slack.js.map +1 -0
  94. package/dist/notify/telegram.d.ts +21 -0
  95. package/dist/notify/telegram.d.ts.map +1 -0
  96. package/dist/notify/telegram.js +89 -0
  97. package/dist/notify/telegram.js.map +1 -0
  98. package/dist/response/file-quarantine.d.ts +63 -0
  99. package/dist/response/file-quarantine.d.ts.map +1 -0
  100. package/dist/response/file-quarantine.js +137 -0
  101. package/dist/response/file-quarantine.js.map +1 -0
  102. package/dist/response/index.d.ts +4 -0
  103. package/dist/response/index.d.ts.map +1 -0
  104. package/dist/response/index.js +4 -0
  105. package/dist/response/index.js.map +1 -0
  106. package/dist/response/ip-blocker.d.ts +69 -0
  107. package/dist/response/ip-blocker.d.ts.map +1 -0
  108. package/dist/response/ip-blocker.js +191 -0
  109. package/dist/response/ip-blocker.js.map +1 -0
  110. package/dist/response/process-killer.d.ts +49 -0
  111. package/dist/response/process-killer.d.ts.map +1 -0
  112. package/dist/response/process-killer.js +230 -0
  113. package/dist/response/process-killer.js.map +1 -0
  114. package/dist/rules/builtin-rules.d.ts +12 -0
  115. package/dist/rules/builtin-rules.d.ts.map +1 -0
  116. package/dist/rules/builtin-rules.js +471 -0
  117. package/dist/rules/builtin-rules.js.map +1 -0
  118. package/dist/threat-cloud/client-id.d.ts +13 -0
  119. package/dist/threat-cloud/client-id.d.ts.map +1 -0
  120. package/dist/threat-cloud/client-id.js +38 -0
  121. package/dist/threat-cloud/client-id.js.map +1 -0
  122. package/dist/threat-cloud/index.d.ts +103 -0
  123. package/dist/threat-cloud/index.d.ts.map +1 -0
  124. package/dist/threat-cloud/index.js +386 -0
  125. package/dist/threat-cloud/index.js.map +1 -0
  126. package/dist/types.d.ts +336 -0
  127. package/dist/types.d.ts.map +1 -0
  128. package/dist/types.js +42 -0
  129. package/dist/types.js.map +1 -0
  130. package/package.json +35 -0
@@ -0,0 +1,62 @@
1
+ /**
2
+ * FalcoMonitor - eBPF-based kernel-level syscall monitoring via Falco
3
+ * FalcoMonitor - 透過 Falco 實作的 eBPF kernel-level syscall 監控
4
+ *
5
+ * Integrates with the CNCF Falco project to provide kernel-level
6
+ * visibility into system calls. Gracefully degrades when Falco
7
+ * is not installed (same pattern as optional LLM providers).
8
+ *
9
+ * @module @panguard-ai/panguard-guard/monitors/falco-monitor
10
+ */
11
+ import { EventEmitter } from 'node:events';
12
+ import type { SecurityEvent } from '@panguard-ai/core';
13
+ /**
14
+ * Raw Falco JSON alert structure
15
+ */
16
+ export interface FalcoAlert {
17
+ priority: string;
18
+ rule: string;
19
+ time: string;
20
+ output: string;
21
+ output_fields?: Record<string, unknown>;
22
+ source?: string;
23
+ tags?: string[];
24
+ hostname?: string;
25
+ }
26
+ /**
27
+ * Parse a raw Falco JSON alert into a Panguard SecurityEvent
28
+ */
29
+ export declare function parseFalcoEvent(raw: FalcoAlert): SecurityEvent;
30
+ /**
31
+ * FalcoMonitor watches Falco alert output and emits SecurityEvents
32
+ *
33
+ * Usage:
34
+ * const monitor = new FalcoMonitor();
35
+ * if (await monitor.checkAvailability()) {
36
+ * monitor.on('event', (event) => processEvent(event));
37
+ * await monitor.start();
38
+ * }
39
+ */
40
+ export declare class FalcoMonitor extends EventEmitter {
41
+ private alertPath;
42
+ private running;
43
+ private fileOffset;
44
+ private watchInterval;
45
+ /**
46
+ * Check if Falco is installed and alert files are accessible
47
+ */
48
+ checkAvailability(): Promise<boolean>;
49
+ /**
50
+ * Start tailing the Falco alert file
51
+ */
52
+ start(): Promise<void>;
53
+ /**
54
+ * Read new lines from the alert file since last offset
55
+ */
56
+ private readNewLines;
57
+ /**
58
+ * Stop monitoring
59
+ */
60
+ stop(): void;
61
+ }
62
+ //# sourceMappingURL=falco-monitor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"falco-monitor.d.ts","sourceRoot":"","sources":["../../src/monitors/falco-monitor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAK3C,OAAO,KAAK,EAAE,aAAa,EAAY,MAAM,mBAAmB,CAAC;AAWjE;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACxC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAmCD;;GAEG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,UAAU,GAAG,aAAa,CA4B9D;AAED;;;;;;;;;GASG;AACH,qBAAa,YAAa,SAAQ,YAAY;IAC5C,OAAO,CAAC,SAAS,CAAuB;IACxC,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,UAAU,CAAK;IACvB,OAAO,CAAC,aAAa,CAA+C;IAEpE;;OAEG;IACG,iBAAiB,IAAI,OAAO,CAAC,OAAO,CAAC;IAwC3C;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAyB5B;;OAEG;IACH,OAAO,CAAC,YAAY;IA0CpB;;OAEG;IACH,IAAI,IAAI,IAAI;CAcb"}
@@ -0,0 +1,226 @@
1
+ /**
2
+ * FalcoMonitor - eBPF-based kernel-level syscall monitoring via Falco
3
+ * FalcoMonitor - 透過 Falco 實作的 eBPF kernel-level syscall 監控
4
+ *
5
+ * Integrates with the CNCF Falco project to provide kernel-level
6
+ * visibility into system calls. Gracefully degrades when Falco
7
+ * is not installed (same pattern as optional LLM providers).
8
+ *
9
+ * @module @panguard-ai/panguard-guard/monitors/falco-monitor
10
+ */
11
+ import { EventEmitter } from 'node:events';
12
+ import { createReadStream, existsSync, watchFile, unwatchFile, statSync } from 'node:fs';
13
+ import { createInterface } from 'node:readline';
14
+ import { execFile } from 'node:child_process';
15
+ import { createLogger } from '@panguard-ai/core';
16
+ const logger = createLogger('panguard-guard:falco-monitor');
17
+ /** Default Falco alert file paths (ordered by preference) */
18
+ const FALCO_ALERT_PATHS = [
19
+ '/var/log/falco/alerts.json',
20
+ '/var/log/falco/events.json',
21
+ '/etc/falco/alerts.json',
22
+ ];
23
+ /**
24
+ * Map Falco priority to Panguard severity
25
+ */
26
+ function mapFalcoPriority(priority) {
27
+ const p = priority.toUpperCase();
28
+ if (p === 'CRITICAL' || p === 'EMERGENCY' || p === 'ALERT')
29
+ return 'critical';
30
+ if (p === 'ERROR')
31
+ return 'high';
32
+ if (p === 'WARNING')
33
+ return 'medium';
34
+ if (p === 'NOTICE')
35
+ return 'low';
36
+ return 'info';
37
+ }
38
+ /**
39
+ * Map Falco tags to MITRE ATT&CK categories
40
+ */
41
+ function mapFalcoCategory(tags) {
42
+ if (!tags || tags.length === 0)
43
+ return 'unknown';
44
+ const tagStr = tags.join(' ').toLowerCase();
45
+ if (tagStr.includes('container') || tagStr.includes('escape'))
46
+ return 'container_escape';
47
+ if (tagStr.includes('shell') || tagStr.includes('terminal'))
48
+ return 'reverse_shell';
49
+ if (tagStr.includes('crypto') || tagStr.includes('mining'))
50
+ return 'cryptomining';
51
+ if (tagStr.includes('credential') || tagStr.includes('shadow'))
52
+ return 'credential_access';
53
+ if (tagStr.includes('network') || tagStr.includes('connect'))
54
+ return 'network_activity';
55
+ if (tagStr.includes('file') || tagStr.includes('write') || tagStr.includes('read'))
56
+ return 'file_access';
57
+ if (tagStr.includes('process') || tagStr.includes('exec'))
58
+ return 'process_execution';
59
+ return tags[0] ?? 'unknown';
60
+ }
61
+ let eventCounter = 0;
62
+ /**
63
+ * Parse a raw Falco JSON alert into a Panguard SecurityEvent
64
+ */
65
+ export function parseFalcoEvent(raw) {
66
+ eventCounter++;
67
+ const fields = raw.output_fields ?? {};
68
+ return {
69
+ id: `falco-${Date.now()}-${eventCounter}`,
70
+ timestamp: raw.time ? new Date(raw.time) : new Date(),
71
+ source: 'falco',
72
+ severity: mapFalcoPriority(raw.priority),
73
+ category: mapFalcoCategory(raw.tags),
74
+ description: raw.output || `Falco rule triggered: ${raw.rule}`,
75
+ raw,
76
+ host: raw.hostname ?? raw.output_fields?.['hostname'] ?? 'unknown',
77
+ metadata: {
78
+ rule: raw.rule,
79
+ priority: raw.priority,
80
+ hostname: raw.hostname,
81
+ tags: raw.tags,
82
+ pid: fields['proc.pid'],
83
+ processName: fields['proc.name'],
84
+ userName: fields['user.name'],
85
+ containerName: fields['container.name'],
86
+ containerId: fields['container.id'],
87
+ filePath: fields['fd.name'],
88
+ sourceIP: fields['fd.sip'],
89
+ destIP: fields['fd.dip'],
90
+ },
91
+ };
92
+ }
93
+ /**
94
+ * FalcoMonitor watches Falco alert output and emits SecurityEvents
95
+ *
96
+ * Usage:
97
+ * const monitor = new FalcoMonitor();
98
+ * if (await monitor.checkAvailability()) {
99
+ * monitor.on('event', (event) => processEvent(event));
100
+ * await monitor.start();
101
+ * }
102
+ */
103
+ export class FalcoMonitor extends EventEmitter {
104
+ alertPath = null;
105
+ running = false;
106
+ fileOffset = 0;
107
+ watchInterval = null;
108
+ /**
109
+ * Check if Falco is installed and alert files are accessible
110
+ */
111
+ async checkAvailability() {
112
+ // Check if falco binary exists
113
+ const hasBinary = await new Promise((resolve) => {
114
+ execFile('which', ['falco'], (error) => {
115
+ resolve(!error);
116
+ });
117
+ });
118
+ if (hasBinary) {
119
+ logger.info('Falco binary detected');
120
+ }
121
+ // Check for alert file
122
+ for (const path of FALCO_ALERT_PATHS) {
123
+ if (existsSync(path)) {
124
+ this.alertPath = path;
125
+ logger.info(`Falco alert file found: ${path}`);
126
+ return true;
127
+ }
128
+ }
129
+ // Allow custom path via env
130
+ const customPath = process.env['FALCO_ALERTS_PATH'];
131
+ if (customPath && existsSync(customPath)) {
132
+ this.alertPath = customPath;
133
+ logger.info(`Falco alert file (custom): ${customPath}`);
134
+ return true;
135
+ }
136
+ if (hasBinary) {
137
+ logger.warn('Falco binary found but no alert file. Ensure Falco is running with json_output=true');
138
+ return false;
139
+ }
140
+ logger.info('Falco not detected, kernel-level monitoring disabled (optional)');
141
+ return false;
142
+ }
143
+ /**
144
+ * Start tailing the Falco alert file
145
+ */
146
+ async start() {
147
+ if (!this.alertPath) {
148
+ throw new Error('Falco alert file not found. Call checkAvailability() first.');
149
+ }
150
+ if (this.running)
151
+ return;
152
+ this.running = true;
153
+ // Start from end of file (only read new alerts)
154
+ try {
155
+ const stats = statSync(this.alertPath);
156
+ this.fileOffset = stats.size;
157
+ }
158
+ catch {
159
+ this.fileOffset = 0;
160
+ }
161
+ logger.info(`FalcoMonitor started, tailing ${this.alertPath}`);
162
+ // Use polling-based file watch for compatibility
163
+ const alertPath = this.alertPath;
164
+ watchFile(alertPath, { interval: 1000 }, () => {
165
+ this.readNewLines(alertPath);
166
+ });
167
+ }
168
+ /**
169
+ * Read new lines from the alert file since last offset
170
+ */
171
+ readNewLines(filePath) {
172
+ try {
173
+ const stats = statSync(filePath);
174
+ if (stats.size <= this.fileOffset) {
175
+ // File was truncated or unchanged
176
+ if (stats.size < this.fileOffset) {
177
+ this.fileOffset = 0;
178
+ }
179
+ return;
180
+ }
181
+ const stream = createReadStream(filePath, {
182
+ start: this.fileOffset,
183
+ encoding: 'utf-8',
184
+ });
185
+ const rl = createInterface({ input: stream, crlfDelay: Infinity });
186
+ rl.on('line', (line) => {
187
+ const trimmed = line.trim();
188
+ if (!trimmed)
189
+ return;
190
+ try {
191
+ const alert = JSON.parse(trimmed);
192
+ if (alert.rule && alert.priority) {
193
+ const event = parseFalcoEvent(alert);
194
+ this.emit('event', event);
195
+ }
196
+ }
197
+ catch {
198
+ // Skip non-JSON lines
199
+ }
200
+ });
201
+ rl.on('close', () => {
202
+ this.fileOffset = stats.size;
203
+ });
204
+ }
205
+ catch (err) {
206
+ logger.error(`Error reading Falco alerts: ${err instanceof Error ? err.message : String(err)}`);
207
+ }
208
+ }
209
+ /**
210
+ * Stop monitoring
211
+ */
212
+ stop() {
213
+ if (!this.running)
214
+ return;
215
+ this.running = false;
216
+ if (this.alertPath) {
217
+ unwatchFile(this.alertPath);
218
+ }
219
+ if (this.watchInterval) {
220
+ clearInterval(this.watchInterval);
221
+ this.watchInterval = null;
222
+ }
223
+ logger.info('FalcoMonitor stopped');
224
+ }
225
+ }
226
+ //# sourceMappingURL=falco-monitor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"falco-monitor.js","sourceRoot":"","sources":["../../src/monitors/falco-monitor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,80 @@
1
+ /**
2
+ * SuricataMonitor - Network intrusion detection via Suricata EVE JSON
3
+ * SuricataMonitor - 透過 Suricata EVE JSON 實作的網路入侵偵測
4
+ *
5
+ * Integrates with Suricata's EVE JSON output to provide deep packet
6
+ * inspection (DPI) capabilities. Gracefully degrades when Suricata
7
+ * is not installed (same pattern as FalcoMonitor).
8
+ *
9
+ * @module @panguard-ai/panguard-guard/monitors/suricata-monitor
10
+ */
11
+ import { EventEmitter } from 'node:events';
12
+ import type { SecurityEvent } from '@panguard-ai/core';
13
+ /**
14
+ * Raw Suricata EVE JSON alert structure
15
+ */
16
+ export interface SuricataEveAlert {
17
+ timestamp: string;
18
+ event_type: string;
19
+ src_ip?: string;
20
+ src_port?: number;
21
+ dest_ip?: string;
22
+ dest_port?: number;
23
+ proto?: string;
24
+ alert?: {
25
+ action?: string;
26
+ gid?: number;
27
+ signature_id?: number;
28
+ rev?: number;
29
+ signature?: string;
30
+ category?: string;
31
+ severity?: number;
32
+ metadata?: Record<string, string[]>;
33
+ };
34
+ flow?: {
35
+ pkts_toserver?: number;
36
+ pkts_toclient?: number;
37
+ bytes_toserver?: number;
38
+ bytes_toclient?: number;
39
+ start?: string;
40
+ };
41
+ app_proto?: string;
42
+ in_iface?: string;
43
+ host?: string;
44
+ }
45
+ /**
46
+ * Parse a raw Suricata EVE JSON alert into a Panguard SecurityEvent
47
+ */
48
+ export declare function parseSuricataEvent(raw: SuricataEveAlert): SecurityEvent | null;
49
+ /**
50
+ * SuricataMonitor watches Suricata EVE JSON output and emits SecurityEvents
51
+ *
52
+ * Usage:
53
+ * const monitor = new SuricataMonitor();
54
+ * if (await monitor.checkAvailability()) {
55
+ * monitor.on('event', (event) => processEvent(event));
56
+ * await monitor.start();
57
+ * }
58
+ */
59
+ export declare class SuricataMonitor extends EventEmitter {
60
+ private evePath;
61
+ private running;
62
+ private fileOffset;
63
+ /**
64
+ * Check if Suricata is installed and EVE log files are accessible
65
+ */
66
+ checkAvailability(): Promise<boolean>;
67
+ /**
68
+ * Start tailing the Suricata EVE log file
69
+ */
70
+ start(): Promise<void>;
71
+ /**
72
+ * Read new lines from the EVE log since last offset
73
+ */
74
+ private readNewLines;
75
+ /**
76
+ * Stop monitoring
77
+ */
78
+ stop(): void;
79
+ }
80
+ //# sourceMappingURL=suricata-monitor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"suricata-monitor.d.ts","sourceRoot":"","sources":["../../src/monitors/suricata-monitor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAK3C,OAAO,KAAK,EAAE,aAAa,EAAY,MAAM,mBAAmB,CAAC;AAWjE;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE;QACN,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,GAAG,CAAC,EAAE,MAAM,CAAC;QACb,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,GAAG,CAAC,EAAE,MAAM,CAAC;QACb,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;KACrC,CAAC;IACF,IAAI,CAAC,EAAE;QACL,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB,cAAc,CAAC,EAAE,MAAM,CAAC;QACxB,cAAc,CAAC,EAAE,MAAM,CAAC;QACxB,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,CAAC;IACF,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AA2CD;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,gBAAgB,GAAG,aAAa,GAAG,IAAI,CA8B9E;AAED;;;;;;;;;GASG;AACH,qBAAa,eAAgB,SAAQ,YAAY;IAC/C,OAAO,CAAC,OAAO,CAAuB;IACtC,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,UAAU,CAAK;IAEvB;;OAEG;IACG,iBAAiB,IAAI,OAAO,CAAC,OAAO,CAAC;IAwC3C;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAyB5B;;OAEG;IACH,OAAO,CAAC,YAAY;IA0CpB;;OAEG;IACH,IAAI,IAAI,IAAI;CAUb"}
@@ -0,0 +1,227 @@
1
+ /**
2
+ * SuricataMonitor - Network intrusion detection via Suricata EVE JSON
3
+ * SuricataMonitor - 透過 Suricata EVE JSON 實作的網路入侵偵測
4
+ *
5
+ * Integrates with Suricata's EVE JSON output to provide deep packet
6
+ * inspection (DPI) capabilities. Gracefully degrades when Suricata
7
+ * is not installed (same pattern as FalcoMonitor).
8
+ *
9
+ * @module @panguard-ai/panguard-guard/monitors/suricata-monitor
10
+ */
11
+ import { EventEmitter } from 'node:events';
12
+ import { createReadStream, existsSync, watchFile, unwatchFile, statSync } from 'node:fs';
13
+ import { createInterface } from 'node:readline';
14
+ import { execFile } from 'node:child_process';
15
+ import { createLogger } from '@panguard-ai/core';
16
+ const logger = createLogger('panguard-guard:suricata-monitor');
17
+ /** Default Suricata EVE log paths (ordered by preference) */
18
+ const SURICATA_EVE_PATHS = [
19
+ '/var/log/suricata/eve.json',
20
+ '/var/log/suricata/fast.json',
21
+ '/usr/local/var/log/suricata/eve.json',
22
+ ];
23
+ /**
24
+ * Map Suricata severity (1-4) to Panguard severity
25
+ */
26
+ function mapSuricataSeverity(severity) {
27
+ if (severity === 1)
28
+ return 'critical';
29
+ if (severity === 2)
30
+ return 'high';
31
+ if (severity === 3)
32
+ return 'medium';
33
+ return 'low';
34
+ }
35
+ /**
36
+ * Map Suricata alert category to Panguard category
37
+ */
38
+ function mapSuricataCategory(category, signature) {
39
+ if (!category && !signature)
40
+ return 'unknown';
41
+ const text = `${category ?? ''} ${signature ?? ''}`.toLowerCase();
42
+ // More specific categories first, then general ones
43
+ if (text.includes('c2') || text.includes('command and control') || text.includes('cnc'))
44
+ return 'command_and_control';
45
+ if (text.includes('mining') || text.includes('crypto') || text.includes('stratum'))
46
+ return 'cryptomining';
47
+ if (text.includes('exfil') || text.includes('data leak'))
48
+ return 'data_exfiltration';
49
+ if (text.includes('shellcode') || text.includes('exploit'))
50
+ return 'exploit';
51
+ if (text.includes('trojan') || text.includes('malware') || text.includes('backdoor'))
52
+ return 'malware';
53
+ if (text.includes('scan') || text.includes('recon') || text.includes('discovery'))
54
+ return 'reconnaissance';
55
+ if (text.includes('dos') || text.includes('denial'))
56
+ return 'denial_of_service';
57
+ if (text.includes('credential') || text.includes('brute') || text.includes('login'))
58
+ return 'credential_access';
59
+ if (text.includes('web') || text.includes('sql') || text.includes('xss') || text.includes('rfi'))
60
+ return 'web_attack';
61
+ if (text.includes('policy') || text.includes('not-suspicious'))
62
+ return 'policy_violation';
63
+ return category ?? 'network_activity';
64
+ }
65
+ let eventCounter = 0;
66
+ /**
67
+ * Parse a raw Suricata EVE JSON alert into a Panguard SecurityEvent
68
+ */
69
+ export function parseSuricataEvent(raw) {
70
+ // Only process alert events
71
+ if (raw.event_type !== 'alert' || !raw.alert)
72
+ return null;
73
+ eventCounter++;
74
+ const alert = raw.alert;
75
+ return {
76
+ id: `suricata-${Date.now()}-${eventCounter}`,
77
+ timestamp: raw.timestamp ? new Date(raw.timestamp) : new Date(),
78
+ source: 'suricata',
79
+ severity: mapSuricataSeverity(alert.severity),
80
+ category: mapSuricataCategory(alert.category, alert.signature),
81
+ description: alert.signature ?? `Suricata alert: SID ${alert.signature_id ?? 'unknown'}`,
82
+ raw,
83
+ host: raw.host ?? 'unknown',
84
+ metadata: {
85
+ signatureId: alert.signature_id,
86
+ signature: alert.signature,
87
+ alertCategory: alert.category,
88
+ alertAction: alert.action,
89
+ sourceIP: raw.src_ip,
90
+ sourcePort: raw.src_port,
91
+ destIP: raw.dest_ip,
92
+ destPort: raw.dest_port,
93
+ protocol: raw.proto,
94
+ appProto: raw.app_proto,
95
+ interface: raw.in_iface,
96
+ },
97
+ };
98
+ }
99
+ /**
100
+ * SuricataMonitor watches Suricata EVE JSON output and emits SecurityEvents
101
+ *
102
+ * Usage:
103
+ * const monitor = new SuricataMonitor();
104
+ * if (await monitor.checkAvailability()) {
105
+ * monitor.on('event', (event) => processEvent(event));
106
+ * await monitor.start();
107
+ * }
108
+ */
109
+ export class SuricataMonitor extends EventEmitter {
110
+ evePath = null;
111
+ running = false;
112
+ fileOffset = 0;
113
+ /**
114
+ * Check if Suricata is installed and EVE log files are accessible
115
+ */
116
+ async checkAvailability() {
117
+ // Check if suricata binary exists
118
+ const hasBinary = await new Promise((resolve) => {
119
+ execFile('which', ['suricata'], (error) => {
120
+ resolve(!error);
121
+ });
122
+ });
123
+ if (hasBinary) {
124
+ logger.info('Suricata binary detected');
125
+ }
126
+ // Check for EVE log file
127
+ for (const path of SURICATA_EVE_PATHS) {
128
+ if (existsSync(path)) {
129
+ this.evePath = path;
130
+ logger.info(`Suricata EVE log found: ${path}`);
131
+ return true;
132
+ }
133
+ }
134
+ // Allow custom path via env
135
+ const customPath = process.env['SURICATA_EVE_PATH'];
136
+ if (customPath && existsSync(customPath)) {
137
+ this.evePath = customPath;
138
+ logger.info(`Suricata EVE log (custom): ${customPath}`);
139
+ return true;
140
+ }
141
+ if (hasBinary) {
142
+ logger.warn('Suricata binary found but no EVE log file. Ensure Suricata is running with eve-log enabled');
143
+ return false;
144
+ }
145
+ logger.info('Suricata not detected, network IDS monitoring disabled (optional)');
146
+ return false;
147
+ }
148
+ /**
149
+ * Start tailing the Suricata EVE log file
150
+ */
151
+ async start() {
152
+ if (!this.evePath) {
153
+ throw new Error('Suricata EVE log not found. Call checkAvailability() first.');
154
+ }
155
+ if (this.running)
156
+ return;
157
+ this.running = true;
158
+ // Start from end of file (only read new alerts)
159
+ try {
160
+ const stats = statSync(this.evePath);
161
+ this.fileOffset = stats.size;
162
+ }
163
+ catch {
164
+ this.fileOffset = 0;
165
+ }
166
+ logger.info(`SuricataMonitor started, tailing ${this.evePath}`);
167
+ // Use polling-based file watch for compatibility
168
+ const evePath = this.evePath;
169
+ watchFile(evePath, { interval: 1000 }, () => {
170
+ this.readNewLines(evePath);
171
+ });
172
+ }
173
+ /**
174
+ * Read new lines from the EVE log since last offset
175
+ */
176
+ readNewLines(filePath) {
177
+ try {
178
+ const stats = statSync(filePath);
179
+ if (stats.size <= this.fileOffset) {
180
+ // File was truncated or unchanged
181
+ if (stats.size < this.fileOffset) {
182
+ this.fileOffset = 0;
183
+ }
184
+ return;
185
+ }
186
+ const stream = createReadStream(filePath, {
187
+ start: this.fileOffset,
188
+ encoding: 'utf-8',
189
+ });
190
+ const rl = createInterface({ input: stream, crlfDelay: Infinity });
191
+ rl.on('line', (line) => {
192
+ const trimmed = line.trim();
193
+ if (!trimmed)
194
+ return;
195
+ try {
196
+ const eve = JSON.parse(trimmed);
197
+ const event = parseSuricataEvent(eve);
198
+ if (event) {
199
+ this.emit('event', event);
200
+ }
201
+ }
202
+ catch {
203
+ // Skip non-JSON lines
204
+ }
205
+ });
206
+ rl.on('close', () => {
207
+ this.fileOffset = stats.size;
208
+ });
209
+ }
210
+ catch (err) {
211
+ logger.error(`Error reading Suricata EVE log: ${err instanceof Error ? err.message : String(err)}`);
212
+ }
213
+ }
214
+ /**
215
+ * Stop monitoring
216
+ */
217
+ stop() {
218
+ if (!this.running)
219
+ return;
220
+ this.running = false;
221
+ if (this.evePath) {
222
+ unwatchFile(this.evePath);
223
+ }
224
+ logger.info('SuricataMonitor stopped');
225
+ }
226
+ }
227
+ //# sourceMappingURL=suricata-monitor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"suricata-monitor.js","sourceRoot":"","sources":["../../src/monitors/suricata-monitor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Email SMTP notification integration
3
+ * Email SMTP 通知整合
4
+ *
5
+ * Sends threat alerts via raw SMTP without external dependencies.
6
+ * Uses Node.js net/tls modules for direct SMTP communication.
7
+ * 透過原始 SMTP 發送威脅警報,不使用外部相依套件。
8
+ * 使用 Node.js net/tls 模組進行直接 SMTP 通訊。
9
+ *
10
+ * @module @panguard-ai/panguard-guard/notify/email
11
+ */
12
+ import type { EmailConfig, NotificationResult, ThreatVerdict } from '../types.js';
13
+ /**
14
+ * Send a threat alert via Email (raw SMTP)
15
+ * 透過 Email (原始 SMTP) 發送威脅警報
16
+ *
17
+ * @param config - Email SMTP configuration / Email SMTP 配置
18
+ * @param verdict - The threat verdict / 威脅判決
19
+ * @param eventDescription - Event description / 事件描述
20
+ * @returns Notification result / 通知結果
21
+ */
22
+ export declare function sendEmailNotify(config: EmailConfig, verdict: ThreatVerdict, eventDescription: string): Promise<NotificationResult>;
23
+ //# sourceMappingURL=email.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"email.d.ts","sourceRoot":"","sources":["../../src/notify/email.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAKH,OAAO,KAAK,EAAE,WAAW,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAIlF;;;;;;;;GAQG;AACH,wBAAsB,eAAe,CACnC,MAAM,EAAE,WAAW,EACnB,OAAO,EAAE,aAAa,EACtB,gBAAgB,EAAE,MAAM,GACvB,OAAO,CAAC,kBAAkB,CAAC,CA0B7B"}