Add reverse SSH tunnel (autossh) as VPN option in operator wizard
Generates a dedicated tunnel keypair during setup, prints public key for operator to pre-stage on server, writes private key to SD card. On first boot: installs autossh, writes bb-tunnel.service with correct RemoteForward and reconnect settings. Zero network traffic until operator initiates connection through the tunnel port.
This commit is contained in:
+94
-2
@@ -316,11 +316,18 @@ step "VPN Tunnel"
|
|||||||
echo " [1] None"
|
echo " [1] None"
|
||||||
echo " [2] Tailscale"
|
echo " [2] Tailscale"
|
||||||
echo " [3] WireGuard"
|
echo " [3] WireGuard"
|
||||||
prompt_default vpn_opt "Select VPN (1-3)" "1"
|
echo " [4] Reverse SSH Tunnel (autossh) — no traffic until operator connects"
|
||||||
|
prompt_default vpn_opt "Select VPN (1-4)" "1"
|
||||||
|
|
||||||
BB_VPN="none"
|
BB_VPN="none"
|
||||||
TAILSCALE_KEY=""
|
TAILSCALE_KEY=""
|
||||||
WG_CONFIG=""
|
WG_CONFIG=""
|
||||||
|
AUTOSSH_SERVER=""
|
||||||
|
AUTOSSH_USER="root"
|
||||||
|
AUTOSSH_PORT="22"
|
||||||
|
AUTOSSH_REMOTE_PORT=""
|
||||||
|
AUTOSSH_PRIVKEY=""
|
||||||
|
AUTOSSH_PUBKEY=""
|
||||||
|
|
||||||
if [[ "$vpn_opt" == "1" ]]; then
|
if [[ "$vpn_opt" == "1" ]]; then
|
||||||
BB_VPN="none"
|
BB_VPN="none"
|
||||||
@@ -333,6 +340,29 @@ elif [[ "$vpn_opt" == "3" ]]; then
|
|||||||
prompt_default wg_config_path "Path to WireGuard config (wg0.conf)" ""
|
prompt_default wg_config_path "Path to WireGuard config (wg0.conf)" ""
|
||||||
[[ -f "$wg_config_path" ]] || error "File not found: $wg_config_path"
|
[[ -f "$wg_config_path" ]] || error "File not found: $wg_config_path"
|
||||||
WG_CONFIG=$(cat "$wg_config_path")
|
WG_CONFIG=$(cat "$wg_config_path")
|
||||||
|
elif [[ "$vpn_opt" == "4" ]]; then
|
||||||
|
BB_VPN="autossh"
|
||||||
|
prompt_default AUTOSSH_SERVER "Operator SSH server (host or IP)" ""
|
||||||
|
[[ -n "$AUTOSSH_SERVER" ]] || error "Server address required"
|
||||||
|
prompt_default AUTOSSH_USER "SSH user on server" "root"
|
||||||
|
prompt_default AUTOSSH_PORT "SSH port on server" "22"
|
||||||
|
DEFAULT_REMOTE_PORT=$(( 20000 + RANDOM % 10000 ))
|
||||||
|
prompt_default AUTOSSH_REMOTE_PORT "Remote tunnel port (device SSH appears here on server)" "$DEFAULT_REMOTE_PORT"
|
||||||
|
|
||||||
|
# Generate dedicated tunnel keypair — keeps it separate from device management key
|
||||||
|
_TMP_TKEY=$(mktemp)
|
||||||
|
ssh-keygen -t ed25519 -N "" -C "bb-tunnel-${DEVICE_ID}" -f "$_TMP_TKEY" -q
|
||||||
|
AUTOSSH_PRIVKEY=$(cat "$_TMP_TKEY")
|
||||||
|
AUTOSSH_PUBKEY=$(cat "${_TMP_TKEY}.pub")
|
||||||
|
rm -f "$_TMP_TKEY" "${_TMP_TKEY}.pub"
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo -e " ${YELLOW}Add this public key to ${AUTOSSH_USER}@${AUTOSSH_SERVER}:~/.ssh/authorized_keys before powering on:${NC}"
|
||||||
|
echo ""
|
||||||
|
echo -e " ${BOLD}${AUTOSSH_PUBKEY}${NC}"
|
||||||
|
echo ""
|
||||||
|
echo -n -e "${CYAN} Press Enter once the key is on the server:${NC} "
|
||||||
|
read -r
|
||||||
else
|
else
|
||||||
error "Invalid VPN option"
|
error "Invalid VPN option"
|
||||||
fi
|
fi
|
||||||
@@ -365,7 +395,11 @@ fi
|
|||||||
echo "WiFi: ${BOLD}$([ -n "$WIFI_SSID" ] && echo "$WIFI_SSID" || echo "disabled")${NC}"
|
echo "WiFi: ${BOLD}$([ -n "$WIFI_SSID" ] && echo "$WIFI_SSID" || echo "disabled")${NC}"
|
||||||
echo "SSH Mode: ${BOLD}${SSH_MODE}${NC}"
|
echo "SSH Mode: ${BOLD}${SSH_MODE}${NC}"
|
||||||
echo "Auto-start: ${BOLD}${BB_MODE}${NC}"
|
echo "Auto-start: ${BOLD}${BB_MODE}${NC}"
|
||||||
echo "VPN: ${BOLD}${BB_VPN}${NC}"
|
if [[ "$BB_VPN" == "autossh" ]]; then
|
||||||
|
echo "VPN: ${BOLD}autossh → ${AUTOSSH_USER}@${AUTOSSH_SERVER}:${AUTOSSH_PORT} (remote port ${AUTOSSH_REMOTE_PORT})${NC}"
|
||||||
|
else
|
||||||
|
echo "VPN: ${BOLD}${BB_VPN}${NC}"
|
||||||
|
fi
|
||||||
echo "Alerter: ${BOLD}$([ -n "$BB_ALERTER_WEBHOOK" ] && echo "enabled" || echo "disabled")${NC}"
|
echo "Alerter: ${BOLD}$([ -n "$BB_ALERTER_WEBHOOK" ] && echo "enabled" || echo "disabled")${NC}"
|
||||||
echo ""
|
echo ""
|
||||||
|
|
||||||
@@ -526,6 +560,21 @@ if [[ "$BB_VPN" == "wireguard" && -n "$WG_CONFIG" ]]; then
|
|||||||
chmod 600 "${MOUNT_POINT}/etc/wireguard/wg0.conf"
|
chmod 600 "${MOUNT_POINT}/etc/wireguard/wg0.conf"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Store autossh config if needed
|
||||||
|
if [[ "$BB_VPN" == "autossh" ]]; then
|
||||||
|
echo "BB_AUTOSSH_SERVER=\"${AUTOSSH_SERVER}\"" >> "${MOUNT_POINT}/root/bb-config.env"
|
||||||
|
echo "BB_AUTOSSH_USER=\"${AUTOSSH_USER}\"" >> "${MOUNT_POINT}/root/bb-config.env"
|
||||||
|
echo "BB_AUTOSSH_PORT=\"${AUTOSSH_PORT}\"" >> "${MOUNT_POINT}/root/bb-config.env"
|
||||||
|
echo "BB_AUTOSSH_REMOTE_PORT=\"${AUTOSSH_REMOTE_PORT}\"" >> "${MOUNT_POINT}/root/bb-config.env"
|
||||||
|
|
||||||
|
# Write tunnel private key — separate from device management key
|
||||||
|
mkdir -p "${MOUNT_POINT}/root/.ssh"
|
||||||
|
echo "$AUTOSSH_PRIVKEY" > "${MOUNT_POINT}/root/.ssh/bb-tunnel-key"
|
||||||
|
chmod 600 "${MOUNT_POINT}/root/.ssh/bb-tunnel-key"
|
||||||
|
info "Tunnel key written to /root/.ssh/bb-tunnel-key"
|
||||||
|
unset AUTOSSH_PRIVKEY
|
||||||
|
fi
|
||||||
|
|
||||||
chmod 600 "${MOUNT_POINT}/root/bb-config.env"
|
chmod 600 "${MOUNT_POINT}/root/bb-config.env"
|
||||||
info "Configuration written"
|
info "Configuration written"
|
||||||
|
|
||||||
@@ -573,6 +622,40 @@ elif [[ "${BB_VPN:-}" == "wireguard" ]]; then
|
|||||||
apt-get update >/dev/null 2>&1
|
apt-get update >/dev/null 2>&1
|
||||||
apt-get install -y wireguard >/dev/null 2>&1
|
apt-get install -y wireguard >/dev/null 2>&1
|
||||||
systemctl enable --now wg-quick@wg0 || echo "[-] WireGuard startup failed"
|
systemctl enable --now wg-quick@wg0 || echo "[-] WireGuard startup failed"
|
||||||
|
elif [[ "${BB_VPN:-}" == "autossh" ]]; then
|
||||||
|
echo "[*] Installing autossh..."
|
||||||
|
apt-get update >/dev/null 2>&1
|
||||||
|
apt-get install -y autossh >/dev/null 2>&1
|
||||||
|
chmod 600 /root/.ssh/bb-tunnel-key 2>/dev/null || true
|
||||||
|
|
||||||
|
cat > /etc/systemd/system/bb-tunnel.service << SVCEOF
|
||||||
|
[Unit]
|
||||||
|
Description=BigBrother reverse SSH tunnel
|
||||||
|
After=network-online.target
|
||||||
|
Wants=network-online.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Environment="AUTOSSH_GATETIME=0"
|
||||||
|
ExecStart=/usr/bin/autossh -M 0 -N \
|
||||||
|
-o ServerAliveInterval=30 \
|
||||||
|
-o ServerAliveCountMax=3 \
|
||||||
|
-o StrictHostKeyChecking=no \
|
||||||
|
-o ExitOnForwardFailure=yes \
|
||||||
|
-i /root/.ssh/bb-tunnel-key \
|
||||||
|
-p ${BB_AUTOSSH_PORT} \
|
||||||
|
-R ${BB_AUTOSSH_REMOTE_PORT}:localhost:22 \
|
||||||
|
${BB_AUTOSSH_USER}@${BB_AUTOSSH_SERVER}
|
||||||
|
Restart=always
|
||||||
|
RestartSec=30
|
||||||
|
User=root
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
|
SVCEOF
|
||||||
|
|
||||||
|
systemctl daemon-reload
|
||||||
|
systemctl enable --now bb-tunnel.service || echo "[-] Tunnel service startup failed"
|
||||||
|
echo "[+] Reverse SSH tunnel configured (remote port ${BB_AUTOSSH_REMOTE_PORT})"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Network alerter
|
# Network alerter
|
||||||
@@ -661,6 +744,15 @@ else
|
|||||||
echo " ssh -i $(dirname $ssh_pubkey_path)/$(basename $ssh_pubkey_path .pub) root@<DEVICE_IP>"
|
echo " ssh -i $(dirname $ssh_pubkey_path)/$(basename $ssh_pubkey_path .pub) root@<DEVICE_IP>"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
if [[ "$BB_VPN" == "autossh" ]]; then
|
||||||
|
echo ""
|
||||||
|
echo "${CYAN}Tunnel connection (after first boot):${NC}"
|
||||||
|
echo " From operator server: ssh -p ${AUTOSSH_REMOTE_PORT} root@127.0.0.1"
|
||||||
|
echo " One-liner from anywhere (requires GatewayPorts yes on server):"
|
||||||
|
echo " ssh -p ${AUTOSSH_REMOTE_PORT} root@${AUTOSSH_SERVER}"
|
||||||
|
fi
|
||||||
|
|
||||||
echo ""
|
echo ""
|
||||||
echo "${CYAN}Monitor first-boot:${NC}"
|
echo "${CYAN}Monitor first-boot:${NC}"
|
||||||
echo " ssh root@<DEVICE_IP> 'tail -f /root/bb-firstboot.log'"
|
echo " ssh root@<DEVICE_IP> 'tail -f /root/bb-firstboot.log'"
|
||||||
|
|||||||
Reference in New Issue
Block a user