{"id":402,"date":"2025-02-05T07:20:52","date_gmt":"2025-02-05T07:20:52","guid":{"rendered":"https:\/\/www.aran.cat\/wp\/?p=402"},"modified":"2025-02-05T07:21:46","modified_gmt":"2025-02-05T07:21:46","slug":"configure-linux-debian-to-boot-into-a-fullscreen-application","status":"publish","type":"post","link":"https:\/\/www.aran.cat\/wp\/?p=402","title":{"rendered":"Configure linux debian to boot into a fullscreen application"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">Running kiosk-mode applications with confidence<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><a href=\"https:\/\/tech-couch.com\/post\/configure-linux-debian-to-boot-into-a-fullscreen-application\">Configure linux debian to boot into a fullscreen application &#8211; Tech Couch<\/a><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Table of contents\n\nCreating a testing environment\nStarting an app in kiosk mode\nFine-tuning chromium for kiosk mode\nHandling power saving and blank screen\nUsing a splash screen during boot\nConfiguring virtual terminals\nPreventing users from escaping the kiosk app\nConsiderations for touchscreen devices\nDevice maintenance and security<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Linux is often used to build so-called \u00abkiosk\u00bb systems; a configuration that will start a fullscreen application right after boot, without any user interaction or login required. This kind of configuration is common for DIY and low-cost devices, but is not as straight-forward as one may assume.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"creating-a-testing-environment\">Creating a testing environment<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Since testing configurations on a physical device can be cumbersome, this article will use&nbsp;<a href=\"https:\/\/www.vagrantup.com\/\" target=\"_blank\" rel=\"noreferrer noopener\">vagrant<\/a>&nbsp;and&nbsp;<a href=\"https:\/\/www.virtualbox.org\/\" target=\"_blank\" rel=\"noreferrer noopener\">virtualbox<\/a>&nbsp;to create a virtual machine to test the configuration and see it in action. Make sure you have both tools installed, then write the following content into a file named&nbsp;<code>Vagrantfile<\/code>:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">Vagrant.configure(\"2\") do |config|\n&nbsp;config.vm.box = \"debian\/bookworm64\"\n&nbsp;config.vm.provider \"virtualbox\" do |vb|\n&nbsp;&nbsp;&nbsp;vb.gui = true\n&nbsp;&nbsp;&nbsp;vb.cpus = 2\n&nbsp;&nbsp;&nbsp;vb.memory = \"2048\"\n&nbsp;end\nend\n<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">You can now start your virtual machine with<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">vagrant up\n<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">To interact with the virtual machine once it has been created, run<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">vagrant ssh\n<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">to obtain an SSH session as the&nbsp;<code>vagrant<\/code>&nbsp;user. This user is automatically created for you and already has&nbsp;<code>sudo<\/code>&nbsp;privileges.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">When you are done testing, or want to start over, you can get rid of the virtual machine with<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">vagrant destroy -f\n<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">To get a new clean virtual machine, simply use&nbsp;<code>vagrant up<\/code>&nbsp;again.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"starting-an-app-in-kiosk-mode\">Starting an app in kiosk mode<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The guide assumes you have a linux debian installation&nbsp;<em>without any desktop environment installed (if you&#8217;re using the vagrant config above, you have exactly that).<\/em><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Before starting, make sure the packages are up to date<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">sudo apt update -y &amp;&amp; sudo apt upgrade -y\n<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Next install the required packages:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">sudo apt install -y xserver-xorg x11-xserver-utils xinit matchbox-window-manager chromium\n<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Here is a brief explanation of what we need each for:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>X server and tools (<code>xserver-xorg<\/code>,\u00a0<code>x11-xserver-utils<\/code>,\u00a0<code>xinit<\/code>):\u00a0<em>Handles the low-level basics for graphical applications, like displays, inputs and rendering.<\/em><\/li>\n<\/ul>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Window manager (<code>matchbox-window-manager<\/code>):\u00a0<em>Manages windows on top of xorg, including features like size, placement and responding to fullscreen requests. We chose this window manager specifically because it is extremely lightweight and works well for kiosk mode setups.<\/em><\/li>\n<\/ul>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Kiosk app (<code>chromium<\/code>):\u00a0<em>The application we want our system to boot into. Chromium is a simple browser that works well for displaying local or remote websites in kiosk mode, but you could use any other graphical application that has fullscreen support in it&#8217;s place.<\/em><\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">With these dependencies installed, it is time to configure the kiosk mode starting sequence. This requires a user that the system will automatically log in as, preferrably a newly created one for this specific purpose:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">sudo useradd -m -s \/bin\/bash -p '' kioskuser\n<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">This creates a new user called&nbsp;<code>kioskuser<\/code>. They have a home created because we need to create init scripts there in a moment, use&nbsp;<code>\/bin\/bash<\/code>&nbsp;as their shell because we need&nbsp;<code>.bashrc<\/code>&nbsp;during startup, and have an empty password to allow passwordless login at boot.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The initial virtual terminal and login screen is handled by the getty service. In order to automatically log into our kiosk account at boot, we need to override the default parameters for it. Create the file&nbsp;<code>\/etc\/systemd\/system\/getty@tty1.service.d\/override.conf<\/code>&nbsp;with adjusted&nbsp;<code>ExecStart<\/code>&nbsp;parameters:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">sudo mkdir \/etc\/systemd\/system\/getty@tty1.service.d\nsudo cat &gt; \/etc\/systemd\/system\/getty@tty1.service.d\/override.conf&lt;&lt; EOF\n[Service]\nExecStart=\nExecStart=-\/sbin\/agetty --autologin kioskuser --noclear %I $TERM\nEOF\n<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Overriding the&nbsp;<code>getty@tty1<\/code>&nbsp;service only applies our automatic login for the first virtual terminal&nbsp;<code>tty1<\/code>&nbsp;<em>(not others available through&nbsp;<\/em><code><em>ctrl<\/em><\/code><em>+<\/em><code><em>alt<\/em><\/code><em>+<\/em><code><em>f2<\/em><\/code><em>&#8230;<\/em><code><em>f6<\/em><\/code><em>, and not remote sessions like SSH)<\/em>. The first blank&nbsp;<code>ExecStart=<\/code>&nbsp;line is intentional and important, as it clears the previous contents inherited from the main&nbsp;<code>getty<\/code>&nbsp;service unit we are overriding. If it were missing, our arguments would be&nbsp;<em>appended<\/em>&nbsp;to the original line, not working as intended. If you named your kiosk user differently, make sure to adjust the last line after the&nbsp;<code>--autologin<\/code>&nbsp;flag to your custom username.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Now that the&nbsp;<code>kioskuser<\/code>&nbsp;is automatically logged in as at boot, we can append a small script to the end of their&nbsp;<code>.bashrc<\/code>&nbsp;file to start the&nbsp;<code>xorg<\/code>&nbsp;display manager for the&nbsp;<code>tty1<\/code>&nbsp;session&nbsp;<em>(and not for subsequent sessions or remote connections)<\/em>:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">sudo cat &gt;&gt; \/home\/kioskuser\/.bashrc&lt;&lt; EOF\nif [ -z \"\\$DISPLAY\" ] &amp;&amp; [ \"\\$(tty)\" = \"\/dev\/tty1\" ]; then\n&nbsp;&nbsp;startx\nfi\nEOF\n<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The last task is to start the window manager and kiosk application once the xorg server is ready. We can simply write those commands to a&nbsp;<code>.xinitrc<\/code>&nbsp;file, which gets executed once the&nbsp;<code>startx<\/code>&nbsp;command completes:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">cat &gt; \/home\/kioskuser\/.xinitrc&lt;&lt; EOF\nmatchbox-window-manager &amp;\nchromium --kiosk https:\/\/tech-couch.com\nEOF\nsudo chown kioskuser:kioskuser \/home\/kioskuser\/.xinitrc\n<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Note the ampersand&nbsp;<code>&amp;<\/code>&nbsp;after the first command, ensuring the window manager starts in the background and does not block the chromium process.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Using the&nbsp;<code>--kiosk<\/code>&nbsp;flag for chromium will automatically start it in fullscreen and disable some UI elements, like tabs and the search bar the top. Instead of a remote URL, you could also provide a filepath to a local HTML file.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">All that is left to do now is reboot the machine to see the configuration take effect:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">sudo reboot\n<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The virtual machine should now boot directly into the chromium application.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"fine-tuning-chromium-for-kiosk-mode\">Fine-tuning chromium for kiosk mode<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">While supplying the&nbsp;<code>--kiosk<\/code>&nbsp;flag is a good start, there are other useful flags when running chromium in kiosk mode:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>--no-first-run<\/code>\u00a0suppresses the first-run dialog (asking to sign in \/ sync profiles)<\/li>\n<\/ul>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>--incognito<\/code>\u00a0ensures browsing history, cookies and site data are not stored, since kiosk applications have to use for these features.<\/li>\n<\/ul>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>--disable-restore-session-state<\/code>\u00a0prevents chromium from showing a \u00abrestore closed tabs\u00bb page after unexpected shutdown, like power loss. Since kiosk mode devices are often turned off by unplugging, this feature may interfere with normal operation.<\/li>\n<\/ul>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>--disable-infobars<\/code>\u00a0hides infobars like the\u00a0<em>\u00abChrome is being controlled by automated test software\u00bb<\/em>\u00a0message that might appear when instrumenting the browser with WebDriver or debugging tools<\/li>\n<\/ul>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>--disable-pinch<\/code>\u00a0disables pinch-to-zoom functionality for touchscreens.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Depending on your use case, you may find some or all of these additional flags useful for chromium kiosk apps.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"handling-power-saving-and-blank-screen\">Handling power saving and blank screen<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">If left in default configuration, the xorg display manager will turn off the screen after some time of inactivity to save power. This may me desirable for interactive devices that have a keyboard or touchscreen attached, as any form of input will wake up the system again. For passive devices like screens displaying advertisements or informational displays, this behavior is problematic and needs to be prevented.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">You can disable these features entirely by combining three&nbsp;<code>xset<\/code>&nbsp;commands. Simply prepend these lines to the&nbsp;<em>beginning<\/em>&nbsp;of&nbsp;<code>\/home\/kioskuser\/.xinitrc<\/code>:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">xset s off\nxset -dpms\nxset s noblank\n<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The first line prevents screen blanking, the second disables dpms&nbsp;<em>(Display Power Management Signaling)<\/em>&nbsp;and the last one prevents any screen saver activation.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"using-a-splash-screen-during-boot\">Using a splash screen during boot<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The default boot process is very noisy, printing numerous colored lines of logging output to the screen. For many devices running kiosk mode, this boot sequence may concern unsuspecting users, so hiding most of the noise is a good idea.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">This can be done by using a plymouth splash screen theme, which first needs to be installed:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">sudo apt install -y plymouth plymouth-themes plymouth-x11\n<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Plymouth comes packaged with several themes by default, you can get a list of them with<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">sudo plymouth-set-default-theme -l\n<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Once you settled on a theme you want, apply it to your environment with<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">sudo plymouth-set-default-theme -R tribar\n<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The&nbsp;<code>tribar<\/code>&nbsp;theme is a good default choice here, as it is lightweight enough to load fast but also clean and unintrusive.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The second part to adjust for a cleaner boot experience is the grub configuration. Open&nbsp;<code>\/etc\/default\/grub<\/code>&nbsp;and set&nbsp;<code>GRUB_TIMEOUT=0<\/code>&nbsp;<em>(create it if missing)<\/em>. Next, find the line&nbsp;<code>GRUB_CMDLINE_LINUX_DEFAULT<\/code>&nbsp;and&nbsp;<em>prepend<\/em>&nbsp;<code>quiet loglevel=0 splash<\/code>&nbsp;to it.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">For example, if your&nbsp;<code>grub<\/code>&nbsp;file looked like this initially:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">GRUB_DEFAULT=0\nGRUB_TIMEOUT=5\nGRUB_DISTRIBUTOR=`lsb_release -i -s 2&gt; \/dev\/null || echo Debian`\nGRUB_CMDLINE_LINUX_DEFAULT=\"net.ifnames=0 biosdevname=0\"\nGRUB_CMDLINE_LINUX=\"consoleblank=0\"\n<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">it should look like this after modification:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">GRUB_DEFAULT=0\nGRUB_TIMEOUT=0\nGRUB_DISTRIBUTOR=`lsb_release -i -s 2&gt; \/dev\/null || echo Debian`\nGRUB_CMDLINE_LINUX_DEFAULT=\" quiet loglevel=0 splash net.ifnames=0 biosdevname=0\"\nGRUB_CMDLINE_LINUX=\"consoleblank=0\"\n<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Finally, run<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">sudo upgrade-grub\n<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">to save your new configuration. The next reboot should be mostly quiet, with a splash screen or animation covering the remaining boot logging noise.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">If you want even more control over the boot animation, you could design your own plymouth theme or show a static image.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"configuring-virtual-terminals\">Configuring virtual terminals<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">It is common for linux systems to dynamically provide several virtual terminals after boot. A virtual terminal is essentially a login session, just like the one we used to automatically log in. At any point in time, you may press&nbsp;<code>ctrl<\/code>+<code>alt<\/code>+<code>f2<\/code>&nbsp;to switch to&nbsp;<code>tty2<\/code>&nbsp;<em>(the second virtual terminal)<\/em>, up to&nbsp;<code>ctrl<\/code>+<code>alt<\/code>+<code>f6<\/code>&nbsp;for the last one.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><em>If you are following along with virtualbox, you need to use the software keyboard from the top menu under&nbsp;<\/em><code><em>input<\/em><\/code><em>&nbsp;&gt;&nbsp;<\/em><code><em>Keyboard<\/em><\/code><em>&nbsp;&gt;&nbsp;<\/em><code><em>Soft Keyboard ...<\/em><\/code><em>&nbsp;to send key combinations to the vm.<\/em><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Keeping this functionality may or may not be desirable: If end users can send inputs&nbsp;<em>(e.g. a keyboard is connected to the device)<\/em>, they can effectively \u00abdisable\u00bb the device by switching to a different virtual console&nbsp;<em>(where the kiosk app isn&#8217;t visible, and just a text-based login appears)<\/em>. Only users familiar with linux systems will recognize this and be able to amend it, while less experienced people have no choice but to restart the device.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">On the other hand, devices that cannot be interacted with directly like informational displays may want to keep this feature enabled to allow operators to quickly debug the device in-place, simply by attaching a keyboard to it and switching to another tty to log in and issue commands.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">If you want to disable virtual terminals and leave only the session used for the kiosk mode app, you need to find these lines in&nbsp;<code>\/etc\/systemd\/logind.conf<\/code>&nbsp;and make sure they are&nbsp;<em>not<\/em>&nbsp;commented out and have the correct values:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">NAutoVTs=1\nReserveVT=0\n<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The first line defines how many total virtual terminals are automatically generated, the second defines a reserved login virtual terminal that is always available&nbsp;<em>(where value&nbsp;<\/em><code><em>0<\/em><\/code><em>&nbsp;disables this feature)<\/em>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Your changes will take effect after the next reboot.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"preventing-users-from-escaping-the-kiosk-app\">Preventing users from escaping the kiosk app<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Simply starting an app in fullscreen may initially look like everything works as intended, but as soon as users have access to input, they may be able to break out of the kiosk app. This can take many forms, for example&nbsp;<code>alt<\/code>+<code>f4<\/code>&nbsp;to close the kiosk app,&nbsp;<code>ctrl<\/code>+<code>tab<\/code>&nbsp;to try and switch to a different program or application-specific shortcuts like&nbsp;<code>ctrl<\/code>+<code>w<\/code>&nbsp;to close the current tab in chromium&nbsp;<em>(thus closing the browser, since only one tab was open)<\/em>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The only reliable way to prevent these issues is to unbind all&nbsp;<code>ctrl<\/code>&nbsp;and&nbsp;<code>alt<\/code>&nbsp;keys&nbsp;<em>(left and right)<\/em>, as this leaves their key combinations inaccessible. You can unbind them using&nbsp;<code>xmodmap<\/code>&nbsp;when&nbsp;<code>kioskuser<\/code>&nbsp;starts their xorg session by prepending this command to the beginning of&nbsp;<code>\/home\/kioskuser\/.xinitrc<\/code>:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">xmodmap -e \"keycode 37 = NoSymbol\" \\\n        -e \"keycode 64 = NoSymbol\" \\\n        -e \"keycode 105 = NoSymbol\" \\\n        -e \"keycode 108 = NoSymbol\"\n<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">This solution has the added benefit that it only affects the kiosk app session on&nbsp;<code>tty1<\/code>, other sessions&nbsp;<em>(e.g. over SSH)<\/em>&nbsp;and other users remain unaffected.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">After a reboot, feel free to try all key combinations to ensure you cannot escape the kiosk environment with them anymore.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><em>If you are following along with virtualbox, you need to use the software keyboard from the top menu under&nbsp;<\/em><code><em>input<\/em><\/code><em>&nbsp;&gt;&nbsp;<\/em><code><em>Keyboard<\/em><\/code><em>&nbsp;&gt;&nbsp;<\/em><code><em>Soft Keyboard ...<\/em><\/code><em>&nbsp;to send key combinations to the vm.<\/em><\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"considerations-for-touchscreen-devices\">Considerations for touchscreen devices<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Before adding touchscreen features to this setup, take a moment to consider if debian is the right platform for your needs. Handheld-optimized distributions like android will be significantly easier to set up for touch devices, and you are less likely to find edge-case issues or hardware incompatibilities with them.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The primary need of a touchscreen device is a soft keyboard&nbsp;<em>(an on-screen software keyboard)<\/em>&nbsp;to allow users to input keystrokes without a physical keyboard connected. There are many options here, from lightweight choices like&nbsp;<code>matchbox-keyboard<\/code>&nbsp;<em>(a good choice for the&nbsp;<\/em><code><em>matchbox-window-manager<\/em><\/code><em>)<\/em>&nbsp;to more complex and feature-rich alternatives like&nbsp;<code>florence<\/code>&nbsp;or&nbsp;<code>onboard<\/code>. The choice is mainly up to your device&#8217;s needs and personal preference, but be warned that setting up dynamic focus (automatically show\/hide the keyboard when text input is selected) may be tricky on some combinations.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Since most touch devices do not show a cursor to the user, you likely want to hide the one on your touch device as well. An easy solution is to use&nbsp;<code>unclutter<\/code>&nbsp;with an idle timeout of 0 seconds, to hide the cursor most of the time. This setup may cause a flickering cursor on mouse move for some touchscreens, in which case you need to use a more complex solution like creating and installing a cursor theme with an invisible cursor icon.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Lastly, your kiosk application may behave unexpectedly with touch devices. The chromium browser for example, includes support for some touch gestures, like navigating with swiping motions or zooming with a pinch gesture. These can be easily disabled with flags&nbsp;<code>--overscroll-history-navigation=0<\/code>&nbsp;and&nbsp;<code>--disable-pinch<\/code>, respectively. Spend some time checking if and what touch gestures your application supports, and consider how that may negatively impact the user experience.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"device-maintenance-and-security\">Device maintenance and security<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">After setting up your device, you may think about how to maintain it in the future. Running an SSH server on the device to remotely manage it may seem like a good idea at first, but be careful to either disable SSH login for the&nbsp;<code>kioskuser<\/code>&nbsp;account or limit logins to key-only authentication, as otherwise you provide remote access to anything in the device&#8217;s network through the passwordless kiosk application user.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">On the topic of security, you should make it a point to treat all your deployed\/installed devices as hostile. Even if no remote access is possible over SSH, an attacker could simply plug the storage disk into one of their machines and freely read\/change any files on the system. Do not store credentials on the device (like S3 storage bucket logins or FTP credentials), not even hardcoded into a compiled binary (strings can be stripped out of executables easily with the&nbsp;<code>strings<\/code>&nbsp;command or debugging software).<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">If your device needs authenticated access to remote infrastructure, for example to forward orders or reports, consider deploying a purpose-built REST API with limited access for the devices, and provide different API tokens for each device to easily lock specific ones out of the service should they start behaving undesirably or their token becomes compromised. Audit logging and rigid monitoring\/alerting are a valuable addition of such an API in production environments.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Running kiosk-mode applications with confidence Configure linux debian to boot into a fullscreen application &#8211; Tech Couch Linux is often used to build so-called \u00abkiosk\u00bb systems; a configuration that will start a fullscreen application right after boot, without any user interaction or login required. This kind of configuration is common [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"inline_featured_image":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[5,16,4],"tags":[],"class_list":["post-402","post","type-post","status-publish","format-standard","hentry","category-debian","category-informatica","category-programari-lliure"],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/www.aran.cat\/wp\/index.php?rest_route=\/wp\/v2\/posts\/402","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.aran.cat\/wp\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.aran.cat\/wp\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.aran.cat\/wp\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.aran.cat\/wp\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=402"}],"version-history":[{"count":1,"href":"https:\/\/www.aran.cat\/wp\/index.php?rest_route=\/wp\/v2\/posts\/402\/revisions"}],"predecessor-version":[{"id":403,"href":"https:\/\/www.aran.cat\/wp\/index.php?rest_route=\/wp\/v2\/posts\/402\/revisions\/403"}],"wp:attachment":[{"href":"https:\/\/www.aran.cat\/wp\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=402"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.aran.cat\/wp\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=402"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.aran.cat\/wp\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=402"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}