@ebowwa/hetzner 0.3.0 → 0.3.2

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/package.json CHANGED
@@ -1,64 +1,21 @@
1
1
  {
2
2
  "name": "@ebowwa/hetzner",
3
- "version": "0.3.0",
3
+ "version": "0.3.2",
4
4
  "description": "Hetzner Cloud API client - servers, volumes, SSH keys, actions, pricing",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
7
7
  "types": "./dist/index.d.ts",
8
8
  "exports": {
9
9
  ".": {
10
- "types": "./dist/index.d.ts",
11
10
  "default": "./dist/index.js"
12
11
  },
13
- "./client": {
14
- "types": "./dist/client.d.ts",
15
- "default": "./dist/client.js"
16
- },
17
- "./types": {
18
- "types": "./dist/types.d.ts",
19
- "default": "./dist/types.js"
20
- },
21
- "./schemas": {
22
- "types": "./dist/schemas.d.ts",
23
- "default": "./dist/schemas.js"
24
- },
25
12
  "./bootstrap": {
26
- "types": "./dist/bootstrap/index.d.ts",
27
13
  "default": "./dist/bootstrap/index.js"
28
14
  },
29
15
  "./onboarding": {
30
- "types": "./dist/onboarding/index.d.ts",
31
16
  "default": "./dist/onboarding/index.js"
32
- },
33
- "./servers": {
34
- "types": "./dist/servers.d.ts",
35
- "default": "./dist/servers.js"
36
- },
37
- "./volumes": {
38
- "types": "./dist/volumes.d.ts",
39
- "default": "./dist/volumes.js"
40
- },
41
- "./actions": {
42
- "types": "./dist/actions.d.ts",
43
- "default": "./dist/actions.js"
44
- },
45
- "./ssh-keys": {
46
- "types": "./dist/ssh-keys.d.ts",
47
- "default": "./dist/ssh-keys.js"
48
- },
49
- "./pricing": {
50
- "types": "./dist/pricing.d.ts",
51
- "default": "./dist/pricing.js"
52
- },
53
- "./errors": {
54
- "types": "./dist/errors.d.ts",
55
- "default": "./dist/errors.js"
56
17
  }
57
18
  },
58
- "scripts": {
59
- "build": "bun build src/index.ts --outdir dist --target node --external '@ebowwa/*' --external 'zod' && bun build src/bootstrap/index.ts --outdir dist/bootstrap --target node --external '@ebowwa/*' --external 'zod' && bun build src/onboarding/index.ts --outdir dist/onboarding --target node --external '@ebowwa/*' --external 'zod'",
60
- "prepublishOnly": "bun run build"
61
- },
62
19
  "keywords": [
63
20
  "hetzner",
64
21
  "cloud",
@@ -87,12 +44,6 @@
87
44
  "README.md"
88
45
  ],
89
46
  "dependencies": {
90
- "@ebowwa/codespaces-types": "^1.4.0",
91
- "@ebowwa/terminal": "^0.3.0",
92
47
  "zod": "^3.24.1"
93
- },
94
- "devDependencies": {
95
- "@types/bun": "latest",
96
- "typescript": "^5.9.3"
97
48
  }
98
49
  }
@@ -1,15 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../src/bootstrap/ssh-hardening.ts", "../../src/bootstrap/firewall.ts", "../../src/bootstrap/kernel-hardening.ts", "../../src/bootstrap/security-audit.ts", "../../src/bootstrap/genesis.ts", "../../src/bootstrap/cloud-init.ts"],
4
- "sourcesContent": [
5
- "/**\n * SSH Hardening Cloud-Init Components\n *\n * Composable cloud-init blocks for securing sshd on new servers.\n * Includes: hardened sshd config, fail2ban, and health monitoring.\n *\n * Background: Hetzner public IPs get brute-forced constantly (~5k failed SSH\n * logins per 24h observed on genesis). Without hardening, the default sshd\n * MaxStartups (10:30:100) gets overwhelmed and legitimate connections time out\n * with \"Timed out while waiting for handshake\".\n *\n * This module is imported by both cloud-init.ts (seed/worker nodes) and\n * genesis.ts (control plane) so every new server gets hardened at first boot.\n *\n * Three composable functions return cloud-init line arrays for splicing into\n * the appropriate YAML sections:\n * - sshdHardeningPackages() → packages: section\n * - sshdHardeningWriteFiles() → write_files: section\n * - sshdHardeningRunCmd() → runcmd: section\n */\n\n/**\n * Packages required for SSH hardening.\n * Returns cloud-init YAML lines for the `packages:` section.\n *\n * - fail2ban: bans IPs after repeated failed SSH attempts (3 tries → 1hr ban)\n */\nexport function sshdHardeningPackages(): string[] {\n return [\n \" - fail2ban\",\n ];\n}\n\n/**\n * Files to write at first boot for SSH hardening.\n * Returns cloud-init YAML lines for the `write_files:` section.\n *\n * Drops 5 files onto the server:\n *\n * 1. /etc/ssh/sshd_config.d/hardened.conf\n * - Disables password auth entirely (key-only)\n * - Raises MaxStartups from default 10:30:100 → 20:50:60 so brute-force\n * traffic doesn't starve legitimate connections\n * - Reduces LoginGraceTime from 2min → 30s (attackers hold slots open)\n * - Limits MaxAuthTries to 3 per connection\n * - Enables keepalive (30s interval, 3 missed = disconnect)\n *\n * 2. /etc/fail2ban/jail.local\n * - Monitors sshd via systemd journal\n * - Bans IP for 1 hour after 3 failures within 10 minutes\n * - Uses nftables (Ubuntu 24.04 default firewall backend)\n *\n * 3. /opt/monitoring/sshd-health.sh\n * - Collects sshd + fail2ban + system metrics into JSON\n * - Writes to /var/log/sshd-health.json (read by the app via SSH)\n * - Auto-restarts sshd if it detects it's down\n *\n * 4. /etc/systemd/system/sshd-health.service (oneshot runner)\n * 5. /etc/systemd/system/sshd-health.timer (runs every 60 seconds)\n */\nexport function sshdHardeningWriteFiles(): string[] {\n const lines: string[] = [];\n\n // 1. Hardened sshd config — dropped into sshd_config.d/ so it overrides defaults\n // without touching the main sshd_config file\n lines.push(\" # Hardened SSH configuration\");\n lines.push(\" - path: /etc/ssh/sshd_config.d/hardened.conf\");\n lines.push(\" owner: root:root\");\n lines.push(\" permissions: '0644'\");\n lines.push(\" content: |\");\n lines.push(\" # Hardened SSH config - applied via cloud-init\");\n lines.push(\" PasswordAuthentication no\");\n lines.push(\" PermitEmptyPasswords no\");\n lines.push(\" KbdInteractiveAuthentication no\");\n lines.push(\" PermitRootLogin prohibit-password\");\n lines.push(\" LoginGraceTime 30\");\n lines.push(\" MaxStartups 20:50:60\");\n lines.push(\" ClientAliveInterval 30\");\n lines.push(\" ClientAliveCountMax 3\");\n lines.push(\" MaxAuthTries 3\");\n lines.push(\"\");\n\n // 2. fail2ban jail — 3 failed attempts in 10min = 1hr ban via nftables\n lines.push(\" # fail2ban SSH jail configuration\");\n lines.push(\" - path: /etc/fail2ban/jail.local\");\n lines.push(\" owner: root:root\");\n lines.push(\" permissions: '0644'\");\n lines.push(\" content: |\");\n lines.push(\" [sshd]\");\n lines.push(\" enabled = true\");\n lines.push(\" port = ssh\");\n lines.push(\" backend = systemd\");\n lines.push(\" maxretry = 3\");\n lines.push(\" findtime = 600\");\n lines.push(\" bantime = 3600\");\n lines.push(\" banaction = nftables-multiport\");\n lines.push(\"\");\n\n // 3. Health monitoring script — collects sshd/fail2ban/system stats into JSON\n // Output at /var/log/sshd-health.json is read by the app's collectSSHDHealth()\n // function (src/lib/metrics.ts) every 5 minutes via SSH\n lines.push(\" # sshd health monitoring script\");\n lines.push(\" - path: /opt/monitoring/sshd-health.sh\");\n lines.push(\" owner: root:root\");\n lines.push(\" permissions: '0755'\");\n lines.push(\" content: |\");\n lines.push(\" #!/bin/bash\");\n lines.push(\" set -euo pipefail\");\n lines.push(\" LOGFILE=\\\"/var/log/sshd-health.json\\\"\");\n lines.push(\" sshd_active=$(systemctl is-active ssh 2>/dev/null || echo \\\"inactive\\\")\");\n lines.push(\" sshd_pid=$(pgrep -x sshd | head -1 || echo \\\"0\\\")\");\n lines.push(\" f2b_active=$(systemctl is-active fail2ban 2>/dev/null || echo \\\"inactive\\\")\");\n lines.push(\" f2b_banned=$(fail2ban-client status sshd 2>/dev/null | grep \\\"Currently banned\\\" | awk '{print $NF}' || echo \\\"0\\\")\");\n lines.push(\" f2b_total=$(fail2ban-client status sshd 2>/dev/null | grep \\\"Total banned\\\" | awk '{print $NF}' || echo \\\"0\\\")\");\n lines.push(\" failed_1h=$(journalctl -u ssh --since \\\"1 hour ago\\\" --no-pager 2>/dev/null | grep -c \\\"Failed\\\" || true)\");\n lines.push(\" failed_24h=$(journalctl -u ssh --since \\\"24 hours ago\\\" --no-pager 2>/dev/null | grep -c \\\"Failed\\\" || true)\");\n lines.push(\" active_connections=$(ss -tnp | grep -c \\\":22 \\\" || echo \\\"0\\\")\");\n lines.push(\" uptime_seconds=$(awk '{print int($1)}' /proc/uptime)\");\n lines.push(\" load=$(awk '{print $1}' /proc/loadavg)\");\n lines.push(\" mem_used_pct=$(free | awk '/Mem:/{printf \\\"%.1f\\\", $3/$2*100}')\");\n lines.push(\" timestamp=$(date -u +%Y-%m-%dT%H:%M:%SZ)\");\n lines.push(\" cat > \\\"$LOGFILE\\\" <<HEALTHEOF\");\n lines.push(\" {\");\n lines.push(\" \\\"timestamp\\\": \\\"$timestamp\\\",\");\n lines.push(\" \\\"sshd\\\": { \\\"active\\\": \\\"$sshd_active\\\", \\\"pid\\\": $sshd_pid },\");\n lines.push(\" \\\"fail2ban\\\": { \\\"active\\\": \\\"$f2b_active\\\", \\\"currently_banned\\\": $f2b_banned, \\\"total_banned\\\": $f2b_total },\");\n lines.push(\" \\\"connections\\\": { \\\"active\\\": $active_connections, \\\"failed_1h\\\": $failed_1h, \\\"failed_24h\\\": $failed_24h },\");\n lines.push(\" \\\"system\\\": { \\\"uptime_seconds\\\": $uptime_seconds, \\\"load\\\": $load, \\\"memory_used_pct\\\": $mem_used_pct }\");\n lines.push(\" }\");\n lines.push(\" HEALTHEOF\");\n lines.push(\" if [ \\\"$sshd_active\\\" != \\\"active\\\" ]; then\");\n lines.push(\" logger -t sshd-health -p auth.crit \\\"ALERT: sshd is $sshd_active\\\"\");\n lines.push(\" systemctl start ssh 2>/dev/null || logger -t sshd-health -p auth.crit \\\"FAILED to restart sshd\\\"\");\n lines.push(\" fi\");\n lines.push(\"\");\n\n // 4. Systemd oneshot service — wraps the health script for timer-based execution\n lines.push(\" # sshd health check systemd service\");\n lines.push(\" - path: /etc/systemd/system/sshd-health.service\");\n lines.push(\" owner: root:root\");\n lines.push(\" permissions: '0644'\");\n lines.push(\" content: |\");\n lines.push(\" [Unit]\");\n lines.push(\" Description=sshd health check\");\n lines.push(\" After=ssh.service\");\n lines.push(\" [Service]\");\n lines.push(\" Type=oneshot\");\n lines.push(\" ExecStart=/opt/monitoring/sshd-health.sh\");\n lines.push(\"\");\n\n // 5. Systemd timer — fires the health check every 60 seconds, starting 30s after boot\n lines.push(\" # sshd health check timer (every 60s)\");\n lines.push(\" - path: /etc/systemd/system/sshd-health.timer\");\n lines.push(\" owner: root:root\");\n lines.push(\" permissions: '0644'\");\n lines.push(\" content: |\");\n lines.push(\" [Unit]\");\n lines.push(\" Description=Run sshd health check every minute\");\n lines.push(\" [Timer]\");\n lines.push(\" OnBootSec=30\");\n lines.push(\" OnUnitActiveSec=60\");\n lines.push(\" [Install]\");\n lines.push(\" WantedBy=timers.target\");\n lines.push(\"\");\n\n return lines;\n}\n\n/**\n * Commands to activate all SSH hardening services at first boot.\n * Returns cloud-init YAML lines for the `runcmd:` section.\n *\n * Order matters:\n * 1. Create /opt/monitoring dir (health script target)\n * 2. Reload sshd to pick up hardened.conf (fallback: full restart)\n * 3. Enable + start fail2ban (reads jail.local immediately)\n * 4. Reload systemd to pick up the health service/timer units\n * 5. Enable + start the health timer (begins 60s monitoring loop)\n */\nexport function sshdHardeningRunCmd(): string[] {\n const lines: string[] = [];\n\n lines.push(\" # SSH hardening: reload sshd, enable fail2ban and health monitoring\");\n lines.push(\" - mkdir -p /opt/monitoring\");\n lines.push(\" - systemctl reload ssh || systemctl restart ssh\");\n lines.push(\" - systemctl enable --now fail2ban\");\n lines.push(\" - systemctl daemon-reload\");\n lines.push(\" - systemctl enable --now sshd-health.timer\");\n lines.push(\"\");\n\n return lines;\n}\n",
6
- "/**\n * UFW Firewall Cloud-Init Components\n *\n * Composable cloud-init blocks for securing servers with UFW (Uncomplicated Firewall).\n * Includes: default deny incoming, allow outgoing, rate limiting, and logging.\n *\n * Background: Hetzner public IPs face constant scanning and brute-force attacks.\n * UFW provides a simple interface to iptables/nftables with secure defaults.\n *\n * This module is imported by cloud-init.ts (seed/worker nodes) and genesis.ts\n * (control plane) so every new server gets firewall protection at first boot.\n *\n * Three composable functions return cloud-init line arrays for splicing into\n * the appropriate YAML sections:\n * - ufwFirewallPackages() → packages: section\n * - ufwFirewallWriteFiles() → write_files: section\n * - ufwFirewallRunCmd() → runcmd: section\n *\n * Security Policy:\n * - Default: deny incoming, allow outgoing (stateful)\n * - SSH (22): rate limited to prevent brute-force\n * - HTTP/HTTPS (80/443): allowed for web services\n * - Node Agent (8911): allowed for internal communication\n * - Tailscale (41641): allowed for VPN\n * - Logging: enabled with rate limiting to prevent log flooding\n */\n\n/**\n * UFW firewall configuration options.\n */\nexport interface UFWFirewallOptions {\n /** Allow SSH from specific IPs/CIDRs (default: allow from anywhere) */\n allowSSHFrom?: string[];\n\n /** Allow HTTP (port 80) */\n allowHTTP?: boolean;\n\n /** Allow HTTPS (port 443) */\n allowHTTPS?: boolean;\n\n /** Allow Node Agent port (8911) */\n allowNodeAgent?: boolean;\n\n /** Additional ports to allow */\n additionalPorts?: Array<{ port: number; protocol?: string; comment?: string }>;\n\n /** Enable verbose logging (default: rate-limited logging) */\n verboseLogging?: boolean;\n}\n\n/**\n * Default firewall options for Genesis control plane servers.\n */\nexport const DEFAULT_UFW_GENESIS_OPTIONS: UFWFirewallOptions = {\n allowSSHFrom: [], // Empty = allow from anywhere\n allowHTTP: true,\n allowHTTPS: true,\n allowNodeAgent: false, // Genesis doesn't run node-agent\n verboseLogging: false,\n};\n\n/**\n * Default firewall options for worker/seed servers.\n */\nexport const DEFAULT_UFW_WORKER_OPTIONS: UFWFirewallOptions = {\n allowSSHFrom: [], // Empty = allow from anywhere\n allowHTTP: false,\n allowHTTPS: false,\n allowNodeAgent: true, // Workers run node-agent on port 8911\n verboseLogging: false,\n};\n\n/**\n * Packages required for UFW firewall.\n * Returns cloud-init YAML lines for the `packages:` section.\n *\n * - ufw: Uncomplicated Firewall interface to iptables/nftables\n */\nexport function ufwFirewallPackages(): string[] {\n return [\n \" - ufw\",\n ];\n}\n\n/**\n * Files to write at first boot for UFW firewall configuration.\n * Returns cloud-init YAML lines for the `write_files:` section.\n *\n * Drops 2 files onto the server:\n *\n * 1. /etc/ufw/before.rules\n * - Custom before rules for stateful firewall behavior\n * - Allows loopback, established/related connections\n * - Drops invalid packets early\n *\n * 2. /etc/ufw/sysctl.conf\n * - Enables kernel network security parameters\n * - IP spoofing protection\n * - ICMP redirect protection\n * - Log martian packets\n */\nexport function ufwFirewallWriteFiles(options: UFWFirewallOptions = {}): string[] {\n const lines: string[] = [];\n\n // 1. UFW before.rules - stateful firewall rules applied before UFW rules\n lines.push(\" # UFW before.rules - stateful firewall and network security\");\n lines.push(\" - path: /etc/ufw/before.rules\");\n lines.push(\" owner: root:root\");\n lines.push(\" permissions: '0644'\");\n lines.push(\" content: |\");\n lines.push(\" #\");\n lines.push(\" # UFW before.rules - applied before UFW rules\");\n lines.push(\" #\");\n lines.push(\" # Start with the standard configuration\");\n lines.push(\" *filter\");\n lines.push(\" :ufw-before-input - [0:0]\");\n lines.push(\" :ufw-before-output - [0:0]\");\n lines.push(\" :ufw-before-forward - [0:0]\");\n lines.push(\" :ufw-not-local - [0:0]\");\n lines.push(\" # End of lines to adjust\");\n lines.push(\"\");\n lines.push(\" # Allow all on loopback\");\n lines.push(\" -A ufw-before-input -i lo -j ACCEPT\");\n lines.push(\" -A ufw-before-output -o lo -j ACCEPT\");\n lines.push(\"\");\n lines.push(\" # Drop invalid packets\");\n lines.push(\" -A ufw-before-input -m conntrack --ctstate INVALID -j DROP\");\n lines.push(\"\");\n lines.push(\" # Allow established and related connections\");\n lines.push(\" -A ufw-before-input -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT\");\n lines.push(\" -A ufw-before-output -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT\");\n lines.push(\"\");\n lines.push(\" # Allow ICMP messages (required for PMTU discovery)\");\n lines.push(\" -A ufw-before-input -p icmp --icmp-type destination-unreachable -j ACCEPT\");\n lines.push(\" -A ufw-before-input -p icmp --icmp-type time-exceeded -j ACCEPT\");\n lines.push(\" -A ufw-before-input -p icmp --icmp-type parameter-problem -j ACCEPT\");\n lines.push(\" -A ufw-before-input -p icmp --icmp-type echo-request -j ACCEPT\");\n lines.push(\"\");\n lines.push(\" # Drop packets with bogus TCP flags (potential scan)\");\n lines.push(\" -A ufw-before-input -p tcp --tcp-flags ALL NONE -j DROP\");\n lines.push(\" -A ufw-before-input -p tcp --tcp-flags ALL ALL -j DROP\");\n lines.push(\"\");\n lines.push(\" # Commit changes\");\n lines.push(\" COMMIT\");\n lines.push(\"\");\n\n // 2. UFW sysctl.conf - kernel network security parameters\n lines.push(\" # UFW sysctl.conf - kernel network hardening\");\n lines.push(\" - path: /etc/ufw/sysctl.conf\");\n lines.push(\" owner: root:root\");\n lines.push(\" permissions: '0644'\");\n lines.push(\" content: |\");\n lines.push(\" #\");\n lines.push(\" # UFW sysctl.conf - kernel network security parameters\");\n lines.push(\" #\");\n lines.push(\"\");\n lines.push(\" # IP spoofing protection\");\n lines.push(\" net/ipv4/conf/all/rp_filter=1\");\n lines.push(\" net/ipv4/conf/default/rp_filter=1\");\n lines.push(\"\");\n lines.push(\" # Ignore ICMP redirect messages\");\n lines.push(\" net/ipv4/conf/all/accept_redirects=0\");\n lines.push(\" net/ipv6/conf/all/accept_redirects=0\");\n lines.push(\" net/ipv4/conf/default/accept_redirects=0\");\n lines.push(\" net/ipv6/conf/default/accept_redirects=0\");\n lines.push(\"\");\n lines.push(\" # Ignore send redirects\");\n lines.push(\" net/ipv4/conf/all/send_redirects=0\");\n lines.push(\" net/ipv4/conf/default/send_redirects=0\");\n lines.push(\"\");\n lines.push(\" # Log martian packets (packets with impossible addresses)\");\n lines.push(\" net/ipv4/conf/all/log_martians=1\");\n lines.push(\" net/ipv4/conf/default/log_martians=1\");\n lines.push(\"\");\n lines.push(\" # SYN cookies protection (SYN flood mitigation)\");\n lines.push(\" net/ipv4/tcp_syncookies=1\");\n lines.push(\"\");\n lines.push(\" # Source address verification (spoofing protection)\");\n lines.push(\" net/ipv4/conf/all/secure_redirects=1\");\n lines.push(\" net/ipv4/conf/default/secure_redirects=1\");\n lines.push(\"\");\n\n return lines;\n}\n\n/**\n * Commands to configure and activate UFW firewall at first boot.\n * Returns cloud-init YAML lines for the `runcmd:` section.\n *\n * Order matters:\n * 1. Set default policies (deny incoming, allow outgoing)\n * 2. Allow loopback interface\n * 3. Allow SSH with rate limiting (prevents brute-force)\n * 4. Allow HTTP/HTTPS if enabled\n * 5. Allow Node Agent port if enabled\n * 6. Allow Tailscale port (required for VPN)\n * 7. Enable logging with rate limiting\n * 8. Enable and reload UFW\n * 9. Display firewall status\n */\nexport function ufwFirewallRunCmd(options: UFWFirewallOptions = {}): string[] {\n const {\n allowSSHFrom = [],\n allowHTTP = true,\n allowHTTPS = true,\n allowNodeAgent = false,\n additionalPorts = [],\n verboseLogging = false,\n } = options;\n\n const lines: string[] = [];\n\n lines.push(\" # UFW Firewall: Configure and enable secure firewall\");\n lines.push(\"\");\n\n // Set default policies\n lines.push(\" # Set default policies: deny incoming, allow outgoing\");\n lines.push(\" - ufw --force reset\");\n lines.push(\" - ufw default deny incoming\");\n lines.push(\" - ufw default allow outgoing\");\n lines.push(\" - ufw default deny forwarded\");\n lines.push(\"\");\n\n // Allow loopback\n lines.push(\" # Allow loopback interface\");\n lines.push(\" - ufw allow in on lo\");\n lines.push(\"\");\n\n // Allow SSH with rate limiting\n if (allowSSHFrom.length === 0) {\n // Allow SSH from anywhere with rate limiting\n lines.push(\" # Allow SSH with rate limiting (6 connections in 30 seconds)\");\n lines.push(\" - ufw limit 22/tcp comment 'Rate-limited SSH'\");\n } else {\n // Allow SSH from specific IPs/CIDRs\n for (const source of allowSSHFrom) {\n lines.push(` - ufw allow from ${source} to any port 22 proto tcp comment 'SSH from ${source}'`);\n }\n }\n lines.push(\"\");\n\n // Allow HTTP if enabled\n if (allowHTTP) {\n lines.push(\" # Allow HTTP\");\n lines.push(\" - ufw allow 80/tcp comment 'HTTP'\");\n }\n\n // Allow HTTPS if enabled\n if (allowHTTPS) {\n lines.push(\" # Allow HTTPS\");\n lines.push(\" - ufw allow 443/tcp comment 'HTTPS'\");\n }\n lines.push(\"\");\n\n // Allow Node Agent port if enabled\n if (allowNodeAgent) {\n lines.push(\" # Allow Node Agent (internal communication)\");\n lines.push(\" - ufw allow 8911/tcp comment 'Node Agent'\");\n lines.push(\"\");\n }\n\n // Allow Tailscale (required for VPN functionality)\n lines.push(\" # Allow Tailscale VPN\");\n lines.push(\" - ufw allow 41641/udp comment 'Tailscale'\");\n lines.push(\"\");\n\n // Additional ports\n if (additionalPorts.length > 0) {\n lines.push(\" # Additional custom ports\");\n for (const portConfig of additionalPorts) {\n const protocol = portConfig.protocol || \"tcp\";\n const comment = portConfig.comment || `Custom port ${portConfig.port}`;\n lines.push(` - ufw allow ${portConfig.port}/${protocol} comment '${comment}'`);\n }\n lines.push(\"\");\n }\n\n // Configure logging\n if (verboseLogging) {\n lines.push(\" # Enable verbose logging\");\n lines.push(\" - ufw logging on\");\n lines.push(\" - ufw logging high\");\n } else {\n lines.push(\" # Enable rate-limited logging (prevent log flooding)\");\n lines.push(\" - ufw logging on\");\n lines.push(\" - ufw logging low\");\n }\n lines.push(\"\");\n\n // Enable and reload UFW\n lines.push(\" # Enable and reload UFW\");\n lines.push(\" - ufw --force enable\");\n lines.push(\" - ufw reload\");\n lines.push(\"\");\n\n // Display status\n lines.push(\" # Display firewall status\");\n lines.push(\" - ufw status verbose > /var/log/ufw-bootstrap-status.log\");\n lines.push(\"\");\n\n return lines;\n}\n\n/**\n * Generate complete UFW firewall configuration for Genesis servers.\n *\n * @param options - UFW firewall options (uses DEFAULT_UFW_GENESIS_OPTIONS if not provided)\n * @returns Object with packages, writeFiles, and runCmd arrays\n */\nexport function generateUFWFirewallForGenesis(\n options: UFWFirewallOptions = DEFAULT_UFW_GENESIS_OPTIONS,\n): {\n packages: string[];\n writeFiles: string[];\n runCmd: string[];\n} {\n return {\n packages: ufwFirewallPackages(),\n writeFiles: ufwFirewallWriteFiles(options),\n runCmd: ufwFirewallRunCmd(options),\n };\n}\n\n/**\n * Generate complete UFW firewall configuration for worker/seed servers.\n *\n * @param options - UFW firewall options (uses DEFAULT_UFW_WORKER_OPTIONS if not provided)\n * @returns Object with packages, writeFiles, and runCmd arrays\n */\nexport function generateUFWFirewallForWorker(\n options: UFWFirewallOptions = DEFAULT_UFW_WORKER_OPTIONS,\n): {\n packages: string[];\n writeFiles: string[];\n runCmd: string[];\n} {\n return {\n packages: ufwFirewallPackages(),\n writeFiles: ufwFirewallWriteFiles(options),\n runCmd: ufwFirewallRunCmd(options),\n };\n}\n",
7
- "/**\n * Kernel Hardening Cloud-Init Components\n *\n * Composable cloud-init blocks for securing the Linux kernel on new servers.\n * Implements 2026 best practices for network stack hardening, IP spoofing\n * protection, SYN flood mitigation, and secure core dump policies.\n *\n * Background: Public-facing VPS servers are constantly probed and attacked.\n * Default Linux kernel settings prioritize compatibility over security. This\n * module applies CIS Benchmark-aligned hardening via /etc/sysctl.d/ which\n * persists across reboots and overrides defaults.\n *\n * Three composable functions return cloud-init line arrays for splicing into\n * the appropriate YAML sections:\n * - kernelHardeningPackages() → packages: section (currently empty, reserved)\n * - kernelHardeningWriteFiles() → write_files: section (drops sysctl config)\n * - kernelHardeningRunCmd() → runcmd: section (applies settings immediately)\n *\n * Security Measures Implemented:\n * 1. Network Stack Hardening: SYN cookies, ICMP rate limits, martian packet logging\n * 2. IP Spoofing Protection: Reverse path filtering, source address verification\n * 3. SYN Flood Protection: TCP SYN cookies, reuse time_wait connections\n * 4. Core Dump Restrictions: Disable setuid dumps, limit core dump size to 0\n * 5. File Permissions: Hard links, symlinks, FIFO protection\n * 6. Memory Protection: ASLR, randomize_va_space\n *\n * References:\n * - CIS Benchmark for Ubuntu Linux 24.04\n * - NIST SP 800-53 Revision 5\n * - https://www.kernel.org/doc/Documentation/networking/ip-sysctl.txt\n */\n\n/**\n * Packages required for kernel hardening.\n * Returns cloud-init YAML lines for the `packages:` section.\n *\n * Note: All kernel hardening is done via sysctl configuration, which uses\n * built-in kernel functionality. No additional packages are required.\n * This function is reserved for future expansion (e.g., auditd, kexec-tools).\n */\nexport function kernelHardeningPackages(): string[] {\n return [\n // Reserved for future packages (auditd, kexec-tools, etc.)\n // Currently empty - all hardening via sysctl\n ];\n}\n\n/**\n * Kernel sysctl configuration file for comprehensive hardening.\n * Returns cloud-init YAML lines for the `write_files:` section.\n *\n * Drops /etc/sysctl.d/99-security-hardening.conf which:\n * - Takes precedence over /etc/sysctl.conf (99- prefix ensures last load)\n * - Persists across reboots (sysctl.d files are applied on boot)\n * - Can be applied immediately via `sysctl --system` (see runcmd)\n *\n * Settings organized by category:\n * 1. IP Spoofing Protection: rp_filter, secure redirects\n * 2. SYN Flood Protection: syncookies, tcp_tw_reuse\n * 3. Network Stack: ICMP rate limits, martian logging, ignore broadcasts\n * 4. Core Dumps: Disabled for setuid programs, limited for all processes\n * 5. Memory Protection: ASLR, randomize_va_space\n * 6. Filesystem: Hard link/symlink protection\n */\nexport function kernelHardeningWriteFiles(): string[] {\n const lines: string[] = [];\n\n lines.push(\" # Kernel hardening: sysctl.d configuration for 2026 best practices\");\n lines.push(\" # This file persists across reboots and overrides /etc/sysctl.conf\");\n lines.push(\" - path: /etc/sysctl.d/99-security-hardening.conf\");\n lines.push(\" owner: root:root\");\n lines.push(\" permissions: '0644'\");\n lines.push(\" content: |\");\n lines.push(\" # =================================================================\");\n lines.push(\" # Kernel Security Hardening Configuration\");\n lines.push(\" # =================================================================\");\n lines.push(\" # Applied via cloud-init for com.hetzner.codespaces\");\n lines.push(\" # Version: 1.0.0 (2026 best practices)\");\n lines.push(\" #\");\n lines.push(\" # This configuration follows CIS Benchmark and NIST guidelines\");\n lines.push(\" # See: /usr/share/doc/linux-doc/sysctl/ for parameter documentation\");\n lines.push(\"\");\n lines.push(\" # =================================================================\");\n lines.push(\" # 1. IP SPOOFING PROTECTION\");\n lines.push(\" # =================================================================\");\n lines.push(\" # Enable reverse path filtering (validates source addresses)\");\n lines.push(\" # Prevents IP spoofing attacks by dropping packets with invalid sources\");\n lines.push(\" net.ipv4.conf.all.rp_filter = 1\");\n lines.push(\" net.ipv4.conf.default.rp_filter = 1\");\n lines.push(\"\");\n lines.push(\" # Log martian packets (packets with impossible addresses)\");\n lines.push(\" # Helps detect spoofing attempts and network misconfigurations\");\n lines.push(\" net.ipv4.conf.all.log_martians = 1\");\n lines.push(\"\");\n lines.push(\" # Disable ICMP redirect acceptance (prevent MITM attacks)\");\n lines.push(\" net.ipv4.conf.all.accept_redirects = 0\");\n lines.push(\" net.ipv4.conf.default.accept_redirects = 0\");\n lines.push(\" net.ipv4.conf.all.secure_redirects = 0\");\n lines.push(\" net.ipv4.conf.default.secure_redirects = 0\");\n lines.push(\"\");\n lines.push(\" # Disable sending ICMP redirects\");\n lines.push(\" net.ipv4.conf.all.send_redirects = 0\");\n lines.push(\" net.ipv4.conf.default.send_redirects = 0\");\n lines.push(\"\");\n lines.push(\" # =================================================================\");\n lines.push(\" # 2. SYN FLOOD PROTECTION\");\n lines.push(\" # =================================================================\");\n lines.push(\" # Enable SYN cookies (protects against SYN flood attacks)\");\n lines.push(\" # Allows server to continue accepting connections under SYN flood\");\n lines.push(\" net.ipv4.tcp_syncookies = 1\");\n lines.push(\"\");\n lines.push(\" # Reuse TIME_WAIT sockets for new connections (safer, faster)\");\n lines.push(\" # Reduces connection table exhaustion under high load\");\n lines.push(\" net.ipv4.tcp_tw_reuse = 1\");\n lines.push(\"\");\n lines.push(\" # Reduce SYN backlog and timeouts for faster detection\");\n lines.push(\" net.ipv4.tcp_max_syn_backlog = 2048\");\n lines.push(\" net.ipv4.tcp_synack_retries = 2\");\n lines.push(\" net.ipv4.tcp_syn_retries = 5\");\n lines.push(\"\");\n lines.push(\" # =================================================================\");\n lines.push(\" # 3. NETWORK STACK HARDENING\");\n lines.push(\" # =================================================================\");\n lines.push(\" # Disable ICMP redirect acceptance (IPv6)\");\n lines.push(\" net.ipv6.conf.all.accept_redirects = 0\");\n lines.push(\" net.ipv6.conf.default.accept_redirects = 0\");\n lines.push(\"\");\n lines.push(\" # Ignore ICMP broadcasts (prevent smurf attacks)\");\n lines.push(\" net.ipv4.icmp_echo_ignore_broadcasts = 1\");\n lines.push(\"\");\n lines.push(\" # Ignore bogus ICMP error responses (prevent ICMP attacks)\");\n lines.push(\" net.ipv4.icmp_ignore_bogus_error_responses = 1\");\n lines.push(\"\");\n lines.push(\" # Enable TCP timestamps (RFC 1323) for better sequence handling\");\n lines.push(\" # Also protects against wrapped sequence number attacks\");\n lines.push(\" net.ipv4.tcp_timestamps = 1\");\n lines.push(\"\");\n lines.push(\" # Enable TCP selective acknowledgments (better performance)\");\n lines.push(\" net.ipv4.tcp_sack = 1\");\n lines.push(\"\");\n lines.push(\" # =================================================================\");\n lines.push(\" # 4. CORE DUMP RESTRICTIONS\");\n lines.push(\" # =================================================================\");\n lines.push(\" # Disable core dumps for setuid programs (prevent privilege escalation)\");\n lines.push(\" fs.suid_dumpable = 0\");\n lines.push(\"\");\n lines.push(\" # Limit core dump size to 0 (disable core dumps)\");\n lines.push(\" # Override in /etc/security/limits.conf if needed for debugging\");\n lines.push(\" kernel.core_pattern = |/bin/false\");\n lines.push(\"\");\n lines.push(\" # =================================================================\");\n lines.push(\" # 5. MEMORY PROTECTION (ASLR)\");\n lines.push(\" # =================================================================\");\n lines.push(\" # Enable Address Space Layout Randomization (full)\");\n lines.push(\" # Makes exploitation of memory corruption vulnerabilities harder\");\n lines.push(\" # 0: Disabled, 1: Conservative, 2: Full (default)\");\n lines.push(\" kernel.randomize_va_space = 2\");\n lines.push(\"\");\n lines.push(\" # =================================================================\");\n lines.push(\" # 6. FILESYSTEM PROTECTION\");\n lines.push(\" # =================================================================\");\n lines.push(\" # Hard link/symlink protection (prevent time-of-check time-of-use)\");\n lines.push(\" fs.protected_hardlinks = 1\");\n lines.push(\" fs.protected_symlinks = 1\");\n lines.push(\"\");\n lines.push(\" # FIFO protection (prevent FIFO attacks on world-writable directories)\");\n lines.push(\" fs.protected_fifos = 2\");\n lines.push(\"\");\n lines.push(\" # Regular file protection (prevent file overwrite attacks)\");\n lines.push(\" fs.protected_regular = 2\");\n lines.push(\"\");\n lines.push(\" # =================================================================\");\n lines.push(\" # 7. NETWORK BEHAVIOR TUNING\");\n lines.push(\" # =================================================================\");\n lines.push(\" # Enable TCP Fast Open (TFO) for reduced latency\");\n lines.push(\" net.ipv4.tcp_fastopen = 3\");\n lines.push(\"\");\n lines.push(\" # Disable source routing (prevent packet routing manipulation)\");\n lines.push(\" net.ipv4.conf.all.accept_source_route = 0\");\n lines.push(\" net.ipv4.conf.default.accept_source_route = 0\");\n lines.push(\" net.ipv6.conf.all.accept_source_route = 0\");\n lines.push(\" net.ipv6.conf.default.accept_source_route = 0\");\n lines.push(\"\");\n lines.push(\" # Enable TCP window scaling (RFC 7323) for high-bandwidth links\");\n lines.push(\" net.ipv4.tcp_window_scaling = 1\");\n lines.push(\"\");\n lines.push(\" # =================================================================\");\n lines.push(\" # 8. SECURITY-RELATED KERNEL PARAMETERS\");\n lines.push(\" # =================================================================\");\n lines.push(\" # Disable magic sysrq key (prevent console-based attacks)\");\n lines.push(\" # 0: Disabled, 1: Enable (for debugging only)\");\n lines.push(\" kernel.sysrq = 0\");\n lines.push(\"\");\n lines.push(\" # Disable kexec system call (prevent kernel replacement)\");\n lines.push(\" # 0: Disabled, 1: Enabled\");\n lines.push(\" kernel.kexec_load = 0\");\n lines.push(\"\");\n lines.push(\" # Disable user namespaces (prevent container breakouts)\");\n lines.push(\" # 0: Disabled, 1: Enabled\");\n lines.push(\" user.max_user_namespaces = 0\");\n lines.push(\"\");\n lines.push(\" # Enable unprivileged bpf disabled (prevent eBPF-based exploits)\");\n lines.push(\" # 0: Disabled, 1: Enabled\");\n lines.push(\" kernel.unprivileged_bpf_disabled = 1\");\n lines.push(\"\");\n lines.push(\" # =================================================================\");\n lines.push(\" # 9. ADDITIONAL HARDENING (2026)\");\n lines.push(\" # =================================================================\");\n lines.push(\" # Disable IPv6 if not needed (uncomment if IPv6 is disabled)\");\n lines.push(\" # net.ipv6.conf.all.disable_ipv6 = 1\");\n lines.push(\" # net.ipv6.conf.default.disable_ipv6 = 1\");\n lines.push(\"\");\n lines.push(\" # Enable dmesg restriction (prevent kernel info leaks)\");\n lines.push(\" kernel.dmesg_restrict = 1\");\n lines.push(\"\");\n lines.push(\" # Restrict ptrace scope (prevent process tracing by non-parent)\");\n lines.push(\" # 0: Traditional, 1: Restricted, 2: Admin-only, 3: No attach\");\n lines.push(\" kernel.yama.ptrace_scope = 2\");\n lines.push(\"\");\n lines.push(\" # =================================================================\");\n lines.push(\" # 10. PERFORMANCE TUNING (safe defaults)\");\n lines.push(\" # =================================================================\");\n lines.push(\" # Increase connection tracking table size (for stateful firewalls)\");\n lines.push(\" net.netfilter.nf_conntrack_max = 262144\");\n lines.push(\"\");\n lines.push(\" # Reduce TCP keepalive timeouts for faster dead peer detection\");\n lines.push(\" net.ipv4.tcp_keepalive_time = 600\");\n lines.push(\" net.ipv4.tcp_keepalive_intvl = 30\");\n lines.push(\" net.ipv4.tcp_keepalive_probes = 3\");\n lines.push(\"\");\n\n return lines;\n}\n\n/**\n * Commands to apply kernel hardening settings immediately at first boot.\n * Returns cloud-init YAML lines for the `runcmd:` section.\n *\n * Order matters:\n * 1. Load all sysctl settings from /etc/sysctl.d/*.conf\n * 2. Apply settings immediately (don't wait for reboot)\n * 3. Log applied settings for audit trail\n * 4. Display summary for cloud-init output verification\n */\nexport function kernelHardeningRunCmd(): string[] {\n const lines: string[] = [];\n\n lines.push(\" # Kernel hardening: apply sysctl settings immediately\");\n lines.push(\" # Settings are already in /etc/sysctl.d/99-security-hardening.conf\");\n lines.push(\"\");\n lines.push(\" # Apply all sysctl settings (overrides defaults immediately)\");\n lines.push(\" - sysctl --system\");\n lines.push(\"\");\n lines.push(\" # Log applied settings for audit trail\");\n lines.push(\" - sysctl -a | grep -E '(rp_filter|syncookies|randomize_va|suid_dump)' > /var/log/kernel-hardening.log 2>&1 || true\");\n lines.push(\"\");\n lines.push(\" # Display summary of critical hardening settings\");\n lines.push(\" - |\");\n lines.push(\" echo '========================================'\");\n lines.push(\" echo 'Kernel Hardening Applied (2026)'\");\n lines.push(\" echo '========================================'\");\n lines.push(\" echo 'IP Spoof Protection: '$(sysctl -n net.ipv4.conf.all.rp_filter)\");\n lines.push(\" echo 'SYN Cookies: '$(sysctl -n net.ipv4.tcp_syncookies)\");\n lines.push(\" echo 'ASLR Level: '$(sysctl -n kernel.randomize_va_space)\");\n lines.push(\" echo 'SUID Core Dumps: '$(sysctl -n fs.suid_dumpable)\");\n lines.push(\" echo 'Hard Links Protected: '$(sysctl -n fs.protected_hardlinks)\");\n lines.push(\" echo 'Ptrace Scope: '$(sysctl -n kernel.yama.ptrace_scope)\");\n lines.push(\" echo '========================================'\");\n lines.push(\"\");\n\n return lines;\n}\n",
8
- "/**\n * Security Audit Cloud-Init Components\n *\n * Composable cloud-init blocks for running post-bootstrap security audits.\n * Generates comprehensive security reports for verification and compliance.\n *\n * This module runs LAST in the bootstrap sequence, after all other security\n * hardening is applied. It captures the state of the system for verification.\n *\n * Three composable functions return cloud-init line arrays for splicing into\n * the appropriate YAML sections:\n * - securityAuditPackages() → packages: section\n * - securityAuditWriteFiles() → write_files: section\n * - securityAuditRunCmd() → runcmd: section\n */\n\n/**\n * Packages required for security auditing.\n * Returns cloud-init YAML lines for the `packages:` section.\n *\n * - lynis: Comprehensive security auditing tool\n */\nexport function securityAuditPackages(): string[] {\n return [\n \" - lynis\",\n ];\n}\n\n/**\n * Files to write at first boot for security auditing.\n * Returns cloud-init YAML lines for the `write_files:` section.\n *\n * Drops 1 file onto the server:\n *\n * 1. /opt/monitoring/security-audit.sh\n * - Collects security metrics (UFW, fail2ban, sshd, sysctl)\n * - Runs Lynis audit with warnings-only output\n * - Generates JSON report at /var/log/security-audit.json\n * - Logs summary to /var/log/security-audit.log\n */\nexport function securityAuditWriteFiles(): string[] {\n const lines: string[] = [];\n\n // 1. Security audit script - comprehensive security check\n lines.push(\" # Security audit script - runs after all hardening\");\n lines.push(\" - path: /opt/monitoring/security-audit.sh\");\n lines.push(\" owner: root:root\");\n lines.push(\" permissions: '0755'\");\n lines.push(\" content: |\");\n lines.push(\" #!/bin/bash\");\n lines.push(\" set -euo pipefail\");\n lines.push(\" LOGFILE=\\\"/var/log/security-audit.log\\\"\");\n lines.push(\" REPORTFILE=\\\"/var/log/security-audit.json\\\"\");\n lines.push(\" echo \\\"Security Audit started at $(date -Iseconds)\\\" | tee \\\"$LOGFILE\\\"\");\n lines.push(\"\");\n lines.push(\" # Firewall status\");\n lines.push(\" echo \\\"\\\" | tee -a \\\"$LOGFILE\\\"\");\n lines.push(\" echo \\\"=== UFW Firewall Status ===\\\" | tee -a \\\"$LOGFILE\\\"\");\n lines.push(\" ufw status verbose | tee -a \\\"$LOGFILE\\\" || true\");\n lines.push(\"\");\n lines.push(\" # Fail2ban status\");\n lines.push(\" echo \\\"\\\" | tee -a \\\"$LOGFILE\\\"\");\n lines.push(\" echo \\\"=== Fail2ban Status ===\\\" | tee -a \\\"$LOGFILE\\\"\");\n lines.push(\" systemctl status fail2ban --no-pager | tee -a \\\"$LOGFILE\\\" || true\");\n lines.push(\" fail2ban-client status sshd | tee -a \\\"$LOGFILE\\\" || true\");\n lines.push(\"\");\n lines.push(\" # SSHd status\");\n lines.push(\" echo \\\"\\\" | tee -a \\\"$LOGFILE\\\"\");\n lines.push(\" echo \\\"=== SSHd Status ===\\\" | tee -a \\\"$LOGFILE\\\"\");\n lines.push(\" systemctl status ssh --no-pager | tee -a \\\"$LOGFILE\\\" || true\");\n lines.push(\" sshd -T | grep -E '(PasswordAuthentication|PermitRootLogin|MaxStartups)' | tee -a \\\"$LOGFILE\\\" || true\");\n lines.push(\"\");\n lines.push(\" # Kernel hardening status\");\n lines.push(\" echo \\\"\\\" | tee -a \\\"$LOGFILE\\\"\");\n lines.push(\" echo \\\"=== Kernel Hardening Status ===\\\" | tee -a \\\"$LOGFILE\\\"\");\n lines.push(\" sysctl randomize_va_space kptr_restrict tcp_syncookies | tee -a \\\"$LOGFILE\\\" || true\");\n lines.push(\"\");\n lines.push(\" # Lynis audit (warnings only, non-interactive)\");\n lines.push(\" echo \\\"\\\" | tee -a \\\"$LOGFILE\\\"\");\n lines.push(\" echo \\\"=== Lynis Security Audit ===\\\" | tee -a \\\"$LOGFILE\\\"\");\n lines.push(\" lynis audit system --warnings-only --quiet 2>&1 | tee -a \\\"$LOGFILE\\\" || true\");\n lines.push(\"\");\n lines.push(\" # Generate JSON report\");\n lines.push(\" timestamp=$(date -u +%Y-%m-%dT%H:%M:%SZ)\");\n lines.push(\" ufw_active=$(ufw status | grep -c \\\"Status: active\\\" || echo \\\"0\\\")\");\n lines.push(\" fail2ban_active=$(systemctl is-active fail2ban 2>/dev/null || echo \\\"inactive\\\")\");\n lines.push(\" sshd_active=$(systemctl is-active ssh 2>/dev/null || echo \\\"inactive\\\")\");\n lines.push(\" aslr_enabled=$(cat /proc/sys/kernel/randomize_va_space 2>/dev/null || echo \\\"0\\\")\");\n lines.push(\" cat > \\\"$REPORTFILE\\\" <<AUDEOF\");\n lines.push(\" {\");\n lines.push(\" \\\"timestamp\\\": \\\"$timestamp\\\",\");\n lines.push(\" \\\"firewall\\\": { \\\"active\\\": $ufw_active },\");\n lines.push(\" \\\"fail2ban\\\": { \\\"active\\\": \\\"$fail2ban_active\\\" },\");\n lines.push(\" \\\"sshd\\\": { \\\"active\\\": \\\"$sshd_active\\\" },\");\n lines.push(\" \\\"kernel_hardening\\\": { \\\"aslr_enabled\\\": $aslr_enabled }\");\n lines.push(\" }\");\n lines.push(\" AUDEOF\");\n lines.push(\" echo \\\"Security Audit completed at $(date -Iseconds)\\\" | tee -a \\\"$LOGFILE\\\"\");\n lines.push(\" echo \\\"Report saved to $REPORTFILE\\\" | tee -a \\\"$LOGFILE\\\"\");\n lines.push(\"\");\n\n return lines;\n}\n\n/**\n * Commands to run security audit at first boot.\n * Returns cloud-init YAML lines for the `runcmd:` section.\n *\n * Order matters:\n * 1. Create /opt/monitoring directory (audit script target)\n * 2. Run security audit script (captures state after all hardening)\n * 3. Log audit completion for verification\n */\nexport function securityAuditRunCmd(): string[] {\n const lines: string[] = [];\n\n lines.push(\" # Security audit: run comprehensive security check\");\n lines.push(\" - mkdir -p /opt/monitoring\");\n lines.push(\" - /opt/monitoring/security-audit.sh\");\n lines.push(\" - echo \\\"Security audit completed at $(date -Iseconds)\\\" | tee -a /root/.bootstrap-status\");\n lines.push(\"\");\n\n return lines;\n}\n",
9
- "/**\n * Genesis Server Bootstrap Generator\n *\n * Generates cloud-init YAML scripts for Genesis server provisioning.\n * Genesis is a bootstrap/control plane node that runs com.hetzner.codespaces\n * and manages Hetzner VPS worker nodes.\n *\n * Security Integration:\n * This module integrates all security modules in the correct order:\n * 1. UFW Firewall (network-level defense)\n * 2. Kernel Hardening (system-level hardening)\n * 3. SSH Hardening (service-level hardening)\n * 4. Security Audit (verification and reporting)\n */\n\nimport {\n sshdHardeningPackages,\n sshdHardeningWriteFiles,\n sshdHardeningRunCmd,\n} from \"./ssh-hardening\";\nimport {\n kernelHardeningPackages,\n kernelHardeningWriteFiles,\n kernelHardeningRunCmd,\n} from \"./kernel-hardening\";\nimport {\n ufwFirewallPackages,\n ufwFirewallWriteFiles,\n ufwFirewallRunCmd,\n generateUFWFirewallForGenesis,\n DEFAULT_UFW_GENESIS_OPTIONS,\n} from \"./firewall\";\nimport {\n securityAuditPackages,\n securityAuditWriteFiles,\n securityAuditRunCmd,\n} from \"./security-audit\";\n\nexport interface GenesisBootstrapOptions {\n /** Admin SSH public key for genesis user */\n adminSSHKey: string;\n\n /** Genesis repository URL (default: https://github.com/ebowwa/com.hetzner.codespaces) */\n genesisRepo?: string;\n\n /** Genesis repository branch or tag */\n genesisBranch?: string;\n\n /** Genesis server hostname (default: genesis) */\n hostname?: string;\n\n /** Default Hetzner server type for workers */\n defaultServerType?: string;\n\n /** Default Hetzner location */\n defaultLocation?: string;\n\n /** Maximum concurrent workers */\n maxWorkers?: string;\n\n /** Additional packages to install */\n packages?: string[];\n\n /** Additional commands to run after genesis setup */\n additionalCommands?: string[];\n\n /** Enable security hardening (default: true) */\n enableSecurity?: boolean;\n}\n\n/**\n * Generate a cloud-init YAML script for Genesis server bootstrap\n *\n * @param options - Genesis bootstrap configuration options\n * @returns Cloud-init YAML string\n */\nexport function generateGenesisBootstrap(options: GenesisBootstrapOptions): string {\n const {\n adminSSHKey,\n genesisRepo = \"https://github.com/ebowwa/com.hetzner.codespaces\",\n genesisBranch = \"main\",\n hostname = \"genesis\",\n defaultServerType = \"cpx11\",\n defaultLocation = \"fsn1\",\n maxWorkers = \"10\",\n packages = [],\n additionalCommands = [],\n enableSecurity = true,\n } = options;\n\n if (!adminSSHKey) {\n throw new Error(\"adminSSHKey is required for Genesis bootstrap\");\n }\n\n const lines: string[] = [];\n\n // Cloud-config header\n lines.push(\"#cloud-config\");\n lines.push(\"# Genesis Server Bootstrap Configuration\");\n lines.push(\"# Version: 1.0.0\");\n lines.push(\"\");\n lines.push(\"# This cloud-init config bootstraps a Genesis server that:\");\n lines.push(\"# - Runs com.hetzner.codespaces web application\");\n lines.push(\"# - Uses the existing Hetzner API to create any server\");\n lines.push(\"# - Can be ephemeral and recreated at any time\");\n lines.push(\"\");\n lines.push(\"# IMPORTANT: Never store secrets in cloud-init! Use Vault/SOPS/external sources.\");\n lines.push(\"\");\n\n // STAGE 1: Network & Early Setup\n lines.push(\"# =====================================================\");\n lines.push(\"# STAGE 1: Network & Early Setup (Network stage)\");\n lines.push(\"# =====================================================\");\n lines.push(\"\");\n lines.push(`hostname: ${hostname}`);\n lines.push(\"manage_etc_hosts: true\");\n lines.push(\"timezone: UTC\");\n lines.push(\"\");\n\n // STAGE 2: SSH & Security\n lines.push(\"# =====================================================\");\n lines.push(\"# STAGE 2: SSH & Security (Network stage)\");\n lines.push(\"# =====================================================\");\n lines.push(\"\");\n lines.push(\"ssh_pwauth: false\");\n lines.push(\"\");\n lines.push(\"# Create genesis service user\");\n lines.push(\"users:\");\n lines.push(\" - name: genesis\");\n lines.push(\" gecos: Genesis Service Account\");\n lines.push(\" primary_group: genesis\");\n lines.push(\" groups: docker,wheel\");\n lines.push(\" sudo: ALL=(ALL) NOPASSWD:ALL\");\n lines.push(\" shell: /bin/bash\");\n lines.push(\" lock_passwd: true\");\n lines.push(\" ssh_authorized_keys:\");\n lines.push(` - ${adminSSHKey}`);\n lines.push(\"\");\n\n // STAGE 3: Package Management\n lines.push(\"# =====================================================\");\n lines.push(\"# STAGE 3: Package Management (Config stage)\");\n lines.push(\"# =====================================================\");\n lines.push(\"\");\n lines.push(\"package_update: true\");\n lines.push(\"package_upgrade: false\");\n lines.push(\"package_reboot_if_required: true\");\n lines.push(\"\");\n lines.push(\"packages:\");\n lines.push(\" - curl\");\n lines.push(\" - wget\");\n lines.push(\" - git\");\n lines.push(\" - unzip\");\n lines.push(\" - jq\");\n lines.push(\" - build-essential\");\n\n // Security Module 1: UFW Firewall packages\n if (enableSecurity) {\n lines.push(\" # Security: UFW Firewall\");\n lines.push(...ufwFirewallPackages());\n }\n\n // Security Module 2: Kernel hardening packages\n if (enableSecurity) {\n lines.push(\" # Security: Kernel hardening\");\n lines.push(...kernelHardeningPackages());\n }\n\n // Security Module 3: SSH hardening packages (fail2ban)\n if (enableSecurity) {\n lines.push(\" # Security: SSH hardening\");\n lines.push(...sshdHardeningPackages());\n }\n\n // Security Module 4: Security audit packages (lynis)\n if (enableSecurity) {\n lines.push(\" # Security: Security audit\");\n lines.push(...securityAuditPackages());\n }\n\n // Add additional packages\n for (const pkg of packages) {\n lines.push(` - ${pkg}`);\n }\n lines.push(\"\");\n\n // STAGE 4: Application Setup\n lines.push(\"# =====================================================\");\n lines.push(\"# STAGE 4: Application Setup (Config stage)\");\n lines.push(\"# =====================================================\");\n lines.push(\"\");\n lines.push(\"write_files:\");\n\n // Genesis directories\n lines.push(\" # Genesis application directories\");\n lines.push(\" - path: /opt/genesis\");\n lines.push(\" owner: genesis:genesis\");\n lines.push(\" permissions: '0755'\");\n lines.push(\"\");\n lines.push(\" - path: /opt/genesis/data\");\n lines.push(\" owner: genesis:genesis\");\n lines.push(\" permissions: '0755'\");\n lines.push(\"\");\n lines.push(\" - path: /var/log/genesis\");\n lines.push(\" owner: genesis:genesis\");\n lines.push(\" permissions: '0755'\");\n lines.push(\"\");\n\n // Environment file template\n lines.push(\" # Environment file template (do NOT include actual secrets)\");\n lines.push(\" - path: /etc/default/genesis.template\");\n lines.push(\" owner: genesis:genesis\");\n lines.push(\" permissions: '0640'\");\n lines.push(\" content: |\");\n lines.push(\" # Genesis Server Environment Configuration\");\n lines.push(\" # Copy this to /etc/default/genesis and fill in required values\");\n lines.push(\" #\");\n lines.push(\" # DO NOT commit actual secrets to version control!\");\n lines.push(\"\");\n lines.push(\" # Application Settings\");\n lines.push(\" NODE_ENV=production\");\n lines.push(` PORT=3000`);\n lines.push(` HOST=0.0.0.0`);\n lines.push(\"\");\n lines.push(\" # Hetzner API (REQUIRED - use Vault or Secrets Manager in production)\");\n lines.push(\" # HETZNER_API_TOKEN should be set securely after bootstrap\");\n lines.push(\" HETZNER_DEFAULT_TYPE=\" + defaultServerType);\n lines.push(\" HETZNER_DEFAULT_LOCATION=\" + defaultLocation);\n lines.push(\" MAX_WORKER_NODES=\" + maxWorkers);\n lines.push(\"\");\n\n // Systemd service unit\n lines.push(\" # Genesis systemd service unit\");\n lines.push(\" - path: /etc/systemd/system/genesis.service\");\n lines.push(\" owner: root:root\");\n lines.push(\" permissions: '0644'\");\n lines.push(\" content: |\");\n lines.push(\" [Unit]\");\n lines.push(\" Description=Genesis Application Server (com.hetzner.codespaces)\");\n lines.push(\" Documentation=https://github.com/ebowwa/com.hetzner.codespaces\");\n lines.push(\" After=network-online.target\");\n lines.push(\" Wants=network-online.target\");\n lines.push(\"\");\n lines.push(\" [Service]\");\n lines.push(\" Type=simple\");\n lines.push(\" User=genesis\");\n lines.push(\" Group=genesis\");\n lines.push(\" WorkingDirectory=/opt/genesis\");\n lines.push(\"\");\n lines.push(\" # Execution\");\n lines.push(\" ExecStart=/usr/bin/bun start\");\n lines.push(\" ExecReload=/bin/kill -HUP $MAINPID\");\n lines.push(\"\");\n lines.push(\" # Restart Policy (with rate limiting)\");\n lines.push(\" Restart=on-failure\");\n lines.push(\" RestartSec=5s\");\n lines.push(\" StartLimitIntervalSec=300\");\n lines.push(\" StartLimitBurst=5\");\n lines.push(\"\");\n lines.push(\" # Logging\");\n lines.push(\" StandardOutput=journal\");\n lines.push(\" StandardError=journal\");\n lines.push(\" SyslogIdentifier=genesis\");\n lines.push(\"\");\n lines.push(\" # Environment\");\n lines.push(' Environment=\"NODE_ENV=production\"');\n lines.push(\" EnvironmentFile=/etc/default/genesis\");\n lines.push(\" EnvironmentFile=-/etc/default/genesis.local\");\n lines.push(\"\");\n lines.push(\" # Resource Limits\");\n lines.push(\" LimitNOFILE=65536\");\n lines.push(\"\");\n \n // Security hardening for genesis service\n if (enableSecurity) {\n lines.push(\" # Security Hardening\");\n lines.push(\" NoNewPrivileges=true\");\n lines.push(\" PrivateTmp=true\");\n lines.push(\" ProtectSystem=strict\");\n lines.push(\" ProtectHome=true\");\n lines.push(\" ReadWritePaths=/opt/genesis/data /var/log/genesis\");\n } else {\n lines.push(\" # Security Hardening (minimal)\");\n lines.push(\" NoNewPrivileges=false\");\n lines.push(\" PrivateTmp=false\");\n }\n lines.push(\"\");\n lines.push(\" [Install]\");\n lines.push(\" WantedBy=multi-user.target\");\n lines.push(\"\");\n\n // Bootstrap status tracking\n lines.push(\" # Bootstrap status tracking\");\n lines.push(\" - path: /root/.genesis-bootstrap-status\");\n lines.push(\" owner: root:root\");\n lines.push(\" permissions: '0644'\");\n lines.push(\" content: |\");\n lines.push(\" status=started\");\n lines.push(\" started_at=$(date -Iseconds)\");\n lines.push(\" source=cloud-init\");\n lines.push(\" version=1.0.0\");\n if (enableSecurity) {\n lines.push(\" security=enabled\");\n }\n lines.push(\"\");\n\n // Add bun to /etc/environment\n lines.push(\" # Add bun to /etc/environment for all users/shells\");\n lines.push(\" # Format: Simple KEY=\\\"value\\\" pairs, no variable expansion\");\n lines.push(\" - path: /etc/environment\");\n lines.push(\" owner: root:root\");\n lines.push(\" permissions: '0644'\");\n lines.push(\" content: |\");\n lines.push(' PATH=\"/root/.bun/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin\"');\n lines.push(\"\");\n\n // Security Module 1: UFW Firewall configuration files\n if (enableSecurity) {\n lines.push(\" # Security Module 1: UFW Firewall configuration\");\n lines.push(...ufwFirewallWriteFiles(DEFAULT_UFW_GENESIS_OPTIONS));\n }\n\n // Security Module 2: Kernel hardening configuration files\n if (enableSecurity) {\n lines.push(\" # Security Module 2: Kernel hardening\");\n lines.push(...kernelHardeningWriteFiles());\n }\n\n // Security Module 3: SSH hardening configuration files\n if (enableSecurity) {\n lines.push(\" # Security Module 3: SSH hardening\");\n lines.push(...sshdHardeningWriteFiles());\n }\n\n // Security Module 4: Security audit script\n if (enableSecurity) {\n lines.push(\" # Security Module 4: Security audit\");\n lines.push(...securityAuditWriteFiles());\n }\n\n // STAGE 5: Run Commands\n lines.push(\"# =====================================================\");\n lines.push(\"# STAGE 5: Run Commands (Config stage)\");\n lines.push(\"# =====================================================\");\n lines.push(\"\");\n lines.push(\"runcmd:\");\n\n // Install Bun\n lines.push(\" # Install Bun runtime\");\n lines.push(\" - curl -fsSL https://bun.sh/install | bash\");\n lines.push(\"\");\n\n // Clone genesis application\n lines.push(\" # Clone/pull genesis application\");\n const cloneCmd = genesisBranch\n ? `git clone --depth 1 --branch ${genesisBranch} ${genesisRepo} /opt/genesis`\n : `git clone --depth 1 ${genesisRepo} /opt/genesis`;\n\n lines.push(` - |`);\n lines.push(` if [ ! -d /opt/genesis/.git ]; then`);\n lines.push(` ${cloneCmd}`);\n lines.push(` else`);\n lines.push(` cd /opt/genesis && git pull`);\n lines.push(` fi`);\n lines.push(\"\");\n\n // Install dependencies\n lines.push(\" # Install dependencies\");\n lines.push(\" - cd /opt/genesis && bun install\");\n lines.push(\"\");\n\n // Build application\n lines.push(\" # Build application (if needed)\");\n lines.push(\" - cd /opt/genesis && bun run build\");\n lines.push(\"\");\n\n // Configure environment warning\n lines.push(\" # Configure environment (prompt for secrets or use external source)\");\n lines.push(\" - |\");\n lines.push(` echo \"WARNING: HETZNER_API_TOKEN must be configured in /etc/default/genesis\"`);\n lines.push(\"\");\n\n // Enable and start service\n lines.push(\" # Enable and start genesis service\");\n lines.push(\" - systemctl daemon-reload\");\n lines.push(\" - systemctl enable genesis.service\");\n lines.push(\" - systemctl start genesis.service\");\n lines.push(\"\");\n\n // Security Module 1: UFW Firewall activation (runs first)\n if (enableSecurity) {\n lines.push(\" # Security Module 1: Activate UFW Firewall\");\n lines.push(...ufwFirewallRunCmd(DEFAULT_UFW_GENESIS_OPTIONS));\n }\n\n // Security Module 2: Kernel hardening activation\n if (enableSecurity) {\n lines.push(\" # Security Module 2: Apply kernel hardening\");\n lines.push(...kernelHardeningRunCmd());\n }\n\n // Security Module 3: SSH hardening activation\n if (enableSecurity) {\n lines.push(\" # Security Module 3: Activate SSH hardening\");\n lines.push(...sshdHardeningRunCmd());\n }\n\n // Security Module 4: Security audit (runs last)\n if (enableSecurity) {\n lines.push(\" # Security Module 4: Run security audit\");\n lines.push(...securityAuditRunCmd());\n }\n\n // Mark bootstrap complete\n lines.push(\" # Mark bootstrap complete\");\n lines.push(' - echo \"status=complete\" >> /root/.genesis-bootstrap-status');\n lines.push(' - echo \"completed_at=$(date -Iseconds)\" >> /root/.genesis-bootstrap-status');\n if (enableSecurity) {\n lines.push(' - echo \"security_hardening=applied\" >> /root/.genesis-bootstrap-status');\n }\n lines.push(\"\");\n\n // Additional commands\n if (additionalCommands.length > 0) {\n lines.push(\" # Additional custom commands\");\n for (const cmd of additionalCommands) {\n lines.push(` - ${cmd}`);\n }\n lines.push(\"\");\n }\n\n // STAGE 6: Final\n lines.push(\"# =====================================================\");\n lines.push(\"# STAGE 6: Final (Final stage)\");\n lines.push(\"# =====================================================\");\n lines.push(\"\");\n lines.push('final_message: \"Genesis server bootstrap completed after $UPTIME seconds\"');\n\n return lines.join(\"\\n\");\n}\n\n/**\n * Generate a minimal cloud-init script that uses #include to fetch from a URL\n *\n * This is useful for larger bootstrap scripts or when you want to update\n * the bootstrap without code changes.\n *\n * @param url - URL to fetch the cloud-init config from\n * @returns Cloud-init YAML string with #include directive\n */\nexport function generateRemoteGenesisBootstrap(url: string): string {\n return `#include\\n${url}`;\n}\n\n/**\n * Genesis bootstrap configuration presets for common scenarios\n */\nexport const GenesisBootstrapPresets = {\n /**\n * Default Genesis server with standard configuration and full security\n */\n default: (adminSSHKey: string) =>\n generateGenesisBootstrap({\n adminSSHKey,\n }),\n\n /**\n * Genesis server with ARM architecture (CAX series - best €/performance)\n */\n arm: (adminSSHKey: string) =>\n generateGenesisBootstrap({\n adminSSHKey,\n defaultServerType: \"cax21\",\n }),\n\n /**\n * Genesis server with high-performance CPU (CPX series)\n */\n performance: (adminSSHKey: string) =>\n generateGenesisBootstrap({\n adminSSHKey,\n defaultServerType: \"cpx21\",\n }),\n\n /**\n * Genesis server with dedicated CPU (CCX series)\n */\n dedicated: (adminSSHKey: string) =>\n generateGenesisBootstrap({\n adminSSHKey,\n defaultServerType: \"ccx13\",\n }),\n\n /**\n * Development Genesis server without security hardening\n */\n development: (adminSSHKey: string) =>\n generateGenesisBootstrap({\n adminSSHKey,\n enableSecurity: false,\n packages: [\"htop\", \"vim\", \"tmux\", \"strace\"],\n additionalCommands: [\n \"echo 'Genesis development server ready' | wall\",\n ],\n }),\n\n /**\n * Secure Genesis server with full hardening and verbose logging\n */\n secure: (adminSSHKey: string) =>\n generateGenesisBootstrap({\n adminSSHKey,\n packages: [\"lynis\"],\n additionalCommands: [\n \"echo 'Genesis secure server ready - security audit completed' | wall\",\n ],\n }),\n} as const;\n",
10
- "/**\n * Cloud-Init Bootstrap Generator\n *\n * Generates cloud-init YAML scripts for first-boot server provisioning.\n * Handles seed repository installation and initial setup.\n *\n * Security Integration:\n * This module integrates all security modules in the correct order:\n * 1. UFW Firewall (network-level defense)\n * 2. Kernel Hardening (system-level hardening)\n * 3. SSH Hardening (service-level hardening)\n * 4. Security Audit (verification and reporting)\n */\n\nimport {\n sshdHardeningPackages,\n sshdHardeningWriteFiles,\n sshdHardeningRunCmd,\n} from \"./ssh-hardening\";\nimport {\n ufwFirewallPackages,\n ufwFirewallWriteFiles,\n ufwFirewallRunCmd,\n DEFAULT_UFW_WORKER_OPTIONS,\n} from \"./firewall\";\nimport {\n kernelHardeningPackages,\n kernelHardeningWriteFiles,\n kernelHardeningRunCmd,\n} from \"./kernel-hardening\";\nimport {\n securityAuditPackages,\n securityAuditWriteFiles,\n securityAuditRunCmd,\n} from \"./security-audit\";\n\nexport interface BootstrapOptions {\n /** Seed repository URL (default: https://github.com/ebowwa/seed) */\n seedRepo?: string;\n /** Seed repository branch (default: dev) */\n seedBranch?: string;\n /** Installation path (default: /root/seed) */\n seedPath?: string;\n /** Whether to run setup.sh non-interactively (default: true) */\n runSetup?: boolean;\n /** Additional environment variables for setup.sh */\n setupEnv?: Record<string, string>;\n /** Additional packages to install */\n packages?: string[];\n /** Additional commands to run after seed installation */\n additionalCommands?: string[];\n /** Enable security hardening (default: true) */\n enableSecurity?: boolean;\n}\n\n/**\n * Generate a cloud-init YAML script for seed installation\n *\n * @param options - Bootstrap configuration options\n * @returns Cloud-init YAML string\n */\nexport function generateSeedBootstrap(options: BootstrapOptions = {}): string {\n const {\n seedRepo = \"https://github.com/ebowwa/seed\",\n seedBranch = \"dev\",\n seedPath = \"/root/seed\",\n runSetup = true,\n setupEnv = {},\n packages = [],\n additionalCommands = [],\n enableSecurity = true,\n } = options;\n\n const lines: string[] = [];\n\n // Cloud-config header\n lines.push(\"#cloud-config\");\n lines.push(\"\");\n\n // System updates\n lines.push(\"# Update system packages\");\n lines.push(\"package_update: true\");\n lines.push(\"package_upgrade: true\");\n lines.push(\"\");\n\n // Required packages\n lines.push(\"# Install required packages\");\n lines.push(\"packages:\");\n lines.push(\" - git\");\n lines.push(\" - curl\");\n lines.push(\" - jq\");\n lines.push(\" - unzip\");\n lines.push(\" - tmux\");\n\n // Security Module 1: UFW Firewall packages\n if (enableSecurity) {\n lines.push(\" # Security: UFW Firewall\");\n lines.push(...ufwFirewallPackages());\n }\n\n // Security Module 2: Kernel hardening packages\n if (enableSecurity) {\n lines.push(\" # Security: Kernel hardening\");\n lines.push(...kernelHardeningPackages());\n }\n\n // Security Module 3: SSH hardening packages (fail2ban)\n if (enableSecurity) {\n lines.push(\" # Security: SSH hardening\");\n lines.push(...sshdHardeningPackages());\n }\n\n // Security Module 4: Security audit packages (lynis)\n if (enableSecurity) {\n lines.push(\" # Security: Security audit\");\n lines.push(...securityAuditPackages());\n }\n\n // Add additional packages\n for (const pkg of packages) {\n lines.push(` - ${pkg}`);\n }\n lines.push(\"\");\n\n // Status tracking file\n lines.push(\"# Write bootstrap status file\");\n lines.push(\"write_files:\");\n lines.push(\" - path: /root/.bootstrap-status\");\n lines.push(\" owner: root:root\");\n lines.push(\" permissions: '0644'\");\n lines.push(\" content: |\");\n lines.push(\" status=started\");\n lines.push(\" started_at=$(date -Iseconds)\");\n lines.push(\" source=cloud-init\");\n if (enableSecurity) {\n lines.push(\" security=enabled\");\n }\n lines.push(\"\");\n\n // Add bun to system-wide PATH via /etc/environment\n // NOTE: /etc/environment uses simple KEY=\"value\" format (no variables, no comments)\n // We need to replace PATH rather than append, and include all standard paths\n lines.push(\" # Add bun to /etc/environment for all users/shells\");\n lines.push(\" # Format: Simple KEY=\\\"value\\\" pairs, no variable expansion\");\n lines.push(\" - path: /etc/environment\");\n lines.push(\" owner: root:root\");\n lines.push(\" permissions: '0644'\");\n lines.push(\" content: |\");\n lines.push(\" PATH=\\\"/root/.bun/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin\\\"\");\n lines.push(\"\");\n\n // Security Module 1: UFW Firewall configuration files\n if (enableSecurity) {\n lines.push(\" # Security Module 1: UFW Firewall configuration\");\n lines.push(...ufwFirewallWriteFiles(DEFAULT_UFW_WORKER_OPTIONS));\n }\n\n // Security Module 2: Kernel hardening configuration files\n if (enableSecurity) {\n lines.push(\" # Security Module 2: Kernel hardening\");\n lines.push(...kernelHardeningWriteFiles());\n }\n\n // Security Module 3: SSH hardening configuration files\n if (enableSecurity) {\n lines.push(\" # Security Module 3: SSH hardening\");\n lines.push(...sshdHardeningWriteFiles());\n }\n\n // Security Module 4: Security audit script\n if (enableSecurity) {\n lines.push(\" # Security Module 4: Security audit\");\n lines.push(...securityAuditWriteFiles());\n }\n\n // Node-agent systemd service\n lines.push(\" # Node-agent systemd service for Ralph Loop orchestration\");\n lines.push(\" - path: /etc/systemd/system/node-agent.service\");\n lines.push(\" owner: root:root\");\n lines.push(\" permissions: '0644'\");\n lines.push(\" content: |\");\n lines.push(\" [Unit]\");\n lines.push(\" Description=Node Agent for Ralph Loop Orchestration\");\n lines.push(\" Documentation=https://github.com/ebowwa/seed\");\n lines.push(\" After=network-online.target\");\n lines.push(\" Wants=network-online.target\");\n lines.push(\"\");\n lines.push(\" [Service]\");\n lines.push(\" Type=simple\");\n lines.push(\" User=root\");\n lines.push(` WorkingDirectory=${seedPath}/node-agent`);\n lines.push(\" ExecStart=/root/.bun/bin/bun run src/index.ts\");\n lines.push(` EnvironmentFile=-${seedPath}/node-agent/.env`);\n lines.push(\" Environment=PORT=8911\");\n lines.push(\" Restart=always\");\n lines.push(\" RestartSec=10\");\n lines.push(\" StandardOutput=journal\");\n lines.push(\" StandardError=journal\");\n lines.push(\" SyslogIdentifier=node-agent\");\n lines.push(\"\");\n // Security hardening for node-agent service\n if (enableSecurity) {\n lines.push(\" # Security hardening\");\n lines.push(\" NoNewPrivileges=true\");\n lines.push(\" PrivateTmp=true\");\n lines.push(\" ProtectSystem=strict\");\n lines.push(\" ProtectHome=true\");\n lines.push(\" ReadOnlyPaths=/\");\n lines.push(\" ReadWritePaths=/var/log \" + seedPath + \"/node-agent\");\n }\n lines.push(\"\");\n lines.push(\" [Install]\");\n lines.push(\" WantedBy=multi-user.target\");\n lines.push(\"\");\n\n // Run commands\n lines.push(\"# Bootstrap commands\");\n lines.push(\"runcmd:\");\n\n // Install Bun and create node symlink\n lines.push(\" # Install Bun\");\n lines.push(\" - curl -fsSL https://bun.sh/install | bash\");\n lines.push(\" - ln -sf /root/.bun/bin/bun /root/.bun/bin/node # Create 'node' symlink to bun\");\n lines.push(\"\");\n\n // Clone seed repository\n lines.push(` # Clone seed repository`);\n lines.push(` - git clone --depth 1 --branch ${seedBranch} ${seedRepo} ${seedPath}`);\n lines.push(\"\");\n\n if (runSetup) {\n // Build environment variables\n const envVars = [\"NONINTERACTIVE=1\", ...Object.entries(setupEnv).map(([k, v]) => `${k}=${v}`)];\n const envString = envVars.join(\" \");\n\n lines.push(` # Run seed setup non-interactively`);\n lines.push(` - cd ${seedPath} && ${envString} bash ./setup.sh 2>&1 | tee /var/log/seed-setup.log`);\n lines.push(\"\");\n\n // Create completion marker\n lines.push(` # Mark setup complete`);\n lines.push(` - touch ${seedPath}/.seed-setup-complete`);\n lines.push(\"\");\n }\n\n // Additional commands\n if (additionalCommands.length > 0) {\n lines.push(` # Additional custom commands`);\n for (const cmd of additionalCommands) {\n lines.push(` - ${cmd}`);\n }\n lines.push(\"\");\n }\n\n // Security Module 1: UFW Firewall activation (runs first)\n if (enableSecurity) {\n lines.push(\" # Security Module 1: Activate UFW Firewall\");\n lines.push(...ufwFirewallRunCmd(DEFAULT_UFW_WORKER_OPTIONS));\n }\n\n // Security Module 2: Kernel hardening activation\n if (enableSecurity) {\n lines.push(\" # Security Module 2: Apply kernel hardening\");\n lines.push(...kernelHardeningRunCmd());\n }\n\n // Security Module 3: SSH hardening activation\n if (enableSecurity) {\n lines.push(\" # Security Module 3: Activate SSH hardening\");\n lines.push(...sshdHardeningRunCmd());\n }\n\n // Security Module 4: Security audit (runs last)\n if (enableSecurity) {\n lines.push(\" # Security Module 4: Run security audit\");\n lines.push(...securityAuditRunCmd());\n }\n\n // Mark bootstrap complete\n lines.push(` # Mark bootstrap complete`);\n lines.push(` - echo \"status=complete\" >> /root/.bootstrap-status`);\n lines.push(` - echo \"completed_at=$(date -Iseconds)\" >> /root/.bootstrap-status`);\n if (enableSecurity) {\n lines.push(` - echo \"security_hardening=applied\" >> /root/.bootstrap-status`);\n }\n lines.push(\"\");\n lines.push(\" # Start node-agent service\");\n lines.push(\" - systemctl daemon-reload\");\n lines.push(\" - systemctl enable node-agent\");\n lines.push(\" - systemctl start node-agent\");\n\n return lines.join(\"\\n\");\n}\n\n/**\n * Generate a minimal cloud-init script that uses #include to fetch from a URL\n *\n * This is useful for larger bootstrap scripts or when you want to update\n * the bootstrap without code changes.\n *\n * @param url - URL to fetch the cloud-init config from\n * @returns Cloud-init YAML string with #include directive\n */\nexport function generateRemoteBootstrap(url: string): string {\n return `#include\\n${url}`;\n}\n\n/**\n * Bootstrap configuration presets for common scenarios\n */\nexport const BootstrapPresets = {\n /**\n * Default seed installation with setup.sh and full security hardening\n */\n default: () => generateSeedBootstrap(),\n\n /**\n * Seed installation with full security hardening and verbose logging\n */\n secure: () =>\n generateSeedBootstrap({\n setupEnv: {\n DEBUG: \"1\",\n VERBOSE: \"1\",\n },\n }),\n\n /**\n * Seed installation without running setup.sh (useful for debugging)\n */\n cloneOnly: () => generateSeedBootstrap({ runSetup: false }),\n\n /**\n * Development bootstrap without security hardening (for testing)\n */\n development: () =>\n generateSeedBootstrap({\n enableSecurity: false,\n packages: [\"htop\", \"vim\", \"strace\"],\n }),\n\n /**\n * Verbose bootstrap with logging enabled\n */\n verbose: () =>\n generateSeedBootstrap({\n setupEnv: {\n DEBUG: \"1\",\n VERBOSE: \"1\",\n },\n }),\n} as const;\n\n// Re-export Genesis bootstrap functions\nexport {\n generateGenesisBootstrap,\n generateRemoteGenesisBootstrap,\n GenesisBootstrapPresets,\n type GenesisBootstrapOptions,\n} from \"./genesis\";\n\n// Re-export SSH hardening components so callers can compose custom\n// cloud-init scripts with hardening baked in (e.g. for non-standard node types)\nexport {\n sshdHardeningPackages,\n sshdHardeningWriteFiles,\n sshdHardeningRunCmd,\n} from \"./ssh-hardening\";\n\n// Re-export UFW firewall components\nexport {\n ufwFirewallPackages,\n ufwFirewallWriteFiles,\n ufwFirewallRunCmd,\n DEFAULT_UFW_WORKER_OPTIONS,\n DEFAULT_UFW_GENESIS_OPTIONS,\n generateUFWFirewallForGenesis,\n generateUFWFirewallForWorker,\n type UFWFirewallOptions,\n} from \"./firewall\";\n\n// Re-export kernel hardening components\nexport {\n kernelHardeningPackages,\n kernelHardeningWriteFiles,\n kernelHardeningRunCmd,\n} from \"./kernel-hardening\";\n\n// Re-export security audit components\nexport {\n securityAuditPackages,\n securityAuditWriteFiles,\n securityAuditRunCmd,\n} from \"./security-audit\";\n"
11
- ],
12
- "mappings": "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",
13
- "debugId": "ED96069CAC52F8FC64756E2164756E21",
14
- "names": []
15
- }