⚙ Machine Configuration — Fill In Before Starting

// Setup Guide · Novice Edition

Debian 13 Kiosk
Step-by-Step

Home Assistant browser kiosk · Children's home computer · Inactivity timeout · Password lock

📦 Debian 13 (Trixie) 🦊 Firefox ESR 140.8 ⏱ ~45–60 min 👶 Novice friendly
Before you start: This guide assumes Debian 13 is already installed and you can log in. You'll need an internet connection on the computer. All commands are typed exactly as shown — spelling and spacing matter.
How to read this guide: Dark boxes with orange/green text are commands you type into the Terminal. When you see a # at the start of a line inside a command block, that's a comment explaining what the line does — you don't type those.
Phase 1 Open a Terminal
01
Find and open the Terminal
The Terminal is where you type commands to control the computer. Think of it as the control room.
Look for an app called Terminal, Konsole, or XTERM in your applications menu
Or press Ctrl + Alt + T on your keyboard
A black or dark window with a blinking cursor appears — that's the Terminal
02
Switch to the root (admin) user
Root is the all-powerful administrator account. You need it to install software and change system settings.
Type this command, then press Enter:
su -
It will ask for a password. Type your root password (nothing will appear as you type — that's normal). Press Enter.
You'll know it worked when the prompt changes from $ to # at the end of the line.
Phase 2 Fix Package Sources & Install Software
Important: Debian minimal installs often ship with an incomplete or empty sources.list — the file that tells Debian where to download software from. If this isn't fixed first, every apt install command will fail with "Unable to locate package." Follow steps 03 and 03b before anything else.
03a
Fix the package sources list
Open the sources file in the text editor:
nano /etc/apt/sources.list
Delete everything already in the file using the arrow keys and the Backspace/Delete key. Then type exactly these three lines:
deb http://deb.debian.org/debian trixie main contrib non-free non-free-firmware
deb http://deb.debian.org/debian trixie-updates main contrib non-free non-free-firmware
deb http://security.debian.org/debian-security trixie-security main contrib non-free non-free-firmware
Save: Ctrl + O → Enter → Ctrl + X

What these lines do: They tell Debian to download software from the official Debian servers, including security updates and all software categories.
03b
Update your software list
This tells Debian to read the new sources and download the list of available packages. It must be done after editing sources.list.
apt update
Wait for it to finish — it may take a minute. You'll see a lot of text scroll by, ending with "Reading package lists... Done" and no red errors.
04a
Install all required packages
Firefox ESR 140.8 is already installed — so we only need to install the supporting tools. This may take a minute or two.
apt install -y lightdm openbox xprintidle xdotool xbindkeys unclutter
What each piece does:
lightdm — handles auto-login · openbox — minimal window manager · xprintidle — detects inactivity · xdotool — controls the browser · xbindkeys — blocks keyboard shortcuts · unclutter — hides the mouse cursor when idle
04b
Choose LightDM as the default display manager
During the install, a blue screen will appear asking which display manager to use.
A list appears showing gdm3 and lightdm
Use the arrow keys to highlight lightdm
Press Enter to confirm
Why lightdm? It's lighter weight than gdm3 and has better support for the auto-login kiosk setup we're building.
Phase 3 Create the Kiosk User
05
Create a user called "kiosk"
This is a locked-down user account that only runs the browser. Children will be logged in as this user automatically.
adduser --disabled-password --gecos "" kiosk
The --disabled-password part means this user has no password — they can't log in manually, only automatically.
06
Add kiosk user to the video and audio groups
This lets the kiosk user use the screen and speakers.
usermod -aG video,audio kiosk
"usermod: no changes" — if you see this message, that's perfectly fine. It just means the kiosk user was already added to these groups automatically.
Phase 4 Configure Auto-Login
07
Edit the LightDM auto-login config
We're going to tell LightDM to skip the login screen and go straight to the kiosk user.
Open the config file:
nano /etc/lightdm/lightdm.conf
Use the arrow keys to find the [Seat:*] section. Add or change these lines:

autologin-user=kiosk
autologin-user-timeout=0
user-session=openbox
To save: Press Ctrl + O, then Enter to confirm. Press Ctrl + X to exit.
Phase 5 Configure Openbox & Browser Launch
08
Create the kiosk user's Openbox config folder
Openbox needs a folder to store its settings for the kiosk user.
mkdir -p /home/kiosk/.config/openbox
09
Create the autostart file
This file tells Openbox what to run when the kiosk user logs in.
Create and open the file:
nano /home/kiosk/.config/openbox/autostart
export DISPLAY=:0
export XAUTHORITY=/home/kiosk/.Xauthority

pulseaudio --start &
sleep 2
unclutter -idle 5 &
/home/kiosk/launch-browser.sh &
/home/kiosk/kiosk-idle.sh &
sleep 3 && matchbox-keyboard --fontptsize 10 &
sleep 3 && pactl set-sink-volume alsa_output.pci-0000_01_00.1.hdmi-stereo 125% &
sleep 5 && xbindkeys -f /home/kiosk/.xbindkeysrc &
Save: Ctrl + O → Enter → Ctrl + X

Note: Replace the sink name in the pactl line with your actual HDMI sink name from Phase 14.
10
Disable the right-click menu in Openbox
We remove it so children can't access system options.
nano /home/kiosk/.config/openbox/menu.xml
<?xml version="1.0" encoding="UTF-8"?>
<openbox_menu>
</openbox_menu>
Save: Ctrl + O → Enter → Ctrl + X
Phase 6 Create the Inactivity Timer Script
11
Create the idle reset script
After 15 minutes of no keyboard or mouse activity, it sends the browser back to the Home Assistant homepage.
nano /home/kiosk/kiosk-idle.sh
#!/bin/bash

# 15 minutes in milliseconds
TIMEOUT=900000
HOME_URL="https://192.168.1.42:30103"

while true; do
  IDLE=$(xprintidle)
  if [ "$IDLE" -ge "$TIMEOUT" ]; then
    WID=$(xdotool search --onlyvisible --class firefox | head -1)
    if [ -n "$WID" ]; then
      xdotool windowfocus "$WID"
      xdotool key ctrl+l
      sleep 0.5
      xdotool type "$HOME_URL"
      sleep 0.3
      xdotool key Return
    fi
  fi
  sleep 30
done
Save: Ctrl + O → Enter → Ctrl + X
12
Make the script executable
chmod +x /home/kiosk/kiosk-idle.sh
Phase 7 Keep Browser Running — Auto-Restart
13
Create the browser launcher script
This script launches Firefox in fullscreen mode and automatically restarts it if it ever closes or crashes.
cat > /home/kiosk/launch-browser.sh << 'EOF' #!/bin/bash export DISPLAY=:0 export XAUTHORITY=/home/kiosk/.Xauthority HOME_URL="https://192.168.1.42:30103" export MOZ_DISABLE_AUTO_SAFE_MODE=1 sleep 15 while true; do firefox \ --no-remote \ --profile /home/kiosk/.mozilla/firefox/kiosk \ "$HOME_URL" & sleep 3 WID=$(xdotool search --onlyvisible --class firefox | head -1) if [ -n "$WID" ]; then xdotool windowfocus "$WID" xdotool windowsize "$WID" 100% 100% xdotool windowmove "$WID" 0 0 fi wait sleep 2 done EOF chmod +x /home/kiosk/launch-browser.sh chown kiosk:kiosk /home/kiosk/launch-browser.sh
Replace the URL with your actual Home Assistant address.

Why not --kiosk? Firefox kiosk mode blocks the on-screen keyboard and extensions.

Why sleep 15? This gives the network time to connect before Firefox tries to load Home Assistant.
14
Make the browser launcher executable and verify autostart
chmod +x /home/kiosk/launch-browser.sh
Then verify the autostart file:
nano /home/kiosk/.config/openbox/autostart
Check that the browser line reads exactly:
/home/kiosk/launch-browser.sh &
If it already looks correct — just press Ctrl+X to exit without saving. Move on to Phase 8.
Phase 8 Create Firefox Profile & Fix Ownership
15
Create a dedicated Firefox profile for the kiosk user
mkdir -p /home/kiosk/.mozilla/firefox/kiosk nano /home/kiosk/.mozilla/firefox/profiles.ini

Name=kiosk
IsRelative=1
Path=kiosk
Default=1


StartWithLastProfile=1
Save: Ctrl + O → Enter → Ctrl + X
16
Pre-configure Firefox preferences
Disables the save-password prompt, sets the homepage, and allows self-signed certificates for local Home Assistant.
nano /home/kiosk/.mozilla/firefox/kiosk/user.js
// Always save passwords without prompting
user_pref("signon.rememberSignons", true);
user_pref("signon.autofillForms", true);

// Set Home Assistant as the homepage
user_pref("browser.startup.homepage", "https://192.168.1.42:30103");

// Disable the "restore session" popup after a crash
user_pref("browser.sessionstore.resume_from_crash", false);

// Disable first-run welcome page
user_pref("browser.startup.homepage_override.mstone", "ignore");
user_pref("startup.homepage_welcome_url", "");
user_pref("startup.homepage_welcome_url.additional", "");

// Disable update notifications
user_pref("app.update.auto", false);
user_pref("app.update.enabled", false);

// Allow self-signed certificates for local Home Assistant
user_pref("network.stricttransportsecurity.preloadlist", false);
user_pref("security.cert_pinning.enforcement_level", 0);
user_pref("security.enterprise_roots.enabled", true);
user_pref("security.tls.insecure_fallback_hosts", "192.168.1.42");
Save: Ctrl + O → Enter → Ctrl + X
17
Give all kiosk files to the kiosk user
chown -R kiosk:kiosk /home/kiosk/
18
Reboot the computer
reboot
After rebooting, Firefox should open automatically and go to your Home Assistant address. Log in to Home Assistant and save your password when Firefox asks — this only needs to be done once.
Phase 9 First Boot Setup — Do This Before Locking Down
Important: After the first reboot, complete these steps while you still have easy access to Firefox's toolbar and settings.
19
Log into Home Assistant and save the password
Firefox will ask to save your password — click Save. This only needs to be done once.
20
Grant Home Assistant access to the webcam and microphone
Move the mouse to the top of the screen to reveal the Firefox toolbar
Look for a camera icon or lock icon in the address bar
Click it and set Camera and Microphone to Allow
Once allowed, Firefox remembers this permanently for your HA address.
21
Enable Home Assistant's virtual keyboard
In Home Assistant, click your profile icon (bottom left)
Look for "On-screen keyboard" and toggle it on
Phase 10 Block Keyboard Shortcuts
22
Create the keyboard lockdown config
Blocks common keyboard shortcuts children might use to escape the browser.
cat > /home/kiosk/.xbindkeysrc << 'EOF' "true" Alt+F4 "true" Control+alt+t "true" Mod4 "true" Control+Alt+Delete "true" Alt+Tab "true" Control+w "true" Control+l "true" Control+t "true" Control+n "true" F11 "true" Control+Shift+c "true" F12 "true" Control+Shift+t EOF chown kiosk:kiosk /home/kiosk/.xbindkeysrc touch /home/kiosk/.xbindkeysrc.scm chown kiosk:kiosk /home/kiosk/.xbindkeysrc.scm
Important: Key names must use exact capitalization — Control, Alt, Shift, Mod4. Using lowercase will cause xbindkeys to silently fail.

Note on F11: F11 is blocked to prevent exiting fullscreen. The browser uses xdotool to go fullscreen instead.
Phase 11 How to Access Admin / Exit Kiosk Mode
23
Switching to a root terminal when needed
Press Ctrl + Alt + F2 — switches to a text-only terminal (TTY2)
Log in as root with your root password
Make any changes you need
Press Ctrl + Alt + F7 (or F1) to switch back to the graphical kiosk
To fully stop the kiosk from TTY2: type systemctl stop lightdm
24
Updating the Home Assistant URL later
# From a root terminal (TTY2): nano /home/kiosk/launch-browser.sh nano /home/kiosk/kiosk-idle.sh
Change the HOME_URL line in both files, save, then reboot.
Phase 12 Faster Boot
25
Hide the GRUB boot menu
Open the GRUB config:
nano /etc/default/grub
Find and change these lines:
GRUB_TIMEOUT=0
GRUB_TIMEOUT_STYLE=hidden
Save: Ctrl + O → Enter → Ctrl + X
Then apply the change:
update-grub
⚠️ Emergency recovery: Hold down Shift immediately after powering on to force GRUB to appear even when hidden.
Phase 13 On-Screen Keyboard
26
Virtual on-screen keyboard (for touchscreen use)
Step 1 — Switch to fullscreen mode in launch-browser.sh (uses F11 via xdotool):
cat > /home/kiosk/launch-browser.sh << 'EOF' #!/bin/bash export DISPLAY=:0 export XAUTHORITY=/home/kiosk/.Xauthority HOME_URL="https://192.168.1.42:30103" export MOZ_DISABLE_AUTO_SAFE_MODE=1 sleep 15 while true; do firefox \ --no-remote \ --profile /home/kiosk/.mozilla/firefox/kiosk \ "$HOME_URL" & sleep 3 WID=$(xdotool search --onlyvisible --class firefox | head -1) if [ -n "$WID" ]; then xdotool windowfocus "$WID" xdotool key F11 fi wait sleep 2 done EOF chmod +x /home/kiosk/launch-browser.sh chown kiosk:kiosk /home/kiosk/launch-browser.sh
Step 2 — Add these to /etc/security/pam_env.conf:
MOZ_ENABLE_WAYLAND DEFAULT=0 OVERRIDE=1
MOZ_USE_XINPUT2 DEFAULT=1
Step 3 — Add these to user.js:
user_pref("ui.osk.enabled", true);
user_pref("ui.osk.detect_physical_keyboard", false);
user_pref("ui.osk.require_physical_keypress", false);
user_pref("dom.virtualKeyboard.enabled", true);
Step 4 — Install FX OSK extension (on first boot, reveal toolbar then navigate to):
https://addons.mozilla.org/en-US/firefox/addon/fx-osk/
Note: FX OSK works on most sites. For Home Assistant's own pages, use HA's built-in virtual keyboard instead (Profile → On-screen keyboard toggle).
Phase 14 Audio Booster
27
Enable HDMI audio output with volume boost
Step 1 — Find the kiosk user's UID:
id kiosk
Note the number after uid= — e.g. uid=1001. Use it wherever you see 1001 below.
Step 2 — Find your HDMI audio sink name:
su - kiosk -s /bin/bash -c "DISPLAY=:0 XAUTHORITY=/home/kiosk/.Xauthority XDG_RUNTIME_DIR=/run/user/1001 pactl list sinks short"
Look for a line containing hdmi-stereo. Note the full sink name, e.g. alsa_output.pci-0000_01_00.1.hdmi-stereo.
Step 3 — Set HDMI as the default audio output:
su - kiosk -s /bin/bash -c "DISPLAY=:0 XAUTHORITY=/home/kiosk/.Xauthority XDG_RUNTIME_DIR=/run/user/1001 pactl set-default-sink alsa_output.pci-0000_01_00.1.hdmi-stereo"
Step 4 — Make it permanent:
mkdir -p /home/kiosk/.config/pulse cat > /home/kiosk/.config/pulse/default.pa << 'EOF' .include /etc/pulse/default.pa set-default-sink alsa_output.pci-0000_01_00.1.hdmi-stereo EOF chown -R kiosk:kiosk /home/kiosk/.config/pulse
Step 5 — Add volume to autostart (add after the export lines at top):
sleep 3 && pactl set-sink-volume alsa_output.pci-0000_01_00.1.hdmi-stereo 125% &
Volume adjustment: 125% is the recommended level. Going above 150% may cause audio distortion.
Phase 15 Touch To Close
28
4-finger tap to close Firefox
A Python script that reads raw touch events and closes Firefox when 4 fingers are placed on the screen simultaneously. Runs as a systemd service.
Step 1 — Install the evdev Python library:
apt install -y python3-evdev
Step 2 — Create the gesture script:
cat > /home/kiosk/gesture-close.py << 'EOF' #!/usr/bin/env python3 import evdev import subprocess import time touch_device = None for path in evdev.list_devices(): device = evdev.InputDevice(path) if 'ILITEK' in device.name or 'touch' in device.name.lower(): touch_device = device break if not touch_device: print("Touchscreen not found!") exit(1) print(f"Using device: {touch_device.name} at {touch_device.path}") finger_count = 0 last_trigger = 0 for event in touch_device.read_loop(): if event.type == evdev.ecodes.EV_ABS: if event.code == evdev.ecodes.ABS_MT_TRACKING_ID: if event.value >= 0: finger_count += 1 else: finger_count = max(0, finger_count - 1) if finger_count >= 4: now = time.time() if now - last_trigger > 2: last_trigger = now subprocess.run(['pkill', 'firefox']) EOF chmod +x /home/kiosk/gesture-close.py chown kiosk:kiosk /home/kiosk/gesture-close.py
Step 3 — Create a systemd service:
cat > /etc/systemd/system/kiosk-gesture.service << 'EOF' [Unit] Description=Kiosk 4-finger gesture close After=graphical.target After=systemd-udev-settle.service [Service] ExecStartPre=/bin/sleep 10 ExecStart=/usr/bin/python3 /home/kiosk/gesture-close.py Restart=always RestartSec=5 User=root [Install] WantedBy=graphical.target EOF systemctl daemon-reload systemctl enable kiosk-gesture systemctl start kiosk-gesture
Step 4 — Add sudoers entry and autostart fallback:
echo "kiosk ALL=(root) NOPASSWD: /usr/bin/python3 /home/kiosk/gesture-close.py" >> /etc/sudoers
Add to autostart as a fallback:
sleep 20 && sudo /usr/bin/python3 /home/kiosk/gesture-close.py &
How it works: Place 4 fingers on the screen simultaneously. Firefox will close and the launch-browser.sh restart loop will reopen it after 2 seconds.

Why run as root? Firefox grabs the touch device exclusively. Running the script as root allows it to read touch events even while Firefox has focus.
Done What You've Built
✅ Your kiosk is set up! Here's a summary of what it does:
Auto-login
Boots directly to browser, no login screen
Browser
Firefox ESR 140.8 in fullscreen mode
Inactivity timeout
Returns to HA homepage after 15 min of no activity
Password saving
HA login saved in Firefox profile — auto-fills on every boot
Keyboard lockdown
Alt+F4, Ctrl+T, Ctrl+L, Super key and more all blocked
Auto-restart
Browser relaunches automatically if it ever closes
Admin access
Ctrl+Alt+F2 → log in as root → make changes
4-finger gesture
4-finger tap closes Firefox — restarts after 2 seconds
Audio
HDMI audio at 125% via PipeWire
Webcam & mic
Permitted for Home Assistant — saved permanently
On-screen keyboard
matchbox-keyboard + FX OSK extension
Web filtering
Controlled at the router — no changes needed here
Reminder: The first time the kiosk boots after setup, log into Home Assistant and click "Save password" when Firefox asks. After that, logins are automatic.