Installation du kiosque Objectif → Créer un environnement kiosque sécurisé, minimaliste et clonable, basé sur Debian + Openbox + OpenKiosk. → Utilisation visée : bornes de visioconférence, affichage municipal, postes en accès public. → À la fin : une image système prête à être clonée pour un déploiement rapide sur d’autres machines. Prérequis : → La solution de kiosque repose sur un système centralisé de fichiers de configuration. Ces fichiers doivent être hébergés sur un serveur web accessible par tous les kiosques déployés. → Un serveur web accessible en HTTPS est donc nécessaire, avec un accès SSH permettant de créer et modifier les fichiers de configuration à distance. Nous n'installons pas chaque kiosque en suivant cette procédure. Après avoir réalisé une installation fonctionnelle, nous en avons fait une image que nous installons en quelques minutes grâce à Fog Project . Procédure d'installation Debian Télécharger Debian Choisir la catégorie « Petits CD ou clefs USB ». Conseil pour la création du compte utilisateur : Utilisez le login : kiosk pour simplifier les étapes. (Si vous choisissez un autre nom, pensez à adapter toutes les commandes et configurations de la documentation en conséquence.) Pendant l’installation choisir uniquement : Serveur SSH Utilitaires usuels du système Attention : ne pas installer d’environnement graphique ! Connexion Réseau Dans les exemples ci-dessous, pensez à adapter le nom de l’interface réseau (ici les interfaces sont enp... et wlp...) Connexion filaire Dans le cas d’une connexion filaire ajouter dans le fichier /etc/network/interfaces : auto enp0s31f6 allow-hotplug enp0s31f6 iface enp0s31f6 inet dhcp metric 100 Puis pour activer l’interface : ifup enp0s31f6 WiFi (WPA Personal) Créer un ficher /etc/wpa_supplicant/wpa_supplicant.conf network={ ssid="NOM_DU_WIFI" psk="MOT_DE_PASSE_DU_WIFI" } Puis ajouter dans le fichier /etc/network/interfaces : auto wlp0s20f3 iface wlp0s20f3 inet dhcp wpa-conf /etc/wpa_supplicant/wpa_supplicant.conf metric 200 Puis pour activer l’interface : ifup wlp0s20f3 WiFi (WPA Enterprise) Adaptez cette configuration en fonction de vos paramètres de chiffrement et d'authentification Créer un ficher /etc/wpa_supplicant/wpa_supplicant.conf network={ ssid="mon-ssid" key_mgmt=WPA-EAP eap=PEAP identity="LOGIN" password="PASSWORD" phase2="auth=MSCHAPV2" } Puis ajouter dans le fichier /etc/network/interfaces : auto wlp0s20f3 iface wlp0s20f3 inet dhcp wpa-conf /etc/wpa_supplicant/wpa_supplicant.conf metric 200 Puis pour activer l’interface : ifup wlp0s20f3 Openbox Installer xorg et openbox : apt install -y xorg openbox jq OpenKiosk → Site d'OpenKiosk Comme mentionné sur le site, installer OpenKiosk avec ces commandes (avec wget, car curl n’est pas installé par défaut sur Debian). wget https://www.mozdevgroup.com/dropbox/okcd/115/release/OpenKiosk115.20.0-2025-02-16-x86_64.deb apt install -y ./OpenKiosk115.20.0-2025-02-16-x86_64.deb Pensez à vérifier sur le site qu'OpenKiosk n’a pas été mis à jour. Si une nouvelle version est disponible, adaptez les commandes avec le nom du nouveau fichier. Configuration Désactiver le menu grub au démarrage du PC & les messages kernel au boot Éditer le fichier /etc/default/grub et changez la valeur de GRUB_TIMEOUT à 0 puis GRUB_CMDLINE_LINUX_DEFAULT à "quiet loglevel=0" Pour appliquer ce changement, exécuter la commande suivante : update-grub Configuration d’un auto-login Éditer le fichier /etc/systemd/system/getty@tty1.service.d/override.conf avec : systemctl edit getty@tty1.service Rajouter ces trois lignes : Attention il faut les rajouter à la 3ème ligne du fichier (juste en dessous de la ligne n°2, donc) ! [Service] ExecStart= ExecStart=-/sbin/agetty --autologin root --noclear %I 38400 linux Puis, pour activer ce changement au démarrage du PC : systemctl enable getty@tty1.service Création du script de configuration de premier lancement Vérifiez que Python3 est installé sur la machine. Si ce n'est pas le cas, installez-le. Dans /root/.profile ajouter à la fin : if [ ! -e /home/kiosk/firstTime.ok ]; then python3 /home/kiosk/firstTime.py sleep 2 reboot fi Puis créer un fichier /home/kiosk/firstTime.py avec ce contenu : import os import subprocess from time import sleep import requests import ipaddress import json import uuid import signal import time def command(command): """Executes a command and returns the output""" result = subprocess.run(command, shell=True, capture_output=True, text=True) return result.stdout, result.stderr # Prevent ctrl-c def handler(signum, frame): pass signal.signal(signal.SIGINT, handler) def list_network_interfaces(): """Lists available network interfaces""" stdout, stderr = command("ip link show") interfaces = [] if stderr: print(f"Error retrieving interfaces: {stderr}") else: for line in stdout.splitlines(): if line[0].isdigit(): interface_name = line.split(":")[1].split()[0] interfaces.append(interface_name) if "lo" in interfaces: interfaces.remove("lo") return interfaces def configure_wired(interface): """Configures the wired connection""" print(f"Configuring wired connection on {interface}...") dhcp = input("Do you want to use DHCP? (yes/no): ").strip().lower() if dhcp == 'yes': # Configure DHCP for a wired interface with open("/etc/network/interfaces", "w") as myfile: myfile.write("source /etc/network/interfaces.d/*\n") myfile.write("auto lo\niface lo inet loopback\n") myfile.write(f"auto {interface}\nallow-hotplug {interface}\niface {interface} inet dhcp") command(f"ifup {interface}") print(f"{interface} configured with DHCP.") else: # Manual configuration (static IP) ip = input("Enter the static IP address: ").strip() netmask = input("Enter the subnet mask (e.g., 255.255.255.0): ").strip() cidr = ipaddress.IPv4Network(f"0.0.0.0/{netmask}").prefixlen gateway = input("Enter the default gateway: ").strip() dns = input("Enter the DNS address: ").strip() # Static IP configuration with open("/etc/network/interfaces", "w") as myfile: myfile.write("source /etc/network/interfaces.d/*\n") myfile.write("auto lo\niface lo inet loopback\n") myfile.write(f"auto {interface}\nallow-hotplug {interface}\niface {interface} inet static\n\taddress {ip}/{cidr})\n\tgateway {gateway}") command(f"echo nameserver {dns} > /etc/resolv.conf") command(f"ifup {interface}") print(f"{interface} configured with static IP {ip}.") def configure_wifi(interface): """Configures the Wi-Fi connection""" print(f"Configuring Wi-Fi on {interface}...") ssid = input("Enter the Wi-Fi network name (SSID): ").strip() password = input("Enter the Wi-Fi network password: ").strip() # Configure Wi-Fi via `nmcli` (NetworkManager) with open("/etc/network/interfaces", "w") as myfile: myfile.write("source /etc/network/interfaces.d/*\n") myfile.write("auto lo\niface lo inet loopback\n") myfile.write(f"auto {interface}\nallow-hotplug {interface}\niface {interface} inet dhcp\n\twpa-ssid {ssid}\n\twpa-psk {password}") command(f"ifup {interface}") print(f"Wi-Fi connection established on {interface}.") def configure_network(): """Main function to configure the network interface""" interfaces = list_network_interfaces() if not interfaces: print("No network interfaces found.") return print("Available network interfaces:") print("0. Skip this step") for i, iface in enumerate(interfaces, 1): print(f"{i}. {iface}") choice = int(input("Choose the network interface to configure (number): ").strip()) - 1 if choice not in range(len(interfaces)): print("Invalid choice.") return selected_interface = interfaces[choice] print(f"Chosen interface: {selected_interface}") connection_type = input("Do you want to configure a wired connection or Wi-Fi (only WPA with password)? (wired/wifi): ").strip().lower() if connection_type == "wired": configure_wired(selected_interface) elif connection_type == "wifi": configure_wifi(selected_interface) else: print("Invalid choice.") if not os.path.isfile("firstTime.ok"): print(''' ██ ██ ██ ██████ ███████ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ █████ ██ ██ ██ ███████ █████ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██████ ███████ ██ ██ ''') sleep(2) print("[*] First-time configuration script [*]") print("[*] - Version: 1.0 [*]") print("[*] - By: Alexandre Salmetoz [*]") sleep(2) try: print("\n1. Hostname configuration") hostname = input("Hostname: ") command(f"hostnamectl set-hostname {hostname}") print("Hostname: OK") except Exception as e: print(f"Error: {e}") try: print("\n2. Network connection configuration") configure_network() except Exception as e: print(f"Error: {e}") try: command("touch /home/kiosk/firstTime.ok") with open("/etc/systemd/system/getty@tty1.service.d/override.conf", 'r') as file: content = file.read() content = content.replace('root', 'kiosk') with open("/etc/systemd/system/getty@tty1.service.d/override.conf", 'w') as file: file.write(content) command("systemctl mask getty@tty1.service") except Exception as e: print(f"Error: {e}") print("\n[ Configuration complete! ]\n") print("The device will restart...") Ce script est lancé au premier lancement du pc seulement, pour permettre de configurer le hostname, le réseau et redémarrer Création d’un service système pour récupérer les fichiers de configuration au démarrage du PC Pour ce faire, créer un fichier /etc/systemd/system/kiosk.service avec ce contenu : [Unit] Description=Execute start.sh at startup [Service] ExecStart=/home/kiosk/start.sh Restart=on-failure User=root StandardInput=tty StandardOutput=journal StandardError=journal TTYPath=/dev/tty3 [Install] WantedBy=multi-user.target Puis, pour activer le service : systemctl enable kiosk.service Voici le script qui permet de récupérer les fichiers de configuration auprès du serveur à chaque démarrage, à placer dans /home/kiosk/start.sh : #!/bin/bash start_time=$(date +%s) timeout=10 # Délai d'attente en secondes avant que le script saute cette étape du ping while ! ping -c 1 -W 1 "8.8.8.8" &> /dev/null; do elapsed_time=$(($(date +%s) - start_time)) if [ "$elapsed_time" -ge "$timeout" ]; then log_message "!! Aucune connexion à Internet !!" break fi sleep 0.1 done if [ -e /home/kiosk/firstTime.ok ]; then echo "Démarrage..." python3 /home/kiosk/getConfig.py source /home/kiosk/boot_script.sh fi Ce script va récupérer avec « python3 /home/kiosk/getConfig.py » le fichier de configuration pour OpenKiosk, une Whitelist, un ficher de configuration système et un script qui sera exécuté à chaque démarrage du pc sur un serveur (dont l’url est contenue dans la variable $DOMAIN_NAME), puis placer ces fichiers dans /usr/lib/OpenKiosk/ Rendre ce script exécutable : chmod +x /home/kiosk/start.sh Puis créer le script python /home/kiosk/getConfig.py : import requests import json import subprocess import os DOMAIN_NAME = "kiosk-config.mondomaine.fr" def command(command): """Exécute une commande et retourne la sortie""" result = subprocess.run(command, shell=True, capture_output=True, text=True) return result.stdout hostname = command("hostname")[:-1] # --- Config OpenKiosk --- res = requests.get("https://" + DOMAIN_NAME + "/" + hostname + "/config.cfg") with open("/usr/lib/OpenKiosk/openkiosk.cfg", 'w') as f: f.write(res.text) # --- Config System --- res = requests.get("https://" + DOMAIN_NAME + "/" + hostname + "/config_system.json") with open("/home/kiosk/config_system.json", 'w') as f: f.write(res.text) # --- Boot Script --- res = requests.get("https://" + DOMAIN_NAME + "/" + hostname + "/boot_script.sh") with open("/home/kiosk/boot_script.sh", 'w') as f: f.write(res.text) command("chmod +x /home/kiosk/boot_script.sh") # --- Config Filters --- res = requests.get("https://" + DOMAIN_NAME + "/" + hostname + "/filters.txt") with open("/usr/lib/OpenKiosk/filters.txt", 'w') as f: f.write(res.text) Changez la variable DOMAIN_NAME si nécessaire, les fichiers seront récupérés à la racine. Par exemple, pour un kiosk, les fichiers de configurations seront : → https://$DOMAIN_NAME/$HOSTNAME/config.cfg → https://$DOMAIN_NAME/$HOSTNAME/filters.txt → https://$DOMAIN_NAME/$HOSTNAME/config_system.json → https://$DOMAIN_NAME/$HOSTNAME/boot_script.sh Création d’un service système pour lancer Openbox au démarrage du PC Pour ce faire, créer un fichier /etc/systemd/system/kiosk-openbox.service avec ce contenu : [Unit] Description=Execute start-openbox.sh at startup After=kiosk.service [Service] ExecStart=/home/kiosk/start-openbox.sh Restart=on-failure User=kiosk StandardInput=tty StandardError=journal StandardOutput=journal TTYPath=/dev/tty3 [Install] WantedBy=multi-user.target Puis activer le service : systemctl enable kiosk-openbox.service Ce script permet de lancer Openbox au démarrage du PC, à placer dans /home/kiosk/start-openbox.sh : #!/bin/bash if [ -e /home/kiosk/firstTime.ok ]; then if [ "$(jq -r '.cursor' /home/kiosk/config_system.json)" == "false" ]; then startx -- -nocursor else startx fi fi Pour rendre le script exécutable : chmod +x /home/kiosk/start-openbox.sh Ajouter l’utilisateur kiosk au groupe input : usermod -a -G input kiosk Configuration d’un autostart pour OpenKiosk Créer un fichier autostart dans /home/kiosk/.config/openbox/ : if [ "$(jq -r '.screen_saver' /home/kiosk/config_system.json)" = "false" ]; then xset s off xset s noblank xset -dpms else xset dpms 0 0 $(jq -r '.screen_saver_minutes' /home/kiosk/config_system.json | awk '{print $1*60}') fi if [ "$(jq -r '.sound' /home/kiosk/config_system.json)" = "true" ]; then pactl set-sink-mute @DEFAULT_SINK@ 0 else pactl set-sink-mute @DEFAULT_SINK@ 1 fi xmodmap -e "keycode 64 =" xmodmap -e "keycode 68 =" xmodmap -e "keycode 69 =" xmodmap -e "keycode 70 =" xmodmap -e "keycode 71 =" xmodmap -e "keycode 72 =" xmodmap -e "keycode 73 =" xmodmap -e "keycode 74 =" xmodmap -e "keycode 75 =" xmodmap -e "keycode 76 =" xmodmap -e "keycode 95 =" xmodmap -e "keycode 96 =" xset led named "Num Lock" OpenKiosk Les commandes xset permettent de désactiver l’écran de veille (si besoin de laisser l’écran de veille, commenter ces 3 premières lignes) La commande xmodmap -e "keycode 64 =" permet de désactiver la touche ALT du clavier pour éviter toute tentative de raccourcis clavier Mise en place d’une page par défaut pour OpenKiosk : Créer un fichier /home/kiosk/default.html :
Page par défaut du Kiosque