Files
nebuleair_pro_4g/services/tailscale_bootstrap.sh
PaulVua b008b486ae v1.9.0: Enrolement automatique des capteurs sur le tailnet AirCarto (Tailscale/Headscale)
- installation_part1.sh: install paquet Tailscale + sudoers /usr/bin/tailscale
- services/tailscale_bootstrap.sh (nouveau): script idempotent d'enrolement au boot
- services/setup_services.sh: service systemd nebuleair-tailscale-bootstrap (one-shot)
- update_firmware.sh: nouvelle etape 3d 'Bootstrap Tailscale' (self-heal install + fetch
  authkey depuis data.nebuleair.fr/pro_4G/get_tailscale_key.php + enrolement). Fallback
  HTTPS->HTTP en attendant le cert TLS cote serveur.

Permet l'acces SSH distant aux 200 capteurs deployes via le tailnet une fois que leur
client a clique sur 'Update' dans l'admin web. Necessite l'endpoint serveur
get_tailscale_key.php en place sur data.nebuleair.fr (a deployer en parallele cote
AirCarto, auth par deviceID + rate limit + audit log).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-19 11:58:19 +02:00

58 lines
1.8 KiB
Bash

#!/bin/bash
# File: /var/www/nebuleair_pro_4g/services/tailscale_bootstrap.sh
# Purpose: Enroll the device into the AirCarto Headscale tailnet at boot.
# Idempotent: exits cleanly if already enrolled or if authkey is missing.
#
# Invoked by nebuleair-tailscale-bootstrap.service (one-shot at boot).
# Also safe to call manually from update_firmware.sh.
set -u
LOGIN_SERVER="https://headscale.aircarto.fr"
AUTHKEY_FILE="/etc/tailscale/authkey"
DB_FILE="/var/www/nebuleair_pro_4g/sqlite/sensors.db"
log() { echo "[$(date '+%Y-%m-%d %H:%M:%S')] tailscale-bootstrap: $1"; }
if ! command -v tailscale >/dev/null 2>&1; then
log "tailscale binary not found, skipping (install via update_firmware.sh)"
exit 0
fi
if tailscale ip -4 >/dev/null 2>&1; then
log "already enrolled (IP $(tailscale ip -4)), nothing to do"
exit 0
fi
if [[ ! -s "$AUTHKEY_FILE" ]]; then
log "no authkey at $AUTHKEY_FILE, skipping (will be fetched by update_firmware.sh)"
exit 0
fi
if [[ ! -f "$DB_FILE" ]]; then
log "database $DB_FILE not found, cannot derive hostname"
exit 1
fi
deviceID=$(sqlite3 "$DB_FILE" "SELECT value FROM config_table WHERE key='deviceID'" 2>/dev/null)
if [[ -z "$deviceID" ]]; then
log "deviceID empty in config_table, cannot enroll"
exit 1
fi
# Tailscale hostnames must be RFC 1123 (lowercase letters, digits, hyphens).
deviceID_clean=$(echo "$deviceID" | tr '[:upper:]' '[:lower:]' | tr -c 'a-z0-9-' '-' | sed 's/-\+/-/g; s/^-//; s/-$//')
hostname="nebuleair-pro-${deviceID_clean}"
authkey=$(cat "$AUTHKEY_FILE")
log "enrolling as $hostname..."
if tailscale up \
--login-server="$LOGIN_SERVER" \
--authkey="$authkey" \
--hostname="$hostname"; then
log "enrollment OK, IP $(tailscale ip -4)"
else
log "enrollment FAILED (will retry at next boot or update)"
exit 1
fi