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.
- package/CHANGELOG.md +471 -0
- package/LICENSE +21 -0
- package/README.md +242 -0
- package/build/core/auto-installer.d.ts +102 -0
- package/build/core/auto-installer.d.ts.map +1 -0
- package/build/core/auto-installer.js +833 -0
- package/build/core/backup-manager.d.ts +63 -0
- package/build/core/backup-manager.d.ts.map +1 -0
- package/build/core/backup-manager.js +189 -0
- package/build/core/changelog.d.ts +75 -0
- package/build/core/changelog.d.ts.map +1 -0
- package/build/core/changelog.js +123 -0
- package/build/core/command-allowlist.d.ts +129 -0
- package/build/core/command-allowlist.d.ts.map +1 -0
- package/build/core/command-allowlist.js +849 -0
- package/build/core/config.d.ts +79 -0
- package/build/core/config.d.ts.map +1 -0
- package/build/core/config.js +193 -0
- package/build/core/dependency-validator.d.ts +106 -0
- package/build/core/dependency-validator.d.ts.map +1 -0
- package/build/core/dependency-validator.js +405 -0
- package/build/core/distro-adapter.d.ts +177 -0
- package/build/core/distro-adapter.d.ts.map +1 -0
- package/build/core/distro-adapter.js +481 -0
- package/build/core/distro.d.ts +68 -0
- package/build/core/distro.d.ts.map +1 -0
- package/build/core/distro.js +457 -0
- package/build/core/encrypted-state.d.ts +76 -0
- package/build/core/encrypted-state.d.ts.map +1 -0
- package/build/core/encrypted-state.js +209 -0
- package/build/core/executor.d.ts +56 -0
- package/build/core/executor.d.ts.map +1 -0
- package/build/core/executor.js +350 -0
- package/build/core/installer.d.ts +92 -0
- package/build/core/installer.d.ts.map +1 -0
- package/build/core/installer.js +1072 -0
- package/build/core/logger.d.ts +102 -0
- package/build/core/logger.d.ts.map +1 -0
- package/build/core/logger.js +132 -0
- package/build/core/parsers.d.ts +151 -0
- package/build/core/parsers.d.ts.map +1 -0
- package/build/core/parsers.js +479 -0
- package/build/core/policy-engine.d.ts +170 -0
- package/build/core/policy-engine.d.ts.map +1 -0
- package/build/core/policy-engine.js +656 -0
- package/build/core/preflight.d.ts +157 -0
- package/build/core/preflight.d.ts.map +1 -0
- package/build/core/preflight.js +638 -0
- package/build/core/privilege-manager.d.ts +108 -0
- package/build/core/privilege-manager.d.ts.map +1 -0
- package/build/core/privilege-manager.js +363 -0
- package/build/core/rate-limiter.d.ts +67 -0
- package/build/core/rate-limiter.d.ts.map +1 -0
- package/build/core/rate-limiter.js +129 -0
- package/build/core/rollback.d.ts +73 -0
- package/build/core/rollback.d.ts.map +1 -0
- package/build/core/rollback.js +278 -0
- package/build/core/safeguards.d.ts +58 -0
- package/build/core/safeguards.d.ts.map +1 -0
- package/build/core/safeguards.js +448 -0
- package/build/core/sanitizer.d.ts +118 -0
- package/build/core/sanitizer.d.ts.map +1 -0
- package/build/core/sanitizer.js +459 -0
- package/build/core/secure-fs.d.ts +67 -0
- package/build/core/secure-fs.d.ts.map +1 -0
- package/build/core/secure-fs.js +143 -0
- package/build/core/spawn-safe.d.ts +55 -0
- package/build/core/spawn-safe.d.ts.map +1 -0
- package/build/core/spawn-safe.js +146 -0
- package/build/core/sudo-guard.d.ts +145 -0
- package/build/core/sudo-guard.d.ts.map +1 -0
- package/build/core/sudo-guard.js +349 -0
- package/build/core/sudo-session.d.ts +100 -0
- package/build/core/sudo-session.d.ts.map +1 -0
- package/build/core/sudo-session.js +319 -0
- package/build/core/tool-dependencies.d.ts +61 -0
- package/build/core/tool-dependencies.d.ts.map +1 -0
- package/build/core/tool-dependencies.js +571 -0
- package/build/core/tool-registry.d.ts +111 -0
- package/build/core/tool-registry.d.ts.map +1 -0
- package/build/core/tool-registry.js +656 -0
- package/build/core/tool-wrapper.d.ts +73 -0
- package/build/core/tool-wrapper.d.ts.map +1 -0
- package/build/core/tool-wrapper.js +296 -0
- package/build/index.d.ts +3 -0
- package/build/index.d.ts.map +1 -0
- package/build/index.js +247 -0
- package/build/tools/access-control.d.ts +9 -0
- package/build/tools/access-control.d.ts.map +1 -0
- package/build/tools/access-control.js +1818 -0
- package/build/tools/api-security.d.ts +12 -0
- package/build/tools/api-security.d.ts.map +1 -0
- package/build/tools/api-security.js +901 -0
- package/build/tools/app-hardening.d.ts +11 -0
- package/build/tools/app-hardening.d.ts.map +1 -0
- package/build/tools/app-hardening.js +768 -0
- package/build/tools/backup.d.ts +8 -0
- package/build/tools/backup.d.ts.map +1 -0
- package/build/tools/backup.js +381 -0
- package/build/tools/cloud-security.d.ts +17 -0
- package/build/tools/cloud-security.d.ts.map +1 -0
- package/build/tools/cloud-security.js +739 -0
- package/build/tools/compliance.d.ts +10 -0
- package/build/tools/compliance.d.ts.map +1 -0
- package/build/tools/compliance.js +1225 -0
- package/build/tools/container-security.d.ts +14 -0
- package/build/tools/container-security.d.ts.map +1 -0
- package/build/tools/container-security.js +788 -0
- package/build/tools/deception.d.ts +13 -0
- package/build/tools/deception.d.ts.map +1 -0
- package/build/tools/deception.js +763 -0
- package/build/tools/dns-security.d.ts +93 -0
- package/build/tools/dns-security.d.ts.map +1 -0
- package/build/tools/dns-security.js +745 -0
- package/build/tools/drift-detection.d.ts +8 -0
- package/build/tools/drift-detection.d.ts.map +1 -0
- package/build/tools/drift-detection.js +326 -0
- package/build/tools/ebpf-security.d.ts +15 -0
- package/build/tools/ebpf-security.d.ts.map +1 -0
- package/build/tools/ebpf-security.js +294 -0
- package/build/tools/encryption.d.ts +9 -0
- package/build/tools/encryption.d.ts.map +1 -0
- package/build/tools/encryption.js +1667 -0
- package/build/tools/firewall.d.ts +9 -0
- package/build/tools/firewall.d.ts.map +1 -0
- package/build/tools/firewall.js +1398 -0
- package/build/tools/hardening.d.ts +10 -0
- package/build/tools/hardening.d.ts.map +1 -0
- package/build/tools/hardening.js +2654 -0
- package/build/tools/ids.d.ts +9 -0
- package/build/tools/ids.d.ts.map +1 -0
- package/build/tools/ids.js +624 -0
- package/build/tools/incident-response.d.ts +10 -0
- package/build/tools/incident-response.d.ts.map +1 -0
- package/build/tools/incident-response.js +1180 -0
- package/build/tools/logging.d.ts +12 -0
- package/build/tools/logging.d.ts.map +1 -0
- package/build/tools/logging.js +454 -0
- package/build/tools/malware.d.ts +10 -0
- package/build/tools/malware.d.ts.map +1 -0
- package/build/tools/malware.js +532 -0
- package/build/tools/meta.d.ts +11 -0
- package/build/tools/meta.d.ts.map +1 -0
- package/build/tools/meta.js +2278 -0
- package/build/tools/network-defense.d.ts +12 -0
- package/build/tools/network-defense.d.ts.map +1 -0
- package/build/tools/network-defense.js +760 -0
- package/build/tools/patch-management.d.ts +3 -0
- package/build/tools/patch-management.d.ts.map +1 -0
- package/build/tools/patch-management.js +708 -0
- package/build/tools/process-security.d.ts +12 -0
- package/build/tools/process-security.d.ts.map +1 -0
- package/build/tools/process-security.js +784 -0
- package/build/tools/reporting.d.ts +11 -0
- package/build/tools/reporting.d.ts.map +1 -0
- package/build/tools/reporting.js +559 -0
- package/build/tools/secrets.d.ts +9 -0
- package/build/tools/secrets.d.ts.map +1 -0
- package/build/tools/secrets.js +596 -0
- package/build/tools/siem-integration.d.ts +18 -0
- package/build/tools/siem-integration.d.ts.map +1 -0
- package/build/tools/siem-integration.js +754 -0
- package/build/tools/sudo-management.d.ts +18 -0
- package/build/tools/sudo-management.d.ts.map +1 -0
- package/build/tools/sudo-management.js +737 -0
- package/build/tools/supply-chain-security.d.ts +8 -0
- package/build/tools/supply-chain-security.d.ts.map +1 -0
- package/build/tools/supply-chain-security.js +256 -0
- package/build/tools/threat-intel.d.ts +22 -0
- package/build/tools/threat-intel.d.ts.map +1 -0
- package/build/tools/threat-intel.js +749 -0
- package/build/tools/vulnerability-management.d.ts +11 -0
- package/build/tools/vulnerability-management.d.ts.map +1 -0
- package/build/tools/vulnerability-management.js +667 -0
- package/build/tools/waf.d.ts +12 -0
- package/build/tools/waf.d.ts.map +1 -0
- package/build/tools/waf.js +843 -0
- package/build/tools/wireless-security.d.ts +19 -0
- package/build/tools/wireless-security.d.ts.map +1 -0
- package/build/tools/wireless-security.js +826 -0
- package/build/tools/zero-trust-network.d.ts +8 -0
- package/build/tools/zero-trust-network.d.ts.map +1 -0
- package/build/tools/zero-trust-network.js +367 -0
- package/docs/SAFEGUARDS.md +518 -0
- package/docs/TOOLS-REFERENCE.md +665 -0
- package/package.json +87 -0
|
@@ -0,0 +1,481 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DistroAdapter — unified cross-distribution API for the Kali Defense MCP Server.
|
|
3
|
+
*
|
|
4
|
+
* This module provides a single, cached adapter instance that abstracts away
|
|
5
|
+
* distribution-specific differences in:
|
|
6
|
+
* - Package management (apt / dnf / yum / zypper / pacman / apk)
|
|
7
|
+
* - Service management (systemd / openrc / sysvinit / launchd)
|
|
8
|
+
* - Firewall backends (iptables / nftables / ufw / firewalld)
|
|
9
|
+
* - File system paths (logs, PAM configs, syslog, package tools)
|
|
10
|
+
* - Package integrity checking (debsums / rpm -V)
|
|
11
|
+
* - Automatic updates configuration
|
|
12
|
+
*
|
|
13
|
+
* Supported distributions:
|
|
14
|
+
* Debian, Ubuntu, Kali, Linux Mint, Pop!_OS → debian family
|
|
15
|
+
* RHEL, CentOS, Fedora, Rocky, AlmaLinux → rhel family
|
|
16
|
+
* openSUSE, SLES → suse family
|
|
17
|
+
* Arch, Manjaro → arch family
|
|
18
|
+
* Alpine → alpine family
|
|
19
|
+
*
|
|
20
|
+
* Usage:
|
|
21
|
+
* import { getDistroAdapter } from "../core/distro-adapter.js";
|
|
22
|
+
* const da = await getDistroAdapter();
|
|
23
|
+
* const cmd = da.pkg.installCmd("nginx"); // distro-correct install
|
|
24
|
+
* const logPath = da.paths.syslog; // "/var/log/syslog" or "/var/log/messages"
|
|
25
|
+
*/
|
|
26
|
+
import { detectDistro, getPackageManager, getServiceManager, getFirewallBackend, } from "./distro.js";
|
|
27
|
+
// ── DistroAdapter ────────────────────────────────────────────────────────────
|
|
28
|
+
export class DistroAdapter {
|
|
29
|
+
distro;
|
|
30
|
+
pkg;
|
|
31
|
+
svc;
|
|
32
|
+
fw;
|
|
33
|
+
paths;
|
|
34
|
+
integrity;
|
|
35
|
+
autoUpdate;
|
|
36
|
+
pkgQuery;
|
|
37
|
+
fwPersistence;
|
|
38
|
+
constructor(distro, pkg, svc, fw) {
|
|
39
|
+
this.distro = distro;
|
|
40
|
+
this.pkg = pkg;
|
|
41
|
+
this.svc = svc;
|
|
42
|
+
this.fw = fw;
|
|
43
|
+
this.paths = buildPaths(distro);
|
|
44
|
+
this.integrity = buildIntegrityConfig(distro);
|
|
45
|
+
this.autoUpdate = buildAutoUpdateConfig(distro);
|
|
46
|
+
this.pkgQuery = buildPackageQueryCommands(distro);
|
|
47
|
+
this.fwPersistence = buildFirewallPersistenceConfig(distro);
|
|
48
|
+
}
|
|
49
|
+
/** Human-readable summary of the detected environment. */
|
|
50
|
+
get summary() {
|
|
51
|
+
return (`${this.distro.name} (${this.distro.family}) | ` +
|
|
52
|
+
`pkg=${this.distro.packageManager} | init=${this.distro.initSystem} | ` +
|
|
53
|
+
`fw=${this.fw.name}`);
|
|
54
|
+
}
|
|
55
|
+
/** Whether the distro family is Debian-based. */
|
|
56
|
+
get isDebian() { return this.distro.family === "debian"; }
|
|
57
|
+
/** Whether the distro family is RHEL-based. */
|
|
58
|
+
get isRhel() { return this.distro.family === "rhel"; }
|
|
59
|
+
/** Whether the distro family is SUSE-based. */
|
|
60
|
+
get isSuse() { return this.distro.family === "suse"; }
|
|
61
|
+
/** Whether the distro family is Arch-based. */
|
|
62
|
+
get isArch() { return this.distro.family === "arch"; }
|
|
63
|
+
/** Whether the distro family is Alpine. */
|
|
64
|
+
get isAlpine() { return this.distro.family === "alpine"; }
|
|
65
|
+
/** Install a package using the distro's package manager (returns command array). */
|
|
66
|
+
installPkg(pkg) {
|
|
67
|
+
const cmd = this.pkg.installCmd(pkg);
|
|
68
|
+
return { command: "sudo", args: cmd };
|
|
69
|
+
}
|
|
70
|
+
/** Remove a package using the distro's package manager (returns command array). */
|
|
71
|
+
removePkg(pkg) {
|
|
72
|
+
const cmd = this.pkg.removeCmd(pkg);
|
|
73
|
+
return { command: "sudo", args: cmd };
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
// ── Path builders ────────────────────────────────────────────────────────────
|
|
77
|
+
function buildPaths(distro) {
|
|
78
|
+
const family = distro.family;
|
|
79
|
+
// Syslog location
|
|
80
|
+
const syslog = (() => {
|
|
81
|
+
switch (family) {
|
|
82
|
+
case "debian": return "/var/log/syslog";
|
|
83
|
+
case "rhel": return "/var/log/messages";
|
|
84
|
+
case "suse": return "/var/log/messages";
|
|
85
|
+
case "arch": return "/var/log/messages.log"; // usually journald only
|
|
86
|
+
case "alpine": return "/var/log/messages";
|
|
87
|
+
default: return "/var/log/syslog";
|
|
88
|
+
}
|
|
89
|
+
})();
|
|
90
|
+
// Auth log location
|
|
91
|
+
const authLog = (() => {
|
|
92
|
+
switch (family) {
|
|
93
|
+
case "debian": return "/var/log/auth.log";
|
|
94
|
+
case "rhel": return "/var/log/secure";
|
|
95
|
+
case "suse": return "/var/log/secure";
|
|
96
|
+
case "arch": return "/var/log/auth.log"; // usually journald
|
|
97
|
+
case "alpine": return "/var/log/auth.log";
|
|
98
|
+
default: return "/var/log/auth.log";
|
|
99
|
+
}
|
|
100
|
+
})();
|
|
101
|
+
// PAM paths — Debian uses common-*, RHEL/SUSE use system-auth/password-auth
|
|
102
|
+
const isDebianPam = family === "debian" || family === "alpine";
|
|
103
|
+
const pamAuth = isDebianPam ? "/etc/pam.d/common-auth" : "/etc/pam.d/system-auth";
|
|
104
|
+
const pamPassword = isDebianPam ? "/etc/pam.d/common-password" : "/etc/pam.d/password-auth";
|
|
105
|
+
const pamSession = isDebianPam ? "/etc/pam.d/common-session" : "/etc/pam.d/system-auth";
|
|
106
|
+
const pamAccount = isDebianPam ? "/etc/pam.d/common-account" : "/etc/pam.d/system-auth";
|
|
107
|
+
const pamAllConfigs = isDebianPam
|
|
108
|
+
? ["/etc/pam.d/common-auth", "/etc/pam.d/common-password", "/etc/pam.d/common-session", "/etc/pam.d/common-account"]
|
|
109
|
+
: ["/etc/pam.d/system-auth", "/etc/pam.d/password-auth"];
|
|
110
|
+
// Auto-update config
|
|
111
|
+
const autoUpdateConfig = (() => {
|
|
112
|
+
switch (family) {
|
|
113
|
+
case "debian": return "/etc/apt/apt.conf.d";
|
|
114
|
+
case "rhel": return "/etc/dnf/automatic.conf";
|
|
115
|
+
case "suse": return "/etc/zypp/zypp.conf";
|
|
116
|
+
case "arch": return "/etc/pacman.conf"; // no native auto-update
|
|
117
|
+
case "alpine": return "/etc/apk"; // no native auto-update
|
|
118
|
+
default: return "/etc";
|
|
119
|
+
}
|
|
120
|
+
})();
|
|
121
|
+
const autoUpdatePackage = (() => {
|
|
122
|
+
switch (family) {
|
|
123
|
+
case "debian": return "unattended-upgrades";
|
|
124
|
+
case "rhel": return "dnf-automatic";
|
|
125
|
+
case "suse": return "zypper"; // uses cron/systemd
|
|
126
|
+
default: return "";
|
|
127
|
+
}
|
|
128
|
+
})();
|
|
129
|
+
const autoUpdateService = (() => {
|
|
130
|
+
switch (family) {
|
|
131
|
+
case "debian": return "unattended-upgrades";
|
|
132
|
+
case "rhel": return "dnf-automatic.timer";
|
|
133
|
+
case "suse": return "zypper";
|
|
134
|
+
default: return "";
|
|
135
|
+
}
|
|
136
|
+
})();
|
|
137
|
+
// Firewall persistence
|
|
138
|
+
const firewallPersistenceConfig = (() => {
|
|
139
|
+
switch (family) {
|
|
140
|
+
case "debian": return "/etc/iptables/rules.v4";
|
|
141
|
+
case "rhel": return "/etc/sysconfig/iptables";
|
|
142
|
+
case "suse": return "/etc/sysconfig/iptables";
|
|
143
|
+
case "arch": return "/etc/iptables/iptables.rules";
|
|
144
|
+
case "alpine": return "/etc/iptables/rules-save";
|
|
145
|
+
default: return "/etc/iptables/rules.v4";
|
|
146
|
+
}
|
|
147
|
+
})();
|
|
148
|
+
// Package lock file
|
|
149
|
+
const packageLockFile = (() => {
|
|
150
|
+
switch (distro.packageManager) {
|
|
151
|
+
case "apt": return "/var/lib/dpkg/lock-frontend";
|
|
152
|
+
case "dnf":
|
|
153
|
+
case "yum": return "/var/run/yum.pid";
|
|
154
|
+
case "zypper": return "/var/run/zypp.pid";
|
|
155
|
+
case "pacman": return "/var/lib/pacman/db.lck";
|
|
156
|
+
case "apk": return "/lib/apk/db/lock";
|
|
157
|
+
default: return "";
|
|
158
|
+
}
|
|
159
|
+
})();
|
|
160
|
+
// Network config
|
|
161
|
+
const networkConfigDir = (() => {
|
|
162
|
+
switch (family) {
|
|
163
|
+
case "debian": return "/etc/network";
|
|
164
|
+
case "rhel": return "/etc/sysconfig/network-scripts";
|
|
165
|
+
case "suse": return "/etc/sysconfig/network";
|
|
166
|
+
case "arch": return "/etc/systemd/network";
|
|
167
|
+
case "alpine": return "/etc/network";
|
|
168
|
+
default: return "/etc/network";
|
|
169
|
+
}
|
|
170
|
+
})();
|
|
171
|
+
// GRUB config paths
|
|
172
|
+
const grubConfig = (() => {
|
|
173
|
+
switch (family) {
|
|
174
|
+
case "debian": return "/boot/grub/grub.cfg";
|
|
175
|
+
case "rhel": return "/boot/grub2/grub.cfg";
|
|
176
|
+
case "suse": return "/boot/grub2/grub.cfg";
|
|
177
|
+
case "arch": return "/boot/grub/grub.cfg";
|
|
178
|
+
default: return "/boot/grub/grub.cfg";
|
|
179
|
+
}
|
|
180
|
+
})();
|
|
181
|
+
const grubDefaults = "/etc/default/grub"; // same everywhere
|
|
182
|
+
const grubUpdateCmd = (() => {
|
|
183
|
+
switch (family) {
|
|
184
|
+
case "debian": return ["update-grub"];
|
|
185
|
+
case "rhel": return ["grub2-mkconfig", "-o", "/boot/grub2/grub.cfg"];
|
|
186
|
+
case "suse": return ["grub2-mkconfig", "-o", "/boot/grub2/grub.cfg"];
|
|
187
|
+
case "arch": return ["grub-mkconfig", "-o", "/boot/grub/grub.cfg"];
|
|
188
|
+
default: return ["update-grub"];
|
|
189
|
+
}
|
|
190
|
+
})();
|
|
191
|
+
return {
|
|
192
|
+
syslog, authLog,
|
|
193
|
+
pamAuth, pamPassword, pamSession, pamAccount, pamAllConfigs,
|
|
194
|
+
autoUpdateConfig, autoUpdatePackage, autoUpdateService,
|
|
195
|
+
firewallPersistenceConfig, packageLockFile,
|
|
196
|
+
networkConfigDir,
|
|
197
|
+
modprobeDir: "/etc/modprobe.d", // universal
|
|
198
|
+
grubConfig, grubDefaults, grubUpdateCmd,
|
|
199
|
+
};
|
|
200
|
+
}
|
|
201
|
+
// ── Integrity check ──────────────────────────────────────────────────────────
|
|
202
|
+
function buildIntegrityConfig(distro) {
|
|
203
|
+
switch (distro.family) {
|
|
204
|
+
case "debian":
|
|
205
|
+
return {
|
|
206
|
+
supported: true,
|
|
207
|
+
checkCmd: ["debsums", "-s"],
|
|
208
|
+
checkPackageCmd: (pkg) => ["debsums", "-s", pkg],
|
|
209
|
+
toolName: "debsums",
|
|
210
|
+
installHint: `sudo ${distro.packageManager} install debsums`,
|
|
211
|
+
};
|
|
212
|
+
case "rhel":
|
|
213
|
+
case "suse":
|
|
214
|
+
return {
|
|
215
|
+
supported: true,
|
|
216
|
+
checkCmd: ["rpm", "-Va"],
|
|
217
|
+
checkPackageCmd: (pkg) => ["rpm", "-V", pkg],
|
|
218
|
+
toolName: "rpm",
|
|
219
|
+
installHint: "rpm is pre-installed on RPM-based systems",
|
|
220
|
+
};
|
|
221
|
+
case "arch":
|
|
222
|
+
return {
|
|
223
|
+
supported: true,
|
|
224
|
+
checkCmd: ["pacman", "-Qk"],
|
|
225
|
+
checkPackageCmd: (pkg) => ["pacman", "-Qk", pkg],
|
|
226
|
+
toolName: "pacman",
|
|
227
|
+
installHint: "pacman is the native Arch package manager",
|
|
228
|
+
};
|
|
229
|
+
case "alpine":
|
|
230
|
+
return {
|
|
231
|
+
supported: true,
|
|
232
|
+
checkCmd: ["apk", "verify"],
|
|
233
|
+
checkPackageCmd: (pkg) => ["apk", "verify", pkg],
|
|
234
|
+
toolName: "apk",
|
|
235
|
+
installHint: "apk is the native Alpine package manager",
|
|
236
|
+
};
|
|
237
|
+
default:
|
|
238
|
+
return {
|
|
239
|
+
supported: false,
|
|
240
|
+
checkCmd: ["echo", "Package integrity checking not supported on this distro"],
|
|
241
|
+
checkPackageCmd: () => ["echo", "Not supported"],
|
|
242
|
+
toolName: "unknown",
|
|
243
|
+
installHint: "No package integrity tool available",
|
|
244
|
+
};
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
// ── Auto-update config ───────────────────────────────────────────────────────
|
|
248
|
+
function buildAutoUpdateConfig(distro) {
|
|
249
|
+
switch (distro.family) {
|
|
250
|
+
case "debian":
|
|
251
|
+
return {
|
|
252
|
+
supported: true,
|
|
253
|
+
packageName: "unattended-upgrades",
|
|
254
|
+
checkInstalledCmd: ["dpkg", "-l", "unattended-upgrades"],
|
|
255
|
+
serviceName: "unattended-upgrades",
|
|
256
|
+
configFiles: [
|
|
257
|
+
"/etc/apt/apt.conf.d/20auto-upgrades",
|
|
258
|
+
"/etc/apt/apt.conf.d/50unattended-upgrades",
|
|
259
|
+
],
|
|
260
|
+
installHint: "sudo apt install unattended-upgrades && sudo dpkg-reconfigure -plow unattended-upgrades",
|
|
261
|
+
};
|
|
262
|
+
case "rhel":
|
|
263
|
+
return {
|
|
264
|
+
supported: true,
|
|
265
|
+
packageName: "dnf-automatic",
|
|
266
|
+
checkInstalledCmd: ["rpm", "-q", "dnf-automatic"],
|
|
267
|
+
serviceName: "dnf-automatic.timer",
|
|
268
|
+
configFiles: ["/etc/dnf/automatic.conf"],
|
|
269
|
+
installHint: "sudo dnf install dnf-automatic && sudo systemctl enable --now dnf-automatic.timer",
|
|
270
|
+
};
|
|
271
|
+
case "suse":
|
|
272
|
+
return {
|
|
273
|
+
supported: true,
|
|
274
|
+
packageName: "yast2-online-update-configuration",
|
|
275
|
+
checkInstalledCmd: ["rpm", "-q", "yast2-online-update-configuration"],
|
|
276
|
+
serviceName: "yast-online-update.timer",
|
|
277
|
+
configFiles: ["/etc/zypp/zypp.conf"],
|
|
278
|
+
installHint: "sudo zypper install yast2-online-update-configuration",
|
|
279
|
+
};
|
|
280
|
+
case "arch":
|
|
281
|
+
return {
|
|
282
|
+
supported: false,
|
|
283
|
+
packageName: "",
|
|
284
|
+
checkInstalledCmd: ["echo", "No native auto-update on Arch"],
|
|
285
|
+
serviceName: "",
|
|
286
|
+
configFiles: [],
|
|
287
|
+
installHint: "Arch Linux does not support unattended upgrades natively. Consider a custom systemd timer with `pacman -Syu --noconfirm`.",
|
|
288
|
+
};
|
|
289
|
+
case "alpine":
|
|
290
|
+
return {
|
|
291
|
+
supported: false,
|
|
292
|
+
packageName: "",
|
|
293
|
+
checkInstalledCmd: ["echo", "No native auto-update on Alpine"],
|
|
294
|
+
serviceName: "",
|
|
295
|
+
configFiles: [],
|
|
296
|
+
installHint: "Alpine does not support unattended upgrades natively. Consider a cron job with `apk upgrade`.",
|
|
297
|
+
};
|
|
298
|
+
default:
|
|
299
|
+
return {
|
|
300
|
+
supported: false,
|
|
301
|
+
packageName: "",
|
|
302
|
+
checkInstalledCmd: ["echo", "Unknown distro"],
|
|
303
|
+
serviceName: "",
|
|
304
|
+
configFiles: [],
|
|
305
|
+
installHint: "Unknown distribution",
|
|
306
|
+
};
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
// ── Package query commands ───────────────────────────────────────────────────
|
|
310
|
+
function buildPackageQueryCommands(distro) {
|
|
311
|
+
switch (distro.family) {
|
|
312
|
+
case "debian":
|
|
313
|
+
return {
|
|
314
|
+
listInstalledCmd: ["dpkg", "--get-selections"],
|
|
315
|
+
queryPackageCmd: (pkg) => ["dpkg-query", "-W", "-f", "${Package}\t${Version}\t${Architecture}\n", pkg],
|
|
316
|
+
listUpgradableCmd: ["apt", "list", "--upgradable"],
|
|
317
|
+
showHeldCmd: ["apt-mark", "showhold"],
|
|
318
|
+
simulateUpgradeCmd: ["apt-get", "upgrade", "-s"],
|
|
319
|
+
changelogCmd: (pkg) => ["apt-get", "changelog", pkg],
|
|
320
|
+
policyCmd: (pkg) => ["apt-cache", "policy", pkg],
|
|
321
|
+
isInstalledCmd: (pkg) => ["dpkg", "-l", pkg],
|
|
322
|
+
listKernelsCmd: ["dpkg", "--list", "linux-image-*"],
|
|
323
|
+
autoRemoveCmd: ["apt", "--dry-run", "autoremove"],
|
|
324
|
+
};
|
|
325
|
+
case "rhel":
|
|
326
|
+
return {
|
|
327
|
+
listInstalledCmd: ["rpm", "-qa", "--queryformat", "%{NAME}\t%{VERSION}-%{RELEASE}\t%{ARCH}\n"],
|
|
328
|
+
queryPackageCmd: (pkg) => ["rpm", "-q", "--queryformat", "%{NAME}\t%{VERSION}-%{RELEASE}\t%{ARCH}\n", pkg],
|
|
329
|
+
listUpgradableCmd: [distro.packageManager === "dnf" ? "dnf" : "yum", "check-update"],
|
|
330
|
+
showHeldCmd: [distro.packageManager === "dnf" ? "dnf" : "yum", "versionlock", "list"],
|
|
331
|
+
simulateUpgradeCmd: [distro.packageManager === "dnf" ? "dnf" : "yum", "update", "--assumeno"],
|
|
332
|
+
changelogCmd: (pkg) => [distro.packageManager === "dnf" ? "dnf" : "yum", "changelog", pkg],
|
|
333
|
+
policyCmd: (pkg) => [distro.packageManager === "dnf" ? "dnf" : "yum", "info", pkg],
|
|
334
|
+
isInstalledCmd: (pkg) => ["rpm", "-q", pkg],
|
|
335
|
+
listKernelsCmd: ["rpm", "-qa", "kernel-*"],
|
|
336
|
+
autoRemoveCmd: [distro.packageManager === "dnf" ? "dnf" : "yum", "autoremove", "--assumeno"],
|
|
337
|
+
};
|
|
338
|
+
case "suse":
|
|
339
|
+
return {
|
|
340
|
+
listInstalledCmd: ["rpm", "-qa", "--queryformat", "%{NAME}\t%{VERSION}-%{RELEASE}\t%{ARCH}\n"],
|
|
341
|
+
queryPackageCmd: (pkg) => ["rpm", "-q", "--queryformat", "%{NAME}\t%{VERSION}-%{RELEASE}\t%{ARCH}\n", pkg],
|
|
342
|
+
listUpgradableCmd: ["zypper", "list-updates"],
|
|
343
|
+
showHeldCmd: ["zypper", "locks"],
|
|
344
|
+
simulateUpgradeCmd: ["zypper", "--dry-run", "update"],
|
|
345
|
+
changelogCmd: (pkg) => ["rpm", "-q", "--changelog", pkg],
|
|
346
|
+
policyCmd: (pkg) => ["zypper", "info", pkg],
|
|
347
|
+
isInstalledCmd: (pkg) => ["rpm", "-q", pkg],
|
|
348
|
+
listKernelsCmd: ["rpm", "-qa", "kernel-*"],
|
|
349
|
+
autoRemoveCmd: ["zypper", "--dry-run", "remove", "--clean-deps"],
|
|
350
|
+
};
|
|
351
|
+
case "arch":
|
|
352
|
+
return {
|
|
353
|
+
listInstalledCmd: ["pacman", "-Q"],
|
|
354
|
+
queryPackageCmd: (pkg) => ["pacman", "-Qi", pkg],
|
|
355
|
+
listUpgradableCmd: ["pacman", "-Qu"],
|
|
356
|
+
showHeldCmd: ["grep", "IgnorePkg", "/etc/pacman.conf"],
|
|
357
|
+
simulateUpgradeCmd: ["pacman", "-Syu", "--print"],
|
|
358
|
+
changelogCmd: (pkg) => ["pacman", "-Qc", pkg],
|
|
359
|
+
policyCmd: (pkg) => ["pacman", "-Si", pkg],
|
|
360
|
+
isInstalledCmd: (pkg) => ["pacman", "-Q", pkg],
|
|
361
|
+
listKernelsCmd: ["pacman", "-Q", "linux"],
|
|
362
|
+
autoRemoveCmd: ["pacman", "-Qdtq"],
|
|
363
|
+
};
|
|
364
|
+
case "alpine":
|
|
365
|
+
return {
|
|
366
|
+
listInstalledCmd: ["apk", "info", "-v"],
|
|
367
|
+
queryPackageCmd: (pkg) => ["apk", "info", pkg],
|
|
368
|
+
listUpgradableCmd: ["apk", "version", "-l", "<"],
|
|
369
|
+
showHeldCmd: ["apk", "list", "--locked"],
|
|
370
|
+
simulateUpgradeCmd: ["apk", "upgrade", "--simulate"],
|
|
371
|
+
changelogCmd: (pkg) => ["apk", "info", "-d", pkg],
|
|
372
|
+
policyCmd: (pkg) => ["apk", "policy", pkg],
|
|
373
|
+
isInstalledCmd: (pkg) => ["apk", "info", "-e", pkg],
|
|
374
|
+
listKernelsCmd: ["apk", "info", "linux-*"],
|
|
375
|
+
autoRemoveCmd: ["echo", "Not applicable on Alpine"],
|
|
376
|
+
};
|
|
377
|
+
default:
|
|
378
|
+
return {
|
|
379
|
+
listInstalledCmd: ["echo", "Unknown package manager"],
|
|
380
|
+
queryPackageCmd: () => ["echo", "Unknown"],
|
|
381
|
+
listUpgradableCmd: ["echo", "Unknown"],
|
|
382
|
+
showHeldCmd: ["echo", "Unknown"],
|
|
383
|
+
simulateUpgradeCmd: ["echo", "Unknown"],
|
|
384
|
+
changelogCmd: () => ["echo", "Unknown"],
|
|
385
|
+
policyCmd: () => ["echo", "Unknown"],
|
|
386
|
+
isInstalledCmd: () => ["echo", "Unknown"],
|
|
387
|
+
listKernelsCmd: ["echo", "Unknown"],
|
|
388
|
+
autoRemoveCmd: ["echo", "Unknown"],
|
|
389
|
+
};
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
// ── Firewall persistence config ──────────────────────────────────────────────
|
|
393
|
+
function buildFirewallPersistenceConfig(distro) {
|
|
394
|
+
switch (distro.family) {
|
|
395
|
+
case "debian":
|
|
396
|
+
return {
|
|
397
|
+
packageName: "iptables-persistent",
|
|
398
|
+
checkInstalledCmd: ["dpkg", "-l", "iptables-persistent"],
|
|
399
|
+
installCmd: ["DEBIAN_FRONTEND=noninteractive", "apt-get", "install", "-y", "iptables-persistent"],
|
|
400
|
+
serviceName: "netfilter-persistent",
|
|
401
|
+
enableCmd: ["systemctl", "enable", "netfilter-persistent"],
|
|
402
|
+
saveCmd: ["netfilter-persistent", "save"],
|
|
403
|
+
uninstallHint: "sudo apt-get remove -y iptables-persistent",
|
|
404
|
+
};
|
|
405
|
+
case "rhel":
|
|
406
|
+
return {
|
|
407
|
+
packageName: "iptables-services",
|
|
408
|
+
checkInstalledCmd: ["rpm", "-q", "iptables-services"],
|
|
409
|
+
installCmd: [distro.packageManager === "dnf" ? "dnf" : "yum", "install", "-y", "iptables-services"],
|
|
410
|
+
serviceName: "iptables",
|
|
411
|
+
enableCmd: ["systemctl", "enable", "iptables"],
|
|
412
|
+
saveCmd: ["service", "iptables", "save"],
|
|
413
|
+
uninstallHint: `sudo ${distro.packageManager} remove -y iptables-services`,
|
|
414
|
+
};
|
|
415
|
+
case "suse":
|
|
416
|
+
return {
|
|
417
|
+
packageName: "iptables",
|
|
418
|
+
checkInstalledCmd: ["rpm", "-q", "iptables"],
|
|
419
|
+
installCmd: ["zypper", "install", "-y", "iptables"],
|
|
420
|
+
serviceName: "iptables",
|
|
421
|
+
enableCmd: ["systemctl", "enable", "iptables"],
|
|
422
|
+
saveCmd: ["iptables-save"],
|
|
423
|
+
uninstallHint: "sudo zypper remove -y iptables",
|
|
424
|
+
};
|
|
425
|
+
case "arch":
|
|
426
|
+
return {
|
|
427
|
+
packageName: "iptables",
|
|
428
|
+
checkInstalledCmd: ["pacman", "-Q", "iptables"],
|
|
429
|
+
installCmd: ["pacman", "-S", "--noconfirm", "iptables"],
|
|
430
|
+
serviceName: "iptables",
|
|
431
|
+
enableCmd: ["systemctl", "enable", "iptables"],
|
|
432
|
+
saveCmd: ["iptables-save"],
|
|
433
|
+
uninstallHint: "sudo pacman -R iptables",
|
|
434
|
+
};
|
|
435
|
+
case "alpine":
|
|
436
|
+
return {
|
|
437
|
+
packageName: "iptables",
|
|
438
|
+
checkInstalledCmd: ["apk", "info", "-e", "iptables"],
|
|
439
|
+
installCmd: ["apk", "add", "iptables"],
|
|
440
|
+
serviceName: "iptables",
|
|
441
|
+
enableCmd: ["rc-update", "add", "iptables", "default"],
|
|
442
|
+
saveCmd: ["/etc/init.d/iptables", "save"],
|
|
443
|
+
uninstallHint: "sudo apk del iptables",
|
|
444
|
+
};
|
|
445
|
+
default:
|
|
446
|
+
return {
|
|
447
|
+
packageName: "iptables-persistent",
|
|
448
|
+
checkInstalledCmd: ["echo", "Unknown"],
|
|
449
|
+
installCmd: ["echo", "Cannot install on unknown distro"],
|
|
450
|
+
serviceName: "",
|
|
451
|
+
enableCmd: ["echo", "Unknown"],
|
|
452
|
+
saveCmd: ["iptables-save"],
|
|
453
|
+
uninstallHint: "",
|
|
454
|
+
};
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
// ── Singleton cache ──────────────────────────────────────────────────────────
|
|
458
|
+
let cachedAdapter = null;
|
|
459
|
+
/**
|
|
460
|
+
* Returns the singleton DistroAdapter.
|
|
461
|
+
* On first call it detects the distribution and builds all adapters.
|
|
462
|
+
* Subsequent calls return the cached instance.
|
|
463
|
+
*/
|
|
464
|
+
export async function getDistroAdapter() {
|
|
465
|
+
if (cachedAdapter)
|
|
466
|
+
return cachedAdapter;
|
|
467
|
+
const distro = await detectDistro();
|
|
468
|
+
const pkg = getPackageManager(distro.packageManager);
|
|
469
|
+
const svc = getServiceManager(distro.initSystem);
|
|
470
|
+
const fw = await getFirewallBackend();
|
|
471
|
+
cachedAdapter = new DistroAdapter(distro, pkg, svc, fw);
|
|
472
|
+
console.error(`[distro-adapter] Initialized: ${cachedAdapter.summary}`);
|
|
473
|
+
return cachedAdapter;
|
|
474
|
+
}
|
|
475
|
+
/**
|
|
476
|
+
* Returns the cached adapter if already initialized, or null.
|
|
477
|
+
* Use when you can't await (synchronous contexts).
|
|
478
|
+
*/
|
|
479
|
+
export function getDistroAdapterSync() {
|
|
480
|
+
return cachedAdapter;
|
|
481
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Top-level operating system family.
|
|
3
|
+
* 'wsl' is reported when running inside Windows Subsystem for Linux.
|
|
4
|
+
*/
|
|
5
|
+
export type OsFamily = "linux" | "darwin" | "wsl";
|
|
6
|
+
/** Linux distribution family identifiers. */
|
|
7
|
+
export type DistroFamily = "debian" | "rhel" | "arch" | "alpine" | "suse" | "unknown";
|
|
8
|
+
export type SpecificDistro = "debian" | "ubuntu" | "kali" | "fedora" | "rhel" | "centos" | "arch" | "alpine" | "opensuse" | "macos" | "unknown";
|
|
9
|
+
/** Package manager identifiers (extended with brew). */
|
|
10
|
+
export type PackageManagerName = "apt" | "dnf" | "yum" | "pacman" | "brew" | "apk" | "zypper" | "unknown";
|
|
11
|
+
/** @deprecated Use PackageManagerName. Kept for backwards compatibility. */
|
|
12
|
+
export type PackageManager = PackageManagerName;
|
|
13
|
+
export type InitSystem = "systemd" | "openrc" | "launchd" | "sysvinit" | "unknown";
|
|
14
|
+
export interface PackageManagerCommands {
|
|
15
|
+
installCmd(pkg: string): string[];
|
|
16
|
+
removeCmd(pkg: string): string[];
|
|
17
|
+
updateCmd(): string[];
|
|
18
|
+
searchCmd(term: string): string[];
|
|
19
|
+
listInstalledCmd(): string[];
|
|
20
|
+
}
|
|
21
|
+
export interface ServiceManagerCommands {
|
|
22
|
+
startCmd(svc: string): string[];
|
|
23
|
+
stopCmd(svc: string): string[];
|
|
24
|
+
enableCmd(svc: string): string[];
|
|
25
|
+
disableCmd(svc: string): string[];
|
|
26
|
+
statusCmd(svc: string): string[];
|
|
27
|
+
listServicesCmd(): string[];
|
|
28
|
+
}
|
|
29
|
+
export type FirewallBackendName = "iptables" | "nftables" | "ufw" | "firewalld" | "pf" | "unknown";
|
|
30
|
+
export interface FirewallBackendCommands {
|
|
31
|
+
readonly name: FirewallBackendName;
|
|
32
|
+
allowCmd(port: number, proto?: string): string[];
|
|
33
|
+
denyCmd(port: number, proto?: string): string[];
|
|
34
|
+
listCmd(): string[];
|
|
35
|
+
flushCmd(): string[];
|
|
36
|
+
}
|
|
37
|
+
export interface DistroInfo {
|
|
38
|
+
id: string;
|
|
39
|
+
name: string;
|
|
40
|
+
version: string;
|
|
41
|
+
osFamily: OsFamily;
|
|
42
|
+
specificDistro: SpecificDistro;
|
|
43
|
+
family: DistroFamily;
|
|
44
|
+
packageManager: PackageManagerName;
|
|
45
|
+
initSystem: InitSystem;
|
|
46
|
+
hasFirewalld: boolean;
|
|
47
|
+
hasUfw: boolean;
|
|
48
|
+
hasSelinux: boolean;
|
|
49
|
+
hasApparmor: boolean;
|
|
50
|
+
}
|
|
51
|
+
export declare function detectDistro(): Promise<DistroInfo>;
|
|
52
|
+
export declare function getPackageManager(nameOrDistro?: string): PackageManagerCommands;
|
|
53
|
+
export declare function getServiceManager(initSystem?: InitSystem): ServiceManagerCommands;
|
|
54
|
+
export declare function getFirewallBackend(): Promise<FirewallBackendCommands>;
|
|
55
|
+
export declare function canUseAppArmor(): Promise<boolean>;
|
|
56
|
+
export declare function canUseSELinux(): Promise<boolean>;
|
|
57
|
+
export declare function canUseAuditd(): Promise<boolean>;
|
|
58
|
+
export declare function canUseSystemd(): Promise<boolean>;
|
|
59
|
+
export declare function canUseIPTables(): Promise<boolean>;
|
|
60
|
+
export declare function canUseNFTables(): Promise<boolean>;
|
|
61
|
+
export declare function canUseBPF(): Promise<boolean>;
|
|
62
|
+
export declare function hasTPM(): Promise<boolean>;
|
|
63
|
+
export declare function hasSecureBoot(): Promise<boolean>;
|
|
64
|
+
/** @deprecated Prefer getPackageManager(pkgManager).installCmd(pkg) */
|
|
65
|
+
export declare function getInstallCommand(pkgManager: PackageManagerName, pkg: string): string[];
|
|
66
|
+
/** @deprecated Prefer getPackageManager(pkgManager).updateCmd() */
|
|
67
|
+
export declare function getUpdateCommand(pkgManager: PackageManagerName): string[];
|
|
68
|
+
//# sourceMappingURL=distro.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"distro.d.ts","sourceRoot":"","sources":["../../src/core/distro.ts"],"names":[],"mappings":"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"}
|