<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Lukáš Zapletal</title><link>http://lukas.zapletalovi.com/atom.xml</link><description>Recent content on Lukáš Zapletal</description><generator>Hugo</generator><language>en-us</language><lastBuildDate>Thu, 09 Apr 2026 09:49:06 +0200</lastBuildDate><atom:link href="http://lukas.zapletalovi.com/atom.xml" rel="self" type="application/rss+xml"/><item><title>Netbird DNS Split Configuration</title><link>http://lukas.zapletalovi.com/posts/2026/netbird-dns-split-configuration/</link><pubDate>Wed, 08 Apr 2026 08:16:58 +0200</pubDate><guid>http://lukas.zapletalovi.com/posts/2026/netbird-dns-split-configuration/</guid><description>&lt;p&gt;Many companies provide NetBird VPN access configured with a mandatory DNS
resolving service to ensure malware protection. While this is a solid IT
recommendation for the general workforce, it can be frustrating if you run your
own DNS blocker at home (like Pi-hole or AdGuard Home) and want to keep your
personal traffic routing through it for better performance or hostname
rewrites.&lt;/p&gt;
&lt;p&gt;If your company’s NetBird configuration forces all DNS queries through their
resolvers, you can bypass this and configure split DNS manually. Here is how to
do it on both MacOS and Linux.&lt;/p&gt;</description></item><item><title>Running Jellyfin in Podman</title><link>http://lukas.zapletalovi.com/posts/2026/jellyfin-in-podman/</link><pubDate>Fri, 03 Apr 2026 19:55:00 +0100</pubDate><guid>http://lukas.zapletalovi.com/posts/2026/jellyfin-in-podman/</guid><description>&lt;p&gt;This guide covers deploying a streamlined, self-hosted audio and video
archiving setup using Podman Quadlets. The stack integrates UN/BT tools and a
web-based file management. All services are running rootful with SELinux in
enforcing mode.&lt;/p&gt;
&lt;p&gt;Some containers are configured with host network for maximum performance of the
network stack, this only works in rootful mode.&lt;/p&gt;
&lt;p&gt;By leveraging Quadlets, we can define our containers directly as native systemd
units, allowing for easy daemonless management and auto-updating without
relying on Docker Compose.&lt;/p&gt;</description></item><item><title>Running Immich in Podman</title><link>http://lukas.zapletalovi.com/posts/2026/immich-in-podman/</link><pubDate>Fri, 03 Apr 2026 19:50:00 +0100</pubDate><guid>http://lukas.zapletalovi.com/posts/2026/immich-in-podman/</guid><description>&lt;p&gt;Immich has rapidly become the go-to solution for self-hosters looking to
replace Google Photos. It is a high-performance, self-hosted photo and video
backup application that boasts mobile apps, smooth timeline scrolling, and
robust machine-learning capabilities for facial recognition and object
detection.&lt;/p&gt;
&lt;p&gt;While the official documentation heavily leans on Docker Compose, deploying
Immich using &lt;strong&gt;Podman Quadlets&lt;/strong&gt; is an excellent choice for a daemonless,
systemd-native setup. Quadlets allow you to define container workloads directly
via systemd unit files, making management, auto-updating, and logging
incredibly clean.&lt;/p&gt;</description></item><item><title>Hardened ssh in Fedora 43</title><link>http://lukas.zapletalovi.com/posts/2026/hardened-ssh-in-fedora/</link><pubDate>Wed, 25 Mar 2026 07:50:03 +0100</pubDate><guid>http://lukas.zapletalovi.com/posts/2026/hardened-ssh-in-fedora/</guid><description>&lt;p&gt;If you have a Fedora 43 (or older) system with public IP with ssh port opened,
you are probably getting a lot of records like these:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;sshd-session[20884]: refusing RSA key: Invalid key length [preauth]
sshd-session[31595]: Invalid user shop from 172.94.9.155 port 37434
sshd-session[57487]: Connection closed by 139.0.12.92 port 62968
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;These are scripts, bots or AI, trying to get in. As you already know, password
authentication is not something that should be used in 2026, so you are fine
with public keys. But still, this is polluting the system journal.&lt;/p&gt;</description></item><item><title>SecureBoot/HTTPS Provisioning with Foreman/Satellite</title><link>http://lukas.zapletalovi.com/posts/2026/secureboot-https-provisioning-foreman-satellite/</link><pubDate>Wed, 11 Mar 2026 16:16:34 +0200</pubDate><guid>http://lukas.zapletalovi.com/posts/2026/secureboot-https-provisioning-foreman-satellite/</guid><description>&lt;p&gt;We live in a world where security is paramount, yet network provisioning is
often still done via the ancient PXE protocol, which is by design basically an
insecure remote execution. Hardware has moved on since the PXE times, and we
now have powerful BMC software with capabilities that are a great fit for a
secure, end-to-end network provisioning workflow.&lt;/p&gt;
&lt;p&gt;This post describes a way to leverage the EFI firmware stack on Intel x86_64 to
do most of the security heavy lifting. What you will read was all tested on a
Fedora hypervisor running a Red Hat Satellite 6.18 VM (Katello 4.18), and the
installed host was a Red Hat Enterprise Linux 10.1 VM. This should also work in
other similar environments (e.g., ARM64 EFI) or with Linux distributions that
use the Anaconda installer.&lt;/p&gt;</description></item><item><title>Deploy AdGuard Home via Podman Quadlets</title><link>http://lukas.zapletalovi.com/posts/2025/deploy-adguard-via-quadlets/</link><pubDate>Wed, 24 Sep 2025 11:02:47 +0200</pubDate><guid>http://lukas.zapletalovi.com/posts/2025/deploy-adguard-via-quadlets/</guid><description>&lt;p&gt;&lt;em&gt;Update 2026: Few changes, added host network mode which is more simple and less
confusing.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s install AdGuard Home via Podman Quadlets. Volumes:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo podman volume create adguard-work
sudo podman volume create adguard-conf
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Everything must be done as root since AdGuard needs to bind UDP port. Volume
units:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;cat &amp;lt;&amp;lt;EOF | sudo tee /etc/containers/systemd/adguard-work.volume &amp;gt; /dev/null
[Volume]
VolumeName=adguard-work
EOF
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex="0"&gt;&lt;code&gt;cat &amp;lt;&amp;lt;EOF | sudo tee /etc/containers/systemd/adguard-conf.volume &amp;gt; /dev/null
[Volume]
VolumeName=adguard-conf
EOF
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now the container unit:&lt;/p&gt;</description></item><item><title>Fixed Hugo alias noindex bug</title><link>http://lukas.zapletalovi.com/posts/2025/fixed-hugo/</link><pubDate>Mon, 15 Sep 2025 18:46:34 +0200</pubDate><guid>http://lukas.zapletalovi.com/posts/2025/fixed-hugo/</guid><description>&lt;p&gt;I was experiencing a weird behavior of Google treating my blog - specifically
with pages that had an alias. Turned out that Hugo generator, which I use for
my blog, use client side redirect for aliases:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;---
type: &amp;#34;post&amp;#34;
aliases:
- /2013/07/hidden-gems-of-xterm.html
date: &amp;#34;2013-07-17T00:00:00Z&amp;#34;
tags:
- linux
- fedora
title: Hidden gems of xterm
---
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Generates this alias page:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html lang=&amp;#34;en-us&amp;#34;&amp;gt;
 &amp;lt;head&amp;gt;
 &amp;lt;title&amp;gt;http://localhost:1313/posts/2013/hidden-gems-of-xterm/&amp;lt;/title&amp;gt;
 &amp;lt;link rel=&amp;#34;canonical&amp;#34; href=&amp;#34;http://localhost:1313/posts/2013/hidden-gems-of-xterm/&amp;#34;&amp;gt;
 &amp;lt;meta name=&amp;#34;robots&amp;#34; content=&amp;#34;noindex&amp;#34;&amp;gt;
 &amp;lt;meta charset=&amp;#34;utf-8&amp;#34;&amp;gt;
 &amp;lt;meta http-equiv=&amp;#34;refresh&amp;#34; content=&amp;#34;0; url=http://localhost:1313/posts/2013/hidden-gems-of-xterm/&amp;#34;&amp;gt;
 &amp;lt;/head&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The problem is the &lt;code&gt;noindex&lt;/code&gt; meta which, for some reason, Google understands as
&amp;ldquo;do not index this redirect as well as the canonical page&amp;rdquo;. Therefore, all Hugo
pages with an alias are excluded from Google index completely. Other search
engines behave differently, for example duckduckgogo is fine.&lt;/p&gt;</description></item><item><title>Reserved Custom Keyboard Key in VSCode</title><link>http://lukas.zapletalovi.com/posts/2025/reserved-custom-key-vscode/</link><pubDate>Fri, 18 Jul 2025 10:37:35 +0200</pubDate><guid>http://lukas.zapletalovi.com/posts/2025/reserved-custom-key-vscode/</guid><description>&lt;p&gt;While my primary editor is, and always will be, Vim, I find myself using VS Code more and more for longer editing sessions on larger projects. With its great Go support, decent (though not ideal) refactoring tools, and Copilot, it&amp;rsquo;s an excellent tool.&lt;/p&gt;
&lt;p&gt;Recently, I was exploring its Git capabilities and realized there are no default shortcuts for important actions like git commit or git push. Users are expected to perform these tasks using the mouse in the Source Control view, which is quite limited for editing commit messages; for example, it lacks automatic text wrapping.&lt;/p&gt;</description></item><item><title>Connect to Ancient SSH Server</title><link>http://lukas.zapletalovi.com/posts/2025/connect-to-ancient-ssh-server/</link><pubDate>Mon, 12 May 2025 15:02:59 +0200</pubDate><guid>http://lukas.zapletalovi.com/posts/2025/connect-to-ancient-ssh-server/</guid><description>&lt;p&gt;Modern Linux distributions configure OpenSSH client to refuse connecting to
servers without newer ciphers or key exchange algos. Symptoms are:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Unable to negotiate with 192.168.200.83 port 22: no matching host key type found. Their offer: ssh-rsa,ssh-dss
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The solution is clunky, so I created a small Debian-based container with
OpenSSH client installed, it is an &amp;ldquo;oldstable&amp;rdquo; version old enough not to have a
modern SSH client with modern configuration. Usage:&lt;/p&gt;</description></item><item><title>Directory Similarity Comparison Tool: walkalike</title><link>http://lukas.zapletalovi.com/posts/2025/walkalike-directory-similarity/</link><pubDate>Thu, 24 Apr 2025 08:00:03 +0200</pubDate><guid>http://lukas.zapletalovi.com/posts/2025/walkalike-directory-similarity/</guid><description>&lt;p&gt;I wrote a small but fast tool called
&lt;a href="https://github.com/lzap/walkalike"&gt;walkalike&lt;/a&gt; which calculates how two or more
filesystem trees (or OS images) are similar. Usage:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;walkalike dir1 dirN
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Processing is optimized for SSDs and index creation is parallelized. Example
command:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;walkalike testdata/a testdata/b
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Should print:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;0.4444444444444 testdata/a testdata/b
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Similarity coefficient is between 0.0, when two trees are not similar at all,
or 1.0, when two trees are exactly the same. When multiple directories are
provided, the first directory is compared against 2nd, 3rd and so on.&lt;/p&gt;</description></item><item><title>Generate testing MTLS certificates more easily</title><link>http://lukas.zapletalovi.com/posts/2024/generate-testing-mtls-certificates/</link><pubDate>Wed, 20 Nov 2024 15:48:23 +0100</pubDate><guid>http://lukas.zapletalovi.com/posts/2024/generate-testing-mtls-certificates/</guid><description>&lt;p&gt;I found a much better tool to generate testing X509 TLS certificates than &lt;a href="http://lukas.zapletalovi.com/posts/2019/testing-tls-ca-server-and-client-certs/"&gt;my own script&lt;/a&gt; which by the way is not correct. Here is how to generate a MTLS pair for typical web testing:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;#!/bin/bash -e

wget -nc https://raw.githubusercontent.com/redhat-qe-security/certgen/refs/heads/master/certgen/lib.sh
source lib.sh

x509KeyGen ca
x509KeyGen server
x509KeyGen client
x509SelfSign --notAfter &amp;#34;13 years&amp;#34; -t ca ca
x509CertSign --notAfter &amp;#34;13 years&amp;#34; --CA ca -t webserver server
x509CertSign --notAfter &amp;#34;13 years&amp;#34; --CA ca -t webclient client

openssl x509 -in ca/cert.pem -text -noout
openssl x509 -in server/cert.pem -text -noout
openssl x509 -in client/cert.pem -text -noout
openssl verify -CAfile ca/cert.pem server/cert.pem
openssl verify -CAfile ca/cert.pem client/cert.pem
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Quick test, a server:&lt;/p&gt;</description></item><item><title>MacOS Text Replacements in Firefox</title><link>http://lukas.zapletalovi.com/posts/2024/macos-text-replacements-in-firefox/</link><pubDate>Thu, 10 Oct 2024 09:33:07 +0200</pubDate><guid>http://lukas.zapletalovi.com/posts/2024/macos-text-replacements-in-firefox/</guid><description>&lt;p&gt;I use MacOS built-in text replacement feature a ton, however, after I started using Firefox recently I quickly found out that it does not work. The feature is disabled in &lt;code&gt;about:config&lt;/code&gt; via setting named &lt;code&gt;widget.macos.automatic.text_replacement&lt;/code&gt;, but even if you enable it it only works for &lt;code&gt;textarea&lt;/code&gt; and not for widely used &lt;code&gt;input&lt;/code&gt; element. And there is no solution so far.&lt;/p&gt;
&lt;p&gt;Well, there is a workaround by using &lt;a href="https://addons.mozilla.org/en-US/firefox/addon/textfast/"&gt;TextFast extension&lt;/a&gt; that does exactly what it is supposed to do. It is a tiny open-source extension and quick look does not show any network activity except optional storing of the list to Firefox Account (disabled by default). And it has a JSON-based importing / exporting capability.&lt;/p&gt;</description></item><item><title>Deploy Invidious via Podman</title><link>http://lukas.zapletalovi.com/posts/2024/deploy-invidious-via-podman/</link><pubDate>Sat, 28 Sep 2024 21:00:06 +0200</pubDate><guid>http://lukas.zapletalovi.com/posts/2024/deploy-invidious-via-podman/</guid><description>&lt;p&gt;Here is how you deploy &lt;a href="https://invidious.io/"&gt;Invidious&lt;/a&gt; via Podman 5.x or
higher. All commands are executed as a normal user, if you want to use root
then you need to modify some paths. Root-less containers are preferred together
with SELinux in enforcing mode for maximum security.&lt;/p&gt;
&lt;p&gt;Create a new volume for database:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;podman volume create invidious-db
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Start a temporary container:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;podman run --rm -it --name invidious-init -v invidious-db:/var/lib/postgresql/data:Z -p 5432:5432 -e POSTGRES_DB=invidious -e POSTGRES_USER=kemal -e POSTGRES_PASSWORD=kemal docker.io/library/postgres:14
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In another terminal, migrate the database:&lt;/p&gt;</description></item><item><title>Unifi Controller in Fedora/CentOS/RHEL</title><link>http://lukas.zapletalovi.com/posts/2024/unifi-controller-in-fedora-centos-rhel/</link><pubDate>Thu, 12 Sep 2024 14:39:37 +0200</pubDate><guid>http://lukas.zapletalovi.com/posts/2024/unifi-controller-in-fedora-centos-rhel/</guid><description>&lt;p&gt;&lt;em&gt;Update: Updated in 2026 with newer MongoDB version.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;This article contains instructions how to run Unifi Controller from Ubiquiti
via podman from Fedora, CentOS, RHEL, clones or pretty much any Linux
distribution as long as it is version 5.x or higher. I tested this on Fedora
versions 40-43 running with SELinux in enforcing mode and rootless containers
via quadlets.&lt;/p&gt;
&lt;p&gt;The article assumes this is a rootful deployment, but I also tested this on
rootless containers. I tend to use rootful containers on my home-lab Fedora
servers with SELinux turned on. If you intend to install as a regular user,
make sure to use correct paths for systemd units.&lt;/p&gt;</description></item><item><title>AWS CLI via Podman</title><link>http://lukas.zapletalovi.com/posts/2024/aws-cli-podman/</link><pubDate>Tue, 11 Jun 2024 14:46:08 +0200</pubDate><guid>http://lukas.zapletalovi.com/posts/2024/aws-cli-podman/</guid><description>&lt;p&gt;The extensive AWS CLI is quite painful to install on Fedora or RHEL since the
API is moving so fast that is gets outdated quite quickly. Luckily, Amazon
provides containers published both on AWS and Docker registries. Configuration
is easy:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;podman run --rm -it -v ~/.aws:/root/.aws amazon/aws-cli configure

AWS Access Key ID [****************xwcz]:
AWS Secret Access Key [****************CAC1]:
Default region name [None]: us-east-1
Default output format [None]:
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Note the volume mapping, the configuration of the current user is shared with
the container. If you want to keep the configuration separate, use a different
directory.&lt;/p&gt;</description></item><item><title>Fedora 40 on Intel NUC 13th gen</title><link>http://lukas.zapletalovi.com/posts/2024/fedora-40-on-nuc-32-pro/</link><pubDate>Sat, 27 Apr 2024 22:52:03 +0200</pubDate><guid>http://lukas.zapletalovi.com/posts/2024/fedora-40-on-nuc-32-pro/</guid><description>&lt;p&gt;My main machine for all upstream work was Intel NUC 8th gen running i3-8109U
CPU, 32 GB RAM and NVME, SSD and two USB HDDs. Originally, I only used this
little machine as a file server and backup server but shortly after I added
bunch of other services which ended up with this mess of NVMe/SSD/HDD.&lt;/p&gt;
&lt;p&gt;Last week when I was testing bootable container installations of Anaconda in a
libvirt VM and decided to configure a new raw partition storage pool and (ehm)
I made a small typo. As you guessed, I completely destroyed one of my volumes
(file server data). Recovery from backups was painful as I do not have much
experience with &lt;code&gt;btrfs&lt;/code&gt; snapshots, I just wanted to try this file system out as
I heard about it. But I did it, family photos and videos were saved, ton of
&amp;ldquo;scratch&amp;rdquo; data was lost, probably nothing of a value.&lt;/p&gt;</description></item><item><title>Synchronize files with rclone over WebDAV</title><link>http://lukas.zapletalovi.com/posts/2024/synchronize-files-with-rclone-over-webdav/</link><pubDate>Sat, 27 Apr 2024 22:07:09 +0200</pubDate><guid>http://lukas.zapletalovi.com/posts/2024/synchronize-files-with-rclone-over-webdav/</guid><description>&lt;p&gt;We have a mix of devices at home ranging from Linux workstations, servers,
Macbooks, a Mac Mini and a Windows PC. Up until now, I was using Samba for a
home &amp;ldquo;share&amp;rdquo; folder which was also used to do backups of the Windows PC (family
photos and videos). But it was always a pain, smb protocol is somehow slow,
unreliable and painful to set up for seamless MacOS integration. In fact, it
never worked reliably for me.&lt;/p&gt;</description></item><item><title>Enable libvirt 5.6+ over TCP</title><link>http://lukas.zapletalovi.com/posts/2023/enable-libvirt-over-tcp/</link><pubDate>Mon, 11 Sep 2023 09:09:11 +0200</pubDate><guid>http://lukas.zapletalovi.com/posts/2023/enable-libvirt-over-tcp/</guid><description>&lt;p&gt;I use libvirt quite a lot during my development and I like to use it both through local UNIX sockets and unauthenticated TCP. With the libvirt version 5.6.0 the project moved to socket activation and many tutorials on the internet are not correct on how to setup libvirt for TCP communication. This post will help.&lt;/p&gt;
&lt;p&gt;The first thing to realize is that the options which were previously used for this have no effect anymore, this is documented in the example configuration:&lt;/p&gt;</description></item><item><title>About Structured Logging in Go 1.21</title><link>http://lukas.zapletalovi.com/posts/2023/about-structured-logging-in-go121/</link><pubDate>Wed, 28 Jun 2023 20:00:00 +0200</pubDate><guid>http://lukas.zapletalovi.com/posts/2023/about-structured-logging-in-go121/</guid><description>&lt;p&gt;About structured logging in Go 1.21&lt;/p&gt;
&lt;p&gt;Upcoming version of the Go programming language, which is expected to be
released in the fall of 2023, will introduce a new package named &lt;code&gt;slog&lt;/code&gt;. It
provides a clean and consistent API for structured logging. Let&amp;rsquo;s take a closer
look on how to use this new library.&lt;/p&gt;
&lt;p&gt;Structured logging utilizes key-value structures for storing messages which can
be parsed, filtered and analyzed more efficiently in contrast to traditional
logging which is rather human readable and natural to write. Compare the
following:&lt;/p&gt;</description></item><item><title>New in Go 1.20: wrapping multiple errors</title><link>http://lukas.zapletalovi.com/posts/2022/wrapping-multiple-errors/</link><pubDate>Thu, 08 Dec 2022 09:21:12 +0100</pubDate><guid>http://lukas.zapletalovi.com/posts/2022/wrapping-multiple-errors/</guid><description>&lt;p&gt;Go 1.20, which is expected to be released in February 2023, comes with a small
change that can possibly improve error handling in applications which heavily
use error wrapping. Let&amp;rsquo;s take a look how it looks, but first, short recap of
what error wrapping is. Feel free to skip to &amp;ldquo;New in Go 1.20&amp;rdquo; section down
below for the news.&lt;/p&gt;
&lt;p&gt;Errors in Go are values which implements a very simple interface:&lt;/p&gt;</description></item></channel></rss>