#!/bin/bash # ============================================================================= # kiosk-manager.sh — Debian 13 (Trixie) # Arquitectura: lightdm autologin → openbox → chromium --kiosk # lightdm gestiona sesión logind y seat correctamente (sin entorno gráfico) # Requiere: root # ============================================================================= SELECTED_USER="" BROWSER_BIN="" # ─── utilidades ─────────────────────────────────────────────────────────────── check_root() { [[ "$EUID" -ne 0 ]] && { echo "❌ Ejecutar como root"; exit 1; } } detect_browser() { BROWSER_BIN=$(command -v firefox-esr 2>/dev/null || command -v firefox 2>/dev/null || true) } pause() { echo "" read -rp " Pulsa ENTER para continuar..." } user_home() { getent passwd "$1" | cut -d: -f6 } # ─── 1. Crear usuario ───────────────────────────────────────────────────────── create_user() { echo "" echo " ╔─ PASO 1: Crear usuario kiosk ──────────────────────╗" echo "" read -rp " Nombre de usuario: " NEW_USER echo "" if [ -z "$NEW_USER" ]; then echo " ❌ Nombre vacío" pause; return 1 fi if id "$NEW_USER" &>/dev/null; then echo " ⚠ El usuario '$NEW_USER' ya existe" read -rp " ¿Usar este usuario? [s/N]: " yn [[ "$yn" != "s" && "$yn" != "S" ]] && { pause; return 1; } SELECTED_USER="$NEW_USER" echo " ✔ Usando: $SELECTED_USER" else adduser \ --disabled-password \ --gecos "Kiosk" \ --shell /bin/bash \ "$NEW_USER" passwd -l "$NEW_USER" SELECTED_USER="$NEW_USER" echo "" echo " ✔ Usuario creado: $SELECTED_USER" fi echo "" echo " Aplicando privilegios mínimos..." # video y render se mantienen: necesarios para acceso GPU for grp in sudo adm dialout cdrom floppy plugdev netdev; do deluser "$SELECTED_USER" "$grp" 2>/dev/null || true done usermod -aG video "$SELECTED_USER" usermod -aG render "$SELECTED_USER" 2>/dev/null || true echo " ✔ Grupos configurados (video y render incluidos para GPU)" echo "" echo " ╚────────────────────────────────────────────────────╝" pause } # ─── 2. Instalar paquetes ───────────────────────────────────────────────────── install_packages() { echo "" echo " ╔─ PASO 2: Instalar paquetes ────────────────────────╗" echo "" echo " Actualizando índice..." apt-get update -qq echo " Instalando stack X + lightdm + openbox + firefox-esr..." # lightdm: display manager — gestiona sesión logind y seat # lightdm-gtk-greeter: greeter requerido por lightdm (no visible con autologin) # openbox: WM mínimo sin compositor ni escritorio # chromium: navegador kiosk # x11-xserver-utils: xset (screensaver/DPMS) # x11-utils: xrandr # unclutter-xfixes: ocultar cursor # fonts-liberation: fuentes base para chromium apt-get install -y --no-install-recommends \ lightdm \ lightdm-gtk-greeter \ openbox \ x11-xserver-utils \ x11-utils \ unclutter-xfixes \ fonts-liberation detect_browser if [ -z "$BROWSER_BIN" ]; then echo " ❌ Firefox ESR no encontrado tras la instalación" pause; return 1 fi echo "" echo " ✔ Firefox ESR: $BROWSER_BIN" echo " ✔ lightdm instalado" echo " ✔ openbox instalado" echo "" echo " ╚────────────────────────────────────────────────────╝" pause } # ─── 3. Configurar kiosk ────────────────────────────────────────────────────── setup_kiosk() { echo "" echo " ╔─ PASO 3: Configurar kiosk ─────────────────────────╗" echo "" if [ -z "$SELECTED_USER" ]; then echo " ❌ Ejecuta primero el Paso 1" pause; return 1 fi if ! id "$SELECTED_USER" &>/dev/null; then echo " ❌ Usuario '$SELECTED_USER' no existe" pause; return 1 fi detect_browser if [ -z "$BROWSER_BIN" ]; then echo " ❌ Firefox ESR no instalado — ejecuta primero el Paso 2" pause; return 1 fi local url while true; do read -rp " URL del kiosk: " url [[ "$url" =~ ^https?:// ]] && break echo " ❌ Debe empezar por http:// o https://" done local home_dir home_dir=$(user_home "$SELECTED_USER") echo "" # ── [1/6] Limpiar configuración anterior si existe ──────────────────────── echo " [1/6] Limpiando configuración anterior..." rm -f "$home_dir/.bash_profile" rm -rf "/etc/systemd/system/getty@tty7.service.d" systemctl daemon-reload 2>/dev/null || true echo " ✔ Limpieza completada" # ── [2/6] Openbox: rc.xml sin keybindings ni menú ──────────────────────── echo " [2/6] Configurando Openbox..." local ob_dir="$home_dir/.config/openbox" mkdir -p "$ob_dir" # rc.xml: sin atajos de teclado, sin menú contextual, Chromium fullscreen cat > "$ob_dir/rc.xml" <<'EOF' yes no 1 1 0 0000 C-g 1 200 0 false 200 no no no true true yes above 1 no true true yes above 1 EOF cat > "$ob_dir/menu.xml" <<'EOF' EOF # autostart: lanza Chromium al arrancar openbox cat > "$ob_dir/autostart" </dev/null && unclutter --timeout 3 --fork # Esperar a que openbox inicialice completamente sleep 1 # Chromium en modo kiosk $BROWSER_BIN \\ --kiosk "$url" \\ \ --no-first-run \\ --no-sandbox \\ --disable-infobars \\ --disable-session-crashed-bubble \\ --disable-translate \\ --disable-extensions \\ --disable-sync \\ --disable-background-networking \\ --disable-features=TranslateUI \\ --check-for-update-interval=31536000 \\ --noerrdialogs & EOF chown -R "$SELECTED_USER":"$SELECTED_USER" "$ob_dir" echo " ✔ Openbox configurado (sin keybindings, sin menú)" # ── [3/6] Guardar URL ───────────────────────────────────────────────────── echo "$url" > "$home_dir/.kiosk_url" chown "$SELECTED_USER":"$SELECTED_USER" "$home_dir/.kiosk_url" # ── [4/6] lightdm: autologin directo al usuario kiosk ──────────────────── # lightdm gestiona correctamente: # - sesión logind (seat0 asignado) # - acceso a dispositivos DRM/GPU via logind # - D-Bus de sesión # Con autologin-user-timeout=0 el greeter no se muestra nunca echo " [4/6] Configurando lightdm autologin..." mkdir -p /etc/lightdm/lightdm.conf.d cat > /etc/lightdm/lightdm.conf.d/kiosk.conf </dev/null || true sleep 1 # Desmontar overlay previo si existe umount "/home/$SELECTED_USER" 2>/dev/null || true # Crear copia base del home ya configurado rm -rf "$base_dir" mkdir -p "$base_dir" cp -a "$home_dir/." "$base_dir/" echo " ✔ Base guardada en: $base_dir" # Servicio systemd que monta el overlay ANTES de que lightdm arranque cat > "/etc/systemd/system/kiosk-overlay-${SELECTED_USER}.service" </dev/null)" printf " lightdm : %s\n" "$(systemctl is-active lightdm 2>/dev/null)" echo "" echo " ── Autologin configurado ────────────────────────────" local conf="/etc/lightdm/lightdm.conf.d/kiosk.conf" if [ -f "$conf" ]; then grep -E "autologin-user=|autologin-session=" "$conf" else echo " ⚠ Sin configuración de autologin" fi echo "" echo " ── OverlayFS ────────────────────────────────────────" if mount | grep -q 'overlay on /home'; then mount | grep 'overlay on /home' | awk '{printf " ✔ Activo: %s\n", $3}' else echo " ⚠ Overlay no montado (reinicia para activarlo)" fi echo "" echo " ── lightdm ──────────────────────────────────────────" systemctl status lightdm --no-pager --lines=5 echo "" echo " ── Procesos kiosk activos ───────────────────────────" ps aux | grep -E "Xorg|openbox|firefox|lightdm" | grep -v grep \ | awk '{printf " %-12s %s\n", $1, $11}' \ || echo " (ninguno)" pause } # ─── desinstalar ────────────────────────────────────────────────────────────── uninstall_kiosk() { echo "" echo " Usuarios disponibles (UID ≥ 1000):" echo " ------------------------------------" getent passwd | awk -F: '$3 >= 1000 && $3 < 65534 { print " " $1 }' | sort echo " ------------------------------------" read -rp " Usuario a desinstalar: " DEL_USER if ! id "$DEL_USER" &>/dev/null; then echo " ❌ Usuario '$DEL_USER' no existe" pause; return 1 fi local home_dir home_dir=$(user_home "$DEL_USER") echo "" echo " ⚠ Se eliminará la configuración kiosk de: $DEL_USER" echo " El usuario y su home NO se borran" read -rp " ¿Confirmar? [s/N]: " confirm [[ "$confirm" != "s" && "$confirm" != "S" ]] && { echo " Cancelado"; pause; return; } echo "" # Matar sesión activa pkill -u "$DEL_USER" 2>/dev/null && echo " ✔ Sesión terminada" || true # Desmontar y eliminar overlay umount "/home/$DEL_USER" 2>/dev/null || true systemctl stop "kiosk-overlay-${DEL_USER}.service" 2>/dev/null || true systemctl disable "kiosk-overlay-${DEL_USER}.service" 2>/dev/null || true rm -f "/etc/systemd/system/kiosk-overlay-${DEL_USER}.service" rm -rf "/opt/kiosk-base/$DEL_USER" rm -rf "/run/kiosk-${DEL_USER}-upper" "/run/kiosk-${DEL_USER}-work" echo " ✔ Overlay eliminado" # Eliminar configuración lightdm rm -f /etc/lightdm/lightdm.conf.d/kiosk.conf echo " ✔ Configuración lightdm eliminada" # Deshabilitar lightdm systemctl disable lightdm 2>/dev/null || true systemctl set-default multi-user.target echo " ✔ lightdm deshabilitado" # Eliminar configuración X del usuario rm -f "$home_dir/.kiosk_url" rm -f "$home_dir/.config/openbox/rc.xml" rm -f "$home_dir/.config/openbox/menu.xml" rm -f "$home_dir/.config/openbox/autostart" echo " ✔ Configuración openbox eliminada" [ "$SELECTED_USER" = "$DEL_USER" ] && SELECTED_USER="" echo "" echo " ✔ Desinstalado correctamente" pause } # ─── menú ───────────────────────────────────────────────────────────────────── menu() { clear detect_browser local lightdm_status lightdm_status=$(systemctl is-active lightdm 2>/dev/null || echo "inactivo") echo "" echo " ╔══════════════════════════════════════════════╗" echo " ║ KIOSK MANAGER — Debian 13 (Trixie) ║" echo " ╠══════════════════════════════════════════════╣" printf " ║ Usuario : %-33s║\n" "${SELECTED_USER:-}" printf " ║ Browser : %-33s║\n" "${BROWSER_BIN:-}" printf " ║ lightdm : %-33s║\n" "$lightdm_status" echo " ╠══════════════════════════════════════════════╣" echo " ║ ║" echo " ║ 1) Crear usuario kiosk ║" echo " ║ 2) Instalar paquetes ║" echo " ║ 3) Configurar kiosk ║" echo " ║ ───────────────────────────── ║" echo " ║ 4) Estado ║" echo " ║ 5) Desinstalar kiosk ║" echo " ║ 6) Salir ║" echo " ║ ║" echo " ╚══════════════════════════════════════════════╝" echo "" read -rp " Opción: " opt echo "" case "$opt" in 1) create_user ;; 2) install_packages ;; 3) setup_kiosk ;; 4) status ;; 5) uninstall_kiosk ;; 6) echo " Saliendo..."; exit 0 ;; *) echo " ⚠ Opción no válida"; sleep 1 ;; esac } # ─── entrada ────────────────────────────────────────────────────────────────── check_root while true; do menu; done