<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel>
<title>davidjenei.com</title>
<link>https://davidjenei.com</link>
<description>davidjenei.com</description>
<atom:link href="https://davidjenei.com/feed.xml" rel="self" type="application/rss+xml"/>
<item>
<title>Hello again!</title>
<link>https://davidjenei.com/blog/hello-again.html</link>
<guid>https://davidjenei.com/blog/hello-again.html</guid>
<pubDate>Tue, 23 Jun 2026 00:00:00 +0000</pubDate>
<description><![CDATA[
<p>The site is back online, now with a new RSS feed (Hello Levente!).</p>
<p>Hopefully the auto-discovery works as well:</p>
<pre><code>&#60;link rel="alternate" type="application&#47;rss+xml" title="davidjenei.com" href="&#47;feed.xml"&#62;
</code></pre>
<p>Still using my handcrafted, Makefile-based static site generator. The feed is
<a href="https://validator.w3.org/feed/check.cgi?url=http%3A//davidjenei.com/feed.xml">valid</a>
for now, though I suspect there is still some room for improvement.</p>
<p>More posts soon.</p>]]></description>
</item>
<item>
<title>Why I write things here</title>
<link>https://davidjenei.com/blog/hello-world.html</link>
<guid>https://davidjenei.com/blog/hello-world.html</guid>
<pubDate>Tue, 23 Jun 2026 00:00:00 +0000</pubDate>
<description><![CDATA[
<p>Welcome!</p>
<p><a href="https://www.goodreads.com/quotes/22763-when-we-read-another-person-thinks-for-us-we-merely">Schopenhauer says</a> when we read we effectively follow someone else&#8217;s
thought process. But if we stay in permanent read-only mode, we gradually lose
our own capacity for thinking.</p>
<p>Fair point, but not everyone has hours to spare detailing new ideas
every day. Writing doesn&#8217;t have to be ambitious and time consuming though.</p>
<p>My goal here is recording and clarifying my own thinking. Some
say that the best way to deeply understand something is to write about it.</p>
<p>I recently got introduced to some <a href="https://indieweb.org/principles">indieweb principles</a> which motivated me to
create a place for myself on the internet. Gardening your own corner of
the internet is fun, and I should definitely write more about this to encourage
others.</p>
<p>As for now, I&#8217;m not starting any blog <a href="https://100daystooffload.com/">challenge</a> but I try to keep
practicing writing regularly. I hope it turns out to be useful to anyone else.</p>
<p>References:</p>
<ul>
<li><a href="https://news.ycombinator.com/item?id=23067352">HN: Why it&#8217;s great to write blog</a></li>
<li><a href="https://news.ycombinator.com/item?id=22910532">HN: Why don&#8217;t you have a blog</a></li>
</ul>]]></description>
</item>
<item>
<title>Newsletter - 2024.05</title>
<link>https://davidjenei.com/blog/newsletter-2024-05.html</link>
<guid>https://davidjenei.com/blog/newsletter-2024-05.html</guid>
<pubDate>Tue, 23 Jun 2026 00:00:00 +0000</pubDate>
<description><![CDATA[
<p>This time with music and tv picks.</p>
<h2 id="music">Music</h2>
<p><a href="https://www.youtube.com/watch?v=pHZXTmPnMso&amp;pp=ygUQdGVzc2VyYWN0IGxlZ2lvbg%3D%3D">Tesseract - Legion</a></p>
<p>Djent meets Muse. Exceptional vocal performance by Daniel Tompkins.</p>
<h2 id="tv">TV</h2>
<p><a href="https://www.rottentomatoes.com/tv/state_of_the_union">State of the Union</a></p>
<blockquote>
<p>Before appointments with their (marriage) therapist, Tom and Louise meet at a
pub to try to get their stories consistently coherent.</p>
</blockquote>
<p>Fast-paced comedy hits hard with dense 10-minute episodes, even if you are unmarried.</p>
<h2 id="software-engineering">Software engineering</h2>
<p><a href="https://taylor.town/-10x">-10x engineer</a></p>
<blockquote>
<p>Give zero consideration to how your system design will evolve over time.
Alternatively, drive your team obsess over architecture decisions so that
they don&#8217;t have time to test their hypotheses.</p>
</blockquote>
<p>+1: Build software that is impossible to change. A reminder from <a href="https://www.goodreads.com/en/book/show/39996759">Philosophy of software design</a>: Change amplification is a symptom of complexity which is that a seemingly
simple change requires code modifications in many different places.</p>
<p><a href="https://davidjenei.com/notes/python-isinstance.html">Python isinstance() function</a></p>
<p>How to avoid using <code>isinstance()</code>.</p>
<p><a href="https://pkl-lang.org/index.html">Pkl: configuration as program</a></p>
<p>Configuration file formats lack the expressiveness of a programming language.
This means we don’t have mechanisms to avoid repetetions or validate data
easily.</p>
<blockquote>
<p>By generating this configuration with Pkl, you can reduce verbosity and
increase maintainability through reuse, templating, and abstraction.</p>
</blockquote>
<h2 id="embedded">Embedded</h2>
<p><a href="https://techcommunity.microsoft.com/t5/internet-of-things-blog/microsoft-contributes-azure-rtos-to-open-source/ba-p/3986318">SIL-4 RTOS ThreadX open sourced under MIT licence</a></p>
<p>Getting started with <a href="https://github.com/eclipse-threadx/getting-started">ThreadX</a></p>
<h2 id="now">Now</h2>
<p>Work in progress: Promoting software artifacts, organising integration tests and environments.</p>]]></description>
</item>
<item>
<title>Azure IoT Edge on Toradex modules</title>
<link>https://davidjenei.com/blog/azure-iot-edge.html</link>
<guid>https://davidjenei.com/blog/azure-iot-edge.html</guid>
<pubDate>Tue, 23 Jun 2026 00:00:00 +0000</pubDate>
<description><![CDATA[
<p>Toradex is a well-known manufacturer on the <a href="https://www.toradex.com/computer-on-modules">Computer on Module</a> market.
They offer lots of guides for their hardware modules including
<a href="https://developer.toradex.com/knowledge-base/aws-greengrass-getting-started">tutorials</a> on how to get started with AWS Greengrass, but there is not
much information on the Azure counterpart.</p>
<p>The official Azure IoT Edge documentation has <a href="https://docs.microsoft.com/en-us/azure/iot-edge/how-to-install-iot-edge-linux">instructions</a> for
installing the runtime with package managers on Linux. But on some
constrained hardware, you may want to consider building a minimal Linux
without package managers or the prebuilt package is simply not suitable
for your system. In this post I would like to show how to compile a
Linux image from scratch with Azure IoT Edge runtime. I will also test
the service and deploy an example application to the board in a Linux
container.</p>
<p>For building Linux, I will use the Yocto framework, so first make sure
that you have the <a href="https://www.yoctoproject.org/docs/1.7/yocto-project-qs/yocto-project-qs.html#ubuntu">required packages</a> for your system.</p>
<p>Toradex uses the repo utility to manage multiple git repositories for
their BSP. It is available for many distros, so we can install simply
install with our package manager</p>
<pre><code>david.jenei@yocto-env:~$ sudo apt install repo
</code></pre>
<p>Now we can set up the build environment. Follow this Toradex <a href="https://developer.toradex.com/knowledge-base/board-support-package/openembedded-(core)">tutorial</a>
and check out the bsp layers.</p>
<pre><code>david.jenei@yocto-env:~&#47;oe-core$ repo init -u http:&#47;&#47;git.toradex.com&#47;toradex-bsp-platform.git -b LinuxImage3.0 -m default.xml
david.jenei@yocto-env:~&#47;oe-core$ repo sync
</code></pre>
<p>Open local.conf and set your machine. In this demonstration I am working
with a Colibri i.MX6 board:</p>
<pre><code>MACHINE ?= "colibri-imx6"
</code></pre>
<p>Append this line to the config to accept Freescale EULA, so the build
will complete on your first try:</p>
<pre><code>ACCEPT_FSL_EULA = "1"
</code></pre>
<p>Build the default console image with bitbake:</p>
<pre><code>david.jenei@yocto-env:~&#47;oe-core&#47;build$ bitbake -k console-tdx-image
</code></pre>
<p>When the build completes, you can find the binaries in the deploy
directory:</p>
<pre><code>david.jenei@yocto-env:~&#47;oe-core&#47;build$ ls deploy&#47;images&#47;colibri-imx6&#47;
</code></pre>
<p>I am going to assume here, that you already have bootloader installed on
your board (otherwise you have to enter recovery mode and use
<a href="https://github.com/toradex/imx_loader">imx_loader</a> and execute u-boot.imx).</p>
<p>Connect to the debug serial and get a u-boot shell. Also connect to the
USB OTG port, and attach the eMMC boot partition to your PC as an USB
mass storage.</p>
<pre><code>Colibri iMX6 # ums 0 mmc 0.1
UMS: LUN 0, dev 0, hwpart 1, sector 0x0, count 0x1000
USB EHCI 1.00
</code></pre>
<p>Write the SPL and the u-boot.img to the eMMC with dd:</p>
<blockquote>
<p>Make sure that you select the right output device here (&#47;dev&#47;disk2,
&#47;dev&#47;sda etc. depending on your platform).</p>
</blockquote>
<pre><code>sudo dd if=.&#47;SPL-colibri-imx6-2019.07+gitAUTOINC+e1cbe8c74e-r0-spl-2019.07+gitAUTOINC+e1cbe8c74e-r0 of=&#47;dev&#47;disk2 bs=1k seek=1 conv=sync
sudo dd if=.&#47;u-boot-spl-2019.07+gitAUTOINC+e1cbe8c74e-r0.img of=&#47;dev&#47;disk2 bs=1k seek=69 conv=sync
</code></pre>
<p>Reset the board, and check the build time stamp:</p>
<pre><code>Colibri iMX6 # reset
resetting ...

Industrial temperature grade DDR3 timings, 64bit bus width.
Trying to boot from MMC1

U-Boot 2019.07-3.0.3+g694e2136ee (Mar 05 2020 - 11:14:09 +0000)
</code></pre>
<p>Now that we have our fresh bootloader installed on the board, we can try
to compile Azure IoT Edge. Edit local.conf once again, and add the
following:</p>
<pre><code>DISTRO_FEATURES_append = " virtualization"
IMAGE_INSTALL_append = " iotedge-daemon iotedge-cli cgroup-lite rng-tools procps"
</code></pre>
<p>We enable virtualization layer as a distro feature and install a few
packages. With cgroup-lite we can mount cgroups on startup, we need
rng-tools.</p>
<p>Run bitbake again and compile our eMMC user partition image now:</p>
<pre><code>david.jenei@yocto-env:~&#47;oe-core&#47;build$ bitbake -k console-tdx-image
</code></pre>
<p>Enter UMS mode again, and write the contents of the image.</p>
<pre><code>Colibri iMX6 # ums 0 mmc 0
</code></pre>
<p>End of chapter #1. To be continued.</p>]]></description>
</item>
<item>
<title>Minimal container OS with Yocto for embedded</title>
<link>https://davidjenei.com/blog/podman-yocto.html</link>
<guid>https://davidjenei.com/blog/podman-yocto.html</guid>
<pubDate>Tue, 23 Jun 2026 00:00:00 +0000</pubDate>
<description><![CDATA[
<p>Linux containers started to become more widespread in embedded systems during
the last few years. Application portability, ease of configuration, and
isolation are all desirable features in edge devices just as in the cloud. To
quickly get started with containers on ARM devices, you can download pre-built
images like <a href="https://www.armbian.com">Armbian</a> for the <a href="https://www.armbian.com/download/">supported
boards</a> and install Docker using standard
package managers.</p>
<p>If you wish to run all applications in Linux containers, you will
probably aim for a lightweight distribution instead of a full featured
one. Minimal container operating systems like
<a href="https://access.redhat.com/documentation/en-us/openshift_container_platform/4.1/html/architecture/architecture-rhcos">CoreOS</a>,
<a href="https://rancher.com/rancher-os/">RancherOS</a> and others were created for
this purpose and you can use them on regular VMs.</p>
<p>For IoT devices, there is <a href="https://ubuntu.com/download/iot">Ubuntu Core</a>
with off-the-shelf Raspberry and Dragonboard support. But if your
hardware is not supported or you’re not planning to use the snap package
format of Ubuntu, you can always compile your own distribution with
Buildroot or Yocto.</p>
<p>In this tutorial, I will show <strong>how to build a custom Linux OS with
container support for an ARM board and how to deploy some simple apps in
containers</strong>.</p>
<p>For managing containers, I will use <a href="https://podman.io">Podman</a> instead
of Docker as an experiment. I found during my early tests that starting
containers with Docker took ages on my board. But instead of playing
around with different container runtimes, I chose to test Podman, so
later I can <a href="https://developers.redhat.com/blog/2019/01/29/podman-kubernetes-yaml/">move to
Kubernetes</a>
or run rootless containers.</p>
<p>First, set up a basic Yocto environment and clone the poky reference
distribution repository.</p>
<pre><code>git clone -b thud git:&#47;&#47;git.yoctoproject.org&#47;poky
</code></pre>
<p>Configurations in the Yocto build system are stored in layers. The first
layer we need is
<a href="https://github.com/linux-sunxi/meta-sunxi">meta-sunxi</a>, which is the
BSP layer for my Allwinner based Orange Pi board, so let’s download this
layer.</p>
<pre><code>git clone https:&#47;&#47;github.com&#47;linux-sunxi&#47;meta-sunxi.git
</code></pre>
<p>We also need
<a href="http://git.openembedded.org/meta-openembedded">meta-openembedded</a>,
<a href="https://git.yoctoproject.org/cgit/cgit.cgi/meta-virtualization/">meta-virtualization</a>,
<a href="https://git.yoctoproject.org/cgit/cgit.cgi/meta-security">meta-security</a>
layers to compile Podman and the container runtime.</p>
<pre><code>git clone -b thud git:&#47;&#47;git.openembedded.org&#47;meta-openembedded &#38;&#38; \
git clone -b thud git:&#47;&#47;git.yoctoproject.org&#47;meta-virtualization &#38;&#38; \
git clone -b thud git:&#47;&#47;git.yoctoproject.org&#47;meta-security
</code></pre>
<p>Before adding these layers to the build system, we have to setup the
build directory. Run the poky environment setup script which will
automatically generate your <em>&#47;build</em> folder. Note that this command will
change your working directory.</p>
<pre><code>source poky&#47;oe-init-build-env
</code></pre>
<p>Now we can set up the configuration files in the build directory. Enable
the following layers from the previously cloned repos with the
<strong>bitbake-layers</strong> command, so we don’t have to edit <strong>bblayer.conf</strong> by
hand.</p>
<pre><code>bitbake-layers add-layer ..&#47;meta-sunxi&#47; \
    ..&#47;meta-openembedded&#47;meta-oe&#47; \
    ..&#47;meta-openembedded&#47;meta-filesystems&#47; \
    ..&#47;meta-openembedded&#47;meta-python&#47; \
    ..&#47;meta-openembedded&#47;meta-networking&#47; \
    ..&#47;meta-openembedded&#47;meta-perl&#47; \
    ..&#47;meta-virtualization&#47; \
    ..&#47;meta-security&#47;
</code></pre>
<p>For the time being, I am going to add every customisation to the
<strong>local.conf</strong> file. This file stores the local or user specific
configuration. Later we can create a new configuration layer with
recipes for this image to store our changes permanently.</p>
<p>First we set the target device in <strong>local.conf</strong>. I checked the exact
machine name for my board in the BSP layer (<em>meta-sunxi&#47;conf&#47;machine&#47;</em>)
and modified the <code>MACHINE</code> parameter accordingly.</p>
<pre><code># This sets the default machine to be qemux86-64 if no other machine is selected:
MACHINE ??= "orange-pi-one"
</code></pre>
<p>Linux container isolation is built on kernel features like cgroups and
namespaces but the kernel configuration for my board did not enable
these by default.</p>
<p>Instead of editing the kernel configuration in the BSP layer, settings
in meta-virtualization can extend our configuration to enable kernel
features to support containers. The meta-virtualization layer implements
this with defining a new <code>DISTRO_FEATURE</code>. Distro features can enable
functionality across multiple packages. So add this to our local.conf:</p>
<pre><code>DISTRO_FEATURES_append = " virtualization"
</code></pre>
<p>Finally select the packages we want to build into the image.</p>
<pre><code>IMAGE_INSTALL_append = "  podman podman-compose crun cgroup-lite rng-tools \
                          procps ca-certificates python3-setuptools \
                          python3-pyyaml python3-json"
</code></pre>
<p>Here is a little explanation for this part:</p>
<ul>
<li><a href="https://github.com/containers/libpod">podman</a>: Docker compatible
container manager tool for libpod. We will use this command to
manage containers just as with Docker.</li>
<li><a href="https://github.com/containers/podman-compose">podman-compose</a>:
<strong>docker-compose</strong> implementation with <a href="https://podman.io/">podman</a>
backend. We can run multi container applications and store container
configuration in yaml files with this tool.</li>
<li><a href="https://github.com/containers/crun">crun</a>: OCI Container Runtime
written in C. Originally it was written for supporting cgroupV2.
This runtime is a bit more leightweight than runc.</li>
<li><a href="http://git.yoctoproject.org/cgit/cgit.cgi/meta-virtualization/tree/recipes-containers/cgroup-lite/cgroup-lite_1.1.bb?h=fido">cgroup-lite</a>:
mounts cgroups on startup.</li>
<li>rng-tools: on my 4.19 kernel hardware rng is not yet mainlined for
the Allwinner H3 processor, so I need <a href="https://lwn.net/Articles/642166/">jitter
entropy</a> to keep my startup time
reasonable and don’t wait for &#47;dev&#47;random too long.</li>
<li>ca-certificates: podman wants to check the server certificates when
pulling new images</li>
<li>some python3 packages: podman-compose depends on these, but were not
included as dependencies the recipe.</li>
<li>e2fsprogs-mke2fs: we also need mkfs to create a data partition for
the containers</li>
</ul>
<p>Now we need to specify the image recipe we want to build. As a starting
point I used the core-image-minimal as the smallest default image. Use
the bitbake command to start the build.</p>
<pre><code>bitbake core-image-minimal
</code></pre>
<blockquote>
<p>This image configuration is the reason why we added all these
seemingly random packages to the build. It is a minimal default
configuration, so we had to add these otherwise essential tools like
rngd to the image.</p>
</blockquote>
<p>After a few hours hopefully the build completes, and you can find the sd
card image in <em>build&#47;tmp&#47;deploy&#47;images</em></p>
<pre><code>ls -ailh build&#47;tmp&#47;deploy&#47;images&#47;orange-pi-one&#47;core-image-minimal-orange-pi-one-20200310152758.rootfs.sunxi-sdimg
</code></pre>
<p>Write this image to an SD card and boot the board with the new image.
Get a terminal using a serial port or SSH.</p>
<p>Before starting a container with podman, we have to modify libpod.conf.</p>
<pre><code>root@orange-pi-one:~# vi &#47;etc&#47;containers&#47;libpod.conf
</code></pre>
<p>Set crun as a container runtime and use cgroupfs instead of systemd to
manage cgroups.</p>
<pre><code>cgroup_manager = "cgroupfs"
runtime = "&#47;usr&#47;bin&#47;crun"
</code></pre>
<p>Now we can try running our first container.</p>
<pre><code>root@orange-pi-one:~# podman run hello-world
Trying to pull docker.io&#47;library&#47;hello-world...
Getting image source signatures
Copying blob b6206e5d545d done
Copying config cfdb1bf11e done
Writing manifest to image destination
Storing signatures

Hello from Docker!
...
</code></pre>
<p>With this build, your root partition has very little free space
available. If you would like to store your containers and container
images on another partition, edit storage.conf.</p>
<pre><code>root@orange-pi-one:~# vi &#47;etc&#47;containers&#47;storage.conf
</code></pre>
<p>Point runroot and graphroot locations to your data partition.</p>
<pre><code># Temporary storage location
#runroot = "&#47;var&#47;run&#47;containers&#47;storage"
runroot = "&#47;mnt&#47;data&#47;storage"

# Primary Read&#47;Write location of container storage
#graphroot = "&#47;var&#47;lib&#47;containers&#47;storage"
graphroot = "&#47;mnt&#47;data&#47;storage
</code></pre>
<p>(Now you can create a new partiton with fdisk and mkfs, then edit your
fstab to mount your partition on startup. Or you can use wic to create
an sd image with an empty data partition)</p>
<p>Test <code>podman-compose</code> with a simple configuration. Create a new compose
file.</p>
<pre><code>vi docker-compose.yml
</code></pre>
<p>Define an example service.</p>
<pre><code>version: &#39;2.0&#39;
services:
  hello-world:
     image: hello-world
</code></pre>
<p>And start this configuration.</p>
<pre><code>root@orange-pi-one:~&#47;test# podman-compose up
podman pod create --name=test --share net
4dc74923c2314d0ef0379f90e0246fab5d41896ae815ee33287b5e6360c40fac
0
podman create --name=test_hello-world_1 --pod=test -l io.podman.compose.config-hash=123 -l io.podman.compose.project=test -l io.podman.compose.version=0.0.1 -l com.docker.compose.container-number=1 -l com.docker.compose.service=hello-world --add-host hello-world:127.0.0.1 --add-host test_hello-world_1:127.0.0.1 hello-world
ea9f6fd6fce3af419d1306b94e9de21f49bb323a870ed053abf4e5a8d9ae1b0c
0
podman start -a test_hello-world_1

Hello from Docker!
</code></pre>
<p>In this example, we used Yocto to build a small Linux image from scratch
and installed essential packages to get started with containers on an
ARM devices. With the lightweight container runtime and the minimal
configuration the image still has a significant size (~250MB) but it is
a good starting point for testing.</p>
<p>The next steps would be saving this configuration in a separate Yocto
layer, but this is a topic for another tutorial.</p>]]></description>
</item>
<item>
<title>Links - 2022.08</title>
<link>https://davidjenei.com/blog/links-2022-08.html</link>
<guid>https://davidjenei.com/blog/links-2022-08.html</guid>
<pubDate>Sun, 28 Jan 2024 00:00:00 +0000</pubDate>
<description><![CDATA[
<h2 id="software-engineering">Software engineering</h2>
<ul>
<li>  <a href="https://blog.ffwll.ch/2022/07/locking-engineering.html">Locking Engineering Principles</a> - Daniel Vetter</li>
<li>  <a href="https://github.com/AsahiLinux/docs/wiki/Introduction-to-Apple-Silicon">Apple Silicion boot flow</a> - Asahi Linux wiki</li>
<li>  <a href="https://googleprojectzero.blogspot.com/2022/08/the-quantum-state-of-linux-kernel.html">The quantum state of Linux kernel garbage collection
CVE-2021-0920</a> - Google project zero</li>
<li>  <a href="https://andrealmeid.com/post/2022-07-31-keep-bisect/">Keeping a project bisectable</a> - André Almeida</li>
<li>  <a href="https://interrupt.memfault.com/blog/git-bisect">Hunting bugs with git biscect</a> - Memfault</li>
</ul>
<h2 id="hardware">Hardware</h2>
<ul>
<li>  <a href="https://www.cnx-software.com/2022/08/01/7-5-inch-e-paper-display-esp32-boards/">$52 7.5-inch E-paper display connects to ESP32 boards</a> - CNX</li>
</ul>
<h2 id="tech">Tech</h2>
<ul>
<li>  <a href="https://semiengineering.com/where-are-the-autonomous-cars/">Where Are The Autonomous Cars?</a> - Semiconductor Engineering</li>
<li>  <a href="https://cloudblogs.microsoft.com/industry-blog/manufacturing/2022/08/11/top-6-findings-from-iot-signals-manufacturing-spotlight/">IoT Signals: Manufacturing Spotlight</a> - Microsoft</li>
</ul>
<h2 id="book">Book</h2>
<ul>
<li>  <a href="http://www.catb.org/~esr/writings/cathedral-bazaar/">The Cathedral and the Bazaar</a> - Eric S. Raymond</li>
</ul>
<blockquote>
<p><a href="http://www.catb.org/~esr/writings/cathedral-bazaar/magic-cauldron/ar01s03.html">The Manufacturing Delusion</a></p>
</blockquote>]]></description>
</item>
<item>
<title>Links - 2022.09</title>
<link>https://davidjenei.com/blog/links-2022-09.html</link>
<guid>https://davidjenei.com/blog/links-2022-09.html</guid>
<pubDate>Sun, 28 Jan 2024 00:00:00 +0000</pubDate>
<description><![CDATA[
<h2 id="software-engineering">Software engineering</h2>
<ul>
<li>  <a href="https://beny23.github.io/posts/my_take_on_engineering_room_9/">Less is more agile</a> - Gerald Benischke</li>
<li>  <a href="https://tech.davis-hansson.com/p/make/">Your Makefiles are worng</a> - Jacob Davis-Hansson</li>
</ul>
<h2 id="hardware">Hardware</h2>
<ul>
<li>  <a href="https://github.com/Anime4000/RTL960x">SFP GPON module firmware customisation</a> - Github</li>
<li>  <a href="https://blog.willemmelching.nl/carhacking/2022/01/02/vw-part1/">VW Golf Steering ECU reversing</a> - Willem Melching</li>
</ul>
<blockquote>
<p>excellent writeup, very detailed.</p>
</blockquote>
<ul>
<li>  <a href="https://programmingwithstyle.com/posts/howihackedmycar/">Hyundai Ioniq firmware update</a> - programmingwithstyle</li>
</ul>
<blockquote>
<p>this monthly is a car hacking special edition</p>
</blockquote>
<ul>
<li>  <a href="https://www.secura.com/blog/tpm-sniffing-attacks-against-non-bitlocker-targets">TPM Sniffing attacks</a> - Jos Wetzels</li>
</ul>
<h2 id="book">Book</h2>
<ul>
<li>  <a href="https://en.wikipedia.org/wiki/Thinking,_Fast_and_Slow">Thinking, Fast and Slow</a> - Daniel Kahneman</li>
</ul>]]></description>
</item>
<item>
<title>Links - 2022.10</title>
<link>https://davidjenei.com/blog/links-2022-10.html</link>
<guid>https://davidjenei.com/blog/links-2022-10.html</guid>
<pubDate>Sun, 28 Jan 2024 00:00:00 +0000</pubDate>
<description><![CDATA[
<h2 id="software-engineering">Software engineering</h2>
<ul>
<li>  <a href="https://blog.robenkleene.com/archive/">The Era of Visual Studio Code</a> - Roben Kleene</li>
<li>  <a href="https://embedded.fm/episodes/423">Phillip on EmbeddedFM</a></li>
</ul>
<h2 id="hardware">Hardware</h2>
<ul>
<li>  <a href="https://www.libcamera.org/docs.html#camera-stack">Welcome to libcamera v0.0.1</a></li>
<li>  <a href="https://wiki.gentoo.org/wiki/User:Sakaki/Sakaki%27s_EFI_Install_Guide/Disabling_the_Intel_Management_Engine">Disabling Intel management engine</a></li>
<li>  <a href="https://www.youtube.com/watch?v=FIXJzIKJxyU">Enhanced Cybersecurity and FIPS 140-2 Compliance using NXP i.MX 8X</a></li>
</ul>]]></description>
</item>
<item>
<title>Join Ubuntu 18.04 LXC container to Active Directory</title>
<link>https://davidjenei.com/blog/ubuntu-lxc-ad.html</link>
<guid>https://davidjenei.com/blog/ubuntu-lxc-ad.html</guid>
<pubDate>Sun, 28 Jan 2024 00:00:00 +0000</pubDate>
<description><![CDATA[
<p>An Active Directory service can help you manage user accounts effectively
even on Linux hosts. If you need a shared workstation with
a multiple users and already have a domain controller in your network,
you can join your servers to the domain instead of recreating accounts
and different access levels on each host manually.</p>
<p>There are plenty of tutorials out there how to do this on a Linux
machine. But if you prefer running <a href="https://linuxcontainers.org">LXC
containers</a> as workstations rather than
regular VMs, you may need to change a few things like tweaking the
<strong>uid&#47;gid mapping</strong>.</p>
<p>This short tutorial will show you how to join a newly created LXC container
to an Active Directory and how to configure SSH to login with your
domain account.</p>
<p>I will assume that you already:</p>
<ul>
<li>have a running Active Directory in your network</li>
<li>have an administrator account for the AD server</li>
<li>installed LXC on your Linux host</li>
</ul>
<p>Let&#8217;s start with launcing a new lxc container:</p>
<pre><code>lxc launch ubuntu:18.04 ad-join-test
Creating ad-join-test
Starting ad-join-test
</code></pre>
<p>Get a shell inside:</p>
<pre><code>lxc exec ad-join-test -- &#47;bin&#47;bash
root@ad-join-test:~#
</code></pre>
<p>On Ubuntu or similar distros, we can use <a href="https://wiki.ubuntu.com/Enterprise/Authentication/sssd">System Security Services
Daemon</a> (sssd)
for connecting to remote authentication providers. The documentation
recommends using an automated tool to configure it and here I am going
to use the
<a href="http://manpages.ubuntu.com/manpages/bionic/man8/realm.8.html">realm</a>
command-line tool for quick enrollment.</p>
<p>But first we need to install realmd and a few more packages:</p>
<pre><code>root@ad-join-test:~# apt update &#38;&#38; apt install realmd sssd-tools
sssd libnss-sss libpam-sss adcli packagekit
</code></pre>
<p>Now we can try to discover our realm:</p>
<pre><code>root@ad-join-test:~# realm discover eilabs.local
</code></pre>
<p>In case of no answer here, make sure that you can resolve the name of
domain controller:</p>
<pre><code>root@ad-join-test:~# nslookup -type=srv _ldap._tcp.eilabs.local
</code></pre>
<blockquote>
<p>I couldn&#8217;t resolve the domain name of my domain controller in the
first place, because we used .local as top level domain, which is
<a href="https://github.com/systemd/systemd/issues/8852">nowadays intended to use in multicast
DNS</a>, so I had to
change the systemd-resolver configuration.</p>
</blockquote>
<p>If realm can discover the ldap service, use your administrator account
to join. Realm is a silent program, so I am going to use &#8211;verbose to
see the details of the process:</p>
<pre><code>root@ad-join-test:~# realm join eilabs.local --user=david.jenei --verbose
</code></pre>
<p>Now try to check connection to the domain controller and look up your
user passwd entry:</p>
<pre><code>root@ad-join-test:~# getent passwd david.jenei@eilabs.local
</code></pre>
<p>If you try to login now, you see that the system is using the <code>pam_sss</code>
module now as it should, but there is this error in the auth.log.</p>
<pre><code>pam_sss(login:auth): received for user david.jenei@eilabs.local: 4 (System error)
</code></pre>
<p>Changing the <a href="https://docs.pagure.org/SSSD.sssd/users/troubleshooting.html">debug log level in the
sssd</a>
reveals that there is problem with the uid. If you would like see the
error message, put the debug directive under your domain&#8217;s section in
the sssd configuration (&#47;etc&#47;sssd&#47;sssd.conf) and restart sssd.</p>
<p>Here you can see, that my uid is way out of range, and the default id
mapping in sssd can&#8217;t map those into the allocated uid map:</p>
<pre><code>root@ad-join-test:~# cat &#47;proc&#47;self&#47;uid_map
         0     100000      65536
root@ad-join-test:~# getent passwd david.jenei@eilabs.local
david.jenei@eilabs.local:*:1149001181:1149000513:Jenei,
    David:&#47;home&#47;david.jenei@eilabs.local:&#47;bin&#47;bash
</code></pre>
<p>Add these lines to the sssd configuration for your domain to limit idmap
range and to <strong>map uid&#47;gid into the available space</strong>.</p>
<pre><code>ldap_id_mapping = True
ldap_idmap_range_min = 10000
ldap_idmap_range_max = 50000
ldap_idmap_range_size = 1000
</code></pre>
<p>I also changed the backup homedir line to a new home directory format
and enabled login without fully qualified names:</p>
<pre><code>use_fully_qualified_names = False
override_homedir = &#47;home&#47;%d&#47;%u
</code></pre>
<p>If you restart sssd after changing the configuration, it will fail,
because we also need to manually clear the cache:</p>
<pre><code>root@ad-join-test:~# rm -rf &#47;var&#47;lib&#47;sss&#47;db&#47;*
</code></pre>
<p>Restart sssd service and login with your account:</p>
<pre><code>root@ad-join-test:~# systemctl restart sssd
root@ad-join-test:~# login
ad-join-test login: david.jenei
Password:
Welcome to Ubuntu 18.04.3 LTS (GNU&#47;Linux 4.15.0-88-generic x86_64)
</code></pre>
<p>Run pam-auth-update and enable home directory creation on login. Next
time you login, your home directory will be created automatically.</p>
<pre><code>root@ad-join-test:~# pam-auth-update
</code></pre>
<p>Finally edit &#47;etc&#47;ssh&#47;sshd_config and enable password login:</p>
<pre><code>PasswordAuthentication yes
</code></pre>
<p>Restart the ssh daemon and now you can use SSH with your AD user name to
login to your container.</p>
<pre><code>root@ad-join-test:~# systemctl restart sshd
root@ad-join-test:~# ssh david.jenei@localhost
</code></pre>
<p>For more information, you can check out the details of uid mapping in
LXD
<a href="https://ubuntu.com/blog/custom-user-mappings-in-lxd-containers%5D">here</a>. </p>]]></description>
</item>
</channel></rss>
