kastell 2.2.3 → 2.2.5
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/.claude-plugin/marketplace.json +18 -18
- package/.claude-plugin/plugin.json +45 -39
- package/CHANGELOG.md +1294 -1266
- package/LICENSE +201 -201
- package/NOTICE +5 -5
- package/README.md +1 -1
- package/README.tr.md +1 -1
- package/bin/kastell +2 -2
- package/bin/kastell-mcp +5 -5
- package/dist/adapters/coolify.js +92 -92
- package/dist/adapters/dokploy.js +99 -99
- package/dist/core/audit/formatters/badge.js +20 -20
- package/dist/core/completions.js +631 -631
- package/dist/mcp/server.d.ts.map +1 -1
- package/dist/mcp/server.js +25 -31
- package/dist/mcp/server.js.map +1 -1
- package/dist/mcp/tools/serverExplain.d.ts.map +1 -1
- package/dist/mcp/tools/serverExplain.js.map +1 -1
- package/dist/mcp/tools/serverFleet.d.ts.map +1 -1
- package/dist/mcp/tools/serverFleet.js.map +1 -1
- package/dist/mcp/tools/serverInfo.d.ts +1 -1
- package/dist/mcp/tools/serverInfo.js +1 -1
- package/dist/mcp/tools/serverPlugin.d.ts.map +1 -1
- package/dist/mcp/tools/serverPlugin.js.map +1 -1
- package/dist/mcp-bundle.mjs +101015 -0
- package/dist/utils/cloudInit.js +58 -58
- package/dist/utils/version.d.ts.map +1 -1
- package/dist/utils/version.js +19 -4
- package/dist/utils/version.js.map +1 -1
- package/kastell-plugin/.claude-plugin/plugin.json +20 -20
- package/kastell-plugin/.mcp.json +15 -8
- package/kastell-plugin/README.md +113 -113
- package/kastell-plugin/agents/kastell-auditor.md +77 -77
- package/kastell-plugin/agents/scripts/bucket_mapper.sh +101 -101
- package/kastell-plugin/agents/scripts/trend_report.sh +91 -91
- package/kastell-plugin/hooks/destroy-block.cjs +31 -31
- package/kastell-plugin/hooks/hooks.json +57 -57
- package/kastell-plugin/hooks/pre-commit-audit-guard.cjs +75 -75
- package/kastell-plugin/hooks/session-audit.cjs +86 -86
- package/kastell-plugin/hooks/session-log.cjs +56 -56
- package/kastell-plugin/hooks/stop-quality-check.cjs +72 -72
- package/kastell-plugin/skills/kastell-careful/SKILL.md +64 -64
- package/kastell-plugin/skills/kastell-ops/SKILL.md +139 -139
- package/kastell-plugin/skills/kastell-ops/references/commands.md +45 -45
- package/kastell-plugin/skills/kastell-ops/references/mcp-tools.md +50 -50
- package/kastell-plugin/skills/kastell-ops/references/patterns.md +145 -145
- package/kastell-plugin/skills/kastell-ops/references/pitfalls.md +136 -136
- package/kastell-plugin/skills/kastell-ops/scripts/check_coverage.sh +101 -101
- package/kastell-plugin/skills/kastell-ops/scripts/fleet_report.sh +73 -73
- package/kastell-plugin/skills/kastell-ops/scripts/parse_audit.sh +76 -76
- package/kastell-plugin/skills/kastell-research/SKILL.md +90 -90
- package/kastell-plugin/skills/kastell-scaffold/SKILL.md +104 -104
- package/kastell-plugin/skills/kastell-scaffold/references/template-audit-check.md +150 -150
- package/kastell-plugin/skills/kastell-scaffold/references/template-command.md +80 -80
- package/kastell-plugin/skills/kastell-scaffold/references/template-mcp-tool.md +72 -72
- package/kastell-plugin/skills/kastell-scaffold/references/template-provider.md +67 -67
- package/kastell-plugin/skills/kastell-scaffold/scripts/scaffold.sh +180 -180
- package/kastell-plugin/skills/kastell-scaffold/templates/check-test.ts.tpl +27 -27
- package/kastell-plugin/skills/kastell-scaffold/templates/check.ts.tpl +50 -50
- package/kastell-plugin/skills/kastell-scaffold/templates/command-core.ts.tpl +18 -18
- package/kastell-plugin/skills/kastell-scaffold/templates/command-test.ts.tpl +17 -17
- package/kastell-plugin/skills/kastell-scaffold/templates/command.ts.tpl +25 -25
- package/kastell-plugin/skills/kastell-scaffold/templates/mcp-tool-test.ts.tpl +30 -30
- package/kastell-plugin/skills/kastell-scaffold/templates/mcp-tool.ts.tpl +29 -29
- package/kastell-plugin/skills/kastell-scaffold/templates/provider-test.ts.tpl +34 -34
- package/kastell-plugin/skills/kastell-scaffold/templates/provider.ts.tpl +32 -32
- package/package.json +125 -122
- package/dist/commands/interactive.d.ts +0 -11
- package/dist/commands/interactive.d.ts.map +0 -1
- package/dist/commands/interactive.js +0 -1079
- package/dist/commands/interactive.js.map +0 -1
- package/dist/core/lock.d.ts +0 -66
- package/dist/core/lock.d.ts.map +0 -1
- package/dist/core/lock.js +0 -556
- package/dist/core/lock.js.map +0 -1
package/dist/core/lock.js
DELETED
|
@@ -1,556 +0,0 @@
|
|
|
1
|
-
import { sshExec, assertValidIp } from "../utils/ssh.js";
|
|
2
|
-
import { buildHardeningCommand, buildFail2banCommand, buildKeyCheckCommand } from "./secure.js";
|
|
3
|
-
import { buildFirewallSetupCommand } from "./firewall.js";
|
|
4
|
-
import { runAudit } from "./audit/index.js";
|
|
5
|
-
import { raw } from "../utils/sshCommand.js";
|
|
6
|
-
import { LOCK_FIREWALL_TIMEOUT_MS, LOCK_UPGRADES_TIMEOUT_MS, LOCK_PACKAGES_TIMEOUT_MS, WEAK_CIPHERS, WEAK_MACS, WEAK_KEX } from "../constants.js";
|
|
7
|
-
import { getErrorMessage } from "../utils/errorMapper.js";
|
|
8
|
-
// ─── Command Builders ────────────────────────────────────────────────────────
|
|
9
|
-
export function buildSysctlHardeningCommand() {
|
|
10
|
-
const settings = [
|
|
11
|
-
// Existing baseline settings
|
|
12
|
-
"net.ipv4.conf.all.accept_redirects=0",
|
|
13
|
-
"net.ipv4.conf.default.accept_redirects=0",
|
|
14
|
-
"net.ipv4.conf.all.accept_source_route=0",
|
|
15
|
-
"net.ipv4.conf.default.accept_source_route=0",
|
|
16
|
-
"net.ipv4.conf.all.log_martians=1",
|
|
17
|
-
"net.ipv4.tcp_syncookies=1",
|
|
18
|
-
"kernel.randomize_va_space=2",
|
|
19
|
-
"net.ipv4.icmp_echo_ignore_broadcasts=1",
|
|
20
|
-
// Deep kernel hardening (CIS L2)
|
|
21
|
-
"kernel.dmesg_restrict=1",
|
|
22
|
-
"kernel.kptr_restrict=1",
|
|
23
|
-
"fs.suid_dumpable=0",
|
|
24
|
-
"net.core.bpf_jit_harden=1",
|
|
25
|
-
"kernel.unprivileged_bpf_disabled=1",
|
|
26
|
-
// Reverse path filter — loose mode (2) to not break Docker bridge networking
|
|
27
|
-
"net.ipv4.conf.all.rp_filter=2",
|
|
28
|
-
"net.ipv4.conf.default.rp_filter=2",
|
|
29
|
-
// Disable ICMP redirect sending
|
|
30
|
-
"net.ipv4.conf.all.send_redirects=0",
|
|
31
|
-
"net.ipv4.conf.default.send_redirects=0",
|
|
32
|
-
// Disable secure redirects
|
|
33
|
-
"net.ipv4.conf.all.secure_redirects=0",
|
|
34
|
-
"net.ipv4.conf.default.secure_redirects=0",
|
|
35
|
-
// IPv6 redirect hardening
|
|
36
|
-
"net.ipv6.conf.all.accept_redirects=0",
|
|
37
|
-
"net.ipv6.conf.default.accept_redirects=0",
|
|
38
|
-
].join("\\n");
|
|
39
|
-
return raw([
|
|
40
|
-
`printf '${settings}\\n' > /etc/sysctl.d/99-kastell.conf`,
|
|
41
|
-
"sysctl -p /etc/sysctl.d/99-kastell.conf 2>/dev/null || true",
|
|
42
|
-
].join(" && "));
|
|
43
|
-
}
|
|
44
|
-
export function buildUnattendedUpgradesCommand() {
|
|
45
|
-
const periodicConfig = [
|
|
46
|
-
'APT::Periodic::Update-Package-Lists "1";',
|
|
47
|
-
'APT::Periodic::Unattended-Upgrade "1";',
|
|
48
|
-
'APT::Periodic::AutocleanInterval "7";',
|
|
49
|
-
].join("\\n");
|
|
50
|
-
return raw([
|
|
51
|
-
"DEBIAN_FRONTEND=noninteractive apt-get install -y unattended-upgrades",
|
|
52
|
-
`printf '${periodicConfig}\\n' > /etc/apt/apt.conf.d/20auto-upgrades`,
|
|
53
|
-
].join(" && "));
|
|
54
|
-
}
|
|
55
|
-
export function buildLoginBannersCommand() {
|
|
56
|
-
const bannerText = "Authorized access only. All activity is monitored and logged.";
|
|
57
|
-
return raw([
|
|
58
|
-
`printf '${bannerText}\\n' > /etc/issue`,
|
|
59
|
-
`printf '${bannerText}\\n' > /etc/issue.net`,
|
|
60
|
-
`printf '${bannerText}\\n' > /etc/motd`,
|
|
61
|
-
`grep -qE '^Banner' /etc/ssh/sshd_config || echo 'Banner /etc/issue.net' >> /etc/ssh/sshd_config`,
|
|
62
|
-
"systemctl restart ssh 2>/dev/null || systemctl restart sshd",
|
|
63
|
-
].join(" && "));
|
|
64
|
-
}
|
|
65
|
-
export function buildAuditdCommand() {
|
|
66
|
-
// Deep rules go in 50-kastell-deep.rules (sorts BEFORE 99-kastell.rules -e 2 immutability)
|
|
67
|
-
const deepRules = [
|
|
68
|
-
"# Identity — file integrity",
|
|
69
|
-
"-w /etc/passwd -p wa -k identity",
|
|
70
|
-
"-w /etc/shadow -p wa -k identity",
|
|
71
|
-
"-w /etc/group -p wa -k identity",
|
|
72
|
-
"-w /etc/gshadow -p wa -k identity",
|
|
73
|
-
"# Privilege escalation",
|
|
74
|
-
"-w /etc/sudoers -p wa -k privilege",
|
|
75
|
-
"-w /etc/sudoers.d/ -p wa -k privilege",
|
|
76
|
-
"-a always,exit -F arch=b64 -S setuid -S setgid -S setreuid -S setregid -k privilege",
|
|
77
|
-
"# Time change",
|
|
78
|
-
"-a always,exit -F arch=b64 -S adjtimex -S settimeofday -S clock_settime -k time-change",
|
|
79
|
-
"-w /etc/localtime -p wa -k time-change",
|
|
80
|
-
"# Login and session",
|
|
81
|
-
"-w /var/log/lastlog -p wa -k logins",
|
|
82
|
-
"-w /var/run/faillock/ -p wa -k logins",
|
|
83
|
-
"-w /var/run/utmp -p wa -k session",
|
|
84
|
-
"-w /var/log/wtmp -p wa -k session",
|
|
85
|
-
"-w /var/log/btmp -p wa -k session",
|
|
86
|
-
"# Network changes",
|
|
87
|
-
"-a always,exit -F arch=b64 -S sethostname -S setdomainname -k network-change",
|
|
88
|
-
"-w /etc/hostname -p wa -k network-change",
|
|
89
|
-
"-w /etc/hosts -p wa -k network-change",
|
|
90
|
-
"-w /etc/sysconfig/network -p wa -k network-change",
|
|
91
|
-
"# Kernel modules",
|
|
92
|
-
"-a always,exit -F arch=b64 -S init_module -S delete_module -S finit_module -k kernel-module",
|
|
93
|
-
"-w /sbin/insmod -p x -k kernel-module",
|
|
94
|
-
"-w /sbin/modprobe -p x -k kernel-module",
|
|
95
|
-
"-w /sbin/rmmod -p x -k kernel-module",
|
|
96
|
-
].join("\\n");
|
|
97
|
-
// Immutability directive in 99 — sorts AFTER 50
|
|
98
|
-
const immutableRule = "-e 2";
|
|
99
|
-
return raw([
|
|
100
|
-
"DEBIAN_FRONTEND=noninteractive apt-get install -y auditd audispd-plugins",
|
|
101
|
-
"systemctl enable auditd && systemctl start auditd",
|
|
102
|
-
`printf '${deepRules}\\n' > /etc/audit/rules.d/50-kastell-deep.rules`,
|
|
103
|
-
`printf '${immutableRule}\\n' > /etc/audit/rules.d/99-kastell.rules`,
|
|
104
|
-
"augenrules --load 2>/dev/null || true",
|
|
105
|
-
"service auditd restart 2>/dev/null || systemctl restart auditd 2>/dev/null || true",
|
|
106
|
-
].join(" && "));
|
|
107
|
-
}
|
|
108
|
-
export function buildResourceLimitsCommand() {
|
|
109
|
-
const limitsContent = [
|
|
110
|
-
"* soft nproc 1024",
|
|
111
|
-
"* hard nproc 2048",
|
|
112
|
-
"* soft nofile 65536",
|
|
113
|
-
"* hard nofile 65536",
|
|
114
|
-
"root soft nproc unlimited",
|
|
115
|
-
"root hard nproc unlimited",
|
|
116
|
-
].join("\\n");
|
|
117
|
-
return raw(`printf '${limitsContent}\\n' > /etc/security/limits.d/99-kastell.conf`);
|
|
118
|
-
}
|
|
119
|
-
export function buildServiceDisableCommand() {
|
|
120
|
-
const services = ["bluetooth", "avahi-daemon", "cups", "rpcbind"];
|
|
121
|
-
const disableScript = services
|
|
122
|
-
.map((s) => `systemctl list-unit-files '${s}.service' 2>/dev/null | grep -q '${s}' && systemctl stop ${s} && systemctl disable ${s} 2>/dev/null || true`)
|
|
123
|
-
.join("; ");
|
|
124
|
-
return raw(disableScript);
|
|
125
|
-
}
|
|
126
|
-
export function buildAptValidationCommand() {
|
|
127
|
-
const aptConf = [
|
|
128
|
-
'APT::Get::AllowUnauthenticated "false";',
|
|
129
|
-
'Acquire::AllowInsecureRepositories "false";',
|
|
130
|
-
'Acquire::AllowDowngradeToInsecureRepositories "false";',
|
|
131
|
-
].join("\\n");
|
|
132
|
-
return raw(`printf '${aptConf}\\n' > /etc/apt/apt.conf.d/99-kastell-apt.conf`);
|
|
133
|
-
}
|
|
134
|
-
export function buildLogRetentionCommand() {
|
|
135
|
-
const logrotateConf = [
|
|
136
|
-
"/var/log/syslog",
|
|
137
|
-
"{",
|
|
138
|
-
" daily",
|
|
139
|
-
" missingok",
|
|
140
|
-
" rotate 90",
|
|
141
|
-
" compress",
|
|
142
|
-
" delaycompress",
|
|
143
|
-
" notifempty",
|
|
144
|
-
" postrotate",
|
|
145
|
-
" /usr/lib/rsyslog/rsyslog-rotate",
|
|
146
|
-
" endscript",
|
|
147
|
-
"}",
|
|
148
|
-
].join("\\n");
|
|
149
|
-
return raw([
|
|
150
|
-
"DEBIAN_FRONTEND=noninteractive apt-get install -y logrotate",
|
|
151
|
-
"systemctl enable rsyslog 2>/dev/null || true",
|
|
152
|
-
"systemctl start rsyslog 2>/dev/null || true",
|
|
153
|
-
`printf '${logrotateConf}\\n' > /etc/logrotate.d/99-kastell-syslog`,
|
|
154
|
-
"systemctl enable logrotate.timer 2>/dev/null || true",
|
|
155
|
-
].join(" && "));
|
|
156
|
-
}
|
|
157
|
-
export function buildCloudMetaBlockCommand() {
|
|
158
|
-
return raw([
|
|
159
|
-
"ufw deny out to 169.254.169.254",
|
|
160
|
-
"ufw deny in from 169.254.169.254",
|
|
161
|
-
].join(" && "));
|
|
162
|
-
}
|
|
163
|
-
export function buildAccountLockCommand() {
|
|
164
|
-
return raw([
|
|
165
|
-
"for user in $(awk -F: '($3 >= 1000 && $3 < 65534 && ($7 == \"/bin/bash\" || $7 == \"/bin/sh\")) {print $1}' /etc/passwd); do",
|
|
166
|
-
" if ! who | grep -q \"^$user \"; then",
|
|
167
|
-
" passwd -l $user 2>/dev/null || true",
|
|
168
|
-
" fi",
|
|
169
|
-
"done",
|
|
170
|
-
].join(" "));
|
|
171
|
-
}
|
|
172
|
-
export function buildAideInitCommand() {
|
|
173
|
-
const cronScript = "#!/bin/bash\\n/usr/sbin/aide --check 2>/dev/null || true";
|
|
174
|
-
return raw([
|
|
175
|
-
"DEBIAN_FRONTEND=noninteractive apt-get install -y aide",
|
|
176
|
-
"rm -f /etc/cron.d/kastell-aide",
|
|
177
|
-
`printf '${cronScript}\\n' > /etc/cron.daily/aide-check`,
|
|
178
|
-
"chmod 755 /etc/cron.daily/aide-check",
|
|
179
|
-
"nohup aide --init > /var/log/aide-init.log 2>&1 &",
|
|
180
|
-
].join(" && "));
|
|
181
|
-
}
|
|
182
|
-
export function buildCronAccessCommand() {
|
|
183
|
-
return raw([
|
|
184
|
-
"echo root > /etc/cron.allow",
|
|
185
|
-
"chmod 600 /etc/cron.allow",
|
|
186
|
-
"echo root > /etc/at.allow",
|
|
187
|
-
"chmod 600 /etc/at.allow",
|
|
188
|
-
"touch /etc/at.deny",
|
|
189
|
-
"chmod 600 /etc/at.deny",
|
|
190
|
-
].join(" && "));
|
|
191
|
-
}
|
|
192
|
-
export function buildBackupPermissionsCommand() {
|
|
193
|
-
return raw([
|
|
194
|
-
"DEBIAN_FRONTEND=noninteractive apt-get install -y rsync",
|
|
195
|
-
"mkdir -p /var/backups",
|
|
196
|
-
"chmod 700 /var/backups",
|
|
197
|
-
"chown root:root /var/backups",
|
|
198
|
-
].join(" && "));
|
|
199
|
-
}
|
|
200
|
-
export function buildDnsSecurityCommand() {
|
|
201
|
-
const dropinContent = ["[Resolve]", "DNSSEC=yes", "DNSOverTLS=opportunistic"].join("\\n");
|
|
202
|
-
return raw([
|
|
203
|
-
"cp /etc/systemd/resolved.conf /etc/systemd/resolved.conf.kastell.bak 2>/dev/null || true",
|
|
204
|
-
"mkdir -p /etc/systemd/resolved.conf.d",
|
|
205
|
-
`printf '${dropinContent}\\n' > /etc/systemd/resolved.conf.d/99-kastell-dns.conf`,
|
|
206
|
-
"systemctl restart systemd-resolved",
|
|
207
|
-
"dig google.com +timeout=5 +tries=1 @127.0.0.53 >/dev/null 2>&1",
|
|
208
|
-
].join(" && "));
|
|
209
|
-
}
|
|
210
|
-
export function buildDnsRollbackCommand() {
|
|
211
|
-
return raw([
|
|
212
|
-
"rm -f /etc/systemd/resolved.conf.d/99-kastell-dns.conf",
|
|
213
|
-
"systemctl restart systemd-resolved",
|
|
214
|
-
].join(" && "));
|
|
215
|
-
}
|
|
216
|
-
export function buildPwqualityCommand() {
|
|
217
|
-
const conf = [
|
|
218
|
-
"minlen = 14",
|
|
219
|
-
"dcredit = -1",
|
|
220
|
-
"ucredit = -1",
|
|
221
|
-
"lcredit = -1",
|
|
222
|
-
"ocredit = -1",
|
|
223
|
-
"maxrepeat = 3",
|
|
224
|
-
].join("\\n");
|
|
225
|
-
return raw([
|
|
226
|
-
"apt-cache show libpam-pwquality >/dev/null 2>&1 || { echo 'WARN: libpam-pwquality not available, skipping'; exit 0; }",
|
|
227
|
-
"DEBIAN_FRONTEND=noninteractive apt-get install -y libpam-pwquality",
|
|
228
|
-
`printf '${conf}\\n' > /etc/security/pwquality.conf`,
|
|
229
|
-
].join(" && "));
|
|
230
|
-
}
|
|
231
|
-
export function buildDockerHardeningCommand(platform) {
|
|
232
|
-
const isCoolify = platform === "coolify";
|
|
233
|
-
const isDokploy = platform === "dokploy";
|
|
234
|
-
const settings = {
|
|
235
|
-
"log-driver": "json-file",
|
|
236
|
-
"log-opts": { "max-size": "10m", "max-file": "3" },
|
|
237
|
-
"no-new-privileges": true,
|
|
238
|
-
};
|
|
239
|
-
if (!isDokploy) {
|
|
240
|
-
settings["live-restore"] = true;
|
|
241
|
-
}
|
|
242
|
-
if (!isCoolify && !isDokploy) {
|
|
243
|
-
settings["icc"] = false;
|
|
244
|
-
}
|
|
245
|
-
const hardeningJson = JSON.stringify(settings);
|
|
246
|
-
return raw([
|
|
247
|
-
"command -v jq >/dev/null 2>&1 || { echo 'WARN: jq not found, skipping Docker hardening'; exit 0; }",
|
|
248
|
-
"command -v docker >/dev/null 2>&1 || { echo 'WARN: Docker not installed, skipping Docker hardening'; exit 0; }",
|
|
249
|
-
"mkdir -p /etc/docker && ([ -f /etc/docker/daemon.json ] || echo '{}' > /etc/docker/daemon.json)",
|
|
250
|
-
"cp /etc/docker/daemon.json /etc/docker/daemon.json.bak-docker",
|
|
251
|
-
`printf '%s' '${hardeningJson}' | jq -s '.[0] * .[1]' /etc/docker/daemon.json - > /tmp/daemon-kastell.json`,
|
|
252
|
-
"jq -e . /tmp/daemon-kastell.json >/dev/null 2>&1 || { cp /etc/docker/daemon.json.bak-docker /etc/docker/daemon.json && echo 'daemon.json merge failed: rolled back' >&2 && exit 1; }",
|
|
253
|
-
"mv /tmp/daemon-kastell.json /etc/docker/daemon.json",
|
|
254
|
-
"systemctl reload docker 2>/dev/null || systemctl restart docker",
|
|
255
|
-
].join(" && "));
|
|
256
|
-
}
|
|
257
|
-
export function buildSshCipherCommand() {
|
|
258
|
-
const cipherBlacklist = WEAK_CIPHERS.map((c) => `-${c}`).join(",");
|
|
259
|
-
const macBlacklist = WEAK_MACS.map((m) => `-${m}`).join(",");
|
|
260
|
-
const kexBlacklist = WEAK_KEX.map((k) => `-${k}`).join(",");
|
|
261
|
-
return raw([
|
|
262
|
-
"cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak-cipher",
|
|
263
|
-
"sed -i '/^Ciphers[ \\t]/d; /^MACs[ \\t]/d; /^KexAlgorithms[ \\t]/d' /etc/ssh/sshd_config",
|
|
264
|
-
`printf '\\nCiphers ${cipherBlacklist}\\nMACs ${macBlacklist}\\nKexAlgorithms ${kexBlacklist}\\n' >> /etc/ssh/sshd_config`,
|
|
265
|
-
"if sshd -t; then systemctl restart sshd; else cp /etc/ssh/sshd_config.bak-cipher /etc/ssh/sshd_config && echo 'SSH cipher hardening rolled back: sshd -t failed' >&2 && exit 1; fi",
|
|
266
|
-
].join(" && "));
|
|
267
|
-
}
|
|
268
|
-
export function buildSshFineTuningCommand() {
|
|
269
|
-
const directives = [
|
|
270
|
-
["ClientAliveInterval", "300"],
|
|
271
|
-
["ClientAliveCountMax", "3"],
|
|
272
|
-
["LoginGraceTime", "60"],
|
|
273
|
-
["AllowAgentForwarding", "no"],
|
|
274
|
-
["X11Forwarding", "no"],
|
|
275
|
-
["MaxStartups", "10:30:60"],
|
|
276
|
-
["StrictModes", "yes"],
|
|
277
|
-
["PermitUserEnvironment", "no"],
|
|
278
|
-
["LogLevel", "VERBOSE"],
|
|
279
|
-
["UseDNS", "no"],
|
|
280
|
-
["PrintMotd", "no"],
|
|
281
|
-
["IgnoreRhosts", "yes"],
|
|
282
|
-
["HostbasedAuthentication", "no"],
|
|
283
|
-
["MaxSessions", "10"],
|
|
284
|
-
["PermitEmptyPasswords", "no"],
|
|
285
|
-
];
|
|
286
|
-
const sedLines = directives.map(([key, val]) => `grep -qE '^#?${key}' /etc/ssh/sshd_config && sed -i 's/^#\\?${key}.*/${key} ${val}/' /etc/ssh/sshd_config || echo '${key} ${val}' >> /etc/ssh/sshd_config`);
|
|
287
|
-
return raw([
|
|
288
|
-
"cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak-finetune",
|
|
289
|
-
...sedLines,
|
|
290
|
-
"if sshd -t; then systemctl restart sshd 2>/dev/null || systemctl restart ssh; else cp /etc/ssh/sshd_config.bak-finetune /etc/ssh/sshd_config && echo 'SSH fine-tuning rolled back' >&2 && exit 1; fi",
|
|
291
|
-
].join(" && "));
|
|
292
|
-
}
|
|
293
|
-
export function buildLoginDefsCommand() {
|
|
294
|
-
const entries = [
|
|
295
|
-
["PASS_MIN_DAYS", "1", "/etc/login.defs"],
|
|
296
|
-
["PASS_WARN_AGE", "7", "/etc/login.defs"],
|
|
297
|
-
["ENCRYPT_METHOD", "SHA512", "/etc/login.defs"],
|
|
298
|
-
["UMASK", "027", "/etc/login.defs"],
|
|
299
|
-
];
|
|
300
|
-
const lines = entries.map(([key, val, file]) => `grep -qE '^${key}' ${file} && sed -i 's/^${key}.*/${key} ${val}/' ${file} || echo '${key} ${val}' >> ${file}`);
|
|
301
|
-
const useradd = `grep -qE '^INACTIVE' /etc/default/useradd && sed -i 's/^INACTIVE.*/INACTIVE=30/' /etc/default/useradd || echo 'INACTIVE=30' >> /etc/default/useradd`;
|
|
302
|
-
return raw([...lines, useradd].join(" && "));
|
|
303
|
-
}
|
|
304
|
-
export function buildFaillockCommand() {
|
|
305
|
-
const directives = [
|
|
306
|
-
["deny", "5"],
|
|
307
|
-
["unlock_time", "900"],
|
|
308
|
-
["fail_interval", "900"],
|
|
309
|
-
];
|
|
310
|
-
const lines = directives.map(([key, val]) => `grep -qE '^${key}' /etc/security/faillock.conf 2>/dev/null && sed -i 's/^${key}.*/${key} = ${val}/' /etc/security/faillock.conf || echo '${key} = ${val}' >> /etc/security/faillock.conf`);
|
|
311
|
-
return raw([
|
|
312
|
-
"mkdir -p /etc/security",
|
|
313
|
-
...lines,
|
|
314
|
-
"pam-auth-update --enable faillock 2>/dev/null || true",
|
|
315
|
-
].join(" && "));
|
|
316
|
-
}
|
|
317
|
-
export function buildSudoHardeningCommand() {
|
|
318
|
-
return raw([
|
|
319
|
-
"mkdir -p /etc/sudoers.d",
|
|
320
|
-
`grep -qr 'log_output\\|syslog' /etc/sudoers /etc/sudoers.d/ 2>/dev/null || echo 'Defaults log_output' > /etc/sudoers.d/kastell-logging`,
|
|
321
|
-
"chmod 440 /etc/sudoers.d/kastell-logging 2>/dev/null || true",
|
|
322
|
-
`grep -qr 'requiretty' /etc/sudoers /etc/sudoers.d/ 2>/dev/null || echo 'Defaults requiretty' > /etc/sudoers.d/kastell-requiretty`,
|
|
323
|
-
"chmod 440 /etc/sudoers.d/kastell-requiretty 2>/dev/null || true",
|
|
324
|
-
].join(" && "));
|
|
325
|
-
}
|
|
326
|
-
// ─── Helper ──────────────────────────────────────────────────────────────────
|
|
327
|
-
async function runLockStep(ip, command, opts) {
|
|
328
|
-
try {
|
|
329
|
-
await sshExec(ip, command, opts);
|
|
330
|
-
return { ok: true };
|
|
331
|
-
}
|
|
332
|
-
catch (err) {
|
|
333
|
-
return { ok: false, error: getErrorMessage(err) };
|
|
334
|
-
}
|
|
335
|
-
}
|
|
336
|
-
// ─── Orchestrator ────────────────────────────────────────────────────────────
|
|
337
|
-
export async function applyLock(ip, name, platform, options) {
|
|
338
|
-
assertValidIp(ip);
|
|
339
|
-
const steps = {
|
|
340
|
-
sshHardening: false,
|
|
341
|
-
fail2ban: false,
|
|
342
|
-
banners: false,
|
|
343
|
-
accountLock: false,
|
|
344
|
-
sshCipher: false,
|
|
345
|
-
ufw: false,
|
|
346
|
-
cloudMeta: false,
|
|
347
|
-
dns: false,
|
|
348
|
-
sysctl: false,
|
|
349
|
-
unattendedUpgrades: false,
|
|
350
|
-
aptValidation: false,
|
|
351
|
-
resourceLimits: false,
|
|
352
|
-
serviceDisable: false,
|
|
353
|
-
backupPermissions: false,
|
|
354
|
-
pwquality: false,
|
|
355
|
-
dockerHardening: false,
|
|
356
|
-
auditd: false,
|
|
357
|
-
logRetention: false,
|
|
358
|
-
aide: false,
|
|
359
|
-
cronAccess: false,
|
|
360
|
-
sshFineTuning: false,
|
|
361
|
-
loginDefs: false,
|
|
362
|
-
faillock: false,
|
|
363
|
-
sudoHardening: false,
|
|
364
|
-
};
|
|
365
|
-
const stepErrors = {};
|
|
366
|
-
// Dry run: preview only, no SSH
|
|
367
|
-
if (options.dryRun) {
|
|
368
|
-
return {
|
|
369
|
-
success: true,
|
|
370
|
-
steps,
|
|
371
|
-
};
|
|
372
|
-
}
|
|
373
|
-
const auditPlatform = platform ?? "bare";
|
|
374
|
-
// Pre-audit (non-fatal)
|
|
375
|
-
let scoreBefore;
|
|
376
|
-
try {
|
|
377
|
-
const preAudit = await runAudit(ip, name, auditPlatform);
|
|
378
|
-
if (preAudit.success && preAudit.data) {
|
|
379
|
-
scoreBefore = preAudit.data.overallScore;
|
|
380
|
-
}
|
|
381
|
-
}
|
|
382
|
-
catch {
|
|
383
|
-
// Non-fatal — continue without score
|
|
384
|
-
}
|
|
385
|
-
// Step 0: SSH key check — abort if no keys
|
|
386
|
-
try {
|
|
387
|
-
const keyResult = await sshExec(ip, buildKeyCheckCommand());
|
|
388
|
-
const keyCount = parseInt(keyResult.stdout.trim(), 10);
|
|
389
|
-
if (isNaN(keyCount) || keyCount === 0) {
|
|
390
|
-
return {
|
|
391
|
-
success: false,
|
|
392
|
-
steps,
|
|
393
|
-
error: "No SSH keys found in /root/.ssh/authorized_keys. Cannot disable password authentication without SSH keys — this would permanently lock you out.",
|
|
394
|
-
hint: `Add an SSH key first: ssh-copy-id root@${ip}`,
|
|
395
|
-
};
|
|
396
|
-
}
|
|
397
|
-
}
|
|
398
|
-
catch (err) {
|
|
399
|
-
return {
|
|
400
|
-
success: false,
|
|
401
|
-
steps,
|
|
402
|
-
error: `SSH key check failed: ${getErrorMessage(err)}`,
|
|
403
|
-
};
|
|
404
|
-
}
|
|
405
|
-
// ── Group 1: SSH & Auth ──────────────────────────────────────────────────
|
|
406
|
-
// Step 1: SSH hardening (critical — determines overall success)
|
|
407
|
-
const sshResult = await runLockStep(ip, buildHardeningCommand());
|
|
408
|
-
steps.sshHardening = sshResult.ok;
|
|
409
|
-
if (!sshResult.ok)
|
|
410
|
-
stepErrors.sshHardening = sshResult.error;
|
|
411
|
-
// Step 2: fail2ban
|
|
412
|
-
const fail2banResult = await runLockStep(ip, buildFail2banCommand());
|
|
413
|
-
steps.fail2ban = fail2banResult.ok;
|
|
414
|
-
if (!fail2banResult.ok)
|
|
415
|
-
stepErrors.fail2ban = fail2banResult.error;
|
|
416
|
-
// Step 3: Login banners
|
|
417
|
-
const bannersResult = await runLockStep(ip, buildLoginBannersCommand());
|
|
418
|
-
steps.banners = bannersResult.ok;
|
|
419
|
-
if (!bannersResult.ok)
|
|
420
|
-
stepErrors.banners = bannersResult.error;
|
|
421
|
-
// Step 4: Account locking
|
|
422
|
-
const accountLockResult = await runLockStep(ip, buildAccountLockCommand());
|
|
423
|
-
steps.accountLock = accountLockResult.ok;
|
|
424
|
-
if (!accountLockResult.ok)
|
|
425
|
-
stepErrors.accountLock = accountLockResult.error;
|
|
426
|
-
// Step 5: SSH cipher hardening — with sshd -t rollback
|
|
427
|
-
const sshCipherResult = await runLockStep(ip, buildSshCipherCommand());
|
|
428
|
-
steps.sshCipher = sshCipherResult.ok;
|
|
429
|
-
if (!sshCipherResult.ok)
|
|
430
|
-
stepErrors.sshCipher = sshCipherResult.error;
|
|
431
|
-
// ── Group 2: Firewall & Network ──────────────────────────────────────────
|
|
432
|
-
// Step 6: UFW firewall, 60s timeout for apt
|
|
433
|
-
const ufwResult = await runLockStep(ip, buildFirewallSetupCommand(platform), { timeoutMs: LOCK_FIREWALL_TIMEOUT_MS });
|
|
434
|
-
steps.ufw = ufwResult.ok;
|
|
435
|
-
if (!ufwResult.ok)
|
|
436
|
-
stepErrors.ufw = ufwResult.error;
|
|
437
|
-
// Step 7: Cloud metadata — conditional on UFW
|
|
438
|
-
if (steps.ufw) {
|
|
439
|
-
const cloudMetaResult = await runLockStep(ip, buildCloudMetaBlockCommand());
|
|
440
|
-
steps.cloudMeta = cloudMetaResult.ok;
|
|
441
|
-
if (!cloudMetaResult.ok)
|
|
442
|
-
stepErrors.cloudMeta = cloudMetaResult.error;
|
|
443
|
-
}
|
|
444
|
-
else {
|
|
445
|
-
stepErrors.cloudMeta = "UFW required";
|
|
446
|
-
}
|
|
447
|
-
// Step 8: DNS security — with rollback on failure
|
|
448
|
-
const dnsResult = await runLockStep(ip, buildDnsSecurityCommand(), { timeoutMs: 15_000 });
|
|
449
|
-
steps.dns = dnsResult.ok;
|
|
450
|
-
if (!dnsResult.ok) {
|
|
451
|
-
stepErrors.dns = dnsResult.error;
|
|
452
|
-
await runLockStep(ip, buildDnsRollbackCommand());
|
|
453
|
-
}
|
|
454
|
-
// ── Group 3: System ──────────────────────────────────────────────────────
|
|
455
|
-
// Step 9: sysctl hardening
|
|
456
|
-
const sysctlResult = await runLockStep(ip, buildSysctlHardeningCommand());
|
|
457
|
-
steps.sysctl = sysctlResult.ok;
|
|
458
|
-
if (!sysctlResult.ok)
|
|
459
|
-
stepErrors.sysctl = sysctlResult.error;
|
|
460
|
-
// Step 10: unattended-upgrades, 120s timeout for apt
|
|
461
|
-
const upgradesResult = await runLockStep(ip, buildUnattendedUpgradesCommand(), { timeoutMs: LOCK_UPGRADES_TIMEOUT_MS });
|
|
462
|
-
steps.unattendedUpgrades = upgradesResult.ok;
|
|
463
|
-
if (!upgradesResult.ok)
|
|
464
|
-
stepErrors.unattendedUpgrades = upgradesResult.error;
|
|
465
|
-
// Step 11: APT validation
|
|
466
|
-
const aptResult = await runLockStep(ip, buildAptValidationCommand());
|
|
467
|
-
steps.aptValidation = aptResult.ok;
|
|
468
|
-
if (!aptResult.ok)
|
|
469
|
-
stepErrors.aptValidation = aptResult.error;
|
|
470
|
-
// Step 12: Resource limits
|
|
471
|
-
const limitsResult = await runLockStep(ip, buildResourceLimitsCommand());
|
|
472
|
-
steps.resourceLimits = limitsResult.ok;
|
|
473
|
-
if (!limitsResult.ok)
|
|
474
|
-
stepErrors.resourceLimits = limitsResult.error;
|
|
475
|
-
// Step 13: Service disabling
|
|
476
|
-
const serviceResult = await runLockStep(ip, buildServiceDisableCommand());
|
|
477
|
-
steps.serviceDisable = serviceResult.ok;
|
|
478
|
-
if (!serviceResult.ok)
|
|
479
|
-
stepErrors.serviceDisable = serviceResult.error;
|
|
480
|
-
// Step 14: Backup permissions
|
|
481
|
-
const backupResult = await runLockStep(ip, buildBackupPermissionsCommand(), { timeoutMs: LOCK_PACKAGES_TIMEOUT_MS });
|
|
482
|
-
steps.backupPermissions = backupResult.ok;
|
|
483
|
-
if (!backupResult.ok)
|
|
484
|
-
stepErrors.backupPermissions = backupResult.error;
|
|
485
|
-
// Step 15: Password quality policy
|
|
486
|
-
const pwqualityResult = await runLockStep(ip, buildPwqualityCommand(), { timeoutMs: LOCK_PACKAGES_TIMEOUT_MS });
|
|
487
|
-
steps.pwquality = pwqualityResult.ok;
|
|
488
|
-
if (!pwqualityResult.ok)
|
|
489
|
-
stepErrors.pwquality = pwqualityResult.error;
|
|
490
|
-
// Step 16: Docker runtime hardening
|
|
491
|
-
const dockerResult = await runLockStep(ip, buildDockerHardeningCommand(platform), { timeoutMs: LOCK_PACKAGES_TIMEOUT_MS });
|
|
492
|
-
steps.dockerHardening = dockerResult.ok;
|
|
493
|
-
if (!dockerResult.ok)
|
|
494
|
-
stepErrors.dockerHardening = dockerResult.error;
|
|
495
|
-
// ── Group 4: Monitoring ──────────────────────────────────────────────────
|
|
496
|
-
// Step 17: auditd
|
|
497
|
-
const auditdResult = await runLockStep(ip, buildAuditdCommand(), { timeoutMs: LOCK_PACKAGES_TIMEOUT_MS });
|
|
498
|
-
steps.auditd = auditdResult.ok;
|
|
499
|
-
if (!auditdResult.ok)
|
|
500
|
-
stepErrors.auditd = auditdResult.error;
|
|
501
|
-
// Step 18: Log retention
|
|
502
|
-
const logResult = await runLockStep(ip, buildLogRetentionCommand());
|
|
503
|
-
steps.logRetention = logResult.ok;
|
|
504
|
-
if (!logResult.ok)
|
|
505
|
-
stepErrors.logRetention = logResult.error;
|
|
506
|
-
// Step 19: AIDE (fire-and-forget)
|
|
507
|
-
const aideResult = await runLockStep(ip, buildAideInitCommand(), { timeoutMs: LOCK_PACKAGES_TIMEOUT_MS });
|
|
508
|
-
steps.aide = aideResult.ok;
|
|
509
|
-
if (!aideResult.ok)
|
|
510
|
-
stepErrors.aide = aideResult.error;
|
|
511
|
-
// Step 20: Cron access control
|
|
512
|
-
const cronAccessResult = await runLockStep(ip, buildCronAccessCommand());
|
|
513
|
-
steps.cronAccess = cronAccessResult.ok;
|
|
514
|
-
if (!cronAccessResult.ok)
|
|
515
|
-
stepErrors.cronAccess = cronAccessResult.error;
|
|
516
|
-
// ── Group 5: Score Boost (P87) ─────────────────────────────────────────────
|
|
517
|
-
// Step 21: SSH fine-tuning — with sshd -t rollback
|
|
518
|
-
const sshFineTuneResult = await runLockStep(ip, buildSshFineTuningCommand());
|
|
519
|
-
steps.sshFineTuning = sshFineTuneResult.ok;
|
|
520
|
-
if (!sshFineTuneResult.ok)
|
|
521
|
-
stepErrors.sshFineTuning = sshFineTuneResult.error;
|
|
522
|
-
// Step 22: Login definitions
|
|
523
|
-
const loginDefsResult = await runLockStep(ip, buildLoginDefsCommand());
|
|
524
|
-
steps.loginDefs = loginDefsResult.ok;
|
|
525
|
-
if (!loginDefsResult.ok)
|
|
526
|
-
stepErrors.loginDefs = loginDefsResult.error;
|
|
527
|
-
// Step 23: Faillock
|
|
528
|
-
const faillockResult = await runLockStep(ip, buildFaillockCommand());
|
|
529
|
-
steps.faillock = faillockResult.ok;
|
|
530
|
-
if (!faillockResult.ok)
|
|
531
|
-
stepErrors.faillock = faillockResult.error;
|
|
532
|
-
// Step 24: Sudo hardening
|
|
533
|
-
const sudoHardeningResult = await runLockStep(ip, buildSudoHardeningCommand());
|
|
534
|
-
steps.sudoHardening = sudoHardeningResult.ok;
|
|
535
|
-
if (!sudoHardeningResult.ok)
|
|
536
|
-
stepErrors.sudoHardening = sudoHardeningResult.error;
|
|
537
|
-
// Post-audit (non-fatal)
|
|
538
|
-
let scoreAfter;
|
|
539
|
-
try {
|
|
540
|
-
const postAudit = await runAudit(ip, name, auditPlatform);
|
|
541
|
-
if (postAudit.success && postAudit.data) {
|
|
542
|
-
scoreAfter = postAudit.data.overallScore;
|
|
543
|
-
}
|
|
544
|
-
}
|
|
545
|
-
catch {
|
|
546
|
-
// Non-fatal
|
|
547
|
-
}
|
|
548
|
-
return {
|
|
549
|
-
success: steps.sshHardening,
|
|
550
|
-
steps,
|
|
551
|
-
...(Object.keys(stepErrors).length > 0 && { stepErrors }),
|
|
552
|
-
scoreBefore,
|
|
553
|
-
scoreAfter,
|
|
554
|
-
};
|
|
555
|
-
}
|
|
556
|
-
//# sourceMappingURL=lock.js.map
|
package/dist/core/lock.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"lock.js","sourceRoot":"","sources":["../../src/core/lock.ts"],"names":[],"mappings":"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"}
|