quicklify 0.6.0 โ 0.7.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/README.md +53 -9
- package/dist/commands/domain.d.ts +13 -0
- package/dist/commands/domain.d.ts.map +1 -0
- package/dist/commands/domain.js +218 -0
- package/dist/commands/domain.js.map +1 -0
- package/dist/commands/firewall.d.ts +15 -0
- package/dist/commands/firewall.d.ts.map +1 -0
- package/dist/commands/firewall.js +259 -0
- package/dist/commands/firewall.js.map +1 -0
- package/dist/commands/secure.d.ts +14 -0
- package/dist/commands/secure.d.ts.map +1 -0
- package/dist/commands/secure.js +294 -0
- package/dist/commands/secure.js.map +1 -0
- package/dist/index.js +23 -0
- package/dist/index.js.map +1 -1
- package/dist/types/index.d.ts +25 -0
- package/dist/types/index.d.ts.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -54,6 +54,10 @@ npx quicklify init
|
|
|
54
54
|
- ๐ **Log Viewer** - View Coolify, Docker, or system logs with follow mode
|
|
55
55
|
- ๐ฉบ **Environment Doctor** - Diagnose local setup issues
|
|
56
56
|
- ๐ซ **Bulk Health Check** - Check all servers at once
|
|
57
|
+
- ๐ฅ **Firewall Management** - UFW setup, add/remove ports, protected port safety
|
|
58
|
+
- ๐ **Domain Management** - Bind domains, DNS check, auto SSL via Coolify
|
|
59
|
+
- ๐ก๏ธ **SSH Hardening** - Disable password auth, fail2ban, security audit with score
|
|
60
|
+
- ๐งช **Dry-Run Mode** - Preview commands on firewall/domain/secure before executing
|
|
57
61
|
- ๐ค **Non-Interactive Mode** - CI/CD friendly with `--provider --token --region --size --name` flags
|
|
58
62
|
|
|
59
63
|
## ๐ฆ Installation
|
|
@@ -120,12 +124,12 @@ Visit the URL, create your admin account, and start deploying!
|
|
|
120
124
|
**Important:** Port 8000 is publicly accessible after deployment.
|
|
121
125
|
|
|
122
126
|
**Recommended next steps:**
|
|
123
|
-
1. **
|
|
124
|
-
2.
|
|
125
|
-
3.
|
|
126
|
-
4.
|
|
127
|
-
|
|
128
|
-
|
|
127
|
+
1. **Setup firewall:** `quicklify firewall setup my-server`
|
|
128
|
+
2. **Add a domain:** `quicklify domain add my-server --domain example.com`
|
|
129
|
+
3. **Harden SSH:** `quicklify secure setup my-server`
|
|
130
|
+
4. **Run security audit:** `quicklify secure audit my-server`
|
|
131
|
+
5. Set a **strong password** on first login
|
|
132
|
+
6. Consider **Cloudflare** for DDoS protection
|
|
129
133
|
|
|
130
134
|
## ๐ Supported Providers
|
|
131
135
|
|
|
@@ -166,6 +170,14 @@ For production use, we recommend setting up a domain instead of using the IP add
|
|
|
166
170
|
|
|
167
171
|
## ๐ Recent Updates
|
|
168
172
|
|
|
173
|
+
### v0.7.0 (2026-02-20)
|
|
174
|
+
- **New commands:** `quicklify firewall`, `quicklify domain`, `quicklify secure`
|
|
175
|
+
- **Firewall management:** UFW setup, add/remove ports, protected port 22 safety, Coolify port warnings
|
|
176
|
+
- **Domain management:** Bind domains to Coolify, DNS A record check, auto SSL
|
|
177
|
+
- **SSH hardening:** Disable password auth, key-only root login, fail2ban, security audit with 0-4 score
|
|
178
|
+
- **Dry-run mode:** `--dry-run` flag previews all commands without executing
|
|
179
|
+
- Zero new dependencies, 494 tests with 97%+ statement coverage
|
|
180
|
+
|
|
169
181
|
### v0.6.0 (2026-02-20)
|
|
170
182
|
- **New commands:** `quicklify logs`, `quicklify monitor`, `quicklify health`, `quicklify doctor`
|
|
171
183
|
- **Log viewer:** View Coolify/Docker/system logs with `--follow` real-time streaming
|
|
@@ -258,13 +270,18 @@ For production use, we recommend setting up a domain instead of using the IP add
|
|
|
258
270
|
- [x] Environment diagnostics (`quicklify doctor`)
|
|
259
271
|
- [x] SSH streaming for real-time log following
|
|
260
272
|
|
|
273
|
+
### v0.7.0 (Completed)
|
|
274
|
+
|
|
275
|
+
- [x] Firewall management - UFW setup, add/remove ports (`quicklify firewall`)
|
|
276
|
+
- [x] Domain management - Bind domains, DNS check, SSL (`quicklify domain`)
|
|
277
|
+
- [x] SSH hardening - Password disable, fail2ban, security audit (`quicklify secure`)
|
|
278
|
+
- [x] Dry-run mode for all security commands
|
|
279
|
+
|
|
261
280
|
### Future
|
|
262
281
|
- [ ] Vultr support
|
|
263
282
|
- [ ] Linode / AWS Lightsail support
|
|
264
|
-
- [ ] Domain + SSL configuration helper
|
|
265
283
|
- [ ] Backup/restore commands
|
|
266
284
|
- [ ] Interactive TUI dashboard
|
|
267
|
-
- [ ] Firewall management
|
|
268
285
|
|
|
269
286
|
## ๐ ๏ธ Tech Stack
|
|
270
287
|
|
|
@@ -339,6 +356,30 @@ quicklify health
|
|
|
339
356
|
# Run environment diagnostics
|
|
340
357
|
quicklify doctor
|
|
341
358
|
|
|
359
|
+
# Firewall management
|
|
360
|
+
quicklify firewall setup my-server # Install UFW + Coolify ports
|
|
361
|
+
quicklify firewall add my-server --port 3000 # Open port 3000/tcp
|
|
362
|
+
quicklify firewall add my-server --port 53 --protocol udp # Open port 53/udp
|
|
363
|
+
quicklify firewall remove my-server --port 3000 # Close port 3000
|
|
364
|
+
quicklify firewall list my-server # Show firewall rules
|
|
365
|
+
quicklify firewall status my-server # Check UFW active/inactive
|
|
366
|
+
quicklify firewall setup my-server --dry-run # Preview without executing
|
|
367
|
+
|
|
368
|
+
# Domain management
|
|
369
|
+
quicklify domain add my-server --domain example.com # Bind domain + HTTPS
|
|
370
|
+
quicklify domain add my-server --domain example.com --no-ssl # HTTP only
|
|
371
|
+
quicklify domain remove my-server # Revert to IP:8000
|
|
372
|
+
quicklify domain check my-server --domain example.com # Verify DNS
|
|
373
|
+
quicklify domain list my-server # Show current domain
|
|
374
|
+
quicklify domain add my-server --domain example.com --dry-run # Preview
|
|
375
|
+
|
|
376
|
+
# SSH hardening & security
|
|
377
|
+
quicklify secure status my-server # Show security settings
|
|
378
|
+
quicklify secure audit my-server # Security score (0-4)
|
|
379
|
+
quicklify secure setup my-server # Harden SSH + install fail2ban
|
|
380
|
+
quicklify secure setup my-server --port 2222 # Change SSH port
|
|
381
|
+
quicklify secure setup my-server --dry-run # Preview without executing
|
|
382
|
+
|
|
342
383
|
# Show version
|
|
343
384
|
quicklify --version
|
|
344
385
|
|
|
@@ -420,6 +461,8 @@ tests/
|
|
|
420
461
|
โ โโโ defaults.test.ts # Default config CRUD
|
|
421
462
|
โ โโโ destroy.test.ts # Destroy command unit tests
|
|
422
463
|
โ โโโ doctor.test.ts # Doctor command tests
|
|
464
|
+
โ โโโ domain.test.ts # Domain command tests
|
|
465
|
+
โ โโโ firewall.test.ts # Firewall command tests
|
|
423
466
|
โ โโโ health-command.test.ts # Health command tests
|
|
424
467
|
โ โโโ healthCheck.test.ts # Health check polling tests
|
|
425
468
|
โ โโโ healthCheck-edge.test.ts # Health check edge cases (302, 401, 500)
|
|
@@ -430,6 +473,7 @@ tests/
|
|
|
430
473
|
โ โโโ prompts.test.ts
|
|
431
474
|
โ โโโ providerFactory.test.ts # Provider factory tests
|
|
432
475
|
โ โโโ restart.test.ts # Restart command tests
|
|
476
|
+
โ โโโ secure.test.ts # Secure command tests
|
|
433
477
|
โ โโโ serverSelect.test.ts # Server selection utility tests
|
|
434
478
|
โ โโโ ssh-command.test.ts # SSH command tests
|
|
435
479
|
โ โโโ ssh-utils.test.ts # SSH helper tests
|
|
@@ -455,7 +499,7 @@ Tests run automatically on every push/PR via GitHub Actions across:
|
|
|
455
499
|
|
|
456
500
|
### Coverage
|
|
457
501
|
|
|
458
|
-
Current coverage: **97%+ statements/lines**, **
|
|
502
|
+
Current coverage: **97%+ statements/lines**, **85%+ branches**, **96%+ functions**. 494 tests across 32 test suites.
|
|
459
503
|
|
|
460
504
|
## ๐ง Troubleshooting
|
|
461
505
|
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export declare function isValidDomain(domain: string): boolean;
|
|
2
|
+
export declare function sanitizeDomain(input: string): string;
|
|
3
|
+
export declare function buildSetFqdnCommand(domain: string, ssl: boolean): string;
|
|
4
|
+
export declare function buildGetFqdnCommand(): string;
|
|
5
|
+
export declare function buildDnsCheckCommand(domain: string): string;
|
|
6
|
+
export declare function parseDnsResult(stdout: string): string | null;
|
|
7
|
+
export declare function parseFqdn(stdout: string): string | null;
|
|
8
|
+
export declare function domainCommand(subcommand?: string, query?: string, options?: {
|
|
9
|
+
domain?: string;
|
|
10
|
+
ssl?: boolean;
|
|
11
|
+
dryRun?: boolean;
|
|
12
|
+
}): Promise<void>;
|
|
13
|
+
//# sourceMappingURL=domain.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"domain.d.ts","sourceRoot":"","sources":["../../src/commands/domain.ts"],"names":[],"mappings":"AAMA,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAIrD;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CASpD;AAED,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,GAAG,MAAM,CAIxE;AAED,wBAAgB,mBAAmB,IAAI,MAAM,CAE5C;AAED,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAE3D;AAED,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAI5D;AAED,wBAAgB,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAIvD;AAED,wBAAsB,aAAa,CACjC,UAAU,CAAC,EAAE,MAAM,EACnB,KAAK,CAAC,EAAE,MAAM,EACd,OAAO,CAAC,EAAE;IAAE,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,OAAO,CAAC;IAAC,MAAM,CAAC,EAAE,OAAO,CAAA;CAAE,GAC7D,OAAO,CAAC,IAAI,CAAC,CAiCf"}
|
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
import { resolveServer } from "../utils/serverSelect.js";
|
|
2
|
+
import { checkSshAvailable, sshExec } from "../utils/ssh.js";
|
|
3
|
+
import { logger, createSpinner } from "../utils/logger.js";
|
|
4
|
+
const COOLIFY_ENV_PATH = "/data/coolify/source/.env";
|
|
5
|
+
export function isValidDomain(domain) {
|
|
6
|
+
// RFC 1035 compliant domain validation
|
|
7
|
+
const pattern = /^(?!-)[a-zA-Z0-9-]{1,63}(?<!-)(\.[a-zA-Z0-9-]{1,63})*\.[a-zA-Z]{2,}$/;
|
|
8
|
+
return pattern.test(domain);
|
|
9
|
+
}
|
|
10
|
+
export function sanitizeDomain(input) {
|
|
11
|
+
let domain = input.trim();
|
|
12
|
+
// Strip protocol prefix
|
|
13
|
+
domain = domain.replace(/^https?:\/\//, "");
|
|
14
|
+
// Strip trailing slash
|
|
15
|
+
domain = domain.replace(/\/+$/, "");
|
|
16
|
+
// Strip port
|
|
17
|
+
domain = domain.replace(/:\d+$/, "");
|
|
18
|
+
return domain;
|
|
19
|
+
}
|
|
20
|
+
export function buildSetFqdnCommand(domain, ssl) {
|
|
21
|
+
const protocol = ssl ? "https" : "http";
|
|
22
|
+
const url = `${protocol}://${domain}`;
|
|
23
|
+
return `sed -i 's|^APP_URL=.*|APP_URL=${url}|' ${COOLIFY_ENV_PATH} && cd /data/coolify/source && docker compose up -d --force-recreate`;
|
|
24
|
+
}
|
|
25
|
+
export function buildGetFqdnCommand() {
|
|
26
|
+
return `grep '^APP_URL=' ${COOLIFY_ENV_PATH}`;
|
|
27
|
+
}
|
|
28
|
+
export function buildDnsCheckCommand(domain) {
|
|
29
|
+
return `dig +short A ${domain} 2>/dev/null || host -t A ${domain} 2>/dev/null || nslookup ${domain} 2>/dev/null`;
|
|
30
|
+
}
|
|
31
|
+
export function parseDnsResult(stdout) {
|
|
32
|
+
// dig +short returns just IP addresses
|
|
33
|
+
const ipMatch = stdout.match(/\b(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\b/);
|
|
34
|
+
return ipMatch ? ipMatch[1] : null;
|
|
35
|
+
}
|
|
36
|
+
export function parseFqdn(stdout) {
|
|
37
|
+
const match = stdout.match(/^APP_URL=(.+)$/m);
|
|
38
|
+
if (!match)
|
|
39
|
+
return null;
|
|
40
|
+
return match[1].trim();
|
|
41
|
+
}
|
|
42
|
+
export async function domainCommand(subcommand, query, options) {
|
|
43
|
+
if (!checkSshAvailable()) {
|
|
44
|
+
logger.error("SSH client not found. Please install OpenSSH.");
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
const validSubcommands = ["add", "remove", "check", "list"];
|
|
48
|
+
const sub = subcommand || "list";
|
|
49
|
+
if (!validSubcommands.includes(sub)) {
|
|
50
|
+
logger.error(`Invalid subcommand: ${sub}. Choose from: ${validSubcommands.join(", ")}`);
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
const server = await resolveServer(query, "Select a server for domain management:");
|
|
54
|
+
if (!server)
|
|
55
|
+
return;
|
|
56
|
+
const dryRun = options?.dryRun || false;
|
|
57
|
+
switch (sub) {
|
|
58
|
+
case "add":
|
|
59
|
+
await domainAdd(server.ip, server.name, options, dryRun);
|
|
60
|
+
break;
|
|
61
|
+
case "remove":
|
|
62
|
+
await domainRemove(server.ip, server.name, dryRun);
|
|
63
|
+
break;
|
|
64
|
+
case "check":
|
|
65
|
+
await domainCheck(server.ip, options);
|
|
66
|
+
break;
|
|
67
|
+
case "list":
|
|
68
|
+
await domainList(server.ip, server.name);
|
|
69
|
+
break;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
async function domainAdd(ip, name, options, dryRun) {
|
|
73
|
+
if (!options?.domain) {
|
|
74
|
+
logger.error("Missing --domain. Usage: quicklify domain add <server> --domain example.com");
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
const domain = sanitizeDomain(options.domain);
|
|
78
|
+
if (!isValidDomain(domain)) {
|
|
79
|
+
logger.error(`Invalid domain: ${domain}`);
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
const ssl = options?.ssl !== false; // default true
|
|
83
|
+
const command = buildSetFqdnCommand(domain, ssl);
|
|
84
|
+
if (dryRun) {
|
|
85
|
+
logger.title("Dry Run - Add Domain");
|
|
86
|
+
logger.info(`Server: ${name} (${ip})`);
|
|
87
|
+
logger.info(`Domain: ${domain}`);
|
|
88
|
+
logger.info(`SSL: ${ssl ? "enabled" : "disabled"}`);
|
|
89
|
+
console.log();
|
|
90
|
+
logger.info("Commands to execute:");
|
|
91
|
+
for (const cmd of command.split(" && ")) {
|
|
92
|
+
logger.step(cmd);
|
|
93
|
+
}
|
|
94
|
+
console.log();
|
|
95
|
+
logger.warning("No changes applied. Remove --dry-run to execute.");
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
const spinner = createSpinner(`Setting domain to ${domain}...`);
|
|
99
|
+
spinner.start();
|
|
100
|
+
try {
|
|
101
|
+
// Check if .env file exists
|
|
102
|
+
const checkResult = await sshExec(ip, `test -f ${COOLIFY_ENV_PATH} && echo "exists"`);
|
|
103
|
+
if (!checkResult.stdout.includes("exists")) {
|
|
104
|
+
spinner.fail("Coolify environment file not found");
|
|
105
|
+
logger.error(`Expected: ${COOLIFY_ENV_PATH}`);
|
|
106
|
+
logger.info("Is Coolify installed on this server?");
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
const result = await sshExec(ip, command);
|
|
110
|
+
if (result.code !== 0) {
|
|
111
|
+
spinner.fail("Failed to set domain");
|
|
112
|
+
if (result.stderr)
|
|
113
|
+
logger.error(result.stderr);
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
spinner.succeed(`Domain set to ${domain} on ${name}`);
|
|
117
|
+
const protocol = ssl ? "https" : "http";
|
|
118
|
+
logger.success(`Coolify is now accessible at ${protocol}://${domain}`);
|
|
119
|
+
logger.info("Make sure your DNS A record points to " + ip);
|
|
120
|
+
}
|
|
121
|
+
catch (error) {
|
|
122
|
+
spinner.fail("Failed to set domain");
|
|
123
|
+
logger.error(error instanceof Error ? error.message : String(error));
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
async function domainRemove(ip, name, dryRun) {
|
|
127
|
+
const command = buildSetFqdnCommand(`${ip}:8000`, false);
|
|
128
|
+
if (dryRun) {
|
|
129
|
+
logger.title("Dry Run - Remove Domain");
|
|
130
|
+
logger.info(`Server: ${name} (${ip})`);
|
|
131
|
+
logger.info(`Will reset to: http://${ip}:8000`);
|
|
132
|
+
console.log();
|
|
133
|
+
logger.info("Commands to execute:");
|
|
134
|
+
for (const cmd of command.split(" && ")) {
|
|
135
|
+
logger.step(cmd);
|
|
136
|
+
}
|
|
137
|
+
console.log();
|
|
138
|
+
logger.warning("No changes applied. Remove --dry-run to execute.");
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
const spinner = createSpinner("Removing domain...");
|
|
142
|
+
spinner.start();
|
|
143
|
+
try {
|
|
144
|
+
const result = await sshExec(ip, command);
|
|
145
|
+
if (result.code !== 0) {
|
|
146
|
+
spinner.fail("Failed to remove domain");
|
|
147
|
+
if (result.stderr)
|
|
148
|
+
logger.error(result.stderr);
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
spinner.succeed(`Domain removed from ${name}`);
|
|
152
|
+
logger.success(`Coolify is now accessible at http://${ip}:8000`);
|
|
153
|
+
}
|
|
154
|
+
catch (error) {
|
|
155
|
+
spinner.fail("Failed to remove domain");
|
|
156
|
+
logger.error(error instanceof Error ? error.message : String(error));
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
async function domainCheck(ip, options) {
|
|
160
|
+
if (!options?.domain) {
|
|
161
|
+
logger.error("Missing --domain. Usage: quicklify domain check <server> --domain example.com");
|
|
162
|
+
return;
|
|
163
|
+
}
|
|
164
|
+
const domain = sanitizeDomain(options.domain);
|
|
165
|
+
if (!isValidDomain(domain)) {
|
|
166
|
+
logger.error(`Invalid domain: ${domain}`);
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
const spinner = createSpinner(`Checking DNS for ${domain}...`);
|
|
170
|
+
spinner.start();
|
|
171
|
+
try {
|
|
172
|
+
const result = await sshExec(ip, buildDnsCheckCommand(domain));
|
|
173
|
+
const resolvedIp = parseDnsResult(result.stdout);
|
|
174
|
+
if (!resolvedIp) {
|
|
175
|
+
spinner.fail(`No A record found for ${domain}`);
|
|
176
|
+
logger.info("Add an A record pointing to " + ip);
|
|
177
|
+
return;
|
|
178
|
+
}
|
|
179
|
+
if (resolvedIp === ip) {
|
|
180
|
+
spinner.succeed(`DNS OK: ${domain} โ ${resolvedIp}`);
|
|
181
|
+
}
|
|
182
|
+
else {
|
|
183
|
+
spinner.warn(`DNS mismatch: ${domain} โ ${resolvedIp} (expected ${ip})`);
|
|
184
|
+
logger.info("Update your A record to point to " + ip);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
catch (error) {
|
|
188
|
+
spinner.fail("Failed to check DNS");
|
|
189
|
+
logger.error(error instanceof Error ? error.message : String(error));
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
async function domainList(ip, name) {
|
|
193
|
+
const spinner = createSpinner(`Fetching domain from ${name}...`);
|
|
194
|
+
spinner.start();
|
|
195
|
+
try {
|
|
196
|
+
const result = await sshExec(ip, buildGetFqdnCommand());
|
|
197
|
+
if (result.code !== 0) {
|
|
198
|
+
spinner.fail("Failed to fetch domain");
|
|
199
|
+
if (result.stderr)
|
|
200
|
+
logger.error(result.stderr);
|
|
201
|
+
return;
|
|
202
|
+
}
|
|
203
|
+
const fqdn = parseFqdn(result.stdout);
|
|
204
|
+
if (fqdn) {
|
|
205
|
+
spinner.succeed(`Current domain for ${name}`);
|
|
206
|
+
logger.info(`APP_URL: ${fqdn}`);
|
|
207
|
+
}
|
|
208
|
+
else {
|
|
209
|
+
spinner.succeed(`No custom domain set for ${name}`);
|
|
210
|
+
logger.info(`Default: http://${ip}:8000`);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
catch (error) {
|
|
214
|
+
spinner.fail("Failed to fetch domain");
|
|
215
|
+
logger.error(error instanceof Error ? error.message : String(error));
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
//# sourceMappingURL=domain.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"domain.js","sourceRoot":"","sources":["../../src/commands/domain.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { FirewallStatus, FirewallProtocol } from "../types/index.js";
|
|
2
|
+
export declare const PROTECTED_PORTS: number[];
|
|
3
|
+
export declare const COOLIFY_PORTS: number[];
|
|
4
|
+
export declare function isValidPort(port: number): boolean;
|
|
5
|
+
export declare function isProtectedPort(port: number): boolean;
|
|
6
|
+
export declare function buildUfwRuleCommand(action: "allow" | "delete allow", port: number, protocol?: FirewallProtocol): string;
|
|
7
|
+
export declare function buildFirewallSetupCommand(): string;
|
|
8
|
+
export declare function buildUfwStatusCommand(): string;
|
|
9
|
+
export declare function parseUfwStatus(stdout: string): FirewallStatus;
|
|
10
|
+
export declare function firewallCommand(subcommand?: string, query?: string, options?: {
|
|
11
|
+
port?: string;
|
|
12
|
+
protocol?: string;
|
|
13
|
+
dryRun?: boolean;
|
|
14
|
+
}): Promise<void>;
|
|
15
|
+
//# sourceMappingURL=firewall.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"firewall.d.ts","sourceRoot":"","sources":["../../src/commands/firewall.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,cAAc,EAAgB,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAExF,eAAO,MAAM,eAAe,UAAO,CAAC;AACpC,eAAO,MAAM,aAAa,UAA8B,CAAC;AAEzD,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEjD;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAErD;AAED,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,OAAO,GAAG,cAAc,EAChC,IAAI,EAAE,MAAM,EACZ,QAAQ,GAAE,gBAAwB,GACjC,MAAM,CAER;AAED,wBAAgB,yBAAyB,IAAI,MAAM,CAUlD;AAED,wBAAgB,qBAAqB,IAAI,MAAM,CAE9C;AAED,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,cAAc,CAmB7D;AAED,wBAAsB,eAAe,CACnC,UAAU,CAAC,EAAE,MAAM,EACnB,KAAK,CAAC,EAAE,MAAM,EACd,OAAO,CAAC,EAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,OAAO,CAAA;CAAE,GAC/D,OAAO,CAAC,IAAI,CAAC,CAoCf"}
|
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
import inquirer from "inquirer";
|
|
2
|
+
import { resolveServer } from "../utils/serverSelect.js";
|
|
3
|
+
import { checkSshAvailable, sshExec } from "../utils/ssh.js";
|
|
4
|
+
import { logger, createSpinner } from "../utils/logger.js";
|
|
5
|
+
export const PROTECTED_PORTS = [22];
|
|
6
|
+
export const COOLIFY_PORTS = [80, 443, 8000, 6001, 6002];
|
|
7
|
+
export function isValidPort(port) {
|
|
8
|
+
return Number.isInteger(port) && port >= 1 && port <= 65535;
|
|
9
|
+
}
|
|
10
|
+
export function isProtectedPort(port) {
|
|
11
|
+
return PROTECTED_PORTS.includes(port);
|
|
12
|
+
}
|
|
13
|
+
export function buildUfwRuleCommand(action, port, protocol = "tcp") {
|
|
14
|
+
return `ufw ${action} ${port}/${protocol}`;
|
|
15
|
+
}
|
|
16
|
+
export function buildFirewallSetupCommand() {
|
|
17
|
+
const commands = [
|
|
18
|
+
"apt-get install -y ufw",
|
|
19
|
+
"ufw default deny incoming",
|
|
20
|
+
"ufw default allow outgoing",
|
|
21
|
+
...COOLIFY_PORTS.map((p) => `ufw allow ${p}/tcp`),
|
|
22
|
+
"ufw allow 22/tcp",
|
|
23
|
+
'echo "y" | ufw enable',
|
|
24
|
+
];
|
|
25
|
+
return commands.join(" && ");
|
|
26
|
+
}
|
|
27
|
+
export function buildUfwStatusCommand() {
|
|
28
|
+
return "ufw status numbered";
|
|
29
|
+
}
|
|
30
|
+
export function parseUfwStatus(stdout) {
|
|
31
|
+
const lines = stdout.split("\n");
|
|
32
|
+
const active = stdout.toLowerCase().includes("status: active");
|
|
33
|
+
const rules = [];
|
|
34
|
+
for (const line of lines) {
|
|
35
|
+
// Match lines like: [ 1] 22/tcp ALLOW IN Anywhere
|
|
36
|
+
const match = line.match(/\[\s*\d+\]\s+(\d+)\/(tcp|udp)\s+(ALLOW|DENY)\s+IN\s+(.*)/i);
|
|
37
|
+
if (match) {
|
|
38
|
+
rules.push({
|
|
39
|
+
port: parseInt(match[1], 10),
|
|
40
|
+
protocol: match[2].toLowerCase(),
|
|
41
|
+
action: match[3].toUpperCase(),
|
|
42
|
+
from: match[4].trim() || "Anywhere",
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return { active, rules };
|
|
47
|
+
}
|
|
48
|
+
export async function firewallCommand(subcommand, query, options) {
|
|
49
|
+
if (!checkSshAvailable()) {
|
|
50
|
+
logger.error("SSH client not found. Please install OpenSSH.");
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
const validSubcommands = ["setup", "add", "remove", "list", "status"];
|
|
54
|
+
const sub = subcommand || "status";
|
|
55
|
+
if (!validSubcommands.includes(sub)) {
|
|
56
|
+
logger.error(`Invalid subcommand: ${sub}. Choose from: ${validSubcommands.join(", ")}`);
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
const server = await resolveServer(query, "Select a server for firewall management:");
|
|
60
|
+
if (!server)
|
|
61
|
+
return;
|
|
62
|
+
const dryRun = options?.dryRun || false;
|
|
63
|
+
switch (sub) {
|
|
64
|
+
case "setup":
|
|
65
|
+
await firewallSetup(server.ip, server.name, dryRun);
|
|
66
|
+
break;
|
|
67
|
+
case "add":
|
|
68
|
+
await firewallAdd(server.ip, server.name, options, dryRun);
|
|
69
|
+
break;
|
|
70
|
+
case "remove":
|
|
71
|
+
await firewallRemove(server.ip, server.name, options, dryRun);
|
|
72
|
+
break;
|
|
73
|
+
case "list":
|
|
74
|
+
await firewallList(server.ip, server.name);
|
|
75
|
+
break;
|
|
76
|
+
case "status":
|
|
77
|
+
await firewallStatusCheck(server.ip, server.name);
|
|
78
|
+
break;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
async function firewallSetup(ip, name, dryRun) {
|
|
82
|
+
const command = buildFirewallSetupCommand();
|
|
83
|
+
if (dryRun) {
|
|
84
|
+
logger.title("Dry Run - Firewall Setup");
|
|
85
|
+
logger.info(`Server: ${name} (${ip})`);
|
|
86
|
+
console.log();
|
|
87
|
+
logger.info("Commands to execute:");
|
|
88
|
+
for (const cmd of command.split(" && ")) {
|
|
89
|
+
logger.step(cmd);
|
|
90
|
+
}
|
|
91
|
+
console.log();
|
|
92
|
+
logger.warning("No changes applied. Remove --dry-run to execute.");
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
const spinner = createSpinner("Setting up firewall...");
|
|
96
|
+
spinner.start();
|
|
97
|
+
try {
|
|
98
|
+
const result = await sshExec(ip, command);
|
|
99
|
+
if (result.code !== 0) {
|
|
100
|
+
spinner.fail("Failed to setup firewall");
|
|
101
|
+
if (result.stderr)
|
|
102
|
+
logger.error(result.stderr);
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
spinner.succeed("Firewall configured successfully");
|
|
106
|
+
logger.success(`UFW enabled with Coolify ports (${COOLIFY_PORTS.join(", ")}) + SSH (22)`);
|
|
107
|
+
}
|
|
108
|
+
catch (error) {
|
|
109
|
+
spinner.fail("Failed to setup firewall");
|
|
110
|
+
logger.error(error instanceof Error ? error.message : String(error));
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
async function firewallAdd(ip, name, options, dryRun) {
|
|
114
|
+
const port = parseInt(options?.port || "", 10);
|
|
115
|
+
if (!options?.port || !isValidPort(port)) {
|
|
116
|
+
logger.error("Invalid or missing --port. Must be 1-65535.");
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
const protocol = options?.protocol || "tcp";
|
|
120
|
+
if (protocol !== "tcp" && protocol !== "udp") {
|
|
121
|
+
logger.error("Invalid --protocol. Must be tcp or udp.");
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
const command = buildUfwRuleCommand("allow", port, protocol);
|
|
125
|
+
if (dryRun) {
|
|
126
|
+
logger.title("Dry Run - Add Firewall Rule");
|
|
127
|
+
logger.info(`Server: ${name} (${ip})`);
|
|
128
|
+
logger.step(command);
|
|
129
|
+
logger.warning("No changes applied. Remove --dry-run to execute.");
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
const spinner = createSpinner(`Opening port ${port}/${protocol}...`);
|
|
133
|
+
spinner.start();
|
|
134
|
+
try {
|
|
135
|
+
const result = await sshExec(ip, command);
|
|
136
|
+
if (result.code !== 0) {
|
|
137
|
+
spinner.fail(`Failed to open port ${port}/${protocol}`);
|
|
138
|
+
if (result.stderr)
|
|
139
|
+
logger.error(result.stderr);
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
spinner.succeed(`Port ${port}/${protocol} opened on ${name}`);
|
|
143
|
+
}
|
|
144
|
+
catch (error) {
|
|
145
|
+
spinner.fail(`Failed to open port ${port}/${protocol}`);
|
|
146
|
+
logger.error(error instanceof Error ? error.message : String(error));
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
async function firewallRemove(ip, name, options, dryRun) {
|
|
150
|
+
const port = parseInt(options?.port || "", 10);
|
|
151
|
+
if (!options?.port || !isValidPort(port)) {
|
|
152
|
+
logger.error("Invalid or missing --port. Must be 1-65535.");
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
if (isProtectedPort(port)) {
|
|
156
|
+
logger.error(`Port ${port} is protected and cannot be removed (SSH access).`);
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
159
|
+
const protocol = options?.protocol || "tcp";
|
|
160
|
+
if (protocol !== "tcp" && protocol !== "udp") {
|
|
161
|
+
logger.error("Invalid --protocol. Must be tcp or udp.");
|
|
162
|
+
return;
|
|
163
|
+
}
|
|
164
|
+
if (COOLIFY_PORTS.includes(port)) {
|
|
165
|
+
const { confirm } = await inquirer.prompt([
|
|
166
|
+
{
|
|
167
|
+
type: "confirm",
|
|
168
|
+
name: "confirm",
|
|
169
|
+
message: `Port ${port} is used by Coolify. Are you sure you want to remove it?`,
|
|
170
|
+
default: false,
|
|
171
|
+
},
|
|
172
|
+
]);
|
|
173
|
+
if (!confirm) {
|
|
174
|
+
logger.info("Remove cancelled.");
|
|
175
|
+
return;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
const command = buildUfwRuleCommand("delete allow", port, protocol);
|
|
179
|
+
if (dryRun) {
|
|
180
|
+
logger.title("Dry Run - Remove Firewall Rule");
|
|
181
|
+
logger.info(`Server: ${name} (${ip})`);
|
|
182
|
+
logger.step(command);
|
|
183
|
+
logger.warning("No changes applied. Remove --dry-run to execute.");
|
|
184
|
+
return;
|
|
185
|
+
}
|
|
186
|
+
const spinner = createSpinner(`Closing port ${port}/${protocol}...`);
|
|
187
|
+
spinner.start();
|
|
188
|
+
try {
|
|
189
|
+
const result = await sshExec(ip, command);
|
|
190
|
+
if (result.code !== 0) {
|
|
191
|
+
spinner.fail(`Failed to close port ${port}/${protocol}`);
|
|
192
|
+
if (result.stderr)
|
|
193
|
+
logger.error(result.stderr);
|
|
194
|
+
return;
|
|
195
|
+
}
|
|
196
|
+
spinner.succeed(`Port ${port}/${protocol} closed on ${name}`);
|
|
197
|
+
}
|
|
198
|
+
catch (error) {
|
|
199
|
+
spinner.fail(`Failed to close port ${port}/${protocol}`);
|
|
200
|
+
logger.error(error instanceof Error ? error.message : String(error));
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
async function firewallList(ip, name) {
|
|
204
|
+
const spinner = createSpinner(`Fetching firewall rules from ${name}...`);
|
|
205
|
+
spinner.start();
|
|
206
|
+
try {
|
|
207
|
+
const result = await sshExec(ip, buildUfwStatusCommand());
|
|
208
|
+
if (result.code !== 0) {
|
|
209
|
+
spinner.fail("Failed to fetch firewall rules");
|
|
210
|
+
if (result.stderr)
|
|
211
|
+
logger.error(result.stderr);
|
|
212
|
+
return;
|
|
213
|
+
}
|
|
214
|
+
const status = parseUfwStatus(result.stdout);
|
|
215
|
+
spinner.succeed(`Firewall rules for ${name} (${ip})`);
|
|
216
|
+
if (!status.active) {
|
|
217
|
+
logger.warning("UFW is inactive. Run 'quicklify firewall setup' to enable.");
|
|
218
|
+
return;
|
|
219
|
+
}
|
|
220
|
+
if (status.rules.length === 0) {
|
|
221
|
+
logger.info("No rules configured.");
|
|
222
|
+
return;
|
|
223
|
+
}
|
|
224
|
+
console.log();
|
|
225
|
+
for (const rule of status.rules) {
|
|
226
|
+
logger.step(`${rule.port}/${rule.protocol} โ ${rule.action} from ${rule.from}`);
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
catch (error) {
|
|
230
|
+
spinner.fail("Failed to fetch firewall rules");
|
|
231
|
+
logger.error(error instanceof Error ? error.message : String(error));
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
async function firewallStatusCheck(ip, name) {
|
|
235
|
+
const spinner = createSpinner(`Checking firewall status on ${name}...`);
|
|
236
|
+
spinner.start();
|
|
237
|
+
try {
|
|
238
|
+
const result = await sshExec(ip, "ufw status");
|
|
239
|
+
if (result.code !== 0) {
|
|
240
|
+
spinner.fail("Failed to check firewall status");
|
|
241
|
+
if (result.stderr)
|
|
242
|
+
logger.error(result.stderr);
|
|
243
|
+
return;
|
|
244
|
+
}
|
|
245
|
+
const active = result.stdout.toLowerCase().includes("status: active");
|
|
246
|
+
if (active) {
|
|
247
|
+
spinner.succeed(`UFW is active on ${name}`);
|
|
248
|
+
}
|
|
249
|
+
else {
|
|
250
|
+
spinner.warn(`UFW is inactive on ${name}`);
|
|
251
|
+
logger.info("Run 'quicklify firewall setup' to enable.");
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
catch (error) {
|
|
255
|
+
spinner.fail("Failed to check firewall status");
|
|
256
|
+
logger.error(error instanceof Error ? error.message : String(error));
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
//# sourceMappingURL=firewall.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"firewall.js","sourceRoot":"","sources":["../../src/commands/firewall.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { SshdSetting, SecureAuditResult } from "../types/index.js";
|
|
2
|
+
export declare function parseSshdConfig(content: string): SshdSetting[];
|
|
3
|
+
export declare function parseAuditResult(stdout: string): SecureAuditResult;
|
|
4
|
+
export declare function buildHardeningCommand(options?: {
|
|
5
|
+
port?: number;
|
|
6
|
+
}): string;
|
|
7
|
+
export declare function buildFail2banCommand(): string;
|
|
8
|
+
export declare function buildAuditCommand(): string;
|
|
9
|
+
export declare function buildKeyCheckCommand(): string;
|
|
10
|
+
export declare function secureCommand(subcommand?: string, query?: string, options?: {
|
|
11
|
+
port?: string;
|
|
12
|
+
dryRun?: boolean;
|
|
13
|
+
}): Promise<void>;
|
|
14
|
+
//# sourceMappingURL=secure.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"secure.d.ts","sourceRoot":"","sources":["../../src/commands/secure.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAExE,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,WAAW,EAAE,CA8B9D;AAED,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,iBAAiB,CAgClE;AAED,wBAAgB,qBAAqB,CAAC,OAAO,CAAC,EAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAezE;AAED,wBAAgB,oBAAoB,IAAI,MAAM,CAgB7C;AAED,wBAAgB,iBAAiB,IAAI,MAAM,CAE1C;AAED,wBAAgB,oBAAoB,IAAI,MAAM,CAE7C;AAED,wBAAsB,aAAa,CACjC,UAAU,CAAC,EAAE,MAAM,EACnB,KAAK,CAAC,EAAE,MAAM,EACd,OAAO,CAAC,EAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,OAAO,CAAA;CAAE,GAC5C,OAAO,CAAC,IAAI,CAAC,CA8Bf"}
|
|
@@ -0,0 +1,294 @@
|
|
|
1
|
+
import inquirer from "inquirer";
|
|
2
|
+
import { resolveServer } from "../utils/serverSelect.js";
|
|
3
|
+
import { checkSshAvailable, sshExec } from "../utils/ssh.js";
|
|
4
|
+
import { logger, createSpinner } from "../utils/logger.js";
|
|
5
|
+
export function parseSshdConfig(content) {
|
|
6
|
+
const settings = [];
|
|
7
|
+
const checks = [
|
|
8
|
+
{ key: "PasswordAuthentication", secureValue: "no" },
|
|
9
|
+
{ key: "PermitRootLogin", secureValue: "prohibit-password" },
|
|
10
|
+
{ key: "PubkeyAuthentication", secureValue: "yes" },
|
|
11
|
+
{ key: "MaxAuthTries", secureValue: "3" },
|
|
12
|
+
];
|
|
13
|
+
for (const check of checks) {
|
|
14
|
+
const regex = new RegExp(`^\\s*${check.key}\\s+(.+)`, "m");
|
|
15
|
+
const match = content.match(regex);
|
|
16
|
+
if (match) {
|
|
17
|
+
const value = match[1].trim();
|
|
18
|
+
settings.push({
|
|
19
|
+
key: check.key,
|
|
20
|
+
value,
|
|
21
|
+
status: value.toLowerCase() === check.secureValue.toLowerCase() ? "secure" : "insecure",
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
else {
|
|
25
|
+
settings.push({
|
|
26
|
+
key: check.key,
|
|
27
|
+
value: "",
|
|
28
|
+
status: "missing",
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
return settings;
|
|
33
|
+
}
|
|
34
|
+
export function parseAuditResult(stdout) {
|
|
35
|
+
const sections = stdout.split("---SEPARATOR---");
|
|
36
|
+
const sshdContent = sections[0] || "";
|
|
37
|
+
const fail2banStatus = sections[1] || "";
|
|
38
|
+
const sshdSettings = parseSshdConfig(sshdContent);
|
|
39
|
+
// Find specific settings
|
|
40
|
+
const passwordAuth = sshdSettings.find((s) => s.key === "PasswordAuthentication") || {
|
|
41
|
+
key: "PasswordAuthentication",
|
|
42
|
+
value: "",
|
|
43
|
+
status: "missing",
|
|
44
|
+
};
|
|
45
|
+
const rootLogin = sshdSettings.find((s) => s.key === "PermitRootLogin") || {
|
|
46
|
+
key: "PermitRootLogin",
|
|
47
|
+
value: "",
|
|
48
|
+
status: "missing",
|
|
49
|
+
};
|
|
50
|
+
// Parse fail2ban
|
|
51
|
+
const fail2banInstalled = fail2banStatus.includes("active") || fail2banStatus.includes("inactive");
|
|
52
|
+
const fail2banActive = fail2banStatus.includes("active (running)");
|
|
53
|
+
// Parse SSH port
|
|
54
|
+
const portMatch = sshdContent.match(/^\s*Port\s+(\d+)/m);
|
|
55
|
+
const sshPort = portMatch ? parseInt(portMatch[1], 10) : 22;
|
|
56
|
+
return {
|
|
57
|
+
passwordAuth,
|
|
58
|
+
rootLogin,
|
|
59
|
+
fail2ban: { installed: fail2banInstalled, active: fail2banActive },
|
|
60
|
+
sshPort,
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
export function buildHardeningCommand(options) {
|
|
64
|
+
const commands = [
|
|
65
|
+
"cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak",
|
|
66
|
+
`sed -i 's/^#\\?PasswordAuthentication.*/PasswordAuthentication no/' /etc/ssh/sshd_config`,
|
|
67
|
+
`sed -i 's/^#\\?PermitRootLogin.*/PermitRootLogin prohibit-password/' /etc/ssh/sshd_config`,
|
|
68
|
+
`sed -i 's/^#\\?PubkeyAuthentication.*/PubkeyAuthentication yes/' /etc/ssh/sshd_config`,
|
|
69
|
+
`sed -i 's/^#\\?MaxAuthTries.*/MaxAuthTries 3/' /etc/ssh/sshd_config`,
|
|
70
|
+
];
|
|
71
|
+
if (options?.port && options.port !== 22) {
|
|
72
|
+
commands.push(`sed -i 's/^#\\?Port.*/Port ${options.port}/' /etc/ssh/sshd_config`);
|
|
73
|
+
}
|
|
74
|
+
commands.push("systemctl restart sshd");
|
|
75
|
+
return commands.join(" && ");
|
|
76
|
+
}
|
|
77
|
+
export function buildFail2banCommand() {
|
|
78
|
+
return [
|
|
79
|
+
"apt-get install -y fail2ban",
|
|
80
|
+
`cat > /etc/fail2ban/jail.local << 'JAIL'
|
|
81
|
+
[sshd]
|
|
82
|
+
enabled = true
|
|
83
|
+
port = ssh
|
|
84
|
+
filter = sshd
|
|
85
|
+
logpath = /var/log/auth.log
|
|
86
|
+
maxretry = 5
|
|
87
|
+
bantime = 3600
|
|
88
|
+
findtime = 600
|
|
89
|
+
JAIL`,
|
|
90
|
+
"systemctl enable fail2ban",
|
|
91
|
+
"systemctl restart fail2ban",
|
|
92
|
+
].join(" && ");
|
|
93
|
+
}
|
|
94
|
+
export function buildAuditCommand() {
|
|
95
|
+
return `cat /etc/ssh/sshd_config && echo '---SEPARATOR---' && systemctl status fail2ban 2>&1 || true`;
|
|
96
|
+
}
|
|
97
|
+
export function buildKeyCheckCommand() {
|
|
98
|
+
return "test -f /root/.ssh/authorized_keys && wc -l < /root/.ssh/authorized_keys || echo 0";
|
|
99
|
+
}
|
|
100
|
+
export async function secureCommand(subcommand, query, options) {
|
|
101
|
+
if (!checkSshAvailable()) {
|
|
102
|
+
logger.error("SSH client not found. Please install OpenSSH.");
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
const validSubcommands = ["setup", "status", "audit"];
|
|
106
|
+
const sub = subcommand || "status";
|
|
107
|
+
if (!validSubcommands.includes(sub)) {
|
|
108
|
+
logger.error(`Invalid subcommand: ${sub}. Choose from: ${validSubcommands.join(", ")}`);
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
const server = await resolveServer(query, "Select a server for security management:");
|
|
112
|
+
if (!server)
|
|
113
|
+
return;
|
|
114
|
+
const dryRun = options?.dryRun || false;
|
|
115
|
+
switch (sub) {
|
|
116
|
+
case "setup":
|
|
117
|
+
await secureSetup(server.ip, server.name, options, dryRun);
|
|
118
|
+
break;
|
|
119
|
+
case "status":
|
|
120
|
+
await secureStatus(server.ip, server.name);
|
|
121
|
+
break;
|
|
122
|
+
case "audit":
|
|
123
|
+
await secureAudit(server.ip, server.name);
|
|
124
|
+
break;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
async function secureSetup(ip, name, options, dryRun) {
|
|
128
|
+
// Step 1: Check SSH keys exist
|
|
129
|
+
const keyCheckResult = await sshExec(ip, buildKeyCheckCommand());
|
|
130
|
+
const keyCount = parseInt(keyCheckResult.stdout.trim(), 10);
|
|
131
|
+
if (isNaN(keyCount) || keyCount === 0) {
|
|
132
|
+
logger.error("No SSH keys found in /root/.ssh/authorized_keys");
|
|
133
|
+
logger.error("You MUST add an SSH key before disabling password authentication.");
|
|
134
|
+
logger.info("Run: ssh-copy-id root@" + ip);
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
const port = options?.port ? parseInt(options.port, 10) : undefined;
|
|
138
|
+
if (options?.port && (!port || port < 1 || port > 65535)) {
|
|
139
|
+
logger.error("Invalid --port. Must be 1-65535.");
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
const hardenCmd = buildHardeningCommand(port ? { port } : undefined);
|
|
143
|
+
const fail2banCmd = buildFail2banCommand();
|
|
144
|
+
if (dryRun) {
|
|
145
|
+
logger.title("Dry Run - Security Setup");
|
|
146
|
+
logger.info(`Server: ${name} (${ip})`);
|
|
147
|
+
logger.info(`SSH keys found: ${keyCount}`);
|
|
148
|
+
console.log();
|
|
149
|
+
logger.info("SSH Hardening commands:");
|
|
150
|
+
for (const cmd of hardenCmd.split(" && ")) {
|
|
151
|
+
logger.step(cmd);
|
|
152
|
+
}
|
|
153
|
+
console.log();
|
|
154
|
+
logger.info("Fail2ban commands:");
|
|
155
|
+
for (const cmd of fail2banCmd.split(" && ")) {
|
|
156
|
+
logger.step(cmd.length > 80 ? cmd.substring(0, 80) + "..." : cmd);
|
|
157
|
+
}
|
|
158
|
+
console.log();
|
|
159
|
+
logger.warning("No changes applied. Remove --dry-run to execute.");
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
// Double confirmation (like destroy command)
|
|
163
|
+
const { confirm } = await inquirer.prompt([
|
|
164
|
+
{
|
|
165
|
+
type: "confirm",
|
|
166
|
+
name: "confirm",
|
|
167
|
+
message: `This will harden SSH on "${name}" (${ip}). Password login will be DISABLED. Continue?`,
|
|
168
|
+
default: false,
|
|
169
|
+
},
|
|
170
|
+
]);
|
|
171
|
+
if (!confirm) {
|
|
172
|
+
logger.info("Security setup cancelled.");
|
|
173
|
+
return;
|
|
174
|
+
}
|
|
175
|
+
const { confirmName } = await inquirer.prompt([
|
|
176
|
+
{
|
|
177
|
+
type: "input",
|
|
178
|
+
name: "confirmName",
|
|
179
|
+
message: `Type the server name "${name}" to confirm:`,
|
|
180
|
+
},
|
|
181
|
+
]);
|
|
182
|
+
if (confirmName.trim() !== name) {
|
|
183
|
+
logger.error("Server name does not match. Setup cancelled.");
|
|
184
|
+
return;
|
|
185
|
+
}
|
|
186
|
+
// Step 2: Apply SSH hardening
|
|
187
|
+
const spinner = createSpinner("Applying SSH hardening...");
|
|
188
|
+
spinner.start();
|
|
189
|
+
try {
|
|
190
|
+
const hardenResult = await sshExec(ip, hardenCmd);
|
|
191
|
+
if (hardenResult.code !== 0) {
|
|
192
|
+
spinner.fail("Failed to apply SSH hardening");
|
|
193
|
+
if (hardenResult.stderr)
|
|
194
|
+
logger.error(hardenResult.stderr);
|
|
195
|
+
return;
|
|
196
|
+
}
|
|
197
|
+
spinner.succeed("SSH hardened successfully");
|
|
198
|
+
}
|
|
199
|
+
catch (error) {
|
|
200
|
+
spinner.fail("Failed to apply SSH hardening");
|
|
201
|
+
logger.error(error instanceof Error ? error.message : String(error));
|
|
202
|
+
return;
|
|
203
|
+
}
|
|
204
|
+
// Step 3: Install fail2ban
|
|
205
|
+
const f2bSpinner = createSpinner("Installing fail2ban...");
|
|
206
|
+
f2bSpinner.start();
|
|
207
|
+
try {
|
|
208
|
+
const f2bResult = await sshExec(ip, fail2banCmd);
|
|
209
|
+
if (f2bResult.code !== 0) {
|
|
210
|
+
f2bSpinner.warn("Fail2ban installation had issues (non-fatal)");
|
|
211
|
+
if (f2bResult.stderr)
|
|
212
|
+
logger.warning(f2bResult.stderr);
|
|
213
|
+
}
|
|
214
|
+
else {
|
|
215
|
+
f2bSpinner.succeed("Fail2ban installed and configured");
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
catch (error) {
|
|
219
|
+
f2bSpinner.warn("Fail2ban installation failed (non-fatal)");
|
|
220
|
+
logger.warning(error instanceof Error ? error.message : String(error));
|
|
221
|
+
}
|
|
222
|
+
logger.success(`Security setup complete for ${name}`);
|
|
223
|
+
if (port && port !== 22) {
|
|
224
|
+
logger.warning(`SSH port changed to ${port}. Use: ssh -p ${port} root@${ip}`);
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
async function secureStatus(ip, name) {
|
|
228
|
+
const spinner = createSpinner(`Checking security status of ${name}...`);
|
|
229
|
+
spinner.start();
|
|
230
|
+
try {
|
|
231
|
+
const result = await sshExec(ip, buildAuditCommand());
|
|
232
|
+
if (result.code !== 0 && !result.stdout) {
|
|
233
|
+
spinner.fail("Failed to check security status");
|
|
234
|
+
if (result.stderr)
|
|
235
|
+
logger.error(result.stderr);
|
|
236
|
+
return;
|
|
237
|
+
}
|
|
238
|
+
const audit = parseAuditResult(result.stdout);
|
|
239
|
+
spinner.succeed(`Security status for ${name} (${ip})`);
|
|
240
|
+
console.log();
|
|
241
|
+
const passIcon = (status) => status === "secure" ? "\u2714" : status === "insecure" ? "\u2716" : "?";
|
|
242
|
+
logger.info(`Password Auth: ${passIcon(audit.passwordAuth.status)} ${audit.passwordAuth.value || "not set"}`);
|
|
243
|
+
logger.info(`Root Login: ${passIcon(audit.rootLogin.status)} ${audit.rootLogin.value || "not set"}`);
|
|
244
|
+
logger.info(`Fail2ban: ${audit.fail2ban.installed ? (audit.fail2ban.active ? "\u2714 active" : "\u2716 inactive") : "\u2716 not installed"}`);
|
|
245
|
+
logger.info(`SSH Port: ${audit.sshPort}`);
|
|
246
|
+
}
|
|
247
|
+
catch (error) {
|
|
248
|
+
spinner.fail("Failed to check security status");
|
|
249
|
+
logger.error(error instanceof Error ? error.message : String(error));
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
async function secureAudit(ip, name) {
|
|
253
|
+
const spinner = createSpinner(`Running security audit on ${name}...`);
|
|
254
|
+
spinner.start();
|
|
255
|
+
try {
|
|
256
|
+
const result = await sshExec(ip, buildAuditCommand());
|
|
257
|
+
if (result.code !== 0 && !result.stdout) {
|
|
258
|
+
spinner.fail("Failed to run security audit");
|
|
259
|
+
if (result.stderr)
|
|
260
|
+
logger.error(result.stderr);
|
|
261
|
+
return;
|
|
262
|
+
}
|
|
263
|
+
const audit = parseAuditResult(result.stdout);
|
|
264
|
+
spinner.succeed(`Security audit for ${name} (${ip})`);
|
|
265
|
+
// Score calculation
|
|
266
|
+
let score = 0;
|
|
267
|
+
const maxScore = 4;
|
|
268
|
+
if (audit.passwordAuth.status === "secure")
|
|
269
|
+
score++;
|
|
270
|
+
if (audit.rootLogin.status === "secure")
|
|
271
|
+
score++;
|
|
272
|
+
if (audit.fail2ban.active)
|
|
273
|
+
score++;
|
|
274
|
+
if (audit.sshPort !== 22)
|
|
275
|
+
score++;
|
|
276
|
+
console.log();
|
|
277
|
+
logger.title(`Security Score: ${score}/${maxScore}`);
|
|
278
|
+
// Detailed report
|
|
279
|
+
const check = (ok, msg) => ok ? logger.success(msg) : logger.warning(msg);
|
|
280
|
+
check(audit.passwordAuth.status === "secure", `Password Authentication: ${audit.passwordAuth.value || "not set"} ${audit.passwordAuth.status === "secure" ? "(OK)" : "(should be 'no')"}`);
|
|
281
|
+
check(audit.rootLogin.status === "secure", `Root Login: ${audit.rootLogin.value || "not set"} ${audit.rootLogin.status === "secure" ? "(OK)" : "(should be 'prohibit-password')"}`);
|
|
282
|
+
check(audit.fail2ban.active, `Fail2ban: ${audit.fail2ban.installed ? (audit.fail2ban.active ? "active (OK)" : "installed but inactive") : "not installed"}`);
|
|
283
|
+
check(audit.sshPort !== 22, `SSH Port: ${audit.sshPort} ${audit.sshPort !== 22 ? "(non-default, OK)" : "(default port 22)"}`);
|
|
284
|
+
if (score < maxScore) {
|
|
285
|
+
console.log();
|
|
286
|
+
logger.info("Run 'quicklify secure setup' to improve your security score.");
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
catch (error) {
|
|
290
|
+
spinner.fail("Failed to run security audit");
|
|
291
|
+
logger.error(error instanceof Error ? error.message : String(error));
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
//# sourceMappingURL=secure.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"secure.js","sourceRoot":"","sources":["../../src/commands/secure.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -15,6 +15,9 @@ import { logsCommand } from "./commands/logs.js";
|
|
|
15
15
|
import { monitorCommand } from "./commands/monitor.js";
|
|
16
16
|
import { healthCommand } from "./commands/health.js";
|
|
17
17
|
import { doctorCommand } from "./commands/doctor.js";
|
|
18
|
+
import { firewallCommand } from "./commands/firewall.js";
|
|
19
|
+
import { domainCommand } from "./commands/domain.js";
|
|
20
|
+
import { secureCommand } from "./commands/secure.js";
|
|
18
21
|
const __filename = fileURLToPath(import.meta.url);
|
|
19
22
|
const __dirname = dirname(__filename);
|
|
20
23
|
const pkg = JSON.parse(readFileSync(join(__dirname, "../package.json"), "utf-8"));
|
|
@@ -76,5 +79,25 @@ program
|
|
|
76
79
|
.description("Check your local environment and configuration")
|
|
77
80
|
.option("--check-tokens", "Validate provider API tokens")
|
|
78
81
|
.action((options) => doctorCommand(options, pkg.version));
|
|
82
|
+
program
|
|
83
|
+
.command("firewall [subcommand] [query]")
|
|
84
|
+
.description("Manage server firewall (UFW)")
|
|
85
|
+
.option("--port <port>", "Port number (for add/remove)")
|
|
86
|
+
.option("--protocol <protocol>", "Protocol: tcp or udp (default: tcp)")
|
|
87
|
+
.option("--dry-run", "Show commands without executing")
|
|
88
|
+
.action((subcommand, query, options) => firewallCommand(subcommand, query, options));
|
|
89
|
+
program
|
|
90
|
+
.command("domain [subcommand] [query]")
|
|
91
|
+
.description("Manage server domain and SSL")
|
|
92
|
+
.option("--domain <domain>", "Domain name (for add/check)")
|
|
93
|
+
.option("--no-ssl", "Disable HTTPS (default: enabled)")
|
|
94
|
+
.option("--dry-run", "Show commands without executing")
|
|
95
|
+
.action((subcommand, query, options) => domainCommand(subcommand, query, options));
|
|
96
|
+
program
|
|
97
|
+
.command("secure [subcommand] [query]")
|
|
98
|
+
.description("Manage server security (SSH hardening, fail2ban)")
|
|
99
|
+
.option("--port <port>", "Change SSH port")
|
|
100
|
+
.option("--dry-run", "Show commands without executing")
|
|
101
|
+
.action((subcommand, query, options) => secureCommand(subcommand, query, options));
|
|
79
102
|
program.parse();
|
|
80
103
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/types/index.d.ts
CHANGED
|
@@ -51,4 +51,29 @@ export interface QuicklifyConfig {
|
|
|
51
51
|
size?: string;
|
|
52
52
|
name?: string;
|
|
53
53
|
}
|
|
54
|
+
export type FirewallProtocol = "tcp" | "udp";
|
|
55
|
+
export interface FirewallRule {
|
|
56
|
+
port: number;
|
|
57
|
+
protocol: FirewallProtocol;
|
|
58
|
+
action: "ALLOW" | "DENY";
|
|
59
|
+
from: string;
|
|
60
|
+
}
|
|
61
|
+
export interface FirewallStatus {
|
|
62
|
+
active: boolean;
|
|
63
|
+
rules: FirewallRule[];
|
|
64
|
+
}
|
|
65
|
+
export interface SshdSetting {
|
|
66
|
+
key: string;
|
|
67
|
+
value: string;
|
|
68
|
+
status: "secure" | "insecure" | "missing";
|
|
69
|
+
}
|
|
70
|
+
export interface SecureAuditResult {
|
|
71
|
+
passwordAuth: SshdSetting;
|
|
72
|
+
rootLogin: SshdSetting;
|
|
73
|
+
fail2ban: {
|
|
74
|
+
installed: boolean;
|
|
75
|
+
active: boolean;
|
|
76
|
+
};
|
|
77
|
+
sshPort: number;
|
|
78
|
+
}
|
|
54
79
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,MAAM;IACrB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;CACf"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,MAAM;IACrB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAGD,MAAM,MAAM,gBAAgB,GAAG,KAAK,GAAG,KAAK,CAAC;AAC7C,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,gBAAgB,CAAC;IAC3B,MAAM,EAAE,OAAO,GAAG,MAAM,CAAC;IACzB,IAAI,EAAE,MAAM,CAAC;CACd;AACD,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,OAAO,CAAC;IAChB,KAAK,EAAE,YAAY,EAAE,CAAC;CACvB;AAGD,MAAM,WAAW,WAAW;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,QAAQ,GAAG,UAAU,GAAG,SAAS,CAAC;CAC3C;AACD,MAAM,WAAW,iBAAiB;IAChC,YAAY,EAAE,WAAW,CAAC;IAC1B,SAAS,EAAE,WAAW,CAAC;IACvB,QAAQ,EAAE;QAAE,SAAS,EAAE,OAAO,CAAC;QAAC,MAAM,EAAE,OAAO,CAAA;KAAE,CAAC;IAClD,OAAO,EAAE,MAAM,CAAC;CACjB"}
|