#!/bin/bash # kiosk-setup.sh # OpenKiosk Browser Terminal Setup # Copyright (C) 2026 Rod Wright # SPDX-License-Identifier: GPL-2.0 APP_NAME="OpenKiosk" APP_VERSION="2.0.0" function clean_exit() { # Re-enable unattended-upgrades if $restart_uu; then systemctl start unattended-upgrades >/dev/null 2>&1; fi exit 0 } function abort_exit() { # Re-enable unattended-upgrades if $restart_uu; then systemctl start unattended-upgrades >/dev/null 2>&1; fi exit 1 } function privilege_check() { # test for superuser rights if [[ $EUID -ne 0 ]]; then echo "This script must be run with superuser privileges. Try sudo $0" exit 1 fi } function disable_unattended_upgrades() { # Prevent unattended-upgrades from interfering restart_uu=false while systemctl status unattended-upgrades >/dev/null 2>&1 do systemctl stop unattended-upgrades sleep 5 restart_uu=true done } function update_os() { # Make sure OS is up to date echo "Updating Operating System..." sleep 5 apt-get update -qq if [[ "$kconfig" == "standalone" ]] then if apt-get dist-upgrade -y then echo "...done." echo "" else echo "A problem was encountered during installation." echo "the command that failed was:" echo " apt-get update && apt-get dist-upgrade -y" abort_exit fi fi } function remove_snap() { # Remove snap if installed if snap list >/dev/null 2>&1; then echo "Removing snap..." snap remove lxd snap remove core20 snap remove snapd systemctl stop snapd systemctl disable snapd systemctl mask snapd apt-get purge snapd -y apt-mark hold snapd rm -rf /home/*/snap/ rm -rf /root/snap/ rm -rf /snap rm -rf /var/snap rm -rf /var/lib/snapd echo "...done." fi } function install_rpi5_gl() { echo "Installing gl driver for Raspberry Pi 5..." if apt-get install -y gldriver-test then echo "...done." echo "" else echo "A problem was encountered during installation." echo "the command that failed was:" echo " apt-get install -y gldriver-test" abort_exit fi } function install_x_server() { # Install X server echo "Installing X server..." if apt-get install -y --no-install-recommends xorg openbox xterm xpdf then echo "...done." systemctl enable getty@tty1.service echo "" else echo "A problem was encountered during installation." echo "the command that failed was:" echo " apt-get install -y --no-install-recommends xorg openbox" abort_exit fi } function install_chromium() { # Try to install chromium-browser package, but if that fails, add # repository and install chromium package echo "Installing chromium..." while ! apt-get install -y chromium > /dev/null 2>&1 do if add-apt-repository ppa:xtradeb/apps -y then echo "added chromium repository" echo "" else echo "A problem was encountered during installation." echo "the command that failed was:" echo " add-apt-repository ppa:xtradeb/apps -y" abort_exit fi apt-get update done echo "...done." } function install_webmin() { # Check for webmin installation and prompt for install echo "" echo "Checking for webmin installation..." echo "" if dpkg -l|grep webmin >/dev/null 2>&1 then echo "" echo "webmin is installed. Continuing." echo "" else echo "webmin doesn't seem to be installed." echo "It is an optional package that enables system administration" echo "using a friendly GUI. It is highly recommended, especially for" echo "headless servers without any way to log in directly on the machine." echo "Note that this has the potential to be a security risk, especially" echo "if your passwords aren't sufficiently strong." echo -n "Install it now? [Y/n]: " read reqinstall if [ "$reqinstall" = "N" -o "$reqinstall" = "n" ] then echo "Proceeding without installing webmin. System administration" echo "will require login to the server either directly or via ssh." else echo "" echo "Proceeding with webmin installation" echo "" sleep 3 echo "Installing webmin..." skipwebmin="false" if ! curl -o setup-repos.sh https://raw.githubusercontent.com/webmin/webmin/master/setup-repos.sh then echo "Warning: failed to download Webmin repo setup script." echo -n "Ignore and [c]ontinue or [A]bort? [c/A]: " read wmfailchoice if [ "$wmfailchoice" = "C" -o "$wmfailchoice" = "c" ] then skipwebmin="true" echo "Continuing without installing Webmin. You should investigate the failure" echo "and install Webmin manually after the server is set up if you would like" echo "to be able to manage the server from another computer with a GUI instead" echo "of through ssh only." echo -n "Press enter to continue." read continueok echo "" fi fi if [ "$skipwebmin" = "false" ] then sh setup-repos.sh -f apt-get install -y --install-recommends webmin fi echo "...done." echo "" echo "You can now access webmin using a web browser pointed to:" echo "https://$HOSTNAME:10000" echo "Unless you have obtained valid ssl certificates, your server is" echo "using self-signed certs. This is not necessarily a problem, but" echo "your browser will complain. You can tell the browser to accept the" echo "self signed certificates and the traffic will still be encrypted," echo "but you may be vulnerable to man-in-the-middle attacks. You can" echo "get free valid certificates through LetsEncrypt." echo "See http://letsencrypt.org for more information." echo "" echo -n "Press enter to continue." read continueok echo "" echo "Finished with webmin installation" echo "" sleep 3 fi fi } function install_cups() { # Prompt whether to install print server echo "" echo "Checking for cups print server and driver installation..." echo "" if dpkg -l|grep cups-common >/dev/null 2>&1 then echo "" echo "cups is installed. Continuing." echo "" else echo "The cups print server doesn't seem to be installed." echo "If this will be an interactive kiosk and you would like to" echo "be able to print from it, cups will need to be installed." read -p "Install it now? [Y/n]: " -r reqinstall if [ "$reqinstall" = "N" -o "$reqinstall" = "n" ] then echo "Proceeding without installing cups." else echo "" echo "Proceeding with cups installation" echo "" sleep 3 echo "Installing cups print server..." apt-get install -y cups usermod -G lpadmin $(who|cut -d" " -f1) myhn=`hostname` echo "" echo "" echo "" echo "The cups print server has been installed." echo "After the kiosk is set up and working, edit /etc/openkiosk/openkiosk.conf" echo "and set the TGT_URL parameter to:" echo " https://localhost:631" echo "to add or manage printers via the kiosk browser." echo "When you are finished, change it back to your normal URL." echo "Note that the kiosk browser will, by default, print to the server" echo "default printer." echo "" echo -n "Press enter to continue." read continueok echo "" echo "Finished with cups print server installation" echo "" sleep 3 fi fi } function create_standalone_user() { # Install standalone kiosk user config echo "" echo "Creating kiosk user..." cloneuser.sh `who am i | awk '{print $1}'` kioskuser mkdir -p /home/kioskuser/.config/openbox cp -Rv home/kioskuser /home/ cp home/kioskuser/.profile /home/kioskuser cp home/kioskuser/.config/openbox/rc.xml /home/kioskuser/.config/openbox chown -R kioskuser:kioskuser /home/kioskuser/.config /home/kioskuser/.profile echo "...done." echo "" } function set_kiosk_url() { # Prompt for URL echo "" echo "This web browser based kiosk will need to know the site you would" echo "like to load. This can be a normal website or a file to be displayed" echo "in the browser, but must be available as a web URL (http://something)." echo "" echo "Note that in kiosk mode, your normal navigation buttons and mouse" echo "right-click menus are not available, so you will have no way to go" echo "back or forward in a page unless the page itself provides that" echo "capability." url_ok=false server_url="file:/etc/openkiosk/openkiosk_welcome.html" while ! $url_ok do echo "" echo "Please enter complete URL. Valid formats are:" echo "\"http://somesite.com/somepage\"" echo "\"file:/path/to/file.name\"" echo "" read -p "[file:/etc/openkiosk/openkiosk_welcome.html] :" -r server_url if [[ $server_url == "" ]] then server_url="file:/etc/openkiosk/openkiosk_welcome.html" fi if [[ $server_url == "test" ]] then url_ok=true elif echo "$server_url" | grep -q '^file:' then filepath=$(echo "$server_url"|cut -d":" -f2-) if [ ! -f "$filepath" ] then echo "" echo "There was an error reading the file you entered. The URL must" echo "be a complete valid path specification of the format:" echo "\"file:/path/to/file.name\" on the kiosk's filesystem." else url_ok=true fi else if ! `wget --no-check-certificate -q -o /dev/null -O /dev/null $server_url` then echo "" echo "There was an error retrieving the URL you entered. The URL must" echo "be a complete URL of the format \"http://somesite.com/somepage\"." echo "If this URL is on the local network, try using the IP address or" echo "the local domain. For example, instead of \"http://myserver/mypage\"," echo "try \"http://192.168.1.1/mypage\" or \"http://myserver.local/mypage\"." else url_ok=true fi fi done sed -i 's,'TGT_URL=.*','TGT_URL="\"$server_url\""',' /etc/openkiosk/openkiosk.conf } function set_kiosk_type() { # Prompt for kiosk type echo "" type_choice=false while !$type_choice do echo "Will this kiosk be an interactive kiosk or a display-only kiosk?" echo -n "[I]nteractive or [D]isplay-only? [I] :" read kiosk_type echo "" case "$kiosk_type" in "d" | "D") echo "Configuring for display-only kiosk." echo "How often would you like to check for changes to the page being" echo "displayed? Specify the number of seconds. Enter 0 to disable" echo "periodic checking." echo -n "Seconds between checks? [60] :" read poll_interval echo "" if [[ $poll_interval == "" ]]; then poll_interval=60; fi sed -i 's,'POLL_INTERVAL=.*','POLL_INTERVAL="\"$poll_interval\""',' /etc/openkiosk/openkiosk.conf echo "Disabling screen blanking." sed -i 's,'INHIBIT_BLANK=.*','INHIBIT_BLANK="\"1\""',' /etc/openkiosk/openkiosk.conf type_choice="D" ;; "i" | "I" | "") echo "Configuring for interactive kiosk." type_choice="I" ;; *) echo "Please enter I for interactive or D for display-only." ;; esac done } # -------------- Begin execution -------------- privilege_check echo "" echo " Welcome to $APP_NAME $APP_VERSION installation" echo "" echo "" echo "This script will configure a Debian based system to be a kiosk browser terminal." echo "" echo "" continueok=false while ! $continueok do read -p "Would you like to continue with OpenKiosk setup [Y/n]: " -r continueok case "$continueok" in "n" | "N") echo "Cancelling setup." clean_exit ;; "y" | "Y" | "") continueok=true echo "Continuing with OpenKiosk setup." ;; *) continueok=false echo "Please answer Y (default) or N." ;; esac done echo "" echo "OpenKiosk can be set up as a standalone kiosk or a workstation kiosk." echo "" echo "A standalone kiosk will boot up to a display only or an interactive" echo "kiosk that requires no login. This is useful for a system that is to" echo "be used interactively by multiple people or will be in a public place" echo "displaying automatically updating information non-interactively " echo "(digital signage)." echo "" echo "A workstation kiosk is one that can be used on a normal workstation by" echo "users who log in normally and would like to be able to run a kiosk style" echo "browser or pdf viewer in a full screen or windowed configuration only" echo "on demand." echo "" echo "Which configuration would you like?" kconfig="none" while [[ "$kconfig" == "none" ]] do read -p "Would you like a [S]tandalone or a [W]orkstation configuration? [S/W]?: " -r kconfig case "$kconfig" in "s" | "S") echo "Continuing with standalone configuration." kconfig="standalone" ;; "w" | "W") echo "Continuing with workstation configuration." kconfig="workstation" ;; "c" | "C") echo "Cancelling installation." clean_exit ;; *) echo "Please enter S or W, or enter C to cancel installation." kconfig="none" ;; esac done echo "" echo "Preparing for $kconfig installation. Please wait..." disable_unattended_upgrades # Determine OS Release version echo -n "OS information: " echo "" cat /etc/os-release echo "" sleep 5 chmod +x usr/local/bin/* case "$kconfig" in "standalone") # Copy in the needed files echo "Copying files..." cp -vf distfiles/usr/local/bin/* /usr/local/bin cp -Rvf distfiles/etc/* /etc/ cp -vf distfiles/lib/systemd/system/getty@tty1.service /lib/systemd/system rm /lib/systemd/system/ctrl-alt-del.target ln -s /dev/null /lib/systemd/system/ctrl-alt-del.target echo "...done." echo "" update_os remove_snap # If we are on a Raspberry Pi 5, we'll need to install this for the # xorg server to start if cat /proc/cpuinfo|grep -q "Raspberry Pi 5" >/dev/null 2>&1 then install_rpi5_gl fi install_x_server install_chromium install_webmin install_cups create_standalone_user set_kiosk_url set_kiosk_type echo "" echo "Kiosk configuration is now complete. " echo "" echo "The system must be rebooted for the configuration to take effect." echo "" read -p "Would you like to reboot now? [Y/n]: " -r rebootok case "$rebootok" in "y" | "Y" | "") reboot ;; *) clean_exit ;; esac ;; "workstation") # Copy in the needed files echo "Copying files..." cp -vf distfiles/usr/local/bin/* /usr/local/bin cp -vf distfiles/etc/openkiosk/openkiosk.conf /etc/openkiosk/ cp -vf distfiles/etc/openkiosk/openkiosk_welcome.html /etc/openkiosk/ install_chromium install_cups set_kiosk_url set_kiosk_type echo "" echo "Kiosk configuration is now complete. " echo "" clean_exit ;; *) echo "Unknown configuration type. Aborting." abort_exit ;; esac