Ahmad Khalifa - Experimentshttps://khalifa.ws/2023-08-10T10:00:00+01:00Unattended First Boot Config for Raspberry Pi2023-08-10T10:00:00+01:002023-08-10T10:00:00+01:00Ahmadtag:khalifa.ws,2023-08-10:/posts/unattended-first-boot-config-for-raspberry-pi.html<p>Raspberry Pi OS config file for first boot setup</p><p>Raspberry Pis are pretty useful for doing different "headless" things on the home network.
Their first-time setup is quite manual and not very quick when you want to spin up a fresh
image on an sd card to experiment with something. You have to attach a keyboard and answer
the setup questions manually.</p>
<h3>How can I automate getting an image up and running?</h3>
<p>In the past, I had relied on inserting a systemd service with a script that can configure
the Pi once it has booted, but that wasn't fully skipping the manual first-boot steps.</p>
<p>There is a neat unattended script framework called
<a href="https://gitlab.com/JimDanner/pi-boot-script/-/tree/master">pi-boot-script</a> which seems to
aim to setup the RPi completely for runtime services. But I really just want the RPi up and
running so I can access it from the network without having to attach a keyboard and do lots
of manual data entry.</p>
<p>Turns out the <strong>RPi OS already has framework for first-run customisation</strong> in place.
It seems to be used by the <em>Imager</em> product. And it's actually pretty straightforward and
focuses on the key setup parts.</p>
<p>It works by creating a simple config <code>custom.toml</code> file in the boot partition and when the
RPi goes through its first boot setup, it picks it up and applies the settings from that file
including things like hostname, the main user and enable SSH.</p>
<p>Which is all you need to get a headless RPi running on the network without having to attach
a keyboard. From there you can access through ssh and deploy what you want in a more flexible
way.</p>
<h2>First-boot custom.toml Sample</h2>
<div class="highlight"><pre><span></span><code><span class="c1"># Raspberry Pi First Boot Setup</span>
<span class="k">[system]</span>
<span class="n">hostname</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">"rpihost"</span>
<span class="k">[user]</span>
<span class="n">name</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">"piuser"</span>
<span class="n">password</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">"fill this out"</span>
<span class="n">password_encrypted</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="kc">false</span>
<span class="k">[ssh]</span>
<span class="n">enabled</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="kc">true</span>
<span class="n">authorized_keys</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">[</span><span class="w"> </span><span class="s">"ssh-rsa Abc....== user@hint"</span><span class="w"> </span><span class="p">]</span>
<span class="c1"># this seems to broken in RPi's "init_config" and it sets "-k" instead of "-p"</span>
<span class="c1"># password_authentication = true</span>
<span class="k">[wlan]</span>
<span class="n">country</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">"gb"</span>
<span class="c1"># ssid = ""</span>
<span class="c1"># password = ""</span>
<span class="c1"># password_encrypted = false</span>
<span class="c1"># hidden = false</span>
<span class="k">[locale]</span>
<span class="n">keymap</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">"gb"</span>
<span class="n">timezone</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">"Europe/London"</span>
</code></pre></div>
<p>Few notes about the config file:</p>
<ul>
<li>System/User/SSH and Locale seem to be the minimum for getting an RPi to run</li>
<li>Wlan obviously needed if it's not going to be connected to ethernet, otherwise optional</li>
<li>password_authentication is currently broken and ignored. First boot config will always set
up the RPi for Key-authentication, it's a small bug that will likely be fixed easily.</li>
<li>password_encrypted should be set to <code>true</code> if you're providing the password hash, not a plaintext password</li>
<li>authorized_keys is an array of authorized keys. Copy yours from ~/.ssh/id_rsa.pub file</li>
</ul>
<p>once you're done setting up the file, mount your sd-card's boot partition and copy the file there</p>
<div class="highlight"><pre><span></span><code>mkdir<span class="w"> </span>-v<span class="w"> </span>/mnt/rpi-boot
mount<span class="w"> </span>-v<span class="w"> </span>/dev/**sdb1**<span class="w"> </span>/mnt/rpi-boot
cp<span class="w"> </span>-v<span class="w"> </span>custom.toml<span class="w"> </span>/mnt/rpi-boot
umount<span class="w"> </span>/mnt/rpi-boot<span class="w"> </span><span class="o">&&</span><span class="w"> </span>rmdir<span class="w"> </span>/mnt/rpi-boot
</code></pre></div>
<p>that's it - insert your sd card into the RPi and give it a couple of minutes to expand the filesystem
and set itself up, then you can ssh into it.</p>
<p><code>exit 0</code></p>New Server, Who Dis? (Phishing attempts)2023-06-12T10:00:00+01:002023-06-12T10:00:00+01:00Ahmadtag:khalifa.ws,2023-06-12:/posts/new-server-who-dis-phishing-attempts.html<p>Unfriendly knocking at the server door</p><p>Recently got a new vps box, firewall switched on and working on setting it up
for a while. Then things were ready and I wanted to start testing email delivery
and a few external things. The moment I opened up the firewall, I was inundated with
a slew of probes, scans and all means of phishing attempts.</p>
<p>It was all over the place, the ssh logs, email servers, web server and every open port.
This is not new to me, I've been seeing it happen for years. But what was surprising
here was that it was a brand new server, fresh ip, new domain, barely dipping its toes
into the sea of traffic on the internet, and it was almost instantaneous. Like vultures
were circling and waiting for the firewall to puncture slightly.</p>
<p>Initially, I even skipped setting up fail2ban, but the persistence of certain IPs changed
my mind pretty quickly.</p>
<p>There is no doubt that these attacks won't ever stop, there seems to be some profit
in them since they've increased over the years.</p>
<p>It's a jungle out there, keep your firwalls up, don't expect any grace period when
publishing a new service.
Also, check your logs regularly. I'm not a fan of rapid updates, as it's one of those
things that still carries both a cost and risk, but it still has to be done at regular
intervals.</p>Skip Ubuntu 'Intel RST' Check2021-06-23T10:00:00+01:002021-06-23T10:00:00+01:00Ahmadtag:khalifa.ws,2021-06-23:/posts/skip-ubuntu-intel-rst-check.html<p>Skip Ubuntu Intel RST Check when the Firmware doesn't allow you to disable RST</p><p>Ran into this when I was installing Linux on an HP Gaming laptop that came with Intel Optane memory.
So it had two storage devices, the large HDD and also a smaller NVME drive.
Intel Optane and RST together make the NVME invisible and just acts as a RAID shadow of the
larger drive. In short, a storage cache fo about 13GB for your 500GB hard drive.</p>
<h3>The Problem</h3>
<p>That was all fine until the <em>Ubiquity</em> installer for Ubuntu blocked the installation from the Live disk
starting from version 20 LTS. </p>
<p>Ubiquity's instructions didn't work because the my Firware, <em>InsydeH20</em>, doesn't allow to switch the RST/RAID/NVME off.</p>
<p>So with no ability to switch that off and no way to change the Firmware myself, my options were:</p>
<ol>
<li>Install older Ubuntu 18 LTS which didn't have this check, then upgrade from that</li>
<li>Force Ubiquity to skip the RST check</li>
</ol>
<p>Both work, but both mean that you can't run a dual-boot into Windows where Optane is enabled.</p>
<h3>How do you skip Ubuntu RST check?</h3>
<p><em>Warning you should really know what you're doing before trying this, especially if you will keep dual-booting Windows.</em></p>
<p>This was tested on an HP Pavilion with Firmware 'InsydeH20' version 'F.23' with Intel Optane Memory
and 'Rapid Storage Technology' RAID Driver
1. SATA drive - the main hdd or sdd with AHCI controller (this is your 500GB or so drive)
2. PCIe disk with NVMe controller (usually 13GB or so just for cached data)</p>
<p><em>First step</em>, you have to disable Intel Optane through Windows. This separates the NVME drive from the HDD.
After this point, your Firmware should start recognising two separate drives.</p>
<p><em>Next</em> start your installation as usual by booting from the Live CD.
Ubiquity is a Python-based installer, so we're looking for the Python code that checks for Intel RST being enabled.
It does this by looking at the EFI variables registerd by the Kernel. So we're going to look for that part and always return
that NVMe was not found.</p>
<p>Open a Terminal and run</p>
<div class="highlight"><pre><span></span><code><span class="w"> </span>find<span class="w"> </span>/usr/lib/ubiquity/<span class="w"> </span>-iname<span class="w"> </span>ubi-prepare.py
<span class="w"> </span>sudo<span class="w"> </span>nano<span class="w"> </span>/usr/lib/ubiquity/plugins/ubi-prepare.py
</code></pre></div>
<p>That <code>ubi-prepare.py</code> file should have a function called <code>should_show_rst_page()</code>
Find it and change the <code>return True</code> line to <code>False</code> </p>
<div class="highlight"><pre><span></span><code> <span class="c1"># return True</span>
<span class="k">return</span> <span class="kc">False</span>
</code></pre></div>
<p>Now save that and run your installer as usual.</p>Hold My Screen2021-06-11T10:00:00+01:002021-06-11T10:00:00+01:00Ahmadtag:khalifa.ws,2021-06-11:/posts/hold-my-screen.html<p>How to prevent screen locks and hold your screen</p><p>If you find yourself with an overzealous screen lock timer where you turn your back
to make a coffee and you find your screen locked. And now you have to remember that
difficult password. Or maybe you're using multiple screens and one of them is remotely
logged into another machine, but that other machine keeps locking and the screen
goes blank.</p>
<p>Well, here are a few harmless ways you can employ to delay or stop that screen from
locking.</p>
<h3>Play a video</h3>
<p>Muted videos are probably the easiest way to do this on your own machine.
Just keep the video visible at all times.</p>
<h3>Use a browser</h3>
<p>A browser to hold the screen lock gives you a few possibilities on your local machine or remote ones.
Same rule applies, keep the tab visible.</p>
<ol>
<li>
<p><strong>Play a muted video</strong> on your browser is the easiest option if you're not worried about
who could be checking your traffic</p>
<p>Of course, mute the video, resize it to the smallest possible and set it to repeat</p>
</li>
<li>
<p><strong>Request a wakeLock from a Chrome browser</strong> through the console. This is the easiest if you
have Chrome and can remember to re-request the wakeLock when the tab is not visible.
Hit F12 or open the <em>Developer Console</em> from the menu and type:</p>
<p><code>navigator.wakeLock.request()</code></p>
<p>That's it - you get a promise back, which says it's pending, but if you assign that value
to a variable and re-check it, it will be <em>fulfilled</em></p>
</li>
</ol>
<div class="highlight"><pre><span></span><code><span class="o">></span><span class="w"> </span><span class="nx">w</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">navigator</span><span class="p">.</span><span class="nx">wakeLock</span><span class="p">.</span><span class="nx">request</span><span class="p">();</span>
<span class="o"><</span><span class="w"> </span><span class="nb">Promise</span><span class="w"> </span><span class="p">{</span><span class="o"><</span><span class="nx">pending</span><span class="o">></span><span class="p">}</span>
<span class="o">></span><span class="w"> </span><span class="nx">w</span>
<span class="o"><</span><span class="w"> </span><span class="nb">Promise</span><span class="w"> </span><span class="p">{</span><span class="o"><</span><span class="nx">fulfilled</span><span class="o">>:</span><span class="w"> </span><span class="p">...}</span>
</code></pre></div>
<p>Those are the two main ways I use to hold my screen from locking.</p>miniBidi2005-04-23T10:00:00+01:002021-06-11T10:00:00+01:00Ahmadtag:khalifa.ws,2005-04-23:/posts/minibidi.html<p>miniBidi is a simple C implementation of Unicode UAX #9 for bidirectional text</p><p>miniBidi is a small implementation of Unicode's UAX#9 algorithm for handling right-to-left (RTL) text. It was included
in the <a href="https://www.arabeyes.org/Adawat">Arabeyes Adawat Project</a></p>
<p>It was written primarily to allow <a href="https://www.chiark.greenend.org.uk/~sgtatham/putty/">PuTTY</a> to support displaying RTL text for languages like Arabic, Hebrew, Farsi...
Although there were several other implementations out there at the time, PuTTY's MIT license was not compatible with
any of them. So miniBidi was introduced with a MIT license so it can be <a href="https://git.tartarus.org/?p=simon/putty.git;a=blob;f=minibidi.c;hb=HEAD">included directly into PuTTY's codebase</a>.</p>
<p>Full source code can be found on the <a href="https://gitlab.com/arabeyes-dev/adawat/tree/master/minibidi/">Arabeyes Adawat Project's Gitlab</a></p>