defense-mcp-server 0.6.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 (186) hide show
  1. package/CHANGELOG.md +471 -0
  2. package/LICENSE +21 -0
  3. package/README.md +242 -0
  4. package/build/core/auto-installer.d.ts +102 -0
  5. package/build/core/auto-installer.d.ts.map +1 -0
  6. package/build/core/auto-installer.js +833 -0
  7. package/build/core/backup-manager.d.ts +63 -0
  8. package/build/core/backup-manager.d.ts.map +1 -0
  9. package/build/core/backup-manager.js +189 -0
  10. package/build/core/changelog.d.ts +75 -0
  11. package/build/core/changelog.d.ts.map +1 -0
  12. package/build/core/changelog.js +123 -0
  13. package/build/core/command-allowlist.d.ts +129 -0
  14. package/build/core/command-allowlist.d.ts.map +1 -0
  15. package/build/core/command-allowlist.js +849 -0
  16. package/build/core/config.d.ts +79 -0
  17. package/build/core/config.d.ts.map +1 -0
  18. package/build/core/config.js +193 -0
  19. package/build/core/dependency-validator.d.ts +106 -0
  20. package/build/core/dependency-validator.d.ts.map +1 -0
  21. package/build/core/dependency-validator.js +405 -0
  22. package/build/core/distro-adapter.d.ts +177 -0
  23. package/build/core/distro-adapter.d.ts.map +1 -0
  24. package/build/core/distro-adapter.js +481 -0
  25. package/build/core/distro.d.ts +68 -0
  26. package/build/core/distro.d.ts.map +1 -0
  27. package/build/core/distro.js +457 -0
  28. package/build/core/encrypted-state.d.ts +76 -0
  29. package/build/core/encrypted-state.d.ts.map +1 -0
  30. package/build/core/encrypted-state.js +209 -0
  31. package/build/core/executor.d.ts +56 -0
  32. package/build/core/executor.d.ts.map +1 -0
  33. package/build/core/executor.js +350 -0
  34. package/build/core/installer.d.ts +92 -0
  35. package/build/core/installer.d.ts.map +1 -0
  36. package/build/core/installer.js +1072 -0
  37. package/build/core/logger.d.ts +102 -0
  38. package/build/core/logger.d.ts.map +1 -0
  39. package/build/core/logger.js +132 -0
  40. package/build/core/parsers.d.ts +151 -0
  41. package/build/core/parsers.d.ts.map +1 -0
  42. package/build/core/parsers.js +479 -0
  43. package/build/core/policy-engine.d.ts +170 -0
  44. package/build/core/policy-engine.d.ts.map +1 -0
  45. package/build/core/policy-engine.js +656 -0
  46. package/build/core/preflight.d.ts +157 -0
  47. package/build/core/preflight.d.ts.map +1 -0
  48. package/build/core/preflight.js +638 -0
  49. package/build/core/privilege-manager.d.ts +108 -0
  50. package/build/core/privilege-manager.d.ts.map +1 -0
  51. package/build/core/privilege-manager.js +363 -0
  52. package/build/core/rate-limiter.d.ts +67 -0
  53. package/build/core/rate-limiter.d.ts.map +1 -0
  54. package/build/core/rate-limiter.js +129 -0
  55. package/build/core/rollback.d.ts +73 -0
  56. package/build/core/rollback.d.ts.map +1 -0
  57. package/build/core/rollback.js +278 -0
  58. package/build/core/safeguards.d.ts +58 -0
  59. package/build/core/safeguards.d.ts.map +1 -0
  60. package/build/core/safeguards.js +448 -0
  61. package/build/core/sanitizer.d.ts +118 -0
  62. package/build/core/sanitizer.d.ts.map +1 -0
  63. package/build/core/sanitizer.js +459 -0
  64. package/build/core/secure-fs.d.ts +67 -0
  65. package/build/core/secure-fs.d.ts.map +1 -0
  66. package/build/core/secure-fs.js +143 -0
  67. package/build/core/spawn-safe.d.ts +55 -0
  68. package/build/core/spawn-safe.d.ts.map +1 -0
  69. package/build/core/spawn-safe.js +146 -0
  70. package/build/core/sudo-guard.d.ts +145 -0
  71. package/build/core/sudo-guard.d.ts.map +1 -0
  72. package/build/core/sudo-guard.js +349 -0
  73. package/build/core/sudo-session.d.ts +100 -0
  74. package/build/core/sudo-session.d.ts.map +1 -0
  75. package/build/core/sudo-session.js +319 -0
  76. package/build/core/tool-dependencies.d.ts +61 -0
  77. package/build/core/tool-dependencies.d.ts.map +1 -0
  78. package/build/core/tool-dependencies.js +571 -0
  79. package/build/core/tool-registry.d.ts +111 -0
  80. package/build/core/tool-registry.d.ts.map +1 -0
  81. package/build/core/tool-registry.js +656 -0
  82. package/build/core/tool-wrapper.d.ts +73 -0
  83. package/build/core/tool-wrapper.d.ts.map +1 -0
  84. package/build/core/tool-wrapper.js +296 -0
  85. package/build/index.d.ts +3 -0
  86. package/build/index.d.ts.map +1 -0
  87. package/build/index.js +247 -0
  88. package/build/tools/access-control.d.ts +9 -0
  89. package/build/tools/access-control.d.ts.map +1 -0
  90. package/build/tools/access-control.js +1818 -0
  91. package/build/tools/api-security.d.ts +12 -0
  92. package/build/tools/api-security.d.ts.map +1 -0
  93. package/build/tools/api-security.js +901 -0
  94. package/build/tools/app-hardening.d.ts +11 -0
  95. package/build/tools/app-hardening.d.ts.map +1 -0
  96. package/build/tools/app-hardening.js +768 -0
  97. package/build/tools/backup.d.ts +8 -0
  98. package/build/tools/backup.d.ts.map +1 -0
  99. package/build/tools/backup.js +381 -0
  100. package/build/tools/cloud-security.d.ts +17 -0
  101. package/build/tools/cloud-security.d.ts.map +1 -0
  102. package/build/tools/cloud-security.js +739 -0
  103. package/build/tools/compliance.d.ts +10 -0
  104. package/build/tools/compliance.d.ts.map +1 -0
  105. package/build/tools/compliance.js +1225 -0
  106. package/build/tools/container-security.d.ts +14 -0
  107. package/build/tools/container-security.d.ts.map +1 -0
  108. package/build/tools/container-security.js +788 -0
  109. package/build/tools/deception.d.ts +13 -0
  110. package/build/tools/deception.d.ts.map +1 -0
  111. package/build/tools/deception.js +763 -0
  112. package/build/tools/dns-security.d.ts +93 -0
  113. package/build/tools/dns-security.d.ts.map +1 -0
  114. package/build/tools/dns-security.js +745 -0
  115. package/build/tools/drift-detection.d.ts +8 -0
  116. package/build/tools/drift-detection.d.ts.map +1 -0
  117. package/build/tools/drift-detection.js +326 -0
  118. package/build/tools/ebpf-security.d.ts +15 -0
  119. package/build/tools/ebpf-security.d.ts.map +1 -0
  120. package/build/tools/ebpf-security.js +294 -0
  121. package/build/tools/encryption.d.ts +9 -0
  122. package/build/tools/encryption.d.ts.map +1 -0
  123. package/build/tools/encryption.js +1667 -0
  124. package/build/tools/firewall.d.ts +9 -0
  125. package/build/tools/firewall.d.ts.map +1 -0
  126. package/build/tools/firewall.js +1398 -0
  127. package/build/tools/hardening.d.ts +10 -0
  128. package/build/tools/hardening.d.ts.map +1 -0
  129. package/build/tools/hardening.js +2654 -0
  130. package/build/tools/ids.d.ts +9 -0
  131. package/build/tools/ids.d.ts.map +1 -0
  132. package/build/tools/ids.js +624 -0
  133. package/build/tools/incident-response.d.ts +10 -0
  134. package/build/tools/incident-response.d.ts.map +1 -0
  135. package/build/tools/incident-response.js +1180 -0
  136. package/build/tools/logging.d.ts +12 -0
  137. package/build/tools/logging.d.ts.map +1 -0
  138. package/build/tools/logging.js +454 -0
  139. package/build/tools/malware.d.ts +10 -0
  140. package/build/tools/malware.d.ts.map +1 -0
  141. package/build/tools/malware.js +532 -0
  142. package/build/tools/meta.d.ts +11 -0
  143. package/build/tools/meta.d.ts.map +1 -0
  144. package/build/tools/meta.js +2278 -0
  145. package/build/tools/network-defense.d.ts +12 -0
  146. package/build/tools/network-defense.d.ts.map +1 -0
  147. package/build/tools/network-defense.js +760 -0
  148. package/build/tools/patch-management.d.ts +3 -0
  149. package/build/tools/patch-management.d.ts.map +1 -0
  150. package/build/tools/patch-management.js +708 -0
  151. package/build/tools/process-security.d.ts +12 -0
  152. package/build/tools/process-security.d.ts.map +1 -0
  153. package/build/tools/process-security.js +784 -0
  154. package/build/tools/reporting.d.ts +11 -0
  155. package/build/tools/reporting.d.ts.map +1 -0
  156. package/build/tools/reporting.js +559 -0
  157. package/build/tools/secrets.d.ts +9 -0
  158. package/build/tools/secrets.d.ts.map +1 -0
  159. package/build/tools/secrets.js +596 -0
  160. package/build/tools/siem-integration.d.ts +18 -0
  161. package/build/tools/siem-integration.d.ts.map +1 -0
  162. package/build/tools/siem-integration.js +754 -0
  163. package/build/tools/sudo-management.d.ts +18 -0
  164. package/build/tools/sudo-management.d.ts.map +1 -0
  165. package/build/tools/sudo-management.js +737 -0
  166. package/build/tools/supply-chain-security.d.ts +8 -0
  167. package/build/tools/supply-chain-security.d.ts.map +1 -0
  168. package/build/tools/supply-chain-security.js +256 -0
  169. package/build/tools/threat-intel.d.ts +22 -0
  170. package/build/tools/threat-intel.d.ts.map +1 -0
  171. package/build/tools/threat-intel.js +749 -0
  172. package/build/tools/vulnerability-management.d.ts +11 -0
  173. package/build/tools/vulnerability-management.d.ts.map +1 -0
  174. package/build/tools/vulnerability-management.js +667 -0
  175. package/build/tools/waf.d.ts +12 -0
  176. package/build/tools/waf.d.ts.map +1 -0
  177. package/build/tools/waf.js +843 -0
  178. package/build/tools/wireless-security.d.ts +19 -0
  179. package/build/tools/wireless-security.d.ts.map +1 -0
  180. package/build/tools/wireless-security.js +826 -0
  181. package/build/tools/zero-trust-network.d.ts +8 -0
  182. package/build/tools/zero-trust-network.d.ts.map +1 -0
  183. package/build/tools/zero-trust-network.js +367 -0
  184. package/docs/SAFEGUARDS.md +518 -0
  185. package/docs/TOOLS-REFERENCE.md +665 -0
  186. package/package.json +87 -0
@@ -0,0 +1,1072 @@
1
+ import { executeCommand } from "./executor.js";
2
+ import { detectDistro, getInstallCommand, getUpdateCommand, } from "./distro.js";
3
+ import { getConfig } from "./config.js";
4
+ /**
5
+ * Comprehensive list of defensive security tools across categories.
6
+ */
7
+ export const DEFENSIVE_TOOLS = [
8
+ // ─── Hardening ────────────────────────────────────────────
9
+ {
10
+ name: "Lynis",
11
+ binary: "lynis",
12
+ packages: {
13
+ debian: "lynis",
14
+ rhel: "lynis",
15
+ arch: "lynis",
16
+ alpine: "lynis",
17
+ suse: "lynis",
18
+ fallback: "lynis",
19
+ },
20
+ category: "hardening",
21
+ required: true,
22
+ },
23
+ {
24
+ name: "AIDE",
25
+ binary: "aide",
26
+ packages: {
27
+ debian: "aide",
28
+ rhel: "aide",
29
+ arch: "aide",
30
+ alpine: "aide",
31
+ suse: "aide",
32
+ fallback: "aide",
33
+ },
34
+ category: "hardening",
35
+ required: true,
36
+ },
37
+ {
38
+ name: "Auditd",
39
+ binary: "auditctl",
40
+ packages: {
41
+ debian: "auditd",
42
+ rhel: "audit",
43
+ arch: "audit",
44
+ alpine: "audit",
45
+ suse: "audit",
46
+ fallback: "auditd",
47
+ },
48
+ category: "hardening",
49
+ required: true,
50
+ },
51
+ {
52
+ name: "Sysstat",
53
+ binary: "sar",
54
+ packages: {
55
+ debian: "sysstat",
56
+ rhel: "sysstat",
57
+ arch: "sysstat",
58
+ alpine: "sysstat",
59
+ suse: "sysstat",
60
+ fallback: "sysstat",
61
+ },
62
+ category: "hardening",
63
+ required: false,
64
+ },
65
+ // ─── Firewall ─────────────────────────────────────────────
66
+ {
67
+ name: "iptables",
68
+ binary: "iptables",
69
+ packages: {
70
+ debian: "iptables",
71
+ rhel: "iptables",
72
+ arch: "iptables",
73
+ alpine: "iptables",
74
+ suse: "iptables",
75
+ fallback: "iptables",
76
+ },
77
+ category: "firewall",
78
+ required: true,
79
+ },
80
+ {
81
+ name: "nftables",
82
+ binary: "nft",
83
+ packages: {
84
+ debian: "nftables",
85
+ rhel: "nftables",
86
+ arch: "nftables",
87
+ alpine: "nftables",
88
+ suse: "nftables",
89
+ fallback: "nftables",
90
+ },
91
+ category: "firewall",
92
+ required: false,
93
+ alternativeFor: "iptables",
94
+ },
95
+ {
96
+ name: "UFW",
97
+ binary: "ufw",
98
+ packages: {
99
+ debian: "ufw",
100
+ rhel: "ufw",
101
+ arch: "ufw",
102
+ alpine: "ufw",
103
+ suse: "ufw",
104
+ fallback: "ufw",
105
+ },
106
+ category: "firewall",
107
+ required: false,
108
+ },
109
+ {
110
+ name: "Fail2ban",
111
+ binary: "fail2ban-client",
112
+ packages: {
113
+ debian: "fail2ban",
114
+ rhel: "fail2ban",
115
+ arch: "fail2ban",
116
+ alpine: "fail2ban",
117
+ suse: "fail2ban",
118
+ fallback: "fail2ban",
119
+ },
120
+ category: "firewall",
121
+ required: true,
122
+ },
123
+ // ─── Monitoring ───────────────────────────────────────────
124
+ {
125
+ name: "htop",
126
+ binary: "htop",
127
+ packages: {
128
+ debian: "htop",
129
+ rhel: "htop",
130
+ arch: "htop",
131
+ alpine: "htop",
132
+ suse: "htop",
133
+ fallback: "htop",
134
+ },
135
+ category: "monitoring",
136
+ required: false,
137
+ },
138
+ {
139
+ name: "lsof",
140
+ binary: "lsof",
141
+ packages: {
142
+ debian: "lsof",
143
+ rhel: "lsof",
144
+ arch: "lsof",
145
+ alpine: "lsof",
146
+ suse: "lsof",
147
+ fallback: "lsof",
148
+ },
149
+ category: "monitoring",
150
+ required: true,
151
+ },
152
+ {
153
+ name: "strace",
154
+ binary: "strace",
155
+ packages: {
156
+ debian: "strace",
157
+ rhel: "strace",
158
+ arch: "strace",
159
+ alpine: "strace",
160
+ suse: "strace",
161
+ fallback: "strace",
162
+ },
163
+ category: "monitoring",
164
+ required: false,
165
+ },
166
+ {
167
+ name: "inotify-tools",
168
+ binary: "inotifywait",
169
+ packages: {
170
+ debian: "inotify-tools",
171
+ rhel: "inotify-tools",
172
+ arch: "inotify-tools",
173
+ alpine: "inotify-tools",
174
+ suse: "inotify-tools",
175
+ fallback: "inotify-tools",
176
+ },
177
+ category: "monitoring",
178
+ required: false,
179
+ },
180
+ {
181
+ name: "Snort",
182
+ binary: "snort",
183
+ packages: {
184
+ debian: "snort",
185
+ rhel: "snort",
186
+ arch: "snort",
187
+ alpine: "snort",
188
+ suse: "snort",
189
+ fallback: "snort",
190
+ },
191
+ category: "monitoring",
192
+ required: false,
193
+ },
194
+ {
195
+ name: "Suricata",
196
+ binary: "suricata",
197
+ packages: {
198
+ debian: "suricata",
199
+ rhel: "suricata",
200
+ arch: "suricata",
201
+ alpine: "suricata",
202
+ suse: "suricata",
203
+ fallback: "suricata",
204
+ },
205
+ category: "monitoring",
206
+ required: false,
207
+ alternativeFor: "snort",
208
+ },
209
+ // ─── Assessment ───────────────────────────────────────────
210
+ {
211
+ name: "ClamAV",
212
+ binary: "clamscan",
213
+ packages: {
214
+ debian: "clamav",
215
+ rhel: "clamav",
216
+ arch: "clamav",
217
+ alpine: "clamav",
218
+ suse: "clamav",
219
+ fallback: "clamav",
220
+ },
221
+ category: "assessment",
222
+ required: true,
223
+ },
224
+ {
225
+ name: "rkhunter",
226
+ binary: "rkhunter",
227
+ packages: {
228
+ debian: "rkhunter",
229
+ rhel: "rkhunter",
230
+ arch: "rkhunter",
231
+ alpine: "rkhunter",
232
+ suse: "rkhunter",
233
+ fallback: "rkhunter",
234
+ },
235
+ category: "assessment",
236
+ required: true,
237
+ },
238
+ {
239
+ name: "chkrootkit",
240
+ binary: "chkrootkit",
241
+ packages: {
242
+ debian: "chkrootkit",
243
+ rhel: "chkrootkit",
244
+ arch: "chkrootkit",
245
+ alpine: "chkrootkit",
246
+ suse: "chkrootkit",
247
+ fallback: "chkrootkit",
248
+ },
249
+ category: "assessment",
250
+ required: false,
251
+ alternativeFor: "rkhunter",
252
+ },
253
+ {
254
+ name: "OpenSCAP",
255
+ binary: "oscap",
256
+ packages: {
257
+ debian: "libopenscap8",
258
+ rhel: "openscap-scanner",
259
+ arch: "openscap",
260
+ alpine: "openscap",
261
+ suse: "openscap-utils",
262
+ fallback: "openscap-scanner",
263
+ },
264
+ category: "assessment",
265
+ required: false,
266
+ },
267
+ {
268
+ name: "YARA",
269
+ binary: "yara",
270
+ packages: {
271
+ debian: "yara",
272
+ rhel: "yara",
273
+ arch: "yara",
274
+ alpine: "yara",
275
+ suse: "yara",
276
+ fallback: "yara",
277
+ },
278
+ category: "assessment",
279
+ required: false,
280
+ },
281
+ // ─── Network ──────────────────────────────────────────────
282
+ {
283
+ name: "Nmap",
284
+ binary: "nmap",
285
+ packages: {
286
+ debian: "nmap",
287
+ rhel: "nmap",
288
+ arch: "nmap",
289
+ alpine: "nmap",
290
+ suse: "nmap",
291
+ fallback: "nmap",
292
+ },
293
+ category: "network",
294
+ required: true,
295
+ },
296
+ {
297
+ name: "tcpdump",
298
+ binary: "tcpdump",
299
+ packages: {
300
+ debian: "tcpdump",
301
+ rhel: "tcpdump",
302
+ arch: "tcpdump",
303
+ alpine: "tcpdump",
304
+ suse: "tcpdump",
305
+ fallback: "tcpdump",
306
+ },
307
+ category: "network",
308
+ required: true,
309
+ },
310
+ {
311
+ name: "ss",
312
+ binary: "ss",
313
+ packages: {
314
+ debian: "iproute2",
315
+ rhel: "iproute",
316
+ arch: "iproute2",
317
+ alpine: "iproute2",
318
+ suse: "iproute2",
319
+ fallback: "iproute2",
320
+ },
321
+ category: "network",
322
+ required: true,
323
+ },
324
+ {
325
+ name: "curl",
326
+ binary: "curl",
327
+ packages: {
328
+ debian: "curl",
329
+ rhel: "curl",
330
+ arch: "curl",
331
+ alpine: "curl",
332
+ suse: "curl",
333
+ fallback: "curl",
334
+ },
335
+ category: "network",
336
+ required: true,
337
+ },
338
+ // ─── Access Control ───────────────────────────────────────
339
+ {
340
+ name: "sudo",
341
+ binary: "sudo",
342
+ packages: {
343
+ debian: "sudo",
344
+ rhel: "sudo",
345
+ arch: "sudo",
346
+ alpine: "sudo",
347
+ suse: "sudo",
348
+ fallback: "sudo",
349
+ },
350
+ category: "access",
351
+ required: true,
352
+ },
353
+ {
354
+ name: "AppArmor",
355
+ binary: "apparmor_status",
356
+ packages: {
357
+ debian: "apparmor",
358
+ rhel: "apparmor",
359
+ arch: "apparmor",
360
+ alpine: "apparmor",
361
+ suse: "apparmor",
362
+ fallback: "apparmor",
363
+ },
364
+ category: "access",
365
+ required: false,
366
+ },
367
+ {
368
+ name: "SELinux utilities",
369
+ binary: "getenforce",
370
+ packages: {
371
+ debian: "selinux-utils",
372
+ rhel: "libselinux-utils",
373
+ arch: "selinux-utils",
374
+ alpine: "selinux-utils",
375
+ suse: "selinux-tools",
376
+ fallback: "selinux-utils",
377
+ },
378
+ category: "access",
379
+ required: false,
380
+ alternativeFor: "apparmor",
381
+ },
382
+ // ─── Encryption ───────────────────────────────────────────
383
+ {
384
+ name: "OpenSSL",
385
+ binary: "openssl",
386
+ packages: {
387
+ debian: "openssl",
388
+ rhel: "openssl",
389
+ arch: "openssl",
390
+ alpine: "openssl",
391
+ suse: "openssl",
392
+ fallback: "openssl",
393
+ },
394
+ category: "encryption",
395
+ required: true,
396
+ },
397
+ {
398
+ name: "GnuPG",
399
+ binary: "gpg",
400
+ packages: {
401
+ debian: "gnupg",
402
+ rhel: "gnupg2",
403
+ arch: "gnupg",
404
+ alpine: "gnupg",
405
+ suse: "gpg2",
406
+ fallback: "gnupg",
407
+ },
408
+ category: "encryption",
409
+ required: false,
410
+ },
411
+ {
412
+ name: "cryptsetup",
413
+ binary: "cryptsetup",
414
+ packages: {
415
+ debian: "cryptsetup",
416
+ rhel: "cryptsetup",
417
+ arch: "cryptsetup",
418
+ alpine: "cryptsetup",
419
+ suse: "cryptsetup",
420
+ fallback: "cryptsetup",
421
+ },
422
+ category: "encryption",
423
+ required: false,
424
+ },
425
+ // ─── Integrity ────────────────────────────────────────────
426
+ {
427
+ name: "debsums",
428
+ binary: "debsums",
429
+ packages: {
430
+ debian: "debsums",
431
+ rhel: "debsums",
432
+ arch: "debsums",
433
+ alpine: "debsums",
434
+ suse: "debsums",
435
+ fallback: "debsums",
436
+ },
437
+ category: "integrity",
438
+ required: false,
439
+ },
440
+ // ─── Access Control ───────────────────────────────────────
441
+ {
442
+ name: "libpam-pwquality",
443
+ binary: "pam_pwquality",
444
+ packages: {
445
+ debian: "libpam-pwquality",
446
+ rhel: "libpam-pwquality",
447
+ arch: "libpam-pwquality",
448
+ alpine: "libpam-pwquality",
449
+ suse: "libpam-pwquality",
450
+ fallback: "libpam-pwquality",
451
+ },
452
+ category: "access-control",
453
+ required: false,
454
+ },
455
+ // ─── Compliance ───────────────────────────────────────────
456
+ {
457
+ name: "chrony",
458
+ binary: "chronyd",
459
+ packages: {
460
+ debian: "chrony",
461
+ rhel: "chrony",
462
+ arch: "chrony",
463
+ alpine: "chrony",
464
+ suse: "chrony",
465
+ fallback: "chrony",
466
+ },
467
+ category: "compliance",
468
+ required: false,
469
+ },
470
+ // ─── Logging ──────────────────────────────────────────────
471
+ {
472
+ name: "acct",
473
+ binary: "accton",
474
+ packages: {
475
+ debian: "acct",
476
+ rhel: "acct",
477
+ arch: "acct",
478
+ alpine: "acct",
479
+ suse: "acct",
480
+ fallback: "acct",
481
+ },
482
+ category: "logging",
483
+ required: false,
484
+ },
485
+ // ─── Firewall (persistent) ────────────────────────────────
486
+ {
487
+ name: "iptables-persistent",
488
+ binary: "netfilter-persistent",
489
+ packages: {
490
+ debian: "iptables-persistent",
491
+ rhel: "iptables-persistent",
492
+ arch: "iptables-persistent",
493
+ alpine: "iptables-persistent",
494
+ suse: "iptables-persistent",
495
+ fallback: "iptables-persistent",
496
+ },
497
+ category: "firewall",
498
+ required: false,
499
+ },
500
+ // ─── Container ────────────────────────────────────────────
501
+ {
502
+ name: "Docker",
503
+ binary: "docker",
504
+ packages: {
505
+ debian: "docker.io",
506
+ rhel: "docker-ce",
507
+ arch: "docker",
508
+ alpine: "docker",
509
+ suse: "docker",
510
+ fallback: "docker",
511
+ },
512
+ category: "container",
513
+ required: false,
514
+ },
515
+ // ─── Additional binary-to-package mappings ────────────────
516
+ // These map binaries that are part of larger packages but
517
+ // aren't the primary binary for that package.
518
+ {
519
+ name: "iptables-save",
520
+ binary: "iptables-save",
521
+ packages: {
522
+ debian: "iptables",
523
+ rhel: "iptables",
524
+ arch: "iptables",
525
+ alpine: "iptables",
526
+ suse: "iptables",
527
+ fallback: "iptables",
528
+ },
529
+ category: "firewall",
530
+ required: false,
531
+ },
532
+ {
533
+ name: "iptables-restore",
534
+ binary: "iptables-restore",
535
+ packages: {
536
+ debian: "iptables",
537
+ rhel: "iptables",
538
+ arch: "iptables",
539
+ alpine: "iptables",
540
+ suse: "iptables",
541
+ fallback: "iptables",
542
+ },
543
+ category: "firewall",
544
+ required: false,
545
+ },
546
+ {
547
+ name: "ip6tables",
548
+ binary: "ip6tables",
549
+ packages: {
550
+ debian: "iptables",
551
+ rhel: "iptables",
552
+ arch: "iptables",
553
+ alpine: "iptables",
554
+ suse: "iptables",
555
+ fallback: "iptables",
556
+ },
557
+ category: "firewall",
558
+ required: false,
559
+ },
560
+ {
561
+ name: "ip6tables-save",
562
+ binary: "ip6tables-save",
563
+ packages: {
564
+ debian: "iptables",
565
+ rhel: "iptables",
566
+ arch: "iptables",
567
+ alpine: "iptables",
568
+ suse: "iptables",
569
+ fallback: "iptables",
570
+ },
571
+ category: "firewall",
572
+ required: false,
573
+ },
574
+ {
575
+ name: "ip6tables-restore",
576
+ binary: "ip6tables-restore",
577
+ packages: {
578
+ debian: "iptables",
579
+ rhel: "iptables",
580
+ arch: "iptables",
581
+ alpine: "iptables",
582
+ suse: "iptables",
583
+ fallback: "iptables",
584
+ },
585
+ category: "firewall",
586
+ required: false,
587
+ },
588
+ {
589
+ name: "sysctl",
590
+ binary: "sysctl",
591
+ packages: {
592
+ debian: "procps",
593
+ rhel: "procps-ng",
594
+ arch: "procps-ng",
595
+ alpine: "procps",
596
+ suse: "procps",
597
+ fallback: "procps",
598
+ },
599
+ category: "hardening",
600
+ required: true,
601
+ },
602
+ {
603
+ name: "ausearch",
604
+ binary: "ausearch",
605
+ packages: {
606
+ debian: "auditd",
607
+ rhel: "audit",
608
+ arch: "audit",
609
+ alpine: "audit",
610
+ suse: "audit",
611
+ fallback: "auditd",
612
+ },
613
+ category: "logging",
614
+ required: false,
615
+ },
616
+ {
617
+ name: "aureport",
618
+ binary: "aureport",
619
+ packages: {
620
+ debian: "auditd",
621
+ rhel: "audit",
622
+ arch: "audit",
623
+ alpine: "audit",
624
+ suse: "audit",
625
+ fallback: "auditd",
626
+ },
627
+ category: "logging",
628
+ required: false,
629
+ },
630
+ {
631
+ name: "freshclam",
632
+ binary: "freshclam",
633
+ packages: {
634
+ debian: "clamav-freshclam",
635
+ rhel: "clamav-update",
636
+ arch: "clamav",
637
+ alpine: "clamav",
638
+ suse: "clamav",
639
+ fallback: "clamav-freshclam",
640
+ },
641
+ category: "assessment",
642
+ required: false,
643
+ },
644
+ {
645
+ name: "systemd-analyze",
646
+ binary: "systemd-analyze",
647
+ packages: {
648
+ debian: "systemd",
649
+ rhel: "systemd",
650
+ arch: "systemd",
651
+ alpine: "systemd",
652
+ suse: "systemd",
653
+ fallback: "systemd",
654
+ },
655
+ category: "hardening",
656
+ required: false,
657
+ },
658
+ {
659
+ name: "lsns",
660
+ binary: "lsns",
661
+ packages: {
662
+ debian: "util-linux",
663
+ rhel: "util-linux",
664
+ arch: "util-linux",
665
+ alpine: "util-linux",
666
+ suse: "util-linux",
667
+ fallback: "util-linux",
668
+ },
669
+ category: "container",
670
+ required: false,
671
+ },
672
+ {
673
+ name: "Trivy",
674
+ binary: "trivy",
675
+ packages: {
676
+ debian: "trivy",
677
+ rhel: "trivy",
678
+ arch: "trivy",
679
+ alpine: "trivy",
680
+ suse: "trivy",
681
+ fallback: "trivy",
682
+ },
683
+ category: "container",
684
+ required: false,
685
+ },
686
+ {
687
+ name: "Grype",
688
+ binary: "grype",
689
+ packages: {
690
+ debian: "grype",
691
+ rhel: "grype",
692
+ arch: "grype",
693
+ alpine: "grype",
694
+ suse: "grype",
695
+ fallback: "grype",
696
+ },
697
+ category: "container",
698
+ required: false,
699
+ },
700
+ {
701
+ name: "WireGuard Tools",
702
+ binary: "wg",
703
+ packages: {
704
+ debian: "wireguard-tools",
705
+ rhel: "wireguard-tools",
706
+ arch: "wireguard-tools",
707
+ alpine: "wireguard-tools",
708
+ suse: "wireguard-tools",
709
+ fallback: "wireguard-tools",
710
+ },
711
+ category: "network",
712
+ required: false,
713
+ },
714
+ {
715
+ name: "AppArmor Parser",
716
+ binary: "apparmor_parser",
717
+ packages: {
718
+ debian: "apparmor",
719
+ rhel: "apparmor",
720
+ arch: "apparmor",
721
+ alpine: "apparmor",
722
+ suse: "apparmor",
723
+ fallback: "apparmor",
724
+ },
725
+ category: "container",
726
+ required: false,
727
+ },
728
+ {
729
+ name: "bpftool",
730
+ binary: "bpftool",
731
+ packages: {
732
+ debian: "bpftool",
733
+ rhel: "bpftool",
734
+ arch: "bpf",
735
+ alpine: "bpftool",
736
+ suse: "bpftool",
737
+ fallback: "bpftool",
738
+ },
739
+ category: "monitoring",
740
+ required: false,
741
+ },
742
+ {
743
+ name: "Falco",
744
+ binary: "falco",
745
+ packages: {
746
+ debian: "falco",
747
+ rhel: "falco",
748
+ arch: "falco",
749
+ alpine: "falco",
750
+ suse: "falco",
751
+ fallback: "falco",
752
+ },
753
+ category: "monitoring",
754
+ required: false,
755
+ },
756
+ {
757
+ name: "logrotate",
758
+ binary: "logrotate",
759
+ packages: {
760
+ debian: "logrotate",
761
+ rhel: "logrotate",
762
+ arch: "logrotate",
763
+ alpine: "logrotate",
764
+ suse: "logrotate",
765
+ fallback: "logrotate",
766
+ },
767
+ category: "logging",
768
+ required: false,
769
+ },
770
+ {
771
+ name: "newuidmap",
772
+ binary: "newuidmap",
773
+ packages: {
774
+ debian: "uidmap",
775
+ rhel: "shadow-utils",
776
+ arch: "shadow",
777
+ alpine: "shadow",
778
+ suse: "shadow",
779
+ fallback: "uidmap",
780
+ },
781
+ category: "container",
782
+ required: false,
783
+ },
784
+ {
785
+ name: "newgidmap",
786
+ binary: "newgidmap",
787
+ packages: {
788
+ debian: "uidmap",
789
+ rhel: "shadow-utils",
790
+ arch: "shadow",
791
+ alpine: "shadow",
792
+ suse: "shadow",
793
+ fallback: "uidmap",
794
+ },
795
+ category: "container",
796
+ required: false,
797
+ },
798
+ {
799
+ name: "readelf",
800
+ binary: "readelf",
801
+ packages: {
802
+ debian: "binutils",
803
+ rhel: "binutils",
804
+ arch: "binutils",
805
+ alpine: "binutils",
806
+ suse: "binutils",
807
+ fallback: "binutils",
808
+ },
809
+ category: "assessment",
810
+ required: false,
811
+ },
812
+ {
813
+ name: "TruffleHog",
814
+ binary: "trufflehog",
815
+ packages: {
816
+ debian: "trufflehog",
817
+ rhel: "trufflehog",
818
+ arch: "trufflehog",
819
+ alpine: "trufflehog",
820
+ suse: "trufflehog",
821
+ fallback: "trufflehog",
822
+ },
823
+ category: "assessment",
824
+ required: false,
825
+ },
826
+ {
827
+ name: "Gitleaks",
828
+ binary: "gitleaks",
829
+ packages: {
830
+ debian: "gitleaks",
831
+ rhel: "gitleaks",
832
+ arch: "gitleaks",
833
+ alpine: "gitleaks",
834
+ suse: "gitleaks",
835
+ fallback: "gitleaks",
836
+ },
837
+ category: "assessment",
838
+ required: false,
839
+ },
840
+ {
841
+ name: "Cosign",
842
+ binary: "cosign",
843
+ packages: {
844
+ debian: "cosign",
845
+ rhel: "cosign",
846
+ arch: "cosign",
847
+ alpine: "cosign",
848
+ suse: "cosign",
849
+ fallback: "cosign",
850
+ },
851
+ category: "assessment",
852
+ required: false,
853
+ },
854
+ {
855
+ name: "SLSA Verifier",
856
+ binary: "slsa-verifier",
857
+ packages: {
858
+ debian: "slsa-verifier",
859
+ rhel: "slsa-verifier",
860
+ arch: "slsa-verifier",
861
+ alpine: "slsa-verifier",
862
+ suse: "slsa-verifier",
863
+ fallback: "slsa-verifier",
864
+ },
865
+ category: "assessment",
866
+ required: false,
867
+ },
868
+ {
869
+ name: "checksec",
870
+ binary: "checksec",
871
+ packages: {
872
+ debian: "checksec",
873
+ rhel: "checksec",
874
+ arch: "checksec",
875
+ alpine: "checksec",
876
+ suse: "checksec",
877
+ fallback: "checksec",
878
+ },
879
+ category: "assessment",
880
+ required: false,
881
+ },
882
+ {
883
+ name: "Git",
884
+ binary: "git",
885
+ packages: {
886
+ debian: "git",
887
+ rhel: "git",
888
+ arch: "git",
889
+ alpine: "git",
890
+ suse: "git",
891
+ fallback: "git",
892
+ },
893
+ category: "assessment",
894
+ required: false,
895
+ },
896
+ {
897
+ name: "syft",
898
+ binary: "syft",
899
+ packages: {
900
+ debian: "syft",
901
+ rhel: "syft",
902
+ arch: "syft",
903
+ alpine: "syft",
904
+ suse: "syft",
905
+ fallback: "syft",
906
+ },
907
+ category: "assessment",
908
+ required: false,
909
+ },
910
+ {
911
+ name: "cdxgen",
912
+ binary: "cdxgen",
913
+ packages: {
914
+ debian: "cdxgen",
915
+ rhel: "cdxgen",
916
+ arch: "cdxgen",
917
+ alpine: "cdxgen",
918
+ suse: "cdxgen",
919
+ fallback: "cdxgen",
920
+ },
921
+ category: "assessment",
922
+ required: false,
923
+ },
924
+ ];
925
+ /**
926
+ * Checks whether a tool binary is available on the system.
927
+ * Uses `which` to find the binary, then attempts `--version` for version info.
928
+ */
929
+ export async function checkTool(binary) {
930
+ // Check if binary exists
931
+ const whichResult = await executeCommand({
932
+ command: "which",
933
+ args: [binary],
934
+ timeout: 5000,
935
+ });
936
+ if (whichResult.exitCode !== 0) {
937
+ return { installed: false };
938
+ }
939
+ const binaryPath = whichResult.stdout.trim();
940
+ // Try to get version
941
+ let version;
942
+ const versionResult = await executeCommand({
943
+ command: binary,
944
+ args: ["--version"],
945
+ timeout: 5000,
946
+ });
947
+ if (versionResult.exitCode === 0) {
948
+ // Take first line of version output
949
+ version = versionResult.stdout.trim().split("\n")[0];
950
+ }
951
+ else {
952
+ // Some tools use -v or -V instead
953
+ const altResult = await executeCommand({
954
+ command: binary,
955
+ args: ["-V"],
956
+ timeout: 5000,
957
+ });
958
+ if (altResult.exitCode === 0) {
959
+ version = altResult.stdout.trim().split("\n")[0];
960
+ }
961
+ }
962
+ return { installed: true, version, path: binaryPath };
963
+ }
964
+ /**
965
+ * Checks all defensive tools or a specific category.
966
+ *
967
+ * @param category Optional category to filter by
968
+ * @returns Array of check results
969
+ */
970
+ export async function checkAllTools(category) {
971
+ const tools = category
972
+ ? DEFENSIVE_TOOLS.filter((t) => t.category === category)
973
+ : DEFENSIVE_TOOLS;
974
+ const results = [];
975
+ for (const tool of tools) {
976
+ const check = await checkTool(tool.binary);
977
+ results.push({
978
+ tool,
979
+ installed: check.installed,
980
+ version: check.version,
981
+ path: check.path,
982
+ });
983
+ }
984
+ return results;
985
+ }
986
+ /**
987
+ * Installs a tool using the detected distribution's package manager.
988
+ *
989
+ * @param tool Tool requirement to install
990
+ * @returns Installation result
991
+ */
992
+ export async function installTool(tool) {
993
+ const distro = await detectDistro();
994
+ const pkgManager = distro.packageManager;
995
+ if (pkgManager === "unknown") {
996
+ return {
997
+ tool,
998
+ success: false,
999
+ message: "Cannot install: unknown package manager",
1000
+ };
1001
+ }
1002
+ // Determine the package name for this distro
1003
+ const pkgName = tool.packages[distro.family] ??
1004
+ tool.packages.fallback;
1005
+ if (!pkgName) {
1006
+ return {
1007
+ tool,
1008
+ success: false,
1009
+ message: `No package name configured for ${distro.family}`,
1010
+ };
1011
+ }
1012
+ console.error(`[installer] Installing ${tool.name} (${pkgName}) via ${pkgManager}`);
1013
+ // Run package manager update first
1014
+ const updateCmd = getUpdateCommand(pkgManager);
1015
+ await executeCommand({
1016
+ command: updateCmd[0],
1017
+ args: updateCmd.slice(1),
1018
+ timeout: 120_000,
1019
+ });
1020
+ // Install the package
1021
+ const installCmd = getInstallCommand(pkgManager, pkgName);
1022
+ const result = await executeCommand({
1023
+ command: installCmd[0],
1024
+ args: installCmd.slice(1),
1025
+ timeout: 300_000,
1026
+ });
1027
+ if (result.exitCode === 0) {
1028
+ return {
1029
+ tool,
1030
+ success: true,
1031
+ message: `Successfully installed ${tool.name} (${pkgName})`,
1032
+ };
1033
+ }
1034
+ return {
1035
+ tool,
1036
+ success: false,
1037
+ message: `Failed to install ${tool.name}: ${result.stderr || result.stdout}`,
1038
+ };
1039
+ }
1040
+ /**
1041
+ * Checks for missing tools and optionally installs them.
1042
+ *
1043
+ * @param category Optional category filter
1044
+ * @param dryRun If true, only report what would be installed
1045
+ * @returns Array of install results (or what would be installed)
1046
+ */
1047
+ export async function installMissing(category, dryRun) {
1048
+ const config = getConfig();
1049
+ const effectiveDryRun = dryRun ?? config.dryRun;
1050
+ const checks = await checkAllTools(category);
1051
+ const missing = checks.filter((c) => !c.installed);
1052
+ if (missing.length === 0) {
1053
+ console.error("[installer] All tools are installed");
1054
+ return [];
1055
+ }
1056
+ console.error(`[installer] ${missing.length} tools missing: ${missing.map((m) => m.tool.name).join(", ")}`);
1057
+ const results = [];
1058
+ for (const check of missing) {
1059
+ if (effectiveDryRun) {
1060
+ results.push({
1061
+ tool: check.tool,
1062
+ success: false,
1063
+ message: `[DRY RUN] Would install ${check.tool.name}`,
1064
+ });
1065
+ }
1066
+ else {
1067
+ const result = await installTool(check.tool);
1068
+ results.push(result);
1069
+ }
1070
+ }
1071
+ return results;
1072
+ }