Fix wizard: defaults for all prompts, random hostname/device-id, download robustness
- Add prompt_default() helper: shows defaults, accepts Enter to use them - WiFi: default=n (skip), keeps passphrase prompt loop - Root password: auto-generate with openssl, show in summary if used, operator can override - SSH key: default=1 (generate new) - Device ID: auto-generate bb-<8-char-uuid> - Boot mode: default=1 (passive) - VPN: default=1 (none) - Hostname: NEW section with auto-generated node-<6-char-uuid> default - Alerter: default=n (disabled) - Download: use curl -L (no -f), verify file exists and >50MB - Config summary: show hostname, mask password (show auto-generated clearly) - Apply config: write BB_HOSTNAME to /etc/hostname and /etc/hosts - No eval with user input: use printf -v for variable assignment
This commit is contained in:
+66
-41
@@ -51,6 +51,19 @@ banner() {
|
||||
echo ""
|
||||
}
|
||||
|
||||
prompt_default() {
|
||||
local var="$1" prompt="$2" default="$3"
|
||||
echo -n -e "${CYAN}${prompt}${NC}"
|
||||
[[ -n "$default" ]] && echo -n -e " ${BOLD}[${default}]${NC}"
|
||||
echo -n ": "
|
||||
read -r input
|
||||
if [[ -z "$input" ]]; then
|
||||
printf -v "$var" '%s' "$default"
|
||||
else
|
||||
printf -v "$var" '%s' "$input"
|
||||
fi
|
||||
}
|
||||
|
||||
# ══════════════════════════════════════════════════════════════════════════════
|
||||
# PREFLIGHT
|
||||
# ══════════════════════════════════════════════════════════════════════════════
|
||||
@@ -127,7 +140,12 @@ if [[ -z "$IMAGE" ]]; then
|
||||
IMAGE="${CACHE_DIR}/${IMAGE_FILENAME}"
|
||||
|
||||
if [[ ! -f "$IMAGE" ]]; then
|
||||
curl -fL --progress-bar "$IMAGE_URL" -o "$IMAGE" || error "Failed to download image"
|
||||
curl -L --progress-bar "$IMAGE_URL" -o "$IMAGE" || error "Failed to download image"
|
||||
# Verify download: file exists and is > 50MB
|
||||
if [[ ! -s "$IMAGE" ]] || [[ $(stat -c%s "$IMAGE" 2>/dev/null || echo 0) -lt 52428800 ]]; then
|
||||
rm -f "$IMAGE"
|
||||
error "Download failed or file too small (expected > 50MB)"
|
||||
fi
|
||||
info "Image downloaded: $IMAGE_FILENAME"
|
||||
else
|
||||
info "Image already cached: $IMAGE_FILENAME"
|
||||
@@ -150,16 +168,20 @@ section "Configuration Wizard"
|
||||
|
||||
# WiFi (optional)
|
||||
step "WiFi Configuration"
|
||||
echo -n -e "${CYAN}Configure WiFi? (y/n):${NC} "
|
||||
read -r enable_wifi
|
||||
prompt_default enable_wifi "Configure WiFi? (y/n)" "n"
|
||||
if [[ "$enable_wifi" =~ ^[yY]$ ]]; then
|
||||
echo -n -e "${CYAN}WiFi SSID:${NC} "
|
||||
read -r wifi_ssid
|
||||
echo -n -e "${CYAN}WiFi Passphrase:${NC} "
|
||||
prompt_default wifi_ssid "WiFi SSID" ""
|
||||
while true; do
|
||||
echo -n -e "${CYAN}WiFi Passphrase${NC}: "
|
||||
read -s -r wifi_pass; echo
|
||||
echo -n -e "${CYAN}Confirm Passphrase:${NC} "
|
||||
echo -n -e "${CYAN}Confirm Passphrase${NC}: "
|
||||
read -s -r wifi_pass2; echo
|
||||
[[ "$wifi_pass" == "$wifi_pass2" ]] || error "Passphrases do not match"
|
||||
if [[ "$wifi_pass" == "$wifi_pass2" ]]; then
|
||||
break
|
||||
else
|
||||
warn "Passphrases do not match. Try again."
|
||||
fi
|
||||
done
|
||||
WIFI_SSID="$wifi_ssid"
|
||||
WIFI_PASS="$wifi_pass"
|
||||
unset wifi_pass wifi_pass2
|
||||
@@ -170,33 +192,29 @@ fi
|
||||
|
||||
# Root password (required)
|
||||
step "Root Password"
|
||||
while true; do
|
||||
echo -n -e "${CYAN}Root password:${NC} "
|
||||
read -s -r root_pass; echo
|
||||
echo -n -e "${CYAN}Confirm:${NC} "
|
||||
read -s -r root_pass2; echo
|
||||
if [[ "$root_pass" == "$root_pass2" && -n "$root_pass" ]]; then
|
||||
DEFAULT_ROOT_PASS=$(openssl rand -base64 16 | tr -d '=+/')
|
||||
ROOT_PASS_IS_AUTO=false
|
||||
echo -e "${YELLOW}Auto-generated password: ${BOLD}${DEFAULT_ROOT_PASS}${NC}"
|
||||
prompt_default root_pass "Enter custom password or press Enter to use auto-generated" ""
|
||||
if [[ -z "$root_pass" ]]; then
|
||||
ROOT_PASS="$DEFAULT_ROOT_PASS"
|
||||
ROOT_PASS_IS_AUTO=true
|
||||
else
|
||||
ROOT_PASS="$root_pass"
|
||||
unset root_pass root_pass2
|
||||
break
|
||||
else
|
||||
warn "Passwords do not match or empty. Try again."
|
||||
fi
|
||||
done
|
||||
fi
|
||||
unset root_pass
|
||||
|
||||
# SSH Key
|
||||
step "SSH Key Configuration"
|
||||
echo " [1] Generate new keypair (stored in Infisical)"
|
||||
echo " [2] Use existing public key file"
|
||||
echo -n -e "${CYAN}SSH option (1-2):${NC} "
|
||||
read -r ssh_opt
|
||||
prompt_default ssh_opt "SSH option (1-2)" "1"
|
||||
|
||||
if [[ "$ssh_opt" == "1" ]]; then
|
||||
SSH_MODE="generate"
|
||||
elif [[ "$ssh_opt" == "2" ]]; then
|
||||
SSH_MODE="existing"
|
||||
echo -n -e "${CYAN}Path to public key file:${NC} "
|
||||
read -r ssh_pubkey_path
|
||||
prompt_default ssh_pubkey_path "Path to public key file" ""
|
||||
[[ -f "$ssh_pubkey_path" ]] || error "File not found: $ssh_pubkey_path"
|
||||
SSH_PUBKEY=$(cat "$ssh_pubkey_path")
|
||||
else
|
||||
@@ -205,18 +223,22 @@ fi
|
||||
|
||||
# Device ID
|
||||
step "Device ID"
|
||||
echo -n -e "${CYAN}Device label (e.g. bb-01):${NC} "
|
||||
read -r device_id
|
||||
[[ -n "$device_id" ]] || error "Device ID cannot be empty"
|
||||
DEFAULT_DEVICE_ID="bb-$(cat /proc/sys/kernel/random/uuid | cut -c1-8)"
|
||||
prompt_default device_id "Device label (e.g. bb-a3f2c1)" "$DEFAULT_DEVICE_ID"
|
||||
DEVICE_ID="$device_id"
|
||||
|
||||
# Hostname
|
||||
step "Hostname"
|
||||
DEFAULT_HOSTNAME="node-$(cat /proc/sys/kernel/random/uuid | cut -c1-6)"
|
||||
prompt_default bb_hostname "Hostname" "$DEFAULT_HOSTNAME"
|
||||
BB_HOSTNAME="$bb_hostname"
|
||||
|
||||
# Auto-start mode
|
||||
step "Auto-start Mode on Boot"
|
||||
echo " [1] Passive only (capture + analysis, no active offense)"
|
||||
echo " [2] Full autonomous (all modules)"
|
||||
echo " [3] Manual (operator SSHs in to start)"
|
||||
echo -n -e "${CYAN}Select mode (1-3):${NC} "
|
||||
read -r mode_opt
|
||||
prompt_default mode_opt "Select mode (1-3)" "1"
|
||||
|
||||
if [[ "$mode_opt" == "1" ]]; then
|
||||
BB_MODE="passive"
|
||||
@@ -233,8 +255,7 @@ step "VPN Tunnel"
|
||||
echo " [1] None"
|
||||
echo " [2] Tailscale"
|
||||
echo " [3] WireGuard"
|
||||
echo -n -e "${CYAN}Select VPN (1-3):${NC} "
|
||||
read -r vpn_opt
|
||||
prompt_default vpn_opt "Select VPN (1-3)" "1"
|
||||
|
||||
BB_VPN="none"
|
||||
TAILSCALE_KEY=""
|
||||
@@ -244,13 +265,11 @@ if [[ "$vpn_opt" == "1" ]]; then
|
||||
BB_VPN="none"
|
||||
elif [[ "$vpn_opt" == "2" ]]; then
|
||||
BB_VPN="tailscale"
|
||||
echo -n -e "${CYAN}Tailscale auth key:${NC} "
|
||||
read -r tailscale_key
|
||||
prompt_default tailscale_key "Tailscale auth key" ""
|
||||
TAILSCALE_KEY="$tailscale_key"
|
||||
elif [[ "$vpn_opt" == "3" ]]; then
|
||||
BB_VPN="wireguard"
|
||||
echo -n -e "${CYAN}Path to WireGuard config (wg0.conf):${NC} "
|
||||
read -r wg_config_path
|
||||
prompt_default wg_config_path "Path to WireGuard config (wg0.conf)" ""
|
||||
[[ -f "$wg_config_path" ]] || error "File not found: $wg_config_path"
|
||||
WG_CONFIG=$(cat "$wg_config_path")
|
||||
else
|
||||
@@ -259,11 +278,9 @@ fi
|
||||
|
||||
# Network alerter webhook
|
||||
step "Network Alerter"
|
||||
echo -n -e "${CYAN}Enable alerter webhook? (y/n):${NC} "
|
||||
read -r enable_alerter
|
||||
prompt_default enable_alerter "Enable alerter webhook? (y/n)" "n"
|
||||
if [[ "$enable_alerter" =~ ^[yY]$ ]]; then
|
||||
echo -n -e "${CYAN}Webhook URL (Slack/Discord/Matrix):${NC} "
|
||||
read -r webhook_url
|
||||
prompt_default webhook_url "Webhook URL (Slack/Discord/Matrix)" ""
|
||||
BB_ALERTER_WEBHOOK="$webhook_url"
|
||||
else
|
||||
BB_ALERTER_WEBHOOK=""
|
||||
@@ -275,11 +292,16 @@ fi
|
||||
section "Configuration Summary"
|
||||
|
||||
echo "Device ID: ${BOLD}${DEVICE_ID}${NC}"
|
||||
echo "Hostname: ${BOLD}${BB_HOSTNAME}${NC}"
|
||||
echo "Target: ${BOLD}/dev/${DEVICE}${NC}"
|
||||
echo "Image: ${BOLD}$(basename $IMAGE)${NC}"
|
||||
echo ""
|
||||
if [[ "$ROOT_PASS_IS_AUTO" == true ]]; then
|
||||
echo "Root Pass: ${BOLD}${RED}AUTO-GENERATED — RECORD THIS: ${DEFAULT_ROOT_PASS}${NC}"
|
||||
else
|
||||
echo "Root Pass: ${BOLD}[custom]${NC}"
|
||||
fi
|
||||
echo "WiFi: ${BOLD}$([ -n "$WIFI_SSID" ] && echo "$WIFI_SSID" || echo "disabled")${NC}"
|
||||
echo "Root Pass: ${BOLD}[set]${NC}"
|
||||
echo "SSH Mode: ${BOLD}${SSH_MODE}${NC}"
|
||||
echo "Auto-start: ${BOLD}${BB_MODE}${NC}"
|
||||
echo "VPN: ${BOLD}${BB_VPN}${NC}"
|
||||
@@ -398,7 +420,10 @@ chmod 600 "${SSH_DIR}/authorized_keys"
|
||||
info "SSH authorized_keys configured"
|
||||
|
||||
# Hostname
|
||||
echo "orangepi" > "${MOUNT_POINT}/etc/hostname"
|
||||
step "Setting hostname..."
|
||||
echo "$BB_HOSTNAME" > "${MOUNT_POINT}/etc/hostname"
|
||||
sed -i "s/orangepi/$BB_HOSTNAME/g" "${MOUNT_POINT}/etc/hosts" 2>/dev/null || true
|
||||
info "Hostname set to: $BB_HOSTNAME"
|
||||
|
||||
# Disable first-login wizard
|
||||
rm -f "${MOUNT_POINT}/root/.not_logged_in_yet"
|
||||
|
||||
Reference in New Issue
Block a user