<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>blog.domainmess.org</title>
    <link>https://blog.domainmess.org/post/</link>
    <description>Recent blog posts on blog.domainmess.org</description>
    
    <generator>Hugo -- gohugo.io</generator>
    <copyright>en-us</copyright>
    <lastBuildDate>Thu, 12 Mar 2026 08:46:25 +0100</lastBuildDate><atom:link href="https://blog.domainmess.org/post/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>EOFS Open Filesystem Workshop 2026</title>
      <link>https://blog.domainmess.org/post/eofs_workshop_2026/</link>
      <pubDate>Thu, 12 Mar 2026 08:46:25 +0100</pubDate>
      <guid>https://blog.domainmess.org/post/eofs_workshop_2026/</guid>
      <description>This year I also attented the EOFS Workshop on Open Source Parallel Filesystems. I wrote about the last one already here on my blog and it was always a pleasure to be there. This year the EOFS organized the workshop in Paris; the first time outside of Germany.
In this blogpost I&amp;rsquo;m gonna summarize the parts the I found interesting the most:
GekkoFS GekkoFS is a fast on demand distributed filesystem.&lt;p&gt;This year I also attented the &lt;a href=&#34;https://indico.global/event/16925/contributions/&#34;&gt;EOFS Workshop on Open Source Parallel Filesystems&lt;/a&gt;.
I wrote about the last one already &lt;a href=&#34;./eofs_workshop_2025&#34;&gt;here on my blog&lt;/a&gt; and it was always a pleasure to be there.
This year the &lt;a href=&#34;https://www.eofs.eu/&#34;&gt;EOFS&lt;/a&gt; organized the workshop in Paris; the first time outside of Germany.&lt;/p&gt;
&lt;p&gt;In this blogpost I&amp;rsquo;m gonna summarize the parts the I found interesting the most:&lt;/p&gt;
&lt;h2 id=&#34;gekkofs&#34;&gt;GekkoFS&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;https://storage.bsc.es/projects/gekkofs/documentation/&#34;&gt;GekkoFS&lt;/a&gt; is a fast on demand distributed filesystem.
It is using local storage, RocksDB and Mecury RPC to span a ephemeral filesystem
eg. over all compute nodes participating in a job.
The promise for a user is a shared filesystem with predicable performance due to no interference with other jobs as it would be on a central storage.
Of course that means that all data which is needed for the job must be staged in before the work can begin and wrote back to a persistent storage at job end.
Here an extra step is necessary for the users to take, cause GekkoFS cannot automatically stage in files when they&amp;rsquo;re accessed.&lt;/p&gt;
&lt;p&gt;GekkoFS has a, in my opinion, particularily interesting architecture.
The program runs completely in userspace and does not even require a mount() call, so no root privileges are ever required.
To make that possible it uses &lt;em&gt;LD_PRELOAD&lt;/em&gt; to intercept I/O related syscalls
and checks if they&amp;rsquo;re related to a GekkoFS path.
If so, the call is handled by the GekkoFS binaries, otherwise it is passed on to the kernel regularly.&lt;/p&gt;
&lt;p&gt;However this design desicion also has some major caveats.
First of all, if anything else in the computing job also use on &lt;em&gt;LD_PRELOAD&lt;/em&gt;
and overwrites it, it will make the filesystem crash resulting in a failed job.&lt;/p&gt;
&lt;p&gt;An admin using it also reported, that installing and building GekkoFS is quite cumbersome.
Parts of the building system seem stale and unmaintained and the bootstraping of new
filesystems didn&amp;rsquo;t always succeed.
GekkoFS does not support multithreaded, multinode file copying via mpiutils,
although it brings its own tool todo that.&lt;/p&gt;
&lt;p&gt;All in all is looks like GekkoFS is not really robust against inexperienced users.
This might be due to the small community it has so far.
Anyway I was happy to see that the project proceeds and people are actually using it.&lt;/p&gt;
&lt;h2 id=&#34;beegfs&#34;&gt;BeeGFS&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;https://www.beegfs.io/c/&#34;&gt;BeeGFS&lt;/a&gt; is my eyes kinda the cool kid on the block.
They implement features the speak from sort of a long term vision
which I can see need for in future.&lt;/p&gt;
&lt;p&gt;Inspite of GekkoFS, BeeGFS Clients need a kernel module to mount the filesystem
although the servers reside completely in userspace.
That being said, BeeGFS has a ephermeral mode called beeOND where
multiple hosts can spin up a BeeGFS with a single command&lt;/p&gt;
&lt;p&gt;It also integrates nicly with the Linux kernel page cache where it updates
cached files when they change.&lt;/p&gt;
&lt;p&gt;One of the more futureistic features are the &lt;strong&gt;Remote Storage Targets&lt;/strong&gt;.
A BeeGFS can pull files from S3 endpoints, store them locally for modification
and push them back to the remote target when they&amp;rsquo;re not needed anymore.
This can happen asynchonosly as a background job.
With the new version it is also possible to stub those files, so that only the metadata are kept locally.
Since this half available state introduces a lot of desicion problems about when to report what kind of error,
there are differend states that can be set like:
* available
* auto restore
* manual restore
* delayed restore (eg. for tape archives with ultra long access times)&lt;/p&gt;
&lt;p&gt;Depending on these states the timeout and error behaviour is different to be expecable for users.&lt;/p&gt;
&lt;p&gt;Besides that the also support IPV6 now (lol) and implemented a featureset calles &lt;em&gt;Entry Migration&lt;/em&gt;.
This gives the option to move files between targets as a background job which might be useful for
hot pool emptying, rebalancing and all kinds of metadata drive lifecycle management.&lt;/p&gt;
&lt;p&gt;I find it exciting how the people behind BeeGFS dare to implement features beyond the scope of being just a
distributed filesystem to create a truly generic, modern data storage solution.&lt;/p&gt;
&lt;h2 id=&#34;daos&#34;&gt;DAOS&lt;/h2&gt;
&lt;p&gt;This is one of my favorites.
&lt;a href=&#34;https://daos.io/&#34;&gt;DAOS&lt;/a&gt; is a NVMe only, scale-out filesystem with a very modern design.
Like GekkoFS and unlike Lustre it has no centralised metadata servers
which makes it very easy to scale up and down.
Since it has been aquired by HPE they are now building a product from it
with the clean and simple name &lt;em&gt;&lt;a href=&#34;https://web.archive.org/web/20260316172801/https://www.hpe.com/psnow/doc/a00154232enw&#34;&gt;HPE Cray Supercomputing Storage Systems K3000&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Internally they are working on lot of performance stuff to make DAOS ready for larger clusters.
The biggest so far is the &lt;a href=&#34;https://web.archive.org/web/20250810091155/https://daos.io/wp-content/uploads/2025/02/Argonne-Site-Update-DUG24.pdf&#34;&gt;ALCF&lt;/a&gt;
with almost a thousand servers and recent tests show that even
128 of them deliver a solid 5TB/s via a &lt;a href=&#34;&#34;&gt;Slingshot network&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Another concern is that DAOS uses a lot of RAM since with the old
Intel Optane Persistent Memory a lot of space was quite cheap
compared to todays DRAM prices.
So there goes also a lot of work into reducing the amount of memory used.&lt;/p&gt;
&lt;p&gt;The HDF5 code is probably stale, a team member from HPE said,
as not many people are using that.
So be careful when using.&lt;/p&gt;
&lt;p&gt;In the future DAOS will be also able to understand switch topologies for placement decisions
of data chunks.
This way the fault domains like servers or racks can be used to configure
how DAOS does replication or erasure coding.
A QOS feature is also coming to limit impact of background activities.&lt;/p&gt;
&lt;p&gt;From the DAOS community I learned that also a &lt;a href=&#34;https://daosio.atlassian.net/wiki/spaces/DC/pages/11071979565/S3&#34;&gt;S3 exporter&lt;/a&gt; is available.
However is it not seen as mature for production yet.
The community is working on verbs support via a OPA too.
This has worked on older drivers but is not supported right now
and HPE of course has no interest in spending money on this
since it&amp;rsquo;s a directly competing product.&lt;/p&gt;
&lt;h2 id=&#34;lustre&#34;&gt;Lustre&lt;/h2&gt;
&lt;p&gt;Development of Lustre is still going on.
They implement a lot of modern software defined storage features
that we know from other filesystems.
Highlights this year are the gradual implementation of erasure coding
and the advanced features for dynamic multi-tenancy support.
The latter targets especially cloud providers using Lustre in fast changing environments.
Additionally to the erasure coding it&amp;rsquo;s also possible now to setup fault to management servers.
Another new feature is a Trashcan where users may restore deleted files.
One of the more interesting things is the hybridIO feature where Lustre automatically
switches from aligned direct I/O for larger files to buffered I/O for smaller files.
I wrote about this also in my post from &lt;a href=&#34;./eofs_workshop_2025&#34;&gt;LAD 2023&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;While I certainly honor all the work that people still do in Lustre I also
still feel that Lustre has a very old-fashioned architecture in most aspects
and they try to amend now feature that are expected from more moderns designs.
To me it seems that Lustre has been outperformed and outfeatured over the years
and I predict, that it will be replaced by more convenient solutions.&lt;/p&gt;
&lt;h2 id=&#34;robin-hood&#34;&gt;Robin Hood&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/robinhood-suite/robinhood4&#34;&gt;Robinhood&lt;/a&gt; has evolved a lot since I first mentioned it in the
&lt;a href=&#34;./eofs_workshop_2025&#34;&gt;LAD23 blogpost&lt;/a&gt;.
It’s a filesystem‑agnostic metadata catalog that works with different backends like POSIX, MongoDB, and S3.
The newly released version 4 is a big improvement over version 3,
offering much better performance and fixing several issues that made scaling difficult.
The team is also working on rhb‑policy, which should remove the need for cron‑based scripts
and make policy handling cleaner and more reliable.&lt;/p&gt;
&lt;h2 id=&#34;lustre-db&#34;&gt;lustre-db&lt;/h2&gt;
&lt;p&gt;Lustre-db solves the same problem as Robinhood.
It&amp;rsquo;s a project from the german &lt;a href=&#34;https://www.dkrz.de/&#34;&gt;DKRZ&lt;/a&gt; where they have a 120 PiB Lustre Cluster
and neither the admins nor the users have a overview were the active data lies.&lt;/p&gt;
&lt;p&gt;Classic utils like Linux du takes days for the bigger projects (~200 inodes/sec.) which renders
it practically unusable.&lt;/p&gt;
&lt;p&gt;So the Lustre-db project gets the metadata informations directly a from Lustre
as a binary json blob and stores it on the Lustre data servers.
Reading back these files enables the software to efficiently read the necessary
data way faster the it could get them from the meta data servers.
The drawback is of course that the data is up to 24h old.&lt;/p&gt;
&lt;p&gt;Users can then use a &lt;code&gt;lustre-du&lt;/code&gt; util (up to 10 million inodes/sec.) or
use a web interface to graphically show the size distribution.&lt;/p&gt;
&lt;p&gt;To ensure that the users can only see the meta data of their own files
lustre-db stores the json blobs inside the corresponding directories with the same ACL.
BeeGFS uses the same method to store fast readable file indicies as SQLite databases
inside the storage.&lt;/p&gt;
&lt;p&gt;Unfortunately lustre-db is not yet open sourced but the demand on the conference was high
and it was ensured that it is planned to publicly release it.&lt;/p&gt;
&lt;h2 id=&#34;phobos&#34;&gt;Phobos&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/cea-hpc/phobos&#34;&gt;Phobos&lt;/a&gt; is a parallel, heterogeneous object store which is optimized for tape access
while remaining flexible enough to integrate with a wide range of storage technologies.
It exposes familiar frontend protocols such as S3 and Lustre HSM,
where users can feed data into a unified object‑store layer.
On the backend multiple I/O adapters are available for writing the data out,
to tape, a POSIX filesystems or a RADOS backends.
Phobos supports versioning semantics even for tape‑resident objects and
provides a tagging mechanism that can be applied to subdirectories, tape volumes,
or individual RADOS objects to improve classification and policy targeting.
To apply data policies or migrate data Robinhood is used.&lt;/p&gt;
&lt;p&gt;Its architecture is dedicated to use open formats to ensure long‑term interoperability across diverse storage environments
and prevent any kind of vendor login.&lt;/p&gt;
&lt;h2 id=&#34;misc&#34;&gt;Misc&lt;/h2&gt;
&lt;p&gt;Some random thoughts I heard and discussions that we had:&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;People start making backups on SSD instead of tapes.
Apparently there has been time when they were cheap enough to buy then
a enjoy the low power consumption while keeping the data online.
However right now, this will probably change due to high retail prices.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;Some guys who work in the storage area for three decades already told during a Q&amp;amp;A session
that burst buffers were a thing once.
Meaning that workload which write a lot in short time, can use some kind of write-back cache
and the filesystem takes care of putting all that data into the cluster afterwards.
But, for good reason, they all disappeared over time in the public discussion.
Everyone trying to implement such a feature complained about the headache it gives
when your have to decide how to ensure data integrity and cache coherence.
GPFS is one that still has a feature that can do that.
And Lustre can also do a persistent client side caching as well as a Metadata Writeback cache.
Everyone agreed that best way to handle something like this is if applications are aware of the
caching layers and no generic &amp;ldquo;magic&amp;rdquo; happens under the hood.
I guess the approach that BeeGFS took with writing to a local distributed filesystem
and then have proper command to write back to a remote target in a well-defined way is
a good compromise.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&#34;closing-thoughts&#34;&gt;Closing thoughts&lt;/h2&gt;
&lt;p&gt;I enjoyed the conference very much even though the venue was bit shabby this year.
But the small community feels still super friendly and reachable and it&amp;rsquo;s
amazing how diverse the technical backgrounds and perspectives of the different people are.
E.g. one guy was working for the &lt;a href=&#34;https://www.edf.fr/&#34;&gt;edf&lt;/a&gt; in France
where they use HPC to do analysis on 50 years of collected data from there nuclear power plants %)
All in all, definitely worth for me to go, especially since there are only pure technical talks.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Egress traffic distribution with eBPF</title>
      <link>https://blog.domainmess.org/post/ebpf_bonding/</link>
      <pubDate>Wed, 27 Aug 2025 23:23:23 +0200</pubDate>
      <guid>https://blog.domainmess.org/post/ebpf_bonding/</guid>
      <description>When working with networks types other than Ethernet bonding is often not supported or just with a reduced feature set. With eBPF one can reimplement simple distribution of outgoing traffic.&lt;p&gt;When I administered &lt;a href=&#34;https://en.wikipedia.org/wiki/High-performance_computing&#34;&gt;HPC&lt;/a&gt;
clusters we had Linux machines working as routers between multiple high performance networks.
In this particular case, they were routing traffic from multiple hundreds of compute nodes
which were connected via an &lt;a href=&#34;https://en.wikipedia.org/wiki/Omni-Path&#34;&gt;Omnipath&lt;/a&gt;
(OPA) network to a Infiniband (IB) network wherein the storage resided.
The design used &lt;em&gt;two&lt;/em&gt; Intel Omnipath cards with 100 GBit/s each and &lt;em&gt;one&lt;/em&gt; Infiniband card with 200 GBit/s.
Traffic coming in from OPA was of course all leaving via IB interface
but the other way around was a bit more difficult.
The company who designed the system set up
&lt;a href=&#34;https://web.archive.org/web/20250825184418/https://docs.redhat.com/en/documentation/red_hat_enterprise_linux/8/html/configuring_and_managing_networking/configuring-policy-based-routing-to-define-alternative-routes_configuring-and-managing-networking&#34;&gt;policy based routing&lt;/a&gt;
to select routing tables for all incoming
traffic depending on the interface it was coming from
&lt;br /&gt;
&lt;a href=&#34;https://blog.domainmess.org/pictures/ebpf_ib/r1_rx.png&#34;&gt;&lt;img src=&#34;https://blog.domainmess.org/pictures/ebpf_ib/r1_rx.png#floatright&#34; width=40% &gt;&lt;/a&gt;&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;0:      from all lookup local
32758:  from all iif ib2 lookup 2
32759:  from all iif ib1 lookup 1
32760:  from all iif ib0 lookup 2
32761:  from all iif ib0 lookup 1
32766:  from all lookup main
32767:  from all lookup default
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;where &lt;code&gt;ib0&lt;/code&gt; is the Infinband interface and &lt;code&gt;ib1&lt;/code&gt; and &lt;code&gt;ib2&lt;/code&gt; are the OPA interfaces.
&lt;a href=&#34;https://blog.domainmess.org/pictures/ebpf_ib/r1_tx.png&#34;&gt;&lt;img src=&#34;https://blog.domainmess.org/pictures/ebpf_ib/r1_tx.png#floatright&#34; width=40% &gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This obviously does forward all traffic flowing back from IB to OPA over just the one OPA link.
The other is never used for production traffic, as it can be seen in the transmission graphs.&lt;/p&gt;
&lt;p&gt;So I started to search for a way to solve this&amp;hellip;&lt;/p&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;h2 id=&#34;bonding&#34;&gt;bonding&lt;/h2&gt;
&lt;p&gt;First idea that comes to mind is of course bonding (or teaming).
The operating company already told me that binding IB interfaces is not
the same as with Ethernet.
Particularly that the &lt;a href=&#34;https://web.archive.org/web/20250828111332/https://support.lenovo.com/us/en/solutions/ht501292-omnipath-fabric-ib-bonding-support-active-backup-mode-only-lenovo-intelligent-cluster-solutions&#34;&gt;only bonding mode&lt;/a&gt;
which can be used is &lt;code&gt;active-backup&lt;/code&gt;.
While this would increase fault tolerance it does not distribute traffic
across multiple interfaces.&lt;/p&gt;
&lt;p&gt;A short research revealed that this is due to a
&lt;a href=&#34;https://web.archive.org/web/20250624143051/https://docs.nvidia.com/networking/display/mlnxofedv23070512/ip+over+infiniband+(ipoib)#src-2396583240_safe-id-SVBvdmVySW5maW5pQmFuZChJUG9JQiktYm9uZGluZ2lwb2li&#34;&gt;limitation of the IPoIB driver&lt;/a&gt;
which takes care of sending IP packets over Infiniband or OPA.
Well I&amp;rsquo;m not going to touch that %)&lt;/p&gt;
&lt;h2 id=&#34;netfilter--policy-based-routing&#34;&gt;netfilter / policy based routing&lt;/h2&gt;
&lt;p&gt;Next step would be to try to do this with &lt;code&gt;iptables&lt;/code&gt; or &lt;code&gt;ip rule&lt;/code&gt;.
Because netfilter was not used on those machines at all I didn&amp;rsquo;t look further into it.
Policy based routing was already in use so I searched a little but did not find any
dynamic solution.
Of course it would be possible to create subnet lists and assign them a specific interface.
This is good in a static environment and can even have some advantages when one knows the network topology.
However it does support a dynamic round robin solution.&lt;/p&gt;
&lt;p&gt;Possibly you can build something similar with iptables and fwmarks but as far as I know it also boils down
maintaining subnet lists.&lt;/p&gt;
&lt;h2 id=&#34;ebpf-as-usual&#34;&gt;eBPF as usual&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;https://en.wikipedia.org/wiki/Express_Data_Path&#34;&gt;eBPFs XDP&lt;/a&gt; is also not feasible because the TCP traffic changes from IB to OPA during routing.
So it has to pass the Linux network stack to get packaged into a OPA frame.
Also XDP work only on ingress traffic.
This is where I learned that it is also possible to attach eBPF programs to
traffic control (tc) filters.
Although tc itself cannot change a packets outgoing interface
eBPF can!
And with tc on the other have it is possible to select only egress packets.&lt;/p&gt;
&lt;p&gt;I found this &lt;a href=&#34;https://web.archive.org/web/20250526002612/https://who.ldelossa.is/posts/ebpf-networking-technique-packet-redirection/&#34;&gt;blogpost&lt;/a&gt;
which gives a good example about how to use eBPF in combination with tc.&lt;/p&gt;
&lt;p&gt;Eventually I decided to adapt this and it turns out that it is pretty easy.
Like with for example &lt;a href=&#34;https://web.archive.org/web/20250806234228/https://eunomia.dev/tutorials/42-xdp-loadbalancer/&#34;&gt;a XDP loadbalancer&lt;/a&gt;
one needs to hash the parameters of the traffic flow
and map the result to a interface decision.
I tried the most simple implementation which just takes
source and destination IP address and changes the interface or not.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;    // We select some stable parts of the IP header to keep hashing
    // constant for each flow
    struct {
        __u32 src_ip;
        __u32 dst_ip;
        // HINT: ports or protocols could be added here
    } flow_params = {bpf_ntohl(ipv4-&amp;gt;saddr), bpf_ntohl(ipv4-&amp;gt;daddr)};

    // Select outgoing interface based on flow hash
    __u32 key = xxhash32(&amp;amp;flow_params, sizeof(flow_params), 0) % 2;
    bpf_printk(&amp;#34;redirect: flow based key: %d\n&amp;#34;, key);
    if (key != 0) {
        bpf_printk(&amp;#34;redirect: performing redirect\n&amp;#34;);
        ret = bpf_redirect(TARGET_INTF, 0);
    } else {
        bpf_printk(&amp;#34;redirect: NOT performing redirect\n&amp;#34;);
    }
    return ret;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The full code is available on &lt;a href=&#34;https://github.com/benibr/ebpf_ib&#34;&gt;github.com/benibr/ebpf_ib&lt;/a&gt;.
This example of course uses veth interfaces instead of infiniband since they are easy to test with.&lt;/p&gt;
&lt;p&gt;Although this is of course not production ready it surprisingly works as expected
as the kernel trace file shows:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;nc-217522  [011] bNs2. 10795.081379: bpf_trace_printk: ---------------&amp;lt;BEGIN&amp;gt;---------------
nc-217522  [011] bNs2. 10795.081396: bpf_trace_printk: redirect: checking header for IPv4 proto. result: 800
nc-217522  [011] bNs2. 10795.081398: bpf_trace_printk: redirect: destination address 10.0.2.11
nc-217522  [011] bNs2. 10795.081401: bpf_trace_printk: redirect: NOT performing redirect
nc-217522  [011] bNs2. 10795.081402: bpf_trace_printk: redirect: result: 0
nc-217522  [011] bNs2. 10795.081404: bpf_trace_printk: ---------------&amp;lt;END&amp;gt;---------------

nc-217540  [011] bNs2. 10928.898478: bpf_trace_printk: ---------------&amp;lt;BEGIN&amp;gt;---------------
nc-217540  [011] bNs2. 10928.898494: bpf_trace_printk: redirect: checking header for IPv4 proto. result: 800
nc-217540  [011] bNs2. 10928.898495: bpf_trace_printk: redirect: destination address 10.0.2.40
nc-217540  [011] bNs2. 10928.898498: bpf_trace_printk: redirect: performing redirect
nc-217540  [011] bNs2. 10928.898500: bpf_trace_printk: redirect: result: 7
nc-217540  [011] bNs2. 10928.898501: bpf_trace_printk: ---------------&amp;lt;END&amp;gt;---------------
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;and tcpdump shows us that the router actually sends packets on different interfaces after the redirect:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;19:02:52.343987 veth1@2 In  IP 10.0.1.10.36475 &amp;gt; 10.0.2.11.7777: UDP, length 1
19:02:52.344081 veth2@1 Out IP 10.0.1.10.36475 &amp;gt; 10.0.2.11.7777: UDP, length 1

19:05:47.962493 veth1@2 In  IP 10.0.1.10.52569 &amp;gt; 10.0.2.40.7777: UDP, length 1
19:05:47.962571 veth22@1 Out IP 10.0.1.10.52569 &amp;gt; 10.0.2.40.7777: UDP, length 1
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;In the repository there is also a &lt;a href=&#34;https://github.com/benibr/ebpf_ib/blob/main/Makefile&#34;&gt;Makefile&lt;/a&gt; which automatically sets up a testing enviroment
if you wanna try it out.&lt;/p&gt;
&lt;h2 id=&#34;further-reading&#34;&gt;Further reading&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://web.archive.org/web/20250828110123/https://ebpf.hamza-megahed.com/docs/chapter4/3-tc/&#34;&gt;https://ebpf.hamza-megahed.com/docs/chapter4/3-tc/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://web.archive.org/web/20250526001504/https://qmonnet.github.io/whirl-offload/2020/04/11/tc-bpf-direct-action/&#34;&gt;https://qmonnet.github.io/whirl-offload/2020/04/11/tc-bpf-direct-action/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://web.archive.org/web/20230408082345/https://medium.com/@fedepaol/ebpf-tc-filters-for-egress-traffic-b11cd0234a52&#34;&gt;https://medium.com/@fedepaol/ebpf-tc-filters-for-egress-traffic-b11cd0234a52&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://web.archive.org/web/20250724003555/https://eunomia.dev/tutorials/20-tc/&#34;&gt;https://eunomia.dev/tutorials/20-tc/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;appendix-ecmp-routing&#34;&gt;Appendix: ECMP Routing&lt;/h2&gt;
&lt;p&gt;While this was very interesting exercise, I later discovered though a colleague that the same
outgoing interface distribution is possible via &lt;a href=&#34;https://en.wikipedia.org/wiki/Equal-cost_multi-path_routing&#34;&gt;ECMP&lt;/a&gt;
routing.
The clue here is, that the device (&lt;code&gt;dev&lt;/code&gt;) is an attribute of the nexthop not the route itself so it&amp;rsquo;s easily
configurable with:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;ip route add 10.0.0.0/16 nexthop dev ib1 nexthop dev ib2
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;and looks like this when running&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;[root@router1 ~]# ip r
10.246.0.0/16
        nexthop dev ib1 weight 1
        nexthop dev ib2 weight 1
&lt;/code&gt;&lt;/pre&gt;</description>
    </item>
    
    <item>
      <title>ISC 2025</title>
      <link>https://blog.domainmess.org/post/isc2025/</link>
      <pubDate>Mon, 09 Jun 2025 11:42:11 +0200</pubDate>
      <guid>https://blog.domainmess.org/post/isc2025/</guid>
      <description>Since I work in maintaining a smaller HPC cluster at the moment I had the chance to attend the ISC Conference for the first time. Here is the summary of my notes during the conference and exhibition.
The event overall Overall, I found the exhibition booths to be the most interesting part of the event. They provided a great opportunity to connect effortlessly with various manufacturers and colleagues. The number of sales reps was pleasantly low (apparently, most of them were attending a conference in Paris), allowing me to engage directly in technical discussions almost everywhere.&lt;p&gt;Since I work in maintaining a smaller HPC cluster at the moment I had the chance
to attend the &lt;a href=&#34;https://isc-hpc.com/&#34;&gt;ISC Conference&lt;/a&gt; for the first time.
Here is the summary of my notes during the conference and exhibition.&lt;/p&gt;
&lt;h2 id=&#34;the-event-overall&#34;&gt;The event overall&lt;/h2&gt;
&lt;p&gt;Overall, I found the exhibition booths to be the most interesting part of the event.
They provided a great opportunity to connect effortlessly with various manufacturers and colleagues.
The number of sales reps was pleasantly low (apparently, most of them were attending a conference in Paris),
allowing me to engage directly in technical discussions almost everywhere.&lt;/p&gt;
&lt;p&gt;The presentation program, on the other hand, was rather disappointing to me.
Much of the HPC research is simply too advanced for me, and the talks and panels at my level often lacked quality.&lt;/p&gt;
&lt;p&gt;However, the meetings between our organization and the manufacturers were truly interesting.
The atmosphere was refreshingly friendly—especially when my boss announces that he plans to spend a few millions on a new computing cluster!
The manufacturers take the time to address questions on all levels, making the discussions very insightful.
This format was new to me, and I managed to gain a lot of valuable knowledge from it.&lt;/p&gt;
&lt;h2 id=&#34;cornelis-omnipath&#34;&gt;Cornelis Omnipath&lt;/h2&gt;
&lt;p&gt;I have been quite skeptical about Intel OPA so far, but I must say the folks at Cornelis really won me over.
At least from my perspective, they were technically very competent and presented exciting concepts.
According to their benchmarks, they are, of course, better than Infiniband when it comes to low latency and especially high throughput of small messages.
I also found their plans for the next generation truly fascinating.
They plan their ASICs to support UltraEthernet by default, where the actual Layer 2 protocol will then be negotiated via LLDP.
This means that on a physical card, for example, one VLAN can communicate via OPA, while another uses Ethernet.
Looking at the roadmaps of various manufacturers, it is clear that everyone is aiming for UltraEthernet support.
So, we can stay curious about what will happen in the next few years when it finally becomes available.&lt;/p&gt;
&lt;p&gt;Information about current OPA products: &lt;a href=&#34;https://www.cornelisnetworks.com/&#34;&gt;Cornelis Networks&lt;/a&gt;&lt;br&gt;
Information about UltraEthernet features: &lt;a href=&#34;https://ultraethernet.org/&#34;&gt;UltraEthernet&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&#34;ibm-storage-scale&#34;&gt;IBM Storage Scale&lt;/h2&gt;
&lt;p&gt;As is customary for part-time gods, signing an NDA was required here.
In short, IBM sticks with it&amp;rsquo;s all-in-one approach and continues to offer all the features others have,
while also ensuring compatibility with all other formats and protocols.
All of this is part of the GPFS Spectrum Storage Scale System product catalog. %)
One point they mentioned that I found interesting:
Apparently, more and more of their HPC customers are using applications that want S3 as a storage protocol.&lt;/p&gt;
&lt;h2 id=&#34;ceph&#34;&gt;Ceph&lt;/h2&gt;
&lt;p&gt;There were also a few exhibitors regarding Ceph.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://www.croit.io/&#34;&gt;https://www.croit.io/&lt;/a&gt; from Munich offers an all-inclusive software solution for installing PXE-booting Ceph and DAOS nodes
with a web GUI and all the bells and whistle
Of course also provides Ceph support and consulting.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://www.clyso.com/eu/de/&#34;&gt;https://www.clyso.com/eu/de/&lt;/a&gt;, who also provide support for GWDG, were present as well, though they dodged the question of where Ceph has already been successfully used in an HPC context.
Instead, they offered to drop by to do some consulting ;-)&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Colleguages who are running Ceph already in an HPC context emphasized:
You can run some impressive benchmarks with Ceph and scale out quite broadly,
but a cluster configured this way with a high number of metadata server
is very demanding and cumbersome in everyday operation.
That’s why they’ve significantly scaled back for daily use.
They are still very pleased with the Clyso support,
but much of the collaboration involves finding and fixing bugs that emerge due to their unusual cluster setup.&lt;/p&gt;
&lt;h2 id=&#34;slurm--slinky&#34;&gt;Slurm &amp;amp; Slinky&lt;/h2&gt;
&lt;p&gt;SchedMD gave a big presentation of their new Slurm version.
The REST API and Kubernetes integration (Slinky) were highlighted.
Jobs can now be submitted via K8s deployments manifests, which then run on traditional Slurm compute nodes,
or the other way around — submit jobs via sbatch that then run on K8s workers.
Or mix both.
To make this work, they replaced a large portion of the Kubernetes scheduler with Slurm.
The interesting point here is that the folks at SchedMD report more and more users who have never launched HPC/AI workloads on a traditional login node,
but only know the cloud-native methods.
Another notable takeaway is that they discovered Kubernetes&amp;rsquo; current resource management — especially around hardware pinning — is quite inadequate for HPC demands.
So, some development work will likely flow back into the Kubernetes community here.&lt;/p&gt;
&lt;p&gt;Slurm 25.05: &lt;a href=&#34;https://slurm.schedmd.com/release_notes.html&#34;&gt;slurm.schedmd.com/release_notes.html&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&#34;quobyte&#34;&gt;Quobyte&lt;/h2&gt;
&lt;p&gt;A former colleague of mine works there now, so I spent quite a bit of time with them, and the team was very pleasant and friendly.
They do seem to be making progress, which surprised me considering what I saw of their product a few years ago.
They now appear to have several customers with HPC-like requirements,
but I would still be worried that their product ends up combining the downsides of Ceph and Scale.&lt;/p&gt;
&lt;h2 id=&#34;conclusion&#34;&gt;Conclusion:&lt;/h2&gt;
&lt;p&gt;Hardware continues to get faster as usual,
cloud technologies are making deeper inroads into HPC,
and ##everyone## — even those who just sell hard drives — are AI specialists now, naturally 🙂
However, I thought the event was great and I would attend again.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>dupfs - the duplication filesystem</title>
      <link>https://blog.domainmess.org/post/dupfs/</link>
      <pubDate>Tue, 18 Mar 2025 18:35:47 +0100</pubDate>
      <guid>https://blog.domainmess.org/post/dupfs/</guid>
      <description>Who can truly say that they never wished for a way to write files to two places at the same time?! No I&amp;rsquo;m not talking about setting up a complete Ceph cluster or, god forbids, DRDB. Just something simple that double the writes to two different folders.
I stumbled over this problem again a few weeks ago when I was trying to write config files to a distributed filesystem but wanted to always keep an updated copy on a local one.&lt;p&gt;&lt;a href=&#34;https://blog.domainmess.org/pictures/dupfs/dupfs.png&#34;&gt;&lt;img src=&#39;https://blog.domainmess.org/pictures/dupfs/dupfs.png#floatright&#39; width=400px alt=&#34;&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Who can truly say that they never wished for a way to write files to two places at the same time?!
No I&amp;rsquo;m not talking about setting up a complete Ceph cluster or, god forbids, DRDB.
Just something simple that double the writes to two different folders.&lt;/p&gt;
&lt;p&gt;I stumbled over this problem again a few weeks ago when I was trying
to write config files to a distributed filesystem but wanted to always keep an updated copy on a local one.
After searching through the internet for a while without
finding any tool that writes to two backing directories,
I had one of these how-hard-can-this-be moments and redirected my research
towards figuring out how to write a FUSE filesystem in Python.&lt;/p&gt;
&lt;p&gt;I found the most simple one on
&lt;a href=&#34;https://web.archive.org/web/20250109210514/https://www.stavros.io/posts/python-fuse-filesystem/&#34;&gt;stavros.io&lt;/a&gt;
and started to adjust it so that it can handle two backends. &lt;br&gt;
Another close example can be found in
&lt;a href=&#34;https://web.archive.org/web/20231002154308/https://thepythoncorner.com/posts/2017-02-27-writing-a-fuse-filesystem-in-python/&#34;&gt;the python corner&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Turns out it&amp;rsquo;s not that hard at all to write a simple filesystem and I put the result on &lt;strong&gt;&lt;br&gt;
&lt;a href=&#34;https://github.com/benibr/dupfs/&#34;&gt;github.com/benibr/dupfs&lt;/a&gt;&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;A teacher of mine once said&lt;br&gt;
&amp;ldquo;&lt;em&gt;Everybody should take pitcher of beer or wine and calculate the field axioms from scratch.&lt;/em&gt;&amp;rdquo; &lt;br&gt;
but I would rather say, everyone should write a filesystem once in a lifetime :)&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>EOFS Open Filesystem Workshop 2025</title>
      <link>https://blog.domainmess.org/post/eofs_workshop_2025/</link>
      <pubDate>Thu, 27 Feb 2025 10:00:15 +0100</pubDate>
      <guid>https://blog.domainmess.org/post/eofs_workshop_2025/</guid>
      <description>In 2024 I first attened the EOFS workshop about opensource parallel filesystems. The EOFS organizes this meeting once a year with different partners from german Univeristies to gather people and talk about the current status of open, as in non-proprietary, filesystems. I found this mini conference quite interesting and inspiring and it was one of the reasons I ended up working in HPC.
So I&amp;rsquo;m happy that I have the opportunity to participate again this year in Mainz and I will summarize the things that I find interesting in this blogpost.&lt;p&gt;In 2024 I first attened the
&lt;a href=&#34;https://web.archive.org/web/20250227091255/https://events.scads.ai/event/64/contributions/&#34;&gt;EOFS workshop about opensource parallel filesystems&lt;/a&gt;.
The &lt;a href=&#34;https://www.eofs.eu/&#34;&gt;EOFS&lt;/a&gt; organizes this meeting once a year with different partners from german Univeristies
to gather people and talk about the current status of open, as in non-proprietary, filesystems.
I found this mini conference quite interesting and inspiring and it was one of the reasons I ended up working in HPC.&lt;/p&gt;
&lt;p&gt;So I&amp;rsquo;m happy that I have the opportunity to participate
&lt;a href=&#34;https://web.archive.org/web/20250227115625/https://indico.zdv.uni-mainz.de/event/26/contributions/&#34;&gt;again this year in Mainz&lt;/a&gt;
and I will summarize the things that I find interesting in this blogpost.&lt;/p&gt;
&lt;h2 id=&#34;day-1-27-feb-2025&#34;&gt;Day 1 (27. Feb. 2025)&lt;/h2&gt;
&lt;h3 id=&#34;ceph-as-hpc-storage&#34;&gt;Ceph as HPC storage&lt;/h3&gt;
&lt;p&gt;One participant explained that they are going to use Ceph for the &lt;code&gt;/home/&lt;/code&gt; of their users.
This is particularly interesting because Ceph is a true linear scale out system on commodity hardware
which has a relly large community and is extremely flexible.
They measured ~20GiB/s with a thousand spinning disks in their benchmarks
and expect a theoretical maximum of ~55GiB/s
Since they expect more workloads coming from cloud environments they also expect more users
to ask for S3.
Therefore they will also start to put some of their medium I/O intensive workloads on the NVMe based part of the Ceph cluster as well.&lt;/p&gt;
&lt;h3 id=&#34;lustre-still-standing&#34;&gt;Lustre still standing&lt;/h3&gt;
&lt;p&gt;Lustre seems to be the main champion of the HPC parallel filesystems.
Although a lot of community members complain about the bad documentation and unclear configuration,
it still seems to provide best performance, especially if one knows what I/O pattern to exepect and configures
the striping accordingly. &lt;br&gt;
A fancy new feature that&amp;rsquo;s on Lustres roadmap is the Metadata Writeback Cache.
With that in use a client with a workload with many file creations can write
to a local memFS and the writeback to the Lustre storage server will be done
if someone else tries to access that tree (or after some time). &lt;br&gt;
Multiple other admins complained that they have Lustre in use in their HPC clusters for decades
and somehow try to use it as a one-filesystem-fits-all solution with just a tape library for archiving.
However, different clusters and usergroups definitely have different demands and
you cannot tune your filesystem to serve all of them best.
In the end, maintaining and, even more, upgrading those clusters gets closer to impossible every year.
I myself always felt kinda lost when working with lustre,
and I don&amp;rsquo;t think the way it is administrated is intuitive or modern in any way.
I also don&amp;rsquo;t think that adding more an more features (some very complex) will help with that matter.
If there isn&amp;rsquo;t a real pressure to use Lustre for performance or compatibility reasons I would always
try to pivot to something else.&lt;/p&gt;
&lt;h3 id=&#34;daos-still-rising&#34;&gt;Daos still rising&lt;/h3&gt;
&lt;p&gt;Apparently Daos withstands the discontinuation of Intels Optane persistent memory pretty well!
The whole development team was just moved from Intel to HPE and they seem to be quite committed
to keep the development ongoing.
Also the alternative mode where they replace the persistent memory with a combination of DRAM and NVMes
seems to work out as hoped.
Daos is to me the most exciting project in this area
since it&amp;rsquo;s written specifically for modern storage technologies
with the goal of providing I/O API agnostic datastores.
Also it&amp;rsquo;s very well documented and has intuitive tooling, making it easy to deploy and use.&lt;/p&gt;
&lt;h3 id=&#34;beegfs&#34;&gt;BeeGFS&lt;/h3&gt;
&lt;p&gt;Somewhere in between Lustre and Daos there is BeeGFS.
Although I never used it, it has some interesting features like the on-demand (Beeond) mode
where the distributed filesystem is created dynamically on all nodes that run a job.
They also implement &lt;code&gt;remote storage targets&lt;/code&gt; where the filesystem can asynchronously write back
to a remote S3 endpoint but the machine can still do I/O to the LAN local BeeGFS.
The information about to which remote target a file should go, is stored in the metadata
meaning that it will be an intrinsic part of a file in BeeGFS.
Also the work on there generic POSIX-&amp;gt;POSIX copy tool which is able to do large file transfers
in parallel.
This tool is not only capable of running multithreaded but also cpoy data with multiple nodes
and of course can resume aborted transfers.
I like that they build this tooling not for their own filesystem but as general easy to use
solution replacing eg. MPI based copy mechanisms or simple rsync.&lt;/p&gt;
&lt;h3 id=&#34;filesharing-with-globus&#34;&gt;Filesharing with Globus&lt;/h3&gt;
&lt;p&gt;Another colleague also talked about the pain of copying multiple terabytes around the globe.
They recently joined the Globus service which is basically a filebrowser application
hosted by the University of Chicago.
It allows users to create Globus Connect servers in their own network which have access to a large storage cluster
and then link their SSO solution for user login.
Globus then manages federated login and authorization on published datasets and, if wanted by the user,
initiates peer to peer filetransfers.
The idea is great but they just turned it into a closed source, paid product with lots of plugin subscriptions.
I would rather like to see a federated approach here with software maintained by the community.&lt;/p&gt;
&lt;p&gt;Overall the first day was more than exciting for me. The topic overlap between development and operations
is just right for me and the people at this event are very friendly and approachable.
It turned out that in HPC contexts POSIX style filesystems are still used in most of the cases.
This is for example not the case anymore for software that&amp;rsquo;s meant for running as cloud services.
Also the attempt to build insanely large filesystems and do everything at once an them
seems to finally fall apart.
We can see a lot of people investing in splitting clusters into specialized smaller ones
or at least introduce multiple (more than 3) storage tiers.
However tiering means copying and here the world still lacks some common denominator.
In 2025 it is still an issue copying large files from one system to another %)&lt;/p&gt;
&lt;h2 id=&#34;day-2-28-feb-2025&#34;&gt;Day 2 (28. Feb. 2025)&lt;/h2&gt;
&lt;h3 id=&#34;smartnics&#34;&gt;SmartNICs&lt;/h3&gt;
&lt;p&gt;One of the most interesting talk today was about using smartNICs together with distributed filesystems.
In this case people used a Nvidia BlueFlied 3 to seamlessly encrypt or compress data written to a Lustre filesystem.
The data is mangled while being in the buffer of the network card by one of its RISC-V CPUs.
They also argue this increases security because the code cannot be access by the host system.
Although this is super interesting and crazy bleeding edge technology,
it is also very clear that the usecase it artificial and the usage is immensely complicated
especially if you don&amp;rsquo;t want to introduce latencies.
However another colleague told us, that VAST uses those kind of cards to build storage controllers
that consist of only a PCIe switch+backplane and a set of BlueField cards.
This sounds all very exciting but to be honest, it also makes computer more complicated and
shifts the same problems to another part of your machine.&lt;/p&gt;
&lt;h3 id=&#34;misc-topics&#34;&gt;Misc topics&lt;/h3&gt;
&lt;p&gt;Some of the notes I took about topic which aren&amp;rsquo;t exactly in my interest:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Fraunhofer Institut develops a distributed memory+storage management called GPI
&lt;ul&gt;
&lt;li&gt;It&amp;rsquo;s a alternative to MPI&lt;/li&gt;
&lt;li&gt;They let the application use batches which enables AI workloads for massive random access without bottlenecking in a metadata server&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;People researching on getting AI workloads into the h5bench benchmark&lt;/li&gt;
&lt;li&gt;JULEA is a framework for creating distributed filesystems and has be in development for ~15 years already&lt;/li&gt;
&lt;li&gt;EU rules force the public sector to create solicitations on existing technology
that means the technology level used always lacks multiple years behind&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;explainable-io&#34;&gt;Explainable I/O&lt;/h3&gt;
&lt;p&gt;One Research group is working on visualizing I/O from the submission at application level
down to the actual physical write.
The main idea is to implement traceability to a I/O requests so that they can be observed
through the whole stack.
It is currently being implemented based on eBPF and systemtap and is still heavily under development.
Currently they&amp;rsquo;re still trying to get it to work properly for local I/O first
but they&amp;rsquo;re saying that they managed to do it with an overhead of just 1.3%
which would be alright for debugging.&lt;/p&gt;
&lt;p&gt;We also had discussions about the topics.
On the second day they were mostly focused on the state of HPC in German education.
Many attendants from the universities explained how difficult it is these days
to find student who are interested in storage, filesystems or even operating systems.
Same goes for any kind research proposal, without something with machine learning or at least
energy saving in the title there is almost no interest, means no funding.&lt;/p&gt;
&lt;p&gt;I guess it will take a while till the AI bubble bursts and till then we&amp;rsquo;re going to see a
lot of horrible I/O patterns.
To me this is actually not so much a bad perspective.
A change of conditions usually triggers invention and develops alternative paths to
well established solutions.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Nixos Cheatsheet</title>
      <link>https://blog.domainmess.org/post/nixos-cheatsheet/</link>
      <pubDate>Wed, 01 Jan 2025 14:34:01 +0100</pubDate>
      <guid>https://blog.domainmess.org/post/nixos-cheatsheet/</guid>
      <description>Just a collection of commands an config snippets I use to work with nixos.&lt;h3 id=&#34;start-a-shell-and-install-package-from-local-nixpkgs-repo&#34;&gt;Start a shell and install package from local nixpkgs repo:&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;nix-shell -I nixpkgs=./nixpkgs/ -p package1 package2
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Hints: &lt;a href=&#34;https://www.mankier.com/1/nix-shell&#34;&gt;https://www.mankier.com/1/nix-shell&lt;/a&gt;&lt;/p&gt;
&lt;h3 id=&#34;create-a-container-from-a-configurationnix&#34;&gt;Create a container from a configuration.nix&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;sudo nixos-container create container-name --config-file /path/configuration.nix
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;experimental-nixos-features-in-nixos-rebuild&#34;&gt;Experimental nixos features in nixos-rebuild&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;nixos-rebuild --option experimental-features &amp;#34;nix-command flakes&amp;#34; switch
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;error-file-nixos-config-was-not-found-in-the-nix-search-path-add-it-using-nix_path-or--i&#34;&gt;error: file &amp;rsquo;nixos-config&amp;rsquo; was not found in the Nix search path (add it using $NIX_PATH or -I)&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;nix-channel --update
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;call-flake-by-name&#34;&gt;Call flake by name&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;nixos-rebuild switch --flake .#witness
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;generate-hardware-config&#34;&gt;generate (hardware) config&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;nixos-generate-config
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;simple-flake-for-os-config&#34;&gt;Simple flake for OS config&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;{
  description = &amp;#34;Your new nix config&amp;#34;;

  inputs = {
    # Nixpkgs
    nixpkgs.url = &amp;#34;github:nixos/nixpkgs/nixos-24.11&amp;#34;;

  };

  outputs = {
    self,
    nixpkgs,
    ...
  } @ inputs: let
    inherit (self) outputs;
  in {
    # NixOS configuration entrypoint
    nixosConfigurations = {
      # FIXME replace with your hostname
      teletyper = nixpkgs.lib.nixosSystem {
        specialArgs = {inherit inputs outputs;};
        # &amp;gt; Our main nixos configuration file &amp;lt;
        modules = [./configuration.nix];
      };
    };
  };
}
&lt;/code&gt;&lt;/pre&gt;</description>
    </item>
    
    <item>
      <title>Creating bootable images for physical machines</title>
      <link>https://blog.domainmess.org/post/mkosi_bootimg/</link>
      <pubDate>Thu, 10 Oct 2024 00:04:37 +0200</pubDate>
      <guid>https://blog.domainmess.org/post/mkosi_bootimg/</guid>
      <description>Instead of running through a installer everytime you setup a PC you can create a bootable image with mkosi&lt;p&gt;After my first &lt;a href=&#34;../mkosi&#34;&gt;post about mkosi&lt;/a&gt; where I introduced the tool, I tried to use it as often as I could
to easy the pain of spontanious image creation.
One thing I really don&amp;rsquo;t like todo is to run an OS installer to setup a PC.
Especially if it is a machine which won&amp;rsquo;t use without mouse/screen anyway. &lt;br&gt;
So I&amp;rsquo;d rather create a bootable image, copy it either to a disk directly or use a live system to do that if there&amp;rsquo;s no other way.&lt;/p&gt;
&lt;h2 id=&#34;preparation&#34;&gt;Preparation&lt;/h2&gt;
&lt;p&gt;If you don&amp;rsquo;t have enough space on the boot medium but a lot of memory, you can bootstrap a Archlinux in a RAM disk and work from there&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;cd /tmp
mkdir arch
pacstrap arch base mkosi vim systemd dnf mtools dosfstools xfsprogs apt debootstrap cpio
systemd-nspawn -D arch
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;installation&#34;&gt;Installation&lt;/h2&gt;
&lt;p&gt;The following commands use &lt;code&gt;mkosi&lt;/code&gt; to create such an image for EFI systems:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# for Arch Linux
sudo mkosi --format disk --distribution arch --bootable --output new-server-os-01 --package inux,linux-firmware,systemd,pacman,openssh,tmux,vim,fish,iproute2,dhclient,iputils --cache-dir /var/cache/pacman/pkg/ --root-password foobar2342

# for Debian
sudo mkosi --format disk --distribution debian --release bookworm --bootable --output new-server-os-01 --package linux-image-amd64,systemd --cache-dir /var/cache/pacman/pkg/ --root-password foobar2342

# for Rocky with some basic tools
sudo mkosi --format disk --distribution rocky --release 9 --bootable --output new-server-os-01 --package kernel,systemd,dnf,passwd,iproute,epel-release,vim,dhclient,findutils,less,bash --cache-dir /var/cache/pacman/pkg/ --root-password foobar2342
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Afterwards you can test the full boot loader chain in the image with, or make changes inside the OS&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# test with nspawn
sudo systemd-nspawn -i new-server-os-01.raw -b

# test with qemu
qemu-system-x86_64 -m 2048 -smp 2 -bios /usr/share/ovmf/x64/OVMF_CODE.fd -hda new-server-os-01.raw

# just get a shell inside the image
sudo systemd-nspawn -i new-server-os-01.raw
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Eventually get the size of the physical disk you want to use, resize the image and copy it:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;sudo fdisk -l /dev/sdX | head -n 1
sudo truncate --size 128035676160 new-server-os-01.raw
sudo parted new-server-os-01.raw resizepart 2 100%
sudo dd if=new-server-os-01.raw of=/dev/sdX bs=2M oflag=direct status=progress
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;It might also be necessary to create a EFI boot entry, like this:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;efibootmgr --create --disk /dev/sda --part 1 --loader &amp;#39;\EFI\BOOT\BOOTX64.EFI&amp;#39; --label &amp;#39;Linux&amp;#39; --unicode
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Afterwards you should be good to go :-)&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Vintage Telephone Home Network</title>
      <link>https://blog.domainmess.org/post/vintage_phone_network/</link>
      <pubDate>Sat, 04 May 2024 13:46:23 +0200</pubDate>
      <guid>https://blog.domainmess.org/post/vintage_phone_network/</guid>
      <description>Through my work at Cosmic Cable Ltd. I had some experience with old analog &amp;amp; rotary telephones. Over the time my partner and I wished for some W48 or W49 telephones at home for internal calls. This blogpost will follow the different stages of this setup as (read if) it progresses.
The plan The initial idea was to have 2 telephones one in the living room in the upper floor, the other one somewhere downstairs.&lt;p&gt;Through my work at &lt;a href=&#34;../cosmic_cable&#34;&gt;Cosmic Cable Ltd.&lt;/a&gt; I had some experience with old analog &amp;amp; rotary telephones.
Over the time my partner and I wished for some &lt;a href=&#34;https://en.wikipedia.org/wiki/W48_(telephone)&#34;&gt;W48&lt;/a&gt;
or &lt;a href=&#34;https://de.wikipedia.org/wiki/W_49&#34;&gt;W49&lt;/a&gt; telephones at home for internal calls.
This blogpost will follow the different stages of this setup as (read if) it progresses.&lt;/p&gt;
&lt;h1 id=&#34;the-plan&#34;&gt;The plan&lt;/h1&gt;
&lt;p&gt;The initial idea was to have 2 telephones one in the living room in the upper floor, the other one somewhere downstairs.
So as a first step I was searching for some kind of &lt;a href=&#34;https://en.wikipedia.org/wiki/Analog_telephone_adapter&#34;&gt;ATA&lt;/a&gt;
hardware that is able handle to telephones and supports pulse dialing, which most of the cheap stuff doesn&amp;rsquo;t.
Eventually I found the blog of a similar project called
&lt;a href=&#34;http://web.archive.org/web/20220811055225/http://www.ducktelecom.co.uk/2021/10/calling-between-ports-on-grandstream.html&#34;&gt;duck telecom&lt;/a&gt;
which describes a way to configure a
&lt;a href=&#34;https://web.archive.org/web/20240420124627/https://www.grandstream.com/products/gateways-and-atas/analog-telephone-adaptors/product/ht802&#34;&gt;Grandstream HT802&lt;/a&gt;
to make direct calls between the two provides lines without the necessity of a
external SIP server.&lt;/p&gt;
&lt;p&gt;I ordered one and also a W48 and a W49, both in black at the bay, cleaned, tested and polished them.&lt;/p&gt;
&lt;h1 id=&#34;configuring-the-ht802&#34;&gt;Configuring the HT802&lt;/h1&gt;
&lt;p&gt;Following the &lt;a href=&#34;http://web.archive.org/web/20220811055225/http://www.ducktelecom.co.uk/2021/10/calling-between-ports-on-grandstream.html&#34;&gt;duck telecom howto&lt;/a&gt;
I was able to get two phone ready to call each other without an external SIP server.
The HT802 uses DHCP per default, so once one finds the IP it got it can be access via HTTP and SSH.&lt;/p&gt;
&lt;p&gt;Then first pulse dialing has to be enabled on each port.
&lt;a href=&#34;https://blog.domainmess.org/pictures/vintage_telephone_network/enable_pulse.png&#34;&gt;&lt;img src=&#39;https://blog.domainmess.org/pictures/vintage_telephone_network/enable_pulse.png#floatleft&#39; width=300px alt=&#34;&#34;&gt;&lt;/a&gt;
Then the dialplan of each port has get a short dial to the listing UDP port of the other one respectivly.
For testing I just used &lt;code&gt;01&lt;/code&gt; and &lt;code&gt;02&lt;/code&gt; to call the two ports.
So I had to add &lt;code&gt;&amp;lt;02=*47127*0*0*1*5062&amp;gt;&lt;/code&gt; to the dialplan of the first port.
This string consists of the number which will be replaces befor the &lt;code&gt;=&lt;/code&gt; sign,
the function call direct IP calling (&lt;code&gt;*47&lt;/code&gt;) and then the IP and port to call (&lt;code&gt;127.0.0.1:5060&lt;/code&gt;) delimited with &lt;code&gt;*&lt;/code&gt;.
Check the &lt;code&gt;Local SIP Port&lt;/code&gt; setting to verify that you&amp;rsquo;re using the correct port.&lt;/p&gt;
&lt;p&gt;After fiddling around a while with the configuration I also discovered how to use the CLI which is accessible via SSH.
Every parameter has a unique P-Value number which one must know to get and set those values.
These numbers can be found in the
&lt;a href=&#34;http://web.archive.org/web/20240306111455/https://content.grandstream.com/hubfs/Grandstream_Feb_2021/Zip%20File/config-template.zip&#34;&gt;configuration template&lt;/a&gt;
provided by Grandstream.
Also the &lt;a href=&#34;https://web.archive.org/web/20240000000000*/https://www.grandstream.com/hubfs/Product_Documentation/ht80x_administration_guide.pdf&#34;&gt;HT802 Manual&lt;/a&gt;
can be helpful.
Eventually the necessary config I set via SSH looked like:&lt;/p&gt;
&lt;div style=&#34;width: 25%; float: right; margin-left: 5%; margin-right: 3%; margin-top: 5em;&#34;&gt;
&lt;b&gt;Et voilà, first test successfull&lt;/b&gt;: &lt;br /&gt;
&lt;video width=&#34;320&#34; height=&#34;240&#34; controls&gt;
  &lt;source src=&#34;../../pictures/vintage_telephone_network/first_ring.mp4&#34; type=&#34;video/mp4&#34;&gt;
  &lt;source src=&#34;pictures/vintage_telephone_network/first_ring.ogg&#34; type=&#34;video/ogg&#34;&gt;
  Video playing not supporeted, try a different browser.
&lt;/video&gt;
&lt;/div&gt; 
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# enter configuration mode
config

# enable pulse for both
set 20521 1
set 20522 1

# config pulse mode to general
set P28165 0
set P28166 0

# set dial plan
set 4200 { &amp;lt;02=*47127*0*0*1*5062&amp;gt; | x+ | \+x+ | *x+ | *xx*x+ }
set 4201 { &amp;lt;01=*47127*0*0*1*5060&amp;gt; | x+ | \+x+ | *x+ | *xx*x+ }

# apply changes
commit
exit
reboot
&lt;/code&gt;&lt;/pre&gt;</description>
    </item>
    
    <item>
      <title>My first eBPF tool: bioslow</title>
      <link>https://blog.domainmess.org/post/my_first_ebpf/</link>
      <pubDate>Thu, 18 Apr 2024 15:30:29 +0200</pubDate>
      <guid>https://blog.domainmess.org/post/my_first_ebpf/</guid>
      <description>I always wanted to get hands-on experience with eBPF as it seems to be an exciting technology. A friend of mine recommended me the BCC Toolchain when I investigated some TCP socket issues and I was astonished how rich the possibilities are and how easy the code is compared to writing kernel patches.
When I was working on a test setup for a storage solution, we discovered that the disks images for multiple virtual machines seem to have I/O operations taking longer than 10 seconds.&lt;p&gt;I always wanted to get hands-on experience with eBPF as it seems to be an exciting technology.
A friend of mine recommended me the &lt;a href=&#34;https://github.com/iovisor/bcc&#34;&gt;BCC Toolchain&lt;/a&gt; when I investigated some TCP socket issues
and I was astonished how rich the possibilities are and how easy the code is compared to writing kernel patches.&lt;/p&gt;
&lt;p&gt;When I was working on a test setup for a storage solution, we discovered that the disks images for multiple virtual machines
seem to have I/O operations taking longer than 10 seconds.
We suspected the underlying NetApp Appliance to hang once in a while so I searched for a way to log those long I/Os.&lt;/p&gt;
&lt;p&gt;Within the &lt;a href=&#34;https://github.com/iovisor/bcc&#34;&gt;BCC Toolchain&lt;/a&gt; there are multiple tools for searching for long I/O operations
but I missed something to set a threshold and actual write them to a log file.
So I started to write a bcc style tool myself to do that. &lt;br&gt;
To get started with eBPF in Python I can recommend this very good (but slightly outdated)
&lt;a href=&#34;http://web.archive.org/web/20231019090711/https://android.googlesource.com/platform/external/bcc/+/HEAD/docs/tutorial_bcc_python_developer.md&#34;&gt;bcc Python Developer Tutorial&lt;/a&gt;.
And also the corresponding &lt;a href=&#34;http://web.archive.org/web/20240211222607/https://android.googlesource.com/platform/external/bcc/+/HEAD/docs/reference_guide.md&#34;&gt;reference guide&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;In the end I actually created a tool call &lt;strong&gt;bioslow&lt;/strong&gt; which is capable of
logging all I/Os over a certain threshold in various formats:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;[user@bcc-bioslow]$
sudo ./bioslow -t 15 -u ms
Logging I/O operations longer than 15 msecs

Tracing ... Ctrl-C to end.
2024-04-30 12:53:27.398519: 27 msecs
2024-04-30 12:53:35.941692: 55 msecs
2024-04-30 12:53:35.953540: 61 msecs
2024-04-30 12:53:35.953967: 61 msecs
2024-04-30 12:53:35.966807: 67 msecs
...
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The tool is of course available on &lt;a href=&#34;https://github.com/benibr/bcc-bioslow&#34;&gt;github.com/benibr/bcc-bioslow&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The eBPF code for this is rather small and just diffs the time between the start of a block I/O request and the end of it.
Also the threshold is broken down to a &lt;code&gt;FACTOR&lt;/code&gt; which is passed directly to the eBPF program to filter what is reported up
to the python tooling.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;BPF_HASH(start, struct request *);

void trace_start(struct pt_regs *ctx, struct request *req) {
    // stash start timestamp by request ptr
    u64 ts = bpf_ktime_get_ns();
    start.update(&amp;amp;req, &amp;amp;ts);
}

void trace_stop(struct pt_regs *ctx, struct request *req) {
    u64 *tsp, delta, factor = 0;

    tsp = start.lookup(&amp;amp;req);
    if (tsp != 0) {
        delta = bpf_ktime_get_ns() - *tsp;
        // the FACTOR will be later replaced by &amp;#34;delta /= 1000000000;&amp;#34; or similar
        FACTOR
        if (delta &amp;gt;= factor) {
            delta /= factor;
            bpf_trace_printk(&amp;#34;%d %d %d\\n&amp;#34;,
                req-&amp;gt;__data_len, req-&amp;gt;cmd_flags, delta);
        }
        start.delete(&amp;amp;req);
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The main difficulties I had were: 1) Figuring out which kernel functions I actually need to attach to and
2) synchronizing the time between the monotonic time since boot that the kernel reports and &lt;code&gt;datetime.now()&lt;/code&gt; from Python. &lt;br&gt;
The next thing would be to rewrite the tool so that it uses &lt;code&gt;BPF_PERF_OUTPUT&lt;/code&gt; instead of &lt;code&gt;bpf_trace_printk&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Anyway, this was easier than I expected and real fun. I&amp;rsquo;m already looking forward to another opportunity to use eBPF.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>TCP connection routing with IPtables</title>
      <link>https://blog.domainmess.org/post/iptables-tmp-routing/</link>
      <pubDate>Mon, 12 Feb 2024 23:59:59 +0200</pubDate>
      <guid>https://blog.domainmess.org/post/iptables-tmp-routing/</guid>
      <description>&amp;ldquo;Use less NAT&amp;rdquo; is a sentence I really like to hear. For a customer project we should build a high performace server for a webapplication. One of the requirements was that the ingress connections should not go though a loadbalancer or a NAT. Although that the throughput would probably not be throttled by those techniques and of course the application was really old Python software, but I liked the fact that the setup requirements were different than usual.&lt;p&gt;&amp;ldquo;Use less NAT&amp;rdquo; is a sentence I really like to hear.
For a customer project we should build a high performace server for a webapplication.
One of the requirements was that the ingress connections should not go though a loadbalancer
or a NAT.
Although that the throughput would probably not be throttled by those techniques and
of course the application was really old Python software, but
I liked the fact that the setup requirements were different than usual.&lt;/p&gt;
&lt;p&gt;However the concept was that for an update all application containers should be stopped,
updated and then started again which could mean several minutes of downtime.
So I tried to find a new concept for a rolling update.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://blog.domainmess.org/pictures/iptables-tmp-routing/iptables-tmp-routing.gif&#34;&gt;&lt;img src=&#34;https://blog.domainmess.org/pictures/iptables-tmp-routing/iptables-tmp-routing.gif#floatright&#34; width=40% &gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&#34;rerouting-new-tcp-connections&#34;&gt;Rerouting new TCP connections&lt;/h2&gt;
&lt;p&gt;Without a classic loadbalancer usually a application binds directly to a IP:PORT combination,
receiving all connections to this combination.
If a newer version of this application should take over there must be some other mechanism
to reroute new incoming connections.&lt;/p&gt;
&lt;p&gt;First I tried to teach the application to use the &lt;code&gt;SO_REUSEPORT&lt;/code&gt; socket option but soon I figured
out that it would be too complicated to use that as a rollover mechanism.
The details are described in the blogpost called &lt;a href=&#34;./so_portreuse&#34;&gt;Loadbalancing TCP connections in the Linux kernel&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;My second attempt was to use IPtables to hijack all incoming connections and use a DNAT to route them
to another application container.
The nice thing with IPtables and conntrack is that established connections would be still using the
original routing as long as the connection stays alive but the DNAT rule would be applied to new connections.
This breaks the requriement for a NAT-less handling of connections
but it might be only used during the upgrade.
Additionally it is also possible to use IPtables to actually do wighted loadbalancing of connections.
You can read a good explenation on
&lt;a href=&#34;https://web.archive.org/web/20230326083715/https://scalingo.com/blog/iptables&#34;&gt;this blogpost&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&#34;simulation-and-testing&#34;&gt;Simulation and testing&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# create a container to simlulate existing application
docker run -d --rm --network host --name app-v0.1 hashicorp/http-echo -listen=:8000 -text=&amp;#34;app-v0.1&amp;#34;
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# create an intermediate container with a newer version
# this container will listen on a different port
docker run -d --rm --network host --name app-v0.2-tmp hashicorp/http-echo -listen=:8081 -text=&amp;#34;app-v0.2-tmp&amp;#34;

# create a temporary IPtables rule to reroute the traffic
# to the intermediate container
iptables -t nat -I PREROUTING -p tcp -m tcp --dport 8000 -j DNAT --to-destination :8081
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now one can wait until all connections to container01 are finished.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;conntrack -L -p tcp --dport 8000
tcp      6 431975 ESTABLISHED src=10.82.3.224 dst=10.82.3.224 sport=43014 dport=8000 src=10.82.3.224 dst=10.82.3.224 sport=8000 dport=43014 [ASSURED] mark=0 secctx=system_u:object_r:unlabeled_t:s0 use=1
tcp      6 84 TIME_WAIT src=10.82.3.224 dst=10.82.3.224 sport=60244 dport=8000 src=10.82.3.224 dst=10.82.3.224 sport=8000 dport=60244 [ASSURED] mark=0 secctx=system_u:object_r:unlabeled_t:s0 use=1
tcp      6 71 TIME_WAIT src=10.82.3.224 dst=10.82.3.224 sport=47082 dport=8000 src=127.0.0.1 dst=10.82.3.224 sport=8081 dport=47082 [ASSURED] mark=0 secctx=system_u:object_r:unlabeled_t:s0 use=1
conntrack v1.4.7 (conntrack-tools): 2 flow entries have been shown.
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;Be careful&lt;/strong&gt; about the value of &lt;code&gt;net.netfilter.nf_conntrack_tcp_timeout_established&lt;/code&gt; which tells conntrack when
to forget about connections. Default is 12 hours.&lt;/p&gt;
&lt;p&gt;When all connections to the old &lt;em&gt;app-v0.1&lt;/em&gt; are gone,
we create a new container for permanent usage and remove the DNAT rule.
Then again we do a graceful shutdown of &lt;em&gt;app-v0.2-tmp&lt;/em&gt; and tear down the intermediate container.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# create a new permanent container with the updated version
docker run -d --rm --network host --name app-v0.2 hashicorp/http-echo -listen=:8000 -text=&amp;#34;app-v0.2&amp;#34;

# remove the temporary DNAT rule
iptables -t nat -D PREROUTING -p tcp -m tcp --dport 8000 -j DNAT --to-destination :8081
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Et voilà we upgraded to a new software version without a loadbalancer.&lt;/p&gt;
&lt;h3 id=&#34;foot-notes&#34;&gt;Foot notes&lt;/h3&gt;
&lt;p&gt;If you wanna test this on localhost you have to use this IPtables rule since
traffic for the &lt;code&gt;lo&lt;/code&gt; interface does not go though &lt;code&gt;PREROUTING&lt;/code&gt; chain:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;iptables -t nat -A OUTPUT -p tcp -o lo --dport 8000 -j REDIRECT --to-ports 8081
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;usefull-links&#34;&gt;Usefull links&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://superuser.com/questions/1794238/why-can-two-containers-in-host-network-namespace-both-bind-to-the-same-port()&#34;&gt;Why can two containers in host network namespace both bind to the same port?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.oreilly.com/library/view/mastering-proxmox/9781788397605/ff012083-d242-43ae-b6ad-5084bf47179c.xhtml&#34;&gt;Explaination of net.netfilter.nf_conntrack_tcp_timeout_established&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    
    <item>
      <title>Loadbalancing TCP connections in the Linux kernel</title>
      <link>https://blog.domainmess.org/post/so_portreuse/</link>
      <pubDate>Wed, 20 Dec 2023 16:36:34 +0100</pubDate>
      <guid>https://blog.domainmess.org/post/so_portreuse/</guid>
      <description>During a search to make a Linux application suitable for rolling upgrades I search for a way to overtake a already bound TCP port. I realized that some versions of netcat are able to do that and also worked when I was using Dockers port forwarding feature. So I started to investigate how this works and what one could make of it.
SO_REUSEPORT Apparently there is a kernel feature in Linux since version 3.&lt;p&gt;During a search to make a Linux application suitable for rolling upgrades I search for a way to
overtake a already bound TCP port.
I realized that some versions of netcat are able to do that
and also worked when I was using Dockers port forwarding feature.
So I started to investigate how this works and what one could make of it.&lt;/p&gt;
&lt;h2 id=&#34;so_reuseport&#34;&gt;SO_REUSEPORT&lt;/h2&gt;
&lt;p&gt;Apparently there is a kernel feature in Linux since version 3.9 meant to handle exactly that kind of problem:
Multiple applications or threads shall listen on the same address:port combination.
If the socket option &lt;code&gt;SO_REUSEPORT&lt;/code&gt; is set before the application binds,
other processes with the same UID can attach to the same port.
A lot of software has support for this, often if the work should be spread out over
multiple processes.
One example is the &lt;a href=&#34;https://httpd.apache.org/docs/trunk/mod/mpm_common.html#listen&#34;&gt;mpm module&lt;/a&gt; of the Apache webserver. &lt;br&gt;
&lt;code&gt;SO_REUSEPORT&lt;/code&gt; must not be confused with the &lt;code&gt;SO_REUSEADDR&lt;/code&gt; option.
An excellent explanation of their differences and usage in other operating systems can be found on
&lt;a href=&#34;https://stackoverflow.com/questions/14388706/how-do-so-reuseaddr-and-so-reuseport-differ/14388707#14388707&#34;&gt;StackOverflow&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&#34;load-balancing&#34;&gt;Load Balancing&lt;/h2&gt;
&lt;p&gt;Now there is one problem with the reusable ports. All the sockets that bind to the same address:port combination
form a group and the kernel load balances all the incoming connections in a round-robin fashion.
See the &lt;a href=&#34;http://web.archive.org/web/20231215214630/https://man7.org/linux/man-pages/man7/socket.7.html&#34;&gt;socket 7&lt;/a&gt; manpage:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;For TCP sockets, this option allows accept(2) load
distribution in a multi-threaded server to be improved by
using a distinct listener socket for each thread.  This
provides improved load distribution as compared to
traditional techniques such using a single accept(2)ing
thread that distributes connections, or having multiple
threads that compete to accept(2) from the same socket.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Yeah make sense for a high performance webserver but not when I wanna try to hand over a incoming
connections to a new process.&lt;/p&gt;
&lt;h2 id=&#34;some-tests&#34;&gt;Some tests&lt;/h2&gt;
&lt;p&gt;To test how this behaves I created a Apache config with &lt;code&gt;Listen 80 reuseport&lt;/code&gt; and &lt;code&gt;ListenCoresBucketsRatio 2&lt;/code&gt;.
With this config Apache enables the &lt;code&gt;SO_REUSEPORT&lt;/code&gt; option on its socket.
Sadly there is no easy way in Linux to show all the options of a socket in human readable form. &lt;br&gt;
I used &lt;a href=&#34;https://github.com/veithen/knetstat&#34;&gt;knetstat&lt;/a&gt; to verify that Apache&amp;rsquo;s working correctly.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;$ cat /proc/net/tcpstat 
Recv-Q Send-Q Local Address           Foreign Address         Stat Diag Options
     0      0 0.0.0.0:80              0.0.0.0:*               LSTN      SO_REUSEPORT=1,SO_REUSEADDR=1,SO_KEEPALIVE=0,TCP_NODELAY=0
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;My idea was to start two of those Apaches and simulate a fault state in one and see how the incoming connections
will spread. Therefore I ran the following things as a basic simulation:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# launch to Apaches, on after the other
docker run -d --name test1 --network host httpd:bookworm -v apache-test.conf:/etc/apache2/apache2.conf 
docker run -d --name test2 --network host httpd:bookworm -v apache-test.conf:/etc/apache2/apache2.conf 

# then get the PIDs from one of the containers
ps auxf | grep apache

# and pause all the processes to prevent them from answering on their socket
for i in $(seq 6031 6062); do kill -STOP $i; done

# then test the connection distribution with
for i in $(seq 1 100); do timeout 1 curl https://localhost -k -s -o /dev/null &amp;amp;&amp;amp; echo worked || echo failed; done | sort | uniq -c
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The result looks somehow like this:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;   46 worked
   54 failed
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;So in the end I realized this is not really what I was searching for. I wanted a smooth handover of a bound socket
to a new one and &lt;code&gt;SO_REUSEPORT&lt;/code&gt; is more for balancing connections between multiple processes serving the same content
for performance optimization.&lt;/p&gt;
&lt;h2 id=&#34;ebpf-as-usual&#34;&gt;eBPF as usual&lt;/h2&gt;
&lt;p&gt;However, I realized afterwards that one could write a (e)BPF program and attach it to the groups of socket that are
using the same port. There one has full control over how the connection are distributed although it&amp;rsquo;s not straight
forward due to possible socket reordering. The nice thing although is, that one can overwrite that program during
runtime without restarting the actual serving application.
The &lt;a href=&#34;http://web.archive.org/web/20231215214630/https://man7.org/linux/man-pages/man7/socket.7.html&#34;&gt;socket 7&lt;/a&gt;
manpage says:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;For use with the SO_REUSEPORT option, these options allow
the user to set a classic BPF (SO_ATTACH_REUSEPORT_CBPF)
or an extended BPF (SO_ATTACH_REUSEPORT_EBPF) program
which defines how packets are assigned to the sockets in
the reuseport group.
&amp;hellip;
Sockets are numbered in the order in which they are added
to the group (that is, the order of bind(2) calls for UDP
sockets or the order of listen(2) calls for TCP sockets).
New sockets added to a reuseport group will inherit the
BPF program.  When a socket is removed from a reuseport
group (via close(2)), the last socket in the group will be
moved into the closed socket&amp;rsquo;s position.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This is good to know but still doesn&amp;rsquo;t solve my problem %)
I&amp;rsquo;ll probably write about an alternative solution soon.&lt;/p&gt;
&lt;p&gt;EDIT: There is also a example available of how create
&lt;a href=&#34;https://www.youtube.com/watch?v=fLmjtC1N0uY&amp;amp;list=PLDg_GiBbAx-l4D4oKbscJhPFKv2oqPcD_&amp;amp;index=5&#34;&gt;Hot standby load balancing with SO_REUSEPORT and eBPF&lt;/a&gt;
from Hemanth Malla.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Linux Block I/O debugging</title>
      <link>https://blog.domainmess.org/post/bio_debug/</link>
      <pubDate>Sat, 14 Oct 2023 21:16:18 +0200</pubDate>
      <guid>https://blog.domainmess.org/post/bio_debug/</guid>
      <description>By chance I found the Blog and Videos of Tanel Poder. The content is excellent if you want to get into low-level I/O debugging on Linux, I especially recommend the following blogpost with its corresponding video:
https://tanelpoder.com/posts/high-performance-block-io-on-linux/ https://tanelpoder.com/posts/11m-iops-with-10-ssds-on-amd-threadripper-pro-workstation/ Inspired by the detail of his analysis I started to dig around in Linux block I/O for a while. In this blogpost I collect some useful infos and tools for Linux storage debugging mostly as a notepad for myself.&lt;p&gt;By chance I found the &lt;a href=&#34;https://tanelpoder.com/&#34;&gt;Blog and Videos of Tanel Poder&lt;/a&gt;.
The content is excellent if you want to get into low-level I/O debugging on Linux,
I especially recommend the following blogpost with its corresponding video:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://tanelpoder.com/posts/high-performance-block-io-on-linux/&#34;&gt;https://tanelpoder.com/posts/high-performance-block-io-on-linux/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://tanelpoder.com/posts/11m-iops-with-10-ssds-on-amd-threadripper-pro-workstation/&#34;&gt;https://tanelpoder.com/posts/11m-iops-with-10-ssds-on-amd-threadripper-pro-workstation/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Inspired by the detail of his analysis I started to dig around in Linux block I/O for a while.
In this blogpost I collect some useful infos and tools for Linux storage debugging mostly as a notepad for myself.
May it be helpful for you too.&lt;/p&gt;
&lt;h1 id=&#34;tools&#34;&gt;Tools&lt;/h1&gt;
&lt;h2 id=&#34;bcc&#34;&gt;bcc&lt;/h2&gt;
&lt;p&gt;The &lt;a href=&#34;https://github.com/iovisor/bcc&#34;&gt;BPF Compiler Collection&lt;/a&gt; has a huge set of tools to sniff and snoop on various points of userland/kernel interaction.
No matter if you want to debug TCP connections, memory management or block I/O you&amp;rsquo;ll find something here.
The collection is available on most distros as &lt;code&gt;bcc-tools&lt;/code&gt; but the scripts are often not in $PATH
but must be called manually from &lt;code&gt;/usr/share/bcc/tools/&lt;/code&gt;.
All the tools use small BPF programs which are loaded into the kernel to probe a function or event and collect information about it.
If you&amp;rsquo;re interested in how to do that check out the cool
&lt;a href=&#34;http://web.archive.org/web/20230000000000*/https://android.googlesource.com/platform/external/bcc/+/HEAD/docs/tutorial_bcc_python_developer.md&#34;&gt;bcc Python Developer Tutorial&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;intels-mlc-memory-latency-checker&#34;&gt;Intels mlc: Memory Latency Checker&lt;/h2&gt;
&lt;p&gt;The &lt;a href=&#34;https://www.intel.com/content/www/us/en/developer/articles/tool/intelr-memory-latency-checker.html&#34;&gt;Memory Latency Checker&lt;/a&gt;
is useful to check the throughput and latency from CPU to RAM.
Especially with NUMA systems this can be of great interest to find bottlenecks as the throughput
of a CPU might be capped if the memory latency is too high. &lt;br&gt;
See also &lt;a href=&#34;#numactl&#34;&gt;numactl&lt;/a&gt; and &lt;a href=&#34;#lstopo&#34;&gt;lstopo&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;lstopo&#34;&gt;lstopo&lt;/h2&gt;
&lt;p&gt;When it comes to the physical layout of a machine there are tools like &lt;code&gt;lshw&lt;/code&gt; or &lt;code&gt;lspci&lt;/code&gt; which can give good information.
Additionally the command &lt;code&gt;lstopo --of ascii&lt;/code&gt; from the package &lt;code&gt;hwloc&lt;/code&gt; can draw a picture in a terminal of the hardware topology.&lt;/p&gt;
&lt;h2 id=&#34;0xtools&#34;&gt;0x.tools&lt;/h2&gt;
&lt;p&gt;The tools on &lt;a href=&#34;https://0x.tools&#34;&gt;0x.tools&lt;/a&gt; are interesting for Linux application debugging.
While I did not use them often yet, they contain good examples of how to use &lt;code&gt;perf&lt;/code&gt; to
get a tree visualization of where in the kernel code the CPU spends most time.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;perf record -g -F 2 -a -o perf_log
perf report -i perf_log
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;dstat&#34;&gt;dstat&lt;/h2&gt;
&lt;p&gt;dstat is the successor of the known tools like &lt;code&gt;vmstat&lt;/code&gt;, &lt;code&gt;iostat&lt;/code&gt; and &lt;code&gt;ifstat&lt;/code&gt;.
It aiming to unify the interface, making usage easier and adding more information.
See &lt;a href=&#34;http://web.archive.org/web/20230618074223/https://linux.die.net/man/1/dstat&#34;&gt;https://linux.die.net/man/1/dstat&lt;/a&gt;
for a full manual.
For debugging storage I often use &lt;code&gt;dstat -pcmrd&lt;/code&gt; to see IOPS and throughput like this:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;[root@test /tmp]# dstat -pcmrd
---procs--- ----total-usage---- ------memory-usage----- --io/total- -dsk/total-
run blk new|usr sys idl wai stl| used  free  buf   cach| read  writ| read  writ
1.0   0    |                   | 594M  257M 2172k 2670M|           |
1.0   0   0|  1  55  42   0   0| 594M  185M 2172k 2742M|   0   184 |   0   120M
1.0   0   0|  1  57  41   0   0| 590M  131M 2172k 2801M|   0   175 |   0   164M
1.0   0   0|  1  57  41   0   0| 587M  121M 2172k 2812M|1.00   195 |4096B  164M
1.0   0 3.0|  1  57  40   0   0| 584M  111M 2172k 2826M|1.00   234 |4095B  160M
1.0   0   0|  3  57  41   0   0| 582M  104M 2172k 2836M|   0   222 |   0   148M
1.0   0   0|  0  62  30   6   0| 578M  109M 2172k 2835M|   0   460 |   0   365M
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Here one can see, that one process writes rather large IOPS which occupies more than half a CPU with in kernel code.&lt;/p&gt;
&lt;!--
## nvme

nice tool to handle nvme storages
--&gt;
&lt;h1 id=&#34;typical-issues&#34;&gt;Typical issues&lt;/h1&gt;
&lt;h2 id=&#34;kernel-splits-io-operations&#34;&gt;Kernel splits I/O operations&lt;/h2&gt;
&lt;p&gt;Even though an application submits I/O with a specific blocksize to the kernel the operations might get split
by the blocklayer before they get to the actual disks.
I don&amp;rsquo;t still don&amp;rsquo;t know when this happens exactly but I guess it&amp;rsquo;s to align the operations with the physical blocksizes.
Anyway it might change the result of your test, especially if you sample throughput or IOPS with different blocksizes.&lt;/p&gt;
&lt;p&gt;A good way to analyse this is the tools &lt;code&gt;bitesize&lt;/code&gt; from &lt;a href=&#34;#bcc&#34;&gt;BCC&lt;/a&gt;.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;[root@test]# ./bitesize
Tracing block I/O... Hit Ctrl-C to end. ^C
Process Name = dd
     Kbytes              : count     distribution
         0 -&amp;gt; 1          : 0        |                                        |
         2 -&amp;gt; 3          : 0        |                                        |
         4 -&amp;gt; 7          : 1000     |*****                                   |
         8 -&amp;gt; 15         : 0        |                                        |
        16 -&amp;gt; 31         : 0        |                                        |
        32 -&amp;gt; 63         : 0        |                                        |
        64 -&amp;gt; 127        : 1000     |*****                                   |
       128 -&amp;gt; 255        : 0        |                                        |
       256 -&amp;gt; 511        : 3000     |*****************                       |
       512 -&amp;gt; 1023       : 3000     |*****************                       |
      1024 -&amp;gt; 2047       : 7000     |****************************************|
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Another method is to test with a defined blocksize and check the amount of IOPS done.
This of course is more difficult on busy systems.
The following script iterates over different blocksizes and displays the IOPS with &lt;a href=&#34;#dstat&#34;&gt;dstst&lt;/a&gt;.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;#/bin/bash

trap &amp;#34;echo exiting...; exit&amp;#34; SIGINT

IOSIZES=${1:-512 1024 2048 4k i8k 16k 32k 64k 512k 1M 4M}

for i in ${IOSIZES}; do
        echo &amp;#34;testing with blocksize of $i&amp;#34;
        echo &amp;#34;-----------------------------&amp;#34;
        dd oflag=direct if=/dev/urandom of=/test.img bs=$i &amp;amp;
        timeout 5 dstat -pcmrd
        killall -9 dd
        echo
done
&lt;/code&gt;&lt;/pre&gt;</description>
    </item>
    
    <item>
      <title>LAD23</title>
      <link>https://blog.domainmess.org/post/lad_2023/</link>
      <pubDate>Wed, 04 Oct 2023 15:59:49 +0200</pubDate>
      <guid>https://blog.domainmess.org/post/lad_2023/</guid>
      <description>In Octobre 2023 I attended the LAD23 in Bordeaux: the Lustre Administration and Development workshop. I was working on a ~15 PB (raw capacity) storage system for a University which was based on the Lustre filesystem and my colleague and I wanted to get some information since we both didn&amp;rsquo;t any experience with Lustre yet. It was also my first conference in person since the FOSDEM20.
Conference and Organization The conference was organized by the EOFS took place in the InterContinental Hotel in the city centre of Bordeaux and the Social Event on the first evening was at Château Pape Clément in the vinyards besides the city.&lt;p&gt;&lt;a href=&#34;https://blog.domainmess.org/pictures/lad23/header.png&#34;&gt;&lt;img src=&#34;https://blog.domainmess.org/pictures/lad23/header.png#floatright&#34; width=40% &gt;&lt;/a&gt;
In Octobre 2023 I attended the &lt;a href=&#34;http://web.archive.org/web/20231005074605/https://www.eofs.eu/events/lad23&#34;&gt;LAD23&lt;/a&gt; in Bordeaux: the Lustre Administration and Development workshop.
I was working on a ~15 PB (raw capacity) storage system for a University which was based on the &lt;a href=&#34;https://www.lustre.org/&#34;&gt;Lustre filesystem&lt;/a&gt;
and my colleague and I wanted to get some information since we both didn&amp;rsquo;t any experience with Lustre yet.
It was also my first conference in person since the &lt;a href=&#34;../fosdem_2020/&#34;&gt;FOSDEM20&lt;/a&gt;.&lt;/p&gt;
&lt;h1 id=&#34;conference-and-organization&#34;&gt;Conference and Organization&lt;/h1&gt;
&lt;p&gt;The conference was organized by the &lt;a href=&#34;https://www.eofs.eu/&#34;&gt;EOFS&lt;/a&gt; took place in the InterContinental Hotel in the city centre of Bordeaux and the Social Event on the first
evening was at Château Pape Clément in the vinyards besides the city.
Both places were a bit posh but served good wine and catering and featured nice decor.&lt;/p&gt;
&lt;h1 id=&#34;lustre-news--roadmap&#34;&gt;Lustre News &amp;amp; Roadmap&lt;/h1&gt;
&lt;p&gt;A big part of the conference is the current state of Lustre development.
Traditionally the first talk is a presentation of the &lt;a href=&#34;http://web.archive.org/web/20230928104422/https://www.lustre.org/roadmap/&#34;&gt;Lustre roadmap and upcoming features&lt;/a&gt;
Most interesting for us is the Erasure Coding functionality which is planned to be available in Lustre 2.17, expected at the end of 2024.
This allows a user to get data redundancy without using a RAID configuration below the Lustre system,
resulting in more flexibility.&lt;/p&gt;
&lt;p&gt;Many of the following talks were then Lustre developers presenting their work and users explain how they found bugs and how to fix them.
Here is a list of the things I found most interesting which is of course just an excerpt:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Lustre &amp;amp; Kerberos: A lot of work is done here mainly to allow the integration of lustre in Enterprise/Cloud environments with different users and multi tenancy support.
With Kerberos based authentication it is also possible to prevent unauthorized Lustre servers from joining the cluster.
Another problem that can be addressed is the fact that Lustre trusts the root user on all clients per default.
If an attacker becomes root on one client he can read all data. (This problem can also partially be mitigated by using &lt;code&gt;nodemap&lt;/code&gt;)
The whole Kerberos related code got a major rewrite and a lot of bugfixes coming in Lustre 2.16.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Other people are working on Client Side data compression which directly compresses data on the client before it is send over the network.
This solution does not depend on ZFS compression on the server which is a common usecase today when Lustre is used with ZFS.
The main question about this was if the OSD is able to decompress the stored data and then only serve the parts that were requested by the client
and not the whole compressed block which could lead to traffic amplification.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;One of the most impressive announced features was: Unaligned Direct I/O
Lustre tries to combine the advantages of buffered I/O and direct I/O from 2.16 on.
It automatically uses direct I/O for bigger files and the page cache for smaller files.
The alignment for bigger files is done using a aligned buffer in kernel memory which is
way faster than using a cache and only little slower than direct I/O.
This may increase throughput drastically without the necessity to change the user application.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;lljobstat&lt;/code&gt; is a new tool to debug slow I/O on MDTs/OSTs which has profen very useful according to the developers.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Better fscrypt support to move data without knowing the key which had some pitfalls before.
This will be released even within Lustre 2.15&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The Lustre filesystem is also being prepared for larger devices, with up to 1.5PB per OST&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;And support for Hybrid setups (NVMe+HDD) in ldiskfs is evaluted&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&#34;robin-hood-filesystem-utilities&#34;&gt;Robin Hood Filesystem Utilities&lt;/h1&gt;
&lt;p&gt;I never heard of the &lt;a href=&#34;https://github.com/robinhood-suite/&#34;&gt;robinhood software suite&lt;/a&gt; prior to this event.
Librobinhood is an efficient C-API to store and query any filesystem&amp;rsquo;s metadata in a efficiant way.
This is usually done by loading the metadata into a MongoDB database for searchablity.
The tools support POSIX, Lustre and MongoDB as backend and allows fast searching, filtering and changing metadata.&lt;/p&gt;
&lt;p&gt;What I really liked in their talk this year is that they implemented a expire date for files
which is currently working only on Lustre backend but general POSIX support is planned.
The date is saved as a user visible extended attribute and can later be found
with the robinhood &lt;code&gt;find&lt;/code&gt; tool.
Besides that the tool can also have complex filters or search for other extended attributes.&lt;/p&gt;
&lt;h1 id=&#34;random-notes&#34;&gt;Random notes&lt;/h1&gt;
&lt;p&gt;Here are some further random notes and learnings I took during the conference.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;LNet Network Selection Policy (UDSP) allow to the priority of LNet links.
This can result in equal/weighted loadbalanching between LNet devices.
Also it&amp;rsquo;s possible to use specific links only if no other is available (fallback).
See &lt;code&gt;lnetctl set heath&lt;/code&gt; and &lt;code&gt;lnetctl set priority&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The Linux kernel may split a eg. 16M IO operation into smaller IOs.
One can use &lt;code&gt;blktrace&lt;/code&gt; or &lt;code&gt;perf&lt;/code&gt; to check if submitted IOs are the same as what is iactually send to disk.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;One result from a benchmark analysis talk of HPE: ZFS compression underneath Lustre is worth it and doubled throughput (in Benchmarks, at best case).&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Personally I realized during the conversations on this conference which was my first &lt;a href=&#34;https://en.wikipedia.org/wiki/High-performance_computing&#34;&gt;HPC&lt;/a&gt; related.
First that after getting used to HPC workloads everything else seems too small in size.
People here are talking about a 800TiB NVMe + 1.5 PiB HDD storage as the &amp;ldquo;playground&amp;rdquo;
where their users can test things and it&amp;rsquo;s rather common that people have to move 10-50 PiB form one storage to another.&lt;/p&gt;
&lt;p&gt;Secondly benchmarking is a important part of storage engineering, besides &lt;a href=&#34;&#34;&gt;fio&lt;/a&gt; which I knew there is also &lt;a href=&#34;&#34;&gt;ior&lt;/a&gt;, &lt;a href=&#34;&#34;&gt;io500&lt;/a&gt;, &lt;a href=&#34;&#34;&gt;mdtest&lt;/a&gt;.
Benchmarking should be a standard thing to do for a storage engineer for having a clear idea what to expect from hardware before,
and realizing misconfiguration during production use.&lt;/p&gt;
&lt;p&gt;As Sergey Kachkin said: &lt;em&gt;&amp;ldquo;Storage is developed with benchmarks, tested with benchmarks, sold with benchmarks, only users actually have workloads&amp;rdquo;&lt;/em&gt;&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Routing a specific port though wireguard VPN</title>
      <link>https://blog.domainmess.org/post/single_port_wireguard_routing/</link>
      <pubDate>Mon, 18 Sep 2023 14:51:16 +0200</pubDate>
      <guid>https://blog.domainmess.org/post/single_port_wireguard_routing/</guid>
      <description>Yesterday a friend ask me if it is possible to route the outgoing traffic of a Linux machine with a specific destination port via a wireguard VPN. He used a publicly accessible proxy host to forward SMTP (port TCP/25) via this VPN to a machine in his home network and now he wanted the mailserver to push all the outgoing mail also though this VPN connection to the proxy. However there should no mail relay be involved.&lt;p&gt;Yesterday a friend ask me if it is possible to route the outgoing traffic of a Linux machine with a specific destination port
via a wireguard VPN.
He used a publicly accessible proxy host to forward SMTP (port TCP/25) via this VPN to a machine in his home network
and now he wanted the mailserver to push all the outgoing mail also though this VPN connection to the proxy.
However there should no mail relay be involved.&lt;/p&gt;
&lt;p&gt;My idea was to mark all outgoing traffic with a IPtables rule and use a separate routing table to
send it though the VPN instead of the default gateway of the home network (policy based routing).
After some research I found out that it is actually possible to do this with NFtables based systems.
Although the initial routing decision for locally generated packets is done in Linux before one is able to alter them
via firewall rules, there is a possibility to change their route afterwards.&lt;/p&gt;
&lt;p&gt;As the following flowchart shows, there is a &amp;ldquo;reroute check&amp;rdquo; after the OUTPUT chains of all tables and after that you can still
use the POSTROUTING chains.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://en.wikipedia.org/wiki/Netfilter#/media/File:Netfilter-packet-flow.svg&#34;&gt;
  &lt;figure&gt;
    &lt;img src=&#34;https://upload.wikimedia.org/wikipedia/commons/3/37/Netfilter-packet-flow.svg&#34; alt=&#34;&#34; title=&#34;Netfilter Packet Flow image, published on Wikipedia, CC BY-SA 3.01&#34;&gt;
    &lt;figcaption&gt;Netfilter Packet Flow image, published on Wikipedia, CC BY-SA 3.01&lt;/figcaption&gt;
  &lt;/figure&gt;

&lt;/a&gt;&lt;/p&gt;
  &lt;figcaption&gt;&lt;/figcaption&gt;
&lt;p&gt;That means we first use the following firewall rules to mark all the outgoing SMTP traffic.
The number in the firewall mark is arbitrarily chosen.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;iptables -t mangle -I PREROUTING 1 -j CONNMARK --restore-mark
iptables -t mangle -I OUTPUT 1 -p tcp --dport 25 -j MARK --set-mark 0x25
iptables -t mangle -I OUTPUT 2 -j CONNMARK --save-mark
ip6tables -t mangle -I PREROUTING 1 -j CONNMARK --restore-mark
ip6tables -t mangle -I OUTPUT 1 -p tcp --dport 25 -j MARK --set-mark 0x25
ip6tables -t mangle -I OUTPUT 2 -j CONNMARK --save-mark
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Then we add a new routing table and add a single default route via the VPN to it; this work because wireguard interfaces
are layer 3 only so there is no need for a gateway. The table number is also arbitrarily chosen.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;ip route add default dev wg0 table 25
ip -6 route add default dev wg0 table 25
# optional: naming the routing table
echo &amp;#34;25  smtp&amp;#34; &amp;gt; /etc/iproute2/rt_tables
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now we force the marked traffic to be routed with that newly created table with a IP rule.
This all happens during the &amp;ldquo;routing recheck&amp;rdquo; after the traffic has been marked.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;ip rule add from all fwmark 0x25 lookup 25
ip -6 rule add from all fwmark 0x25 lookup 25
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The packet would now be sent via the wireguard interface but will have the source address that was selected
in the first routing decision.
There we need to change the packet again in the POSTROUTING tables and &amp;ldquo;masquerade&amp;rdquo; them with the correct source address.
This isn&amp;rsquo;t a NAT event yet, since the packet has been created locally and is sent on this interface for the first time.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;iptables -A POSTROUTING -m mark --mark 0x25 -j MASQUERADE
ip6tables -A POSTROUTING -m mark --mark 0x25 -j MASQUERADE
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now we can test if a TCP connection to port 25 is actually going via the VPN:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;tcpdump -nni wg0 port 25 &amp;amp;
nc -vz4 gmail-smtp-in.l.google.com. 25
nc -vz6 gmail-smtp-in.l.google.com. 25
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;If you see at least a SYN packet on the VPN interface, then it works.
Although the reverse path might not yet work.
To allow the machine to receive answers for this connection you must first set the reverse path filtering
in Linux to loose (&lt;code&gt;2&lt;/code&gt;) or turn it off completely (&lt;code&gt;0&lt;/code&gt;).
See also the parameter doc on &lt;a href=&#34;https://sysctl-explorer.net/net/ipv4/rp_filter/&#34;&gt;sysctl-explorer.net&lt;/a&gt; or &lt;a href=&#34;https://www.kernel.org/doc/Documentation/networking/ip-sysctl.txt&#34;&gt;kernel.org&lt;/a&gt;&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;sysctl -w net.ipv4.conf.wg0.rp_filter=2
# or
sysctl -w net.ipv4.conf.all.rp_filter=0
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Also if the VPN interface does not have a public address a forwarding and NAT must be configured on the proxy host.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Remove passwords from Git repository</title>
      <link>https://blog.domainmess.org/post/git_remove_pw/</link>
      <pubDate>Wed, 19 Apr 2023 19:18:47 +0200</pubDate>
      <guid>https://blog.domainmess.org/post/git_remove_pw/</guid>
      <description>When it comes to make code or config publicy available as open source one has always to make sure that the repo doesn&amp;rsquo;t contain any sensitve information.
To remove stuff like passwords from various files in all commits i use bfg.
First I clone a single branch from a local repo which should be adjusted for public. Although I use a seperate branch I also use a seperate git directory because Passwords will be cleaned from all refs/branches, not just the current.&lt;p&gt;When it comes to make code or config publicy available as open source one has always to make sure that
the repo doesn&amp;rsquo;t contain any sensitve information.&lt;/p&gt;
&lt;p&gt;To remove stuff like passwords from various files in all commits i use &lt;a href=&#34;https://rtyley.github.io/bfg-repo-cleaner/&#34;&gt;bfg&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;First I clone a single branch from a local repo which should be adjusted for public.
Although I use a seperate branch I also use a seperate git directory because &lt;br&gt;
&lt;strong&gt;Passwords will be cleaned from all refs/branches, not just the current.&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;git clone --single-branch --branch main file://&lt;span style=&#34;color:#66d9ef&#34;&gt;$(&lt;/span&gt;pwd&lt;span style=&#34;color:#66d9ef&#34;&gt;)&lt;/span&gt;/repo/ repo-public-bfg/ 
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Then I search for passwords which are not comments:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;git grep -Eih (pass|password|auth) | grep -v &amp;#34;^[\s]*;&amp;#34;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Then all the passwords are written to a file eg. &lt;code&gt;passwords.txt&lt;/code&gt;.
It can contain simple strings, one per line which will be replaced by &lt;code&gt;***REMOVED***&lt;/code&gt; or you can define
a search/replace combination using &lt;code&gt;==&amp;gt;&lt;/code&gt; as delimiter. Also regexes are possible for matching.
See also this &lt;a href=&#34;https://gist.github.com/w0rd-driven/60779ad557d9fd86331734f01c0f69f0&#34;&gt;example&lt;/a&gt;.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;password
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;#34;password&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;=password==&amp;gt;=__redacted__
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;password2==&amp;gt;&amp;lt;place_password_here&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;regex:password=[0-9]+==&amp;gt;password=
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Once everything is ready bfg does the actual work and git can do some cleanup:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;bfg --replace-text ../passwords.txt . --no-blob-protection --filter-content-excluding &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;*.jpg&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;git reflog expire --expire&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;now --all &lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; git gc --prune&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;now --aggressive
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;--no-blob-protection&lt;/code&gt; removes the passwords from all commits even the current one. &lt;br&gt;
With &lt;code&gt;--filter-content-excluding&lt;/code&gt; you can exclude files that shouldn&amp;rsquo;t be altered.&lt;/p&gt;
&lt;p&gt;Afterwards all the passwords listed in &lt;code&gt;password.txt&lt;/code&gt; will be redacted in all commits!
To track what has changed and prevent dataloss the passwords are all available as a staged commit.
You can view them with &lt;code&gt;git diff --staged&lt;/code&gt; or drop them with &lt;code&gt;git stash; git stash drop&lt;/code&gt;&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Toronto ||</title>
      <link>https://blog.domainmess.org/post/toronto2/</link>
      <pubDate>Fri, 30 Dec 2022 10:54:05 +0100</pubDate>
      <guid>https://blog.domainmess.org/post/toronto2/</guid>
      <description>Together with a friend, I found a old loudspeaker box in the storage of the CCC which contained the material of the Blinkenlights project. Both of us took one of them since they are beautiful and have the perfect format for a bluetooth sound box and include a nice rotary control element for volume. My friend guessed these speakers where used as a monitor system in dressing rooms and he started replace the speaker inside by a stereo system with bluetooth.&lt;p&gt;Together with a friend, I found a old loudspeaker box in the storage of the &lt;a href=&#34;https://www.ccc.de/en/club&#34;&gt;CCC&lt;/a&gt; which contained the material of the &lt;a href=&#34;http://blinkenlights.de/&#34;&gt;Blinkenlights project&lt;/a&gt;.
Both of us took one of them since they are beautiful and have the perfect format for a bluetooth sound box and include a nice rotary control element for volume.
My friend guessed these speakers where used as a monitor system in dressing rooms and he started replace the speaker inside by a stereo system with bluetooth.
Since the Blinkelights project was last active in Toronto, Canada it stands to reason that the speaker came from there and so he named the box &lt;a href=&#34;https://hand-rich.de/toronto/&#34;&gt;Toronto&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://blog.domainmess.org/pictures/toronto2/front.jpg&#34;&gt;&lt;img src=&#39;https://blog.domainmess.org/pictures/toronto2/front-small.png#floatright&#39; width=450px alt=&#34;&#34;&gt;&lt;/a&gt;
&lt;a href=&#34;https://blog.domainmess.org/pictures/toronto2/plug.jpg&#34;&gt;&lt;img src=&#39;https://blog.domainmess.org/pictures/toronto2/plug-small.png#floatright&#39; width=200px alt=&#34;&#34;&gt;&lt;/a&gt;
&lt;a href=&#34;https://blog.domainmess.org/pictures/toronto2/inside.jpg&#34;&gt;&lt;img src=&#39;https://blog.domainmess.org/pictures/toronto2/inside-small.png#floatright&#39; width=200px alt=&#34;&#34;&gt;&lt;/a&gt;
&lt;a href=&#34;https://blog.domainmess.org/pictures/toronto2/poti2.png&#34;&gt;&lt;img src=&#39;https://blog.domainmess.org/pictures/toronto2/poti2-small.png#floatright&#39; width=400px alt=&#34;&#34;&gt;&lt;/a&gt;
Inspired by his work and blogpost I decided to build my own but I choose to use a Mono speaker and amplifier combined with a bluetooth receiver and 3 Li-Ion 18650 cells.&lt;/p&gt;
&lt;p&gt;Referring to his I just called mine &lt;strong&gt;„Toronto ||“&lt;/strong&gt;&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Mikrotik router as Wireguard VPN gateway</title>
      <link>https://blog.domainmess.org/post/mikrotik_wireguard_router/</link>
      <pubDate>Fri, 11 Nov 2022 02:09:04 +0200</pubDate>
      <guid>https://blog.domainmess.org/post/mikrotik_wireguard_router/</guid>
      <description>In my new apartment I luckily have a fibre (FTTH) which terminates in the living room. My first excitement was curbed when I investigated about the technology in use. The ISP uses a technique called GPON which is probably smart from a economical point of view but also enables some possible (sniffing) attacks. Additionally the provider seems to do some filtering which is not just DNS blocking. Long story short I decided to route all traffic through a VPN and so I began to config a Mikrotik hex POE router to use a Njal.&lt;p&gt;In my new apartment I luckily have a fibre (&lt;a href=&#34;https://en.wikipedia.org/wiki/Fiber_to_the_x&#34;&gt;FTTH&lt;/a&gt;) which terminates in the living room.
My first excitement was curbed when I investigated about the technology in use.
The ISP uses a technique called &lt;a href=&#34;https://en.wikipedia.org/wiki/Passive_optical_network&#34;&gt;GPON&lt;/a&gt; which is probably smart from a economical point of view
but also enables some &lt;a href=&#34;https://web.archive.org/web/20220519151950/http://www.gpon.com/gpon-security&#34;&gt;possible (sniffing) attacks&lt;/a&gt;.
Additionally the provider seems to do some filtering which is not just DNS blocking.
Long story short I decided to route all traffic through a VPN and so I began to config a
&lt;a href=&#34;https://web.archive.org/web/20221027161008/https://mikrotik.com/product/RB960PGS&#34;&gt;Mikrotik hex POE&lt;/a&gt;
router to use a &lt;a href=&#34;https://njal.la/&#34;&gt;Njal.la&lt;/a&gt; &lt;a href=&#34;https://www.wireguard.com/&#34;&gt;Wireguard&lt;/a&gt; VPN.&lt;/p&gt;
&lt;h2 id=&#34;configuring-the-router&#34;&gt;Configuring the router&lt;/h2&gt;
&lt;p&gt;This is the first time I actually use Mirotik router in non default config so it took quite a while for me to figure out how everything fits together.
The requirements are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;DHCP Client on Uplink port&lt;/li&gt;
&lt;li&gt;working Wireguard tunnel&lt;/li&gt;
&lt;li&gt;default route through the wireguard tunnel&lt;/li&gt;
&lt;li&gt;forbid traffic to go directly to the uplink (eg. on Wireguard connection loss)&lt;/li&gt;
&lt;li&gt;DHCP server on all other interfaces&lt;/li&gt;
&lt;li&gt;working DNS resolver on the router&lt;/li&gt;
&lt;li&gt;working IPv6&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;dhcp-client--lan-bridge&#34;&gt;DHCP Client + LAN Bridge&lt;/h3&gt;
&lt;p&gt;First we setup a standard behaviour: use the &lt;code&gt;ether1&lt;/code&gt; port for uplink as DHCP client and bridge the remaining interfaces together.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;/interface list member
add comment=uplink interface=ether1 list=WAN
/ip dhcp-client
add add-default-route=no comment=uplink interface=ether1 use-peer-dns=no \
    use-peer-ntp=no

/interface bridge
add admin-mac=AA:BB:CC:DD:EE:FF auto-mac=no comment=local-bridge name=bridge \
    protocol-mode=none
/interface bridge port
add bridge=bridge comment=defconf interface=ether2
add bridge=bridge comment=defconf interface=ether3
add bridge=bridge comment=defconf interface=ether4
add bridge=bridge comment=defconf interface=ether5
add bridge=bridge comment=defconf interface=sfp1
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Be aware, that we do not want to automatically set a default route to the gateway of the uplink network &lt;code&gt;add-default-route=no&lt;/code&gt;
since we want all traffic go through the VPN at all times.&lt;/p&gt;
&lt;h3 id=&#34;dhcpv4-server&#34;&gt;DHCPv4 Server&lt;/h3&gt;
&lt;p&gt;DHCPv4 is also a very common configuration which, I think, does not need further explanation.
The hex POE router has DHCPv4 on its LAN bridge by default enabled.
Anyway here is a configuration example with one static lease:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;/ip pool
add name=domainmess-home-dhcp-range ranges=192.168.0.100-192.168.0.200
/ip dhcp-server
add address-pool=domainmess-home-dhcp-range authoritative=yes disabled=no interface=bridge \
    lease-script=&amp;#34;&amp;#34; lease-time=10m name=domainmess-home-dhcp-server use-radius=no
/ip dhcp-server lease
add address=192.168.0.200 client-id=\
    aa:bb:cc:ee:ff:aa:bb:cc:ee:f:faa:bb:cc:ee:ff:aa:bb:cc:ee:ff mac-address=\
    AA:BB:CC:DD:EE:FF server=domainmess-home-dhcp-server
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;dhcpv6-server&#34;&gt;DHCPv6 Server&lt;/h3&gt;
&lt;p&gt;DHCPv6 isn&amp;rsquo;t really the right term as the Mikrotik RouterOS does prefix delegation.
That means it announces a prefix which the client can get and might use for further delegation
or address selection.
I use it to assign a /64 network to each client which then will configure automatically one address from that.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;/ipv6 pool
add name=domainmess-home-ipv6-ula prefix=fc00:99ff:4400::/32 prefix-length=64
/ipv6 dhcp-server
add address-pool=domainmess-home-ipv6-ula dhcp-option=&amp;#34;&amp;#34; disabled=no interface=bridge lease-time=3d \
    name=domainmess-home-dhcpv6-pd preference=255 rapid-commit=yes route-distance=1 \
    use-radius=no
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;wireguard&#34;&gt;Wireguard&lt;/h3&gt;
&lt;p&gt;Wireguard is new in RouterOS 7 and is integrated quite well into the Mikrotik config.
We define a interface of the type „Wireguard” and at least on Peer to which we want to connect to.
In our case that is the Njalla VPN server.
The other settings come from the Njalla config, but the important one is that we set &lt;code&gt;0.0.0.0/0&lt;/code&gt; and &lt;code&gt;::/0&lt;/code&gt; in the &lt;code&gt;AllowedIPs&lt;/code&gt;
so that we can route all internet traffic through it and not just a specific subnet.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# keys are just examples
/interface wireguard
add disabled=no listen-port=13231 mtu=1280 name=njalla01 private-key=\
    &amp;#34;gDV016J81d9dWkkw7j9MjDcnmt0HhQHnsG7favtiJU8=&amp;#34;

/interface wireguard peers
add allowed-address=0.0.0.0/0,::/0 disabled=no endpoint-address=\
    wg235.njalla.no endpoint-port=51820 interface=njalla01 \
    persistent-keepalive=25s public-key=\
    &amp;#34;YAV6HyThvZgLTYD6nDIeMeUNKgwnp6jnLdiYYNb9Bnc=&amp;#34;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;em&gt;Hint&lt;/em&gt;: Using a hostname instead of an IP as EndPoint is supported since RouterOS 7.6&lt;/p&gt;
&lt;h3 id=&#34;routes--dns&#34;&gt;Routes + DNS&lt;/h3&gt;
&lt;p&gt;Now Wireguard isn&amp;rsquo;t able to connect to its remote, since there is no working Routing+DNS.
Setting DNS servers is trivial but we need also to route all encrypted Wireguard traffic to the Njalla network via
our uplink port. Same goes for at least one DNS server so that Wireguard can lookup its remote.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Be aware&lt;/strong&gt;: This will make at least some your DNS request bypass the VPN and be victim to censorship or monitoring.
To prevent that, use a static IP as Wireguard remote!&lt;/p&gt;
&lt;p&gt;As a default gateway we then set the &lt;em&gt;Wireguard Interface&lt;/em&gt; instead of a IP address.
That is possible since Wireguard is an IP protocol (Layer 3) and creates a &lt;a href=&#34;https://en.wikipedia.org/wiki/TUN/TAP&#34;&gt;TUN&lt;/a&gt; device
which has no need for a Ethernet header with a gateway MAC address inside it.
The traffic must be routed anyway on the other side of the tunnel (on the Njalla routers) and we therefore can just send IP packets into it.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# route to njalla network via uplink
/ip route
    add disabled=no distance=1 dst-address=198.167.192.0/19 gateway=[/ip dhcp-client get [find interface=ether1] gateway]
    pref-src=&amp;#34;&amp;#34; routing-table=main suppress-hw-offload=no
# default route via njalla VPN
add disabled=no distance=1 dst-address=0.0.0.0/0 gateway=njalla01 pref-src=&amp;#34;&amp;#34; \
    routing-table=main suppress-hw-offload=no
# DNS bypass
add disabled=no distance=1 dst-address=9.9.9.9/32 gateway=192.168.1.254 \
    pref-src=&amp;#34;&amp;#34; routing-table=main suppress-hw-offload=no
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;ipv4-nat&#34;&gt;IPv4 NAT&lt;/h3&gt;
&lt;p&gt;Like on more or less every home route IPv4 source NAT is used to use the IPv4 VPN address for all outgoing traffic.
This is also part of the default conf of many Mikrotik router.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;/ip firewall nat
add action=masquerade chain=srcnat comment=&amp;#34;defconf: masquerade&amp;#34; \
    ipsec-policy=out,none out-interface-list=WAN
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;ipv6-nat&#34;&gt;IPv6 NAT&lt;/h3&gt;
&lt;p&gt;This is definitely the most ugly part. Since Njalla only gives one IPv6 address per VPN connection
we have to setup a IPv6 source NAT (yes, that is possible, didn&amp;rsquo;t believe that either&amp;hellip;)&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;/ipv6 firewall nat
add action=masquerade chain=srcnat ipsec-policy=out,none out-interface=\
    njalla01
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Works as designed and is better than no IPv6 at all!&lt;/p&gt;
&lt;h2 id=&#34;configuring-the-clients&#34;&gt;configuring the clients&lt;/h2&gt;
&lt;p&gt;To use the IPv6 prefix delegation we configured before in the &lt;a href=&#34;#DHCPv6%20Server&#34;&gt;DHCPv6 Server&lt;/a&gt; section, we must also ensure
that the client is asking for it.
For systemd-networkd this is done by adding the following lines to the interface configuration:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;[Network]
DHCP=yes
DHCPPrefixDelegation=yes
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;additional-learnings&#34;&gt;Additional learnings&lt;/h2&gt;
&lt;p&gt;During the whole configuration I learned some related stuff which came in quite handy for using
and debugging Mikrotik Routers.&lt;/p&gt;
&lt;h3 id=&#34;find-ipv6-hosts-in-network&#34;&gt;Find IPv6 hosts in network&lt;/h3&gt;
&lt;p&gt;To find IPv6 hosts in the local network one doesn&amp;rsquo;t need to &lt;code&gt;nmap&lt;/code&gt; but one can use multicast packets on which specific hosts will answer.
For example to find all routers you can just ping&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;$ ping -6 ff02::2%wlan0
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This way you can find a router even if no DHCP is working in your LAN or if the router has no static IP due to some configuration errors.&lt;/p&gt;
&lt;h3 id=&#34;use-link-local-addresses&#34;&gt;Use Link-Local addresses&lt;/h3&gt;
&lt;p&gt;Of course you can also use the Link-Local address to access your router.
Well at least you can if you don&amp;rsquo;t want to use the Webinterface because I couldn&amp;rsquo;t find
any browser that properly supports using Link-Local addresses.
That is not a new phenomenon and is &lt;a href=&#34;https://web.archive.org/web/20220910171029/https://ungleich.ch/u/blog/ipv6-link-local-support-in-browsers/&#34;&gt;otherwise documented&lt;/a&gt;.
However accessing the router via SSH via it&amp;rsquo;s link local address even works if&amp;rsquo;s been rebooted with completely network config.&lt;/p&gt;
&lt;h2 id=&#34;links&#34;&gt;Links&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://forum.mikrotik.com/viewtopic.php?t=181205#p897582&#34;&gt;https://forum.mikrotik.com/viewtopic.php?t=181205#p897582&lt;/a&gt;
&lt;a href=&#34;https://web.archive.org/web/20221024234723/https%3A%2F%2Fforum.mikrotik.com%2Fviewtopic.php%3Ft%3D181205&#34;&gt;https://web.archive.org/web/20221024234723/https%3A%2F%2Fforum.mikrotik.com%2Fviewtopic.php%3Ft%3D181205&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://wiki.mikrotik.com/wiki/Setting_up_DHCPv6&#34;&gt;https://wiki.mikrotik.com/wiki/Setting_up_DHCPv6&lt;/a&gt;
&lt;a href=&#34;https://web.archive.org/web/20221024235049/https://wiki.mikrotik.com/wiki/Setting_up_DHCPv6&#34;&gt;https://web.archive.org/web/20221024235049/https://wiki.mikrotik.com/wiki/Setting_up_DHCPv6&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    
    <item>
      <title>Ansible Role: Proxmox VM Setup</title>
      <link>https://blog.domainmess.org/post/ansible-role-proxmox-vm-setup/</link>
      <pubDate>Sun, 18 Sep 2022 16:50:34 +0200</pubDate>
      <guid>https://blog.domainmess.org/post/ansible-role-proxmox-vm-setup/</guid>
      <description>In my current job we use Proxmox clusters as VM hosts and a lot of Debian VM on them. Most of the VMs are old and handcrafted but for some of them like Jenkins agents and Gitlab runners I created Ansible playbooks to configure them. Of course this is rather useless if there is no way to automatically spawn the whole VM before configuring it and so I started to create a role which creates the VM if it&amp;rsquo;s not already existing.&lt;p&gt;In my current job we use &lt;a href=&#34;https://www.proxmox.com/en/proxmox-ve&#34;&gt;Proxmox&lt;/a&gt; clusters as VM hosts and a lot of Debian VM on them.
Most of the VMs are old and handcrafted but for some of them like Jenkins agents and Gitlab runners
I created Ansible playbooks to configure them.
Of course this is rather useless if there is no way to automatically spawn the whole VM before configuring it
and so I started to create a role which creates the VM if it&amp;rsquo;s not already existing.&lt;/p&gt;
&lt;p&gt;The basic concept is simple.
On every physical host there is a template VM which contains a untouched Debian Cloud image.
If the VM doesn&amp;rsquo;t exist, this template is cloned and the VM parameters are set via the Proxmox API.
The initial config which is necessary for Ansible to ssh into the VM later are passed via &lt;a href=&#34;https://cloudinit.readthedocs.io/en/latest/index.html&#34;&gt;cloud-init&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The role follows the same basic concept of my &lt;a href=&#34;https://github.com/benibr/ansible-role-nspawn-container&#34;&gt;systemd-nspawn container role&lt;/a&gt;, all the parameters of the created machines
shall be defined in a &lt;code&gt;host_vars/name.yml&lt;/code&gt; looking like this:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;---
physical_host: kvm-server-99
vm_cores: 32
vm_memory: 32768
vm_disksize: &amp;#34;20G&amp;#34;
vm_template: &amp;#34;debian11-cloudinit-template&amp;#34;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;With that set it is enough to call the role as first task of the playbook and the VM will be spawned.&lt;/p&gt;
&lt;p&gt;Over time the role became more complex so I decided to release it on Github to share it with the community.&lt;br&gt;
&lt;a href=&#34;https://github.com/benibr/ansible-role-proxmox-vm-setup&#34;&gt;https://github.com/benibr/ansible-role-proxmox-vm-setup&lt;/a&gt;&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Cosmic Cable Ltd.</title>
      <link>https://blog.domainmess.org/post/cosmic_cable/</link>
      <pubDate>Wed, 31 Aug 2022 09:26:46 +0200</pubDate>
      <guid>https://blog.domainmess.org/post/cosmic_cable/</guid>
      <description>In 2016 and 2022 I participated in a project called &amp;ldquo;Cosmic Cable Ldt.&amp;rdquo;, a fictional company which provides telephone booths at Fusion Festival. This was one of the most varied and beautiful projects I&amp;rsquo;ve ever done as it combines work with metal and wood, art and decoration with a technical stack from old dial phones to modern VoIP networking. As I love doing all of this at once, working in a small group of friends on a weird techno festival environment fits me just perfect.&lt;p&gt;&lt;a href=&#34;#&#34;&gt;&lt;img src=&#34;https://blog.domainmess.org/pictures/cosmic_cable/cosmic.cable.limited.jpg&#34; &gt;&lt;/a&gt;
&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;In 2016 and 2022 I participated in a project called &amp;ldquo;Cosmic Cable Ldt.&amp;rdquo;, a fictional company which provides telephone booths at &lt;a href=&#34;https://fusion-festival.de&#34;&gt;Fusion Festival&lt;/a&gt;.
This was one of the most varied and beautiful projects I&amp;rsquo;ve ever done as it combines work with metal and wood, art and decoration with a technical stack from old dial phones
to modern VoIP networking.
As I love doing all of this at once, working in a small group of friends on a weird techno festival environment fits me just perfect.&lt;/p&gt;
&lt;h2 id=&#34;about-cosmic-cable-ltd&#34;&gt;About Cosmic Cable Ltd.&lt;/h2&gt;
&lt;p&gt;Comsic Cable is the lost cause of a post-bureaucratic telephone network provider mostly run by a crew of rogue technicians.
Founded in 2016 as an alternative to the bad mobile network at &lt;a href=&#34;https://www.openstreetmap.org/relation/1424154&#34;&gt;Lärz, Germany&lt;/a&gt;
it provides the most stylish telephone booths at both &lt;a href=&#34;https://fusion-festival.de&#34;&gt;Fusion Festival&lt;/a&gt; and &lt;a href=&#34;https://www.attension-festival.de&#34;&gt;at.tension Festival&lt;/a&gt; to connect guests and crew.
The telephone network is complemented by additional well-known Cosmic Cable services like the &amp;ldquo;Status Box&amp;rdquo; which provides asynchronous communication for guests
as well as yearly changing entertainment options.&lt;/p&gt;
&lt;p&gt;Website: &lt;a href=&#34;http://cosmic.cable.limited/&#34;&gt;http://cosmic.cable.limited&lt;/a&gt; &lt;br&gt;
Github Account: &lt;a href=&#34;https://github.com/cosmiccableltd/&#34;&gt;https://github.com/cosmiccableltd/&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&#34;technical-setup&#34;&gt;Technical Setup&lt;/h2&gt;
&lt;p&gt;Within the Cosmic Cable network everything starts with a classic rotary dial telephone.
Although dial phones are awesome, there exist considerably constraints when using them.
The most important is that with pulse dialing you can only dial once per call.
The moment the dialing is complete you can not dial additional numbers, what prohibits any kind of interactive menus. &lt;br&gt;
Since building a whole analogue telephone network is very time consuming we use old &lt;em&gt;Fritz Boxes&lt;/em&gt; to adapt the telephone to a TCP/IP based network.
Models which are known to work well with &lt;a href=&#34;https://en.wikipedia.org/wiki/Pulse_dialing&#34;&gt;pulse dialing&lt;/a&gt; are e.g. &lt;a href=&#34;https://boxmatrix.info/wiki/FRITZ!Box_Fon_ata&#34;&gt;Fritz Box Fon ATA&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;From then on the we can use all kinds of standard networking gear.
On the festival site we often use &lt;a href=&#34;https://store.ui.com/collections/operator-airmax-devices/products/nanostation-m5&#34;&gt;Ubiquiti Nanostations&lt;/a&gt; to establish radio links when no cable links are available.&lt;/p&gt;
&lt;p&gt;As a software PBX we run a &lt;a href=&#34;https://www.asterisk.org/&#34;&gt;Asterisk&lt;/a&gt; setup which implements the service features that Cosmic Cable offers.
The configuration is available publicly on &lt;a href=&#34;https://github.com/cosmiccableltd/asterisk-conf&#34;&gt;Github&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Another important part of attractive telephone booths is the audiovisual ringing which combines the classical ringtone with some other effect like blinking lights or a flamethrower.
To trigger such events we have used two different concepts over the years.&lt;/p&gt;
&lt;p&gt;First we had selfmade relay or other driver PCBs on the second analogue port on the &lt;em&gt;Fritz Box&lt;/em&gt;. The Asterisk server then automatically called the corresponding number on specific events.&lt;/p&gt;
&lt;p&gt;Later on we developed the so called &lt;a href=&#34;https://github.com/cosmiccableltd/mystery-box&#34;&gt;Mystery Box&lt;/a&gt; which has a analogue telephone pass-through and a 12V output which is constantly toggled as long as there&amp;rsquo;s ringing on the line.
The box also provides connection terminals for 12V powered light as well as a passive &lt;a href=&#34;https://en.wikipedia.org/wiki/Power_over_Ethernet#Passive&#34;&gt;POE&lt;/a&gt; injector to drive the Nanostations.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>mkosi</title>
      <link>https://blog.domainmess.org/post/mkosi/</link>
      <pubDate>Fri, 08 Jul 2022 12:41:51 +0200</pubDate>
      <guid>https://blog.domainmess.org/post/mkosi/</guid>
      <description>Installing (Linux) operating systems is a time consuming and, even worse, repetitive task. The whole &amp;ldquo;burning to disk&amp;rdquo; era is definitely over and bootable USB sticks are useful in some cases (eg. installing a new workstation) but let&amp;rsquo;s be honest, most of the time one installs an OS to be used in some kind of VM or container. For this use case live systems with crude installer software are just not the right tool.&lt;p&gt;Installing (Linux) operating systems is a time consuming and, even worse, repetitive task.
The whole &amp;ldquo;burning to disk&amp;rdquo; era is definitely over and bootable USB sticks are useful in some cases (eg. installing a new workstation)
but let&amp;rsquo;s be honest, most of the time one installs an OS to be used in some kind of VM or container.
For this use case live systems with crude installer software are just not the right tool.
PXE based setups with &lt;code&gt;preseed&lt;/code&gt; or &lt;code&gt;kickstart&lt;/code&gt; are, in my humble opinion the even more wrong since they try to automatically operate an installer
which is meant for human interaction.&lt;/p&gt;
&lt;p&gt;There are some more modern approaches like &lt;a href=&#34;https://cloud-init.io/&#34;&gt;cloud-init&lt;/a&gt; which are way better to handle but they still expect some kind of machine to boot and then do the installation steps.&lt;/p&gt;
&lt;h2 id=&#34;what-defines-a-os-installation&#34;&gt;What defines a OS installation?&lt;/h2&gt;
&lt;p&gt;When someone wants to install an operating system they basically want to define the following things:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Where?
What kind of storage/filesystem is used?&lt;/li&gt;
&lt;li&gt;What?
Which kernel, distribution and arbitrary software should be installed?&lt;/li&gt;
&lt;li&gt;How?
How should it boot and how can I reach it afterwards?&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;For virtual machines the whole setup can be pre-defined and there is no need for interactive options or guided installers.
I just want to define the result, generate it and be able to start it right away.
Doing all of that manually is properly annoying, so I wrote a lot of Ansible code to automatically generate &lt;a href=&#34;https://github.com/benibr/ansible-role-nspawn-container&#34;&gt;container filesystems&lt;/a&gt; or full VMs.&lt;/p&gt;
&lt;h2 id=&#34;mkosi-is-what-i-was-missing&#34;&gt;mkosi is what I was missing!&lt;/h2&gt;
&lt;p&gt;A while ago I stumbled upon &lt;a href=&#34;https://github.com/systemd/mkosi&#34;&gt;mkosi&lt;/a&gt;, a tool from the systemd suite which solves exactly that expectation.
It can generate OS filesystem trees of many different distributions by using there native bootstrapping tools (eg. debootstrap) and can additionally package the result in
an image file with a filesystem and bootloader.
You can use &lt;code&gt;mkosi&lt;/code&gt; as a single command or feed it configuration files.
So it does solve the whole &amp;ldquo;Where?&amp;rdquo; and &amp;ldquo;What?&amp;rdquo; questions and even the &amp;ldquo;How?&amp;rdquo; by being able to set passwords, hostname and SSH keys inside the resulting OS to ensure a user can login after boot.&lt;/p&gt;
&lt;p&gt;That&amp;rsquo;s exactly how I want to install a operating system in 2022!
No matter if I&amp;rsquo;m generating a container for testing or if I want to install a Linux on a physical machine from a arbitrary live system.&lt;/p&gt;
&lt;h2 id=&#34;usage&#34;&gt;Usage&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;The examples in this article may be outdated due to heavy change in the mkosi commandline parameters.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The usage is quite straight forward. Although there aren&amp;rsquo;t many howtos and examples available yet.
Of course the &lt;a href=&#34;https://manpages.debian.org/unstable/mkosi/mkosi.1.en.html&#34;&gt;manpage&lt;/a&gt; is worth a look
but also the &lt;a href=&#34;https://wiki.archlinux.org/title/mkosi&#34;&gt;Archlinux Wiki&lt;/a&gt; and &lt;a href=&#34;https://0pointer.net/blog/mkosi-a-tool-for-generating-os-images.html&#34;&gt;Lennarts blogpost&lt;/a&gt;
have some really interesting informations.&lt;/p&gt;
&lt;h5 id=&#34;creating-a-debian-container-systemd-nspawn&#34;&gt;Creating a Debian container (systemd-nspawn)&lt;/h5&gt;
&lt;p&gt;First a simple task, we create a filesystem tree containing a bootable Debian and run it as a container&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# create a directory with a debian system&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;mkosi --format directory --distribution debian --release buster --output test-container --cache /tmp/cache --hostname reality-check.example.com --password foobar
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# boot it as container with systemd-nspawn&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;systemd-nspawn --boot --directory test-container
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h5 id=&#34;creating-a-archlinux-vm-from-config-file-qemu&#34;&gt;Creating a Archlinux VM from config file (qemu)&lt;/h5&gt;
&lt;p&gt;Now we create a full featured image which can be run as a QEMU instance.
Since we cannot simply create a shell inside such a VM, we have to establish a SSH connection.
&lt;code&gt;mkosi&lt;/code&gt; does all of that for us.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-ini&#34; data-lang=&#34;ini&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# create a image with GPT and BTRFS and install ssh&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;[Distribution]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;Distribution&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;arch&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;[Output]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;Format&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;gpt_btrfs&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;Bootable&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;yes&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;Output&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;test-image.img&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;[Packages]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;Packages&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;openssh&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;[Validation]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;Password&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;foobar&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;[Host]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;Ssh&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;yes&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;Netdev&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;yes&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# build the image from the default config file but use hosts package repos and cache&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# hint: parameters must come before command, otherwise they&amp;#39;re ignored&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;mkosi --cache /var/cache/pacman/pkg/ --use-host-repositories build
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# run the generated image with QEMU&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;mkosi qemu &amp;amp;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# connect to it via SSH&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# hint: the created network interface on the host is automatically configured by systemd-networkd&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# hint: the password is also used as password for the SSH key&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;mkosi ssh
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;em&gt;I&amp;rsquo;ve never felt so satisfied after an OS installation ever before&lt;/em&gt;&lt;/p&gt;
&lt;h5 id=&#34;installing-fedora-in-a-squashfs-qemu&#34;&gt;Installing Fedora in a squashfs (qemu)&lt;/h5&gt;
&lt;p&gt;Now inside the new VM we just overwrite the whole image :-P&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# install dependencies&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;pacman -Sy mkosi dnf squashfs-tools
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# create a new OS image with another password and a Fedora system&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;mkosi --cache /tmp -d fedora --password test -o image.raw --force --format gpt_squashfs
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# move it to the &lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# ATTENTION: make sure you run this inside the right shell!&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;dd &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;image.raw of&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;/dev/sda; sync
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;poweroff
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Afterwards when the VM stopped we can start the image again and voilà a Fedora is booting:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;mkosi boot
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;I feel kinda prepared for any upcoming install parties. Remember the multiboot USB sticks with different OSs on it? Those were times.&lt;/p&gt;
&lt;h2 id=&#34;looking-forward&#34;&gt;Looking forward&lt;/h2&gt;
&lt;p&gt;Knowing about &lt;code&gt;mkosi&lt;/code&gt; will probably change the way how I&amp;rsquo;ll setup machines in future.
It looks like the tool is still in updraft and I expect a whole lot of new supported systems and features.
For example nixOS is not yet supported but might fit perfectly. &lt;br&gt;
Another interesting area might be the creation of images for embedded devices like my favorite &lt;a href=&#34;https://www.pcengines.ch/apu2.htm&#34;&gt;APU boards&lt;/a&gt;
or might one even squint in direction of &lt;a href=&#34;https://postmarketos.org/&#34;&gt;postmarketOS&lt;/a&gt;?!&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Adjustable notebook stand made of wood</title>
      <link>https://blog.domainmess.org/post/notebook_stand/</link>
      <pubDate>Sat, 29 Jan 2022 15:18:27 +0100</pubDate>
      <guid>https://blog.domainmess.org/post/notebook_stand/</guid>
      <description>To work without external display I wanted to have a laptop stand which needs less space on the table than the laptop itself.&lt;p&gt;&lt;a href=&#34;https://blog.domainmess.org/pictures/notebook_stand/packshot.png&#34;&gt;&lt;img src=&#34;https://blog.domainmess.org/pictures/notebook_stand/packshot.png#floatright&#34; width=50% &gt;&lt;/a&gt;
&lt;br/&gt;
Inspired by DIY notebook stands like &lt;a href=&#34;https://www.youtube.com/watch?v=FXzwARoWvzA&#34;&gt;this one&lt;/a&gt; made from steel pipes
this one from cork &lt;a href=&#34;https://www.youtube.com/watch?v=dgoXfEh30gc&#34;&gt;cork&lt;/a&gt; or &lt;a href=&#34;https://www.instructables.com/How-to-Make-a-Wooden-Laptop-Stand-Adjustable-Angle/&#34;&gt;this one&lt;/a&gt; made of wood,
I wanted to build one too.
Of course when the stand should be smaller than the notebook on top of it, the barycenter has to be placed well to prevent wobbling.
I decided to build something from leftover wood as it also might work as counter weight. &lt;br&gt;
As base I used a wooden cylinder in which i drilled pairs of holes on different heights.
A smaller cylinder can be plugged into them so adjust the slope.
The top is a pressed cork floor tile with a medium raw surface and a flat wooden plank glue to stop anything from gliding down.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Sharing filesystems with virtiofs between multiple VMs</title>
      <link>https://blog.domainmess.org/post/virtiofs/</link>
      <pubDate>Tue, 09 Nov 2021 16:41:18 +0100</pubDate>
      <guid>https://blog.domainmess.org/post/virtiofs/</guid>
      <description>Sharing data between VMs is a headache every admin had once in a while. Especially when multiple virtual machines are expected to have read/write access. Besides the oldfashioned ways like NFS and the new shiny stuff like Ceph, the &amp;lsquo;simple&amp;rsquo; sharing of a filesystem from host to VM fits in.
Although some solution can configure this with one click, I wanted to understand with which technology I can do this manually.&lt;p&gt;Sharing data between VMs is a headache every admin had once in a while.
Especially when multiple virtual machines are expected to have read/write access.
Besides the oldfashioned ways like NFS and the new shiny stuff like Ceph,
the &amp;lsquo;simple&amp;rsquo; sharing of a filesystem from host to VM fits in.&lt;/p&gt;
&lt;p&gt;Although some solution can configure this with one click, I wanted to understand with which technology I can do this manually.
I found &lt;a href=&#34;https://virtio-fs.gitlab.io/&#34;&gt;virtiofs&lt;/a&gt; which allows as FUSE process on the host to directly pass filesystem access to a &lt;a href=&#34;https://www.oasis-open.org/committees/tc_home.php?wg_abbrev=virtio&#34;&gt;VIRTIO&lt;/a&gt; device inside the VM.
This means not network protocol is involved, restricting the access to local VMs on the host.
But they can use the hosts Page Cache if so chosen.&lt;/p&gt;
&lt;p&gt;So let&amp;rsquo;s get to it:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;virtiofsd&lt;/code&gt; is part of &lt;code&gt;qemu-system-common&lt;/code&gt; on &lt;a href=&#34;https://packages.debian.org/bullseye-backports/amd64/qemu-system-common/filelist&#34;&gt;Debian&lt;/a&gt; or, if you use &lt;a href=&#34;https://www.proxmox.com/en/&#34;&gt;Proxmox&lt;/a&gt; like I did in this case, you can find it under &lt;code&gt;/usr/lib/kvm/virtiofsd&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;So we start two instances of the daemon sharing the same directory:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;/usr/lib/kvm/virtiofsd --socket-path=/tmp/vm1 -o source=/root/multi-test -o cache=auto -o debug
/usr/lib/kvm/virtiofsd --socket-path=/tmp/vm2 -o source=/root/multi-test -o cache=auto -o debug
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;They open a socket which is now passed to the VM via the QEMU parameters.
When using Proxmox, add the following lines to &lt;code&gt;/etc/pve/nodes/$HOSTANME/qemu-server/$VMID.conf&lt;/code&gt;&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-vm1&#34; data-lang=&#34;vm1&#34;&gt;args: -chardev socket,id=char0,path=/tmp/vm1 -device vhost-user-fs-pci,queue-size=1024,chardev=char0,tag=virtiofs_vm_1 \
      -m 4G -object memory-backend-file,id=mem,size=4G,mem-path=/dev/shm,share=on -numa node,memdev=mem
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-vm2&#34; data-lang=&#34;vm2&#34;&gt;args: -chardev socket,id=char0,path=/tmp/vm2 -device vhost-user-fs-pci,queue-size=1024,chardev=char0,tag=virtiofs_vm_2 \
      -m 4G -object memory-backend-file,id=mem,size=4G,mem-path=/dev/shm,share=on -numa node,memdev=mem
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;code&gt;tag=virtiofs_vm_X&lt;/code&gt; defines the name under which the device will be available inside the VM&lt;/p&gt;
&lt;p&gt;See &lt;a href=&#34;https://virtio-fs.gitlab.io/howto-qemu.html&#34;&gt;virtiofs howto&lt;/a&gt; for further details&lt;/p&gt;
&lt;p&gt;Then poweroff and start the VM to enable the additional device.&lt;/p&gt;
&lt;p&gt;If you&amp;rsquo;re running a Linux kernel &amp;gt;5.4 inside the VM, it supports virtiofs natively:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;mount -t virtiofs virtiofs_vm_1 /mnt
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now the host filesystems is mounted to the VM.&lt;/p&gt;
&lt;p&gt;The VM are not yet configured to access the hosts cache since this method is, yet, still experimental.&lt;/p&gt;
&lt;h2 id=&#34;links&#34;&gt;Links:&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://web.archive.org/web/20211008235317/https://forum.proxmox.com/threads/virtiofs-support.77889/&#34;&gt;https://forum.proxmox.com/threads/virtiofs-support.77889/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://web.archive.org/web/20211110185528/https://www.qemu.org/docs/master/tools/virtiofsd.html?highlight=virtiofs&#34;&gt;https://www.qemu.org/docs/master/tools/virtiofsd.html?highlight=virtiofs#cmdoption-virtiofsd-cache&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    
    <item>
      <title>Ubuntu created with debootstrap not recieving updates</title>
      <link>https://blog.domainmess.org/post/ubuntu_no_updates/</link>
      <pubDate>Tue, 26 Oct 2021 13:44:02 +0200</pubDate>
      <guid>https://blog.domainmess.org/post/ubuntu_no_updates/</guid>
      <description>A while ago I realised, that some of my ubuntu systems, most of them nspawn containers, don&amp;rsquo;t receive any updates. I didn&amp;rsquo;t really care about the containers but as I realised that one of my internet facing host is also affected, I began to search. I searched on https://packages.ubuntu.com/ for the newest kernel and locally with apt-cache policy linux-generic for the newest available on the system. Of course the kernel which apt listed was way older but at leased I thereby saw, that the kernel in the repos should come from the &amp;ldquo;security&amp;rdquo; list.&lt;p&gt;A while ago I realised, that some of my ubuntu systems, most of them nspawn containers, don&amp;rsquo;t receive any updates.
I didn&amp;rsquo;t really care about the containers but as I realised that one of my internet facing host is also affected,
I began to search.
I searched on &lt;a href=&#34;https://packages.ubuntu.com/&#34;&gt;https://packages.ubuntu.com/&lt;/a&gt; for the newest kernel and locally with &lt;code&gt;apt-cache policy linux-generic&lt;/code&gt; for the newest available on the system.
Of course the kernel which apt listed was way older but at leased I thereby saw, that the kernel in the repos should come from the &amp;ldquo;security&amp;rdquo; list.
All the systems had in common that I created them with debootstrap, most of them via a ansible role which explicitly adds universe as a component.
I thought that was enough, but it leads to a &lt;code&gt;sources.list&lt;/code&gt; with just the basic package list, leaving out the &lt;code&gt;security&lt;/code&gt; and &lt;code&gt;updates&lt;/code&gt; lists.&lt;/p&gt;
&lt;p&gt;After I added them manually I got the ton of updates I was missing for something like a year.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-/etc/apt/sources.list&#34; data-lang=&#34;/etc/apt/sources.list&#34;&gt;deb http://de.archive.ubuntu.com/ubuntu focal main universe restricted
deb http://de.archive.ubuntu.com/ubuntu focal-security main universe restricted
deb http://de.archive.ubuntu.com/ubuntu focal-updates main universe restricted
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Afterwards I read the manpage of debootstrap an figured out that it is not capable of bootstrapping from multiple sources.
There is another tool called &lt;a href=&#34;http://wiki.debian.org/Multistrap&#34;&gt;Multistrap&lt;/a&gt; for that, but it needs its information from a configfile and cannot be feeded via commandline parameters.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Update&lt;/strong&gt; (20.09.2022):
For the sake of completeness, the problem is the same for Debian systems and for systems with created with &lt;a href=&#34;https://blog.domainmess.org/post/mkosi/&#34; title=&#34;MaKe Operating System Image&#34;&gt;mkosi&lt;/a&gt;
Here is the full file which contains all repositories:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-/etc/apt/sources.list&#34; data-lang=&#34;/etc/apt/sources.list&#34;&gt;deb http://deb.debian.org/debian bullseye main contrib non-free
deb http://deb.debian.org/debian-security/ bullseye-security main contrib non-free
deb http://deb.debian.org/debian bullseye-updates main contrib non-free
# optional
deb http://deb.debian.org/debian bullseye-backports main contrib non-free
&lt;/code&gt;&lt;/pre&gt;</description>
    </item>
    
    <item>
      <title>Reinitialize pacmans package database</title>
      <link>https://blog.domainmess.org/post/arch_package_db/</link>
      <pubDate>Wed, 08 Sep 2021 14:39:31 +0200</pubDate>
      <guid>https://blog.domainmess.org/post/arch_package_db/</guid>
      <description>I had two Arch Linux machines in short time where pacmans database was deleted by accident (it resides under /var/lib/pacman/). Afterwards pacman doesn&amp;rsquo;t know about any installed packages, which I realized when no updates where available ;-) To verify this situation you can use pacman -Qe to list all installed packages.
If you lost the database, of course your system continues working but it&amp;rsquo;s hard to recover the state of the database.&lt;p&gt;I had two Arch Linux machines in short time where pacmans database was deleted by accident (it resides under &lt;code&gt;/var/lib/pacman/&lt;/code&gt;).
Afterwards pacman doesn&amp;rsquo;t know about any installed packages, which I realized when no updates where available ;-)
To verify this situation you can use &lt;code&gt;pacman -Qe&lt;/code&gt; to list all installed packages.&lt;/p&gt;
&lt;p&gt;If you lost the database, of course your system continues working but it&amp;rsquo;s hard to recover the state of the database.
If you don&amp;rsquo;t have a recent backup you can check for installed and/or upgraded packages in &lt;code&gt;/var/log/pacman.log&lt;/code&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# search for ALPM messages containing installed or upgreaded and write each package name to probably_installed_pkgs.txt&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;grep ALPM /var/log/pacman.log | awk &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;/(installed|upgraded)/ {print $4}&amp;#39;&lt;/span&gt; | sort | uniq &amp;gt; probably_installed_pkgs.txt
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# install each of these packages&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; i in &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;cat probably_installed_pkgs.txt&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    echo &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;$i&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    sudo pacman --noconfirm -S --needed --overwrite &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;*&amp;#34;&lt;/span&gt; $i
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    echo &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;----&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;end
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;--noconfirm&lt;/code&gt; sets pacman to non-interactive &lt;br&gt;
&lt;code&gt;--needed&lt;/code&gt; prevents reinstalls, in case the pkg was already installed before as dependency &lt;br&gt;
&lt;code&gt;--overwrite&lt;/code&gt; tells pacman to ignore already existing files&lt;/p&gt;
&lt;p&gt;This fixed most of misery. But I also had a bunch of packages installed which came from the AUR repos.
To install them I wrote this second loop:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; i in &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;cat probably_installed_pkgs.txt&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#75715e&#34;&gt;# check if pacman is able to find the package in the standard repos&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#75715e&#34;&gt;# otherwise install it with yay from the AUR&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  pacman -Ss $i &lt;span style=&#34;color:#f92672&#34;&gt;||&lt;/span&gt; yay --noconfirm --needed -S --overwrite &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;*&amp;#39;&lt;/span&gt; $i
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;end
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Of course you can combine them into one.&lt;/p&gt;
&lt;p&gt;In the end I save the result in a file.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# save all installed pkg names&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;yay -Qe &amp;gt; installed_pkgs.txt
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# count the installed pkgs&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;yay -Qe | wc -l &amp;gt;&amp;gt; installed_pkgs.txt
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This could be done via cronjob or a pacman post hook&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://man.archlinux.org/man/alpm-hooks.5&#34;&gt;https://man.archlinux.org/man/alpm-hooks.5&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://wiki.archlinux.org/title/Pacman#Hooks&#34;&gt;https://wiki.archlinux.org/title/Pacman#Hooks&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    
    <item>
      <title>Everything standardized, nothing works!</title>
      <link>https://blog.domainmess.org/post/satanstuff/</link>
      <pubDate>Tue, 31 Aug 2021 20:24:36 +0100</pubDate>
      <guid>https://blog.domainmess.org/post/satanstuff/</guid>
      <description>In some setups, mostly big storage arrays, SATA drives are prevented from spinning up automatically. There are many standards and lots of technologies to controll this behaviour. Unfortunately, I learned about all of them.&lt;p&gt;A few years ago I got a new home server which just did not work as I expected. This article will follow the different topics I learned about during this endeavour.&lt;br&gt;
I try to keep all paragraphs separated from each other so that you can skip one if your not interested.&lt;/p&gt;
&lt;h2 id=&#34;the-basic-problem&#34;&gt;The basic problem&lt;/h2&gt;
&lt;p&gt;As described in &lt;a href=&#34;https://blog.domainmess.org/post/homeserver/&#34;&gt;this post&lt;/a&gt; I used an &lt;a href=&#34;https://pcengines.ch/apu2e4.htm&#34;&gt;APU2c4&lt;/a&gt;
and a &lt;a href=&#34;https://web.archive.org/web/20181108164626/https://www.inter-tech.de/en/products/ipc/storage-cases/2u-2404s&#34;&gt;Intertech chassis&lt;/a&gt;
as homeserver and added additional SATA controllers to be able to use 4 to 5 disks.
After realising that controllers with an ASM1061 chip &lt;a href=&#34;https://pcengines.ch/howto.htm#add_on_cards&#34;&gt;won&amp;rsquo;t work&lt;/a&gt; reliable with an APU Board,
I bought one based on a &lt;a href=&#34;https://web.archive.org/web/20210309194840/https://www.marvell.com/content/dam/marvell/en/public-collateral/storage/marvell-storage-88se9215-datasheet-2018-12.pdf&#34;&gt;Marvell 88SE9215&lt;/a&gt;.
So I got the disks, the backplane with its SAS connector, a cable adapting to 4x SATA and the controller with 4x SATA.
I put everything together and surprise: It didn&amp;rsquo;t work, the disks did &lt;strong&gt;not&lt;/strong&gt; turn on! &lt;br&gt;
I tested them with a USB adapter, they worked fine.
Even with just the power cable connected they spinup immediately. So what&amp;rsquo;s going on here?!&lt;/p&gt;
&lt;h2 id=&#34;the-backplane&#34;&gt;The backplane&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;https://blog.domainmess.org/pictures/satanstuff/sas_connector.jpg&#34;&gt;&lt;img src=&#39;https://blog.domainmess.org/pictures/satanstuff/sas_connector.jpg#floatright&#39; width=200px alt=&#34;SAS connector on the backplane&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;So I started digging around, what could it be. First thing that comes to mind is the backplane.
Even if the power cable was connected to the backplane, the drives did not spin up.&lt;/p&gt;
&lt;p&gt;The backplane has a 4 pin molex power connector supplying 12V and 5V. So I took my multimeter and checked for the SATA pinout. Both voltages are available on the disk,
the 3.3V pins where at 0V but they aren&amp;rsquo;t used in disks anyway. I realised that only one 12V Pin is connected, but hey should be enough eh?
&lt;a href=&#34;https://i.pinimg.com/originals/68/d1/2d/68d12d70b0b9cbb1f06557c6ac1391d2.png&#34;&gt;&lt;img src=&#39;https://i.pinimg.com/originals/68/d1/2d/68d12d70b0b9cbb1f06557c6ac1391d2.png#floatright&#39; width=200px alt=&#34;SATA power pinout&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The backplane also has two LEDs per disk to show status and activity.
If a disk is connected the blue status LED lights up, so the backplane registers a device presence.
With some older disk additionally the green activity LED blinks once.
This LED is wired together with the staggered spinup pin (PIN11 of the power connector) which is,
&lt;a href=&#34;https://web.archive.org/web/20201028111006/https://documents.westerndigital.com/content/dam/doc-library/en_us/assets/public/western-digital/collateral/tech-brief/tech-brief-western-digital-power-disable-pin.pdf&#34;&gt;to my research&lt;/a&gt;, normal.&lt;/p&gt;
&lt;p&gt;So this pin is high on my backplane with no drive connected and somewhere around ~3.3V with a connected drive.
Looks like a pull up resistor on the backplane tells the drives to enable staggered spin up.
With staggered spinup enabled the wait for a specific SATA command before they start the motor.
At least this explains why the disks aren&amp;rsquo;t spinning up when connected to the backplane.&lt;/p&gt;
&lt;p&gt;In the end I could not determine any obvious fatal error or manufacturing defect on the backplane.&lt;/p&gt;
&lt;h2 id=&#34;the-cable&#34;&gt;The cable&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;https://blog.domainmess.org/pictures/satanstuff/sff8087_wiretable_only.jpg#floatright&#34;&gt;&lt;img src=&#39;https://blog.domainmess.org/pictures/satanstuff/sff8087_wiretable_only.jpg#floatright&#39; width=200px alt=&#34;SFF-8087 wiretable&#34;&gt;&lt;/a&gt;
So I went on with examining the cable and oh-my-my this is a real abyss of standards and human incompetence! &lt;br&gt;
But let&amp;rsquo;s walk through it step by step.&lt;/p&gt;
&lt;p&gt;The connector on the backplane is a &lt;a href=&#34;https://en.wikipedia.org/wiki/Serial_Attached_SCSI#Connectors&#34;&gt;SFF-8087&lt;/a&gt;
connector (also called miniSAS, or internal SAS) which contains 4 Rx/Tx pairs with their related ground lines.
Additionally there are pins for a 4 pin sideband connection which can be used by controllers to control the backplane (eg. for lighting up error or replacement LEDS).
I also checked these pins on my backplane but could not measure anything on them.&lt;/p&gt;
&lt;p&gt;So far so good, this connector can serve 4 distinct SAS or SATA lanes, &lt;strong&gt;but&lt;/strong&gt; SAS and SATA don&amp;rsquo;t just differ in their commands and protocol but also in their pinout.
SAS controller and devices have the same Rx/Tx pinout on their connectors and the swap is done in the cable (crossover).
However SATA controllers and devices have switched Rx/Tx pins on their connectors and the cable is straight through.&lt;br&gt;
And I now have a SATA disk, a backplane which supports both, an SATA to SFF-8087 SAS cable and a SATA controller, well fuck.&lt;/p&gt;
&lt;p&gt;After spending oceans of time researching I could figure out that there are two different types of that adapter cables with a lot of different names:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;the OCR cable&lt;/strong&gt;
which connects a backplane with SFF-8087 connector to a controller with four SATA ports, that&amp;rsquo;s what I need.&lt;br&gt;
This is also called&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Reverse Fanout&lt;/li&gt;
&lt;li&gt;Reverse Breakout&lt;/li&gt;
&lt;li&gt;Straight Through&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;the OCF cable&lt;/strong&gt;
which connects a SAS controller to a backplane or drive with SATA ports.&lt;br&gt;
This is also called&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Forward&lt;/li&gt;
&lt;li&gt;Fanout&lt;/li&gt;
&lt;li&gt;Breakout&lt;/li&gt;
&lt;li&gt;Crossover&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;And yes, a third of all online shops got it just wrong or didn&amp;rsquo;t get it at all. And Yes, I bought 3 cables, two were wrong, one was the right one.
Each around 16-20€. &lt;br&gt;
I connected everything and guess what: The drive did &lt;strong&gt;not&lt;/strong&gt; spinup!&lt;/p&gt;
&lt;h2 id=&#34;staggered-spinup-ssu&#34;&gt;Staggered Spinup (SSU)&lt;/h2&gt;
&lt;p&gt;Now that I&amp;rsquo;m absolutely sure that I got the right cable I have to search the error somewhere else.
So maybe the disk is somehow told to wait with the spinup.
As mentioned before there is a special pin for signaling the drives to do &lt;a href=&#34;https://web.archive.org/web/20201112014759/https://www.45drives.com/wiki/index.php?title=Using_Staggered_Spin_Up&#34;&gt;staggered spinup&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://blog.domainmess.org/pictures/satanstuff/soldered1.jpg&#34;&gt;&lt;img src=&#39;https://blog.domainmess.org/pictures/satanstuff/soldered1.jpg#floatright&#39; width=225px alt=&#34;SSU and PWDIS soldered to GND&#34;&gt;&lt;/a&gt;
&lt;a href=&#34;https://blog.domainmess.org/pictures/satanstuff/soldered2.jpg&#34;&gt;&lt;img src=&#39;https://blog.domainmess.org/pictures/satanstuff/soldered2.jpg#floatright&#39; width=200px alt=&#34;SSU and PWDIS soldered to GND&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The 11th pin on the SATA power connector is not hardwired to its neighbors and is reserved for staggered spinup and activity signaling.
So if pin 11 is connected to ground, which is done by a resistor on the disk, then the drive will start up immediately (normal mode).
But if the pin is pulled to high, when the drive is connects, it won&amp;rsquo;t spin up until a SATA link is established and the controller sends an appropriate command.&lt;/p&gt;
&lt;p&gt;I was frustrated enough to risk loosing a disk to get this thing working and so I just soldered the pins together and well what to say the drive spun up!
&amp;ldquo;Holy cow I fixed it&amp;rdquo; I thought, went to my computer and realized that the drive was still not listed in Linux.
Instead the kernel told me:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt; 1126.507176&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt; ata4: COMRESET failed &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;errno&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;-32&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  Dec &lt;span style=&#34;color:#ae81ff&#34;&gt;18&lt;/span&gt; 07:34:38 archiso kernel: ata4: COMRESET failed &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;errno&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;-32&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  Dec &lt;span style=&#34;color:#ae81ff&#34;&gt;18&lt;/span&gt; 07:34:38 archiso kernel: ata4: reset failed &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;errno&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;-32&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;, retrying in &lt;span style=&#34;color:#ae81ff&#34;&gt;8&lt;/span&gt; secs
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  Dec &lt;span style=&#34;color:#ae81ff&#34;&gt;18&lt;/span&gt; 07:34:47 archiso kernel: ata4: SATA link down &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;SStatus &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt; SControl 300&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt; 1135.653828&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt; ata3: COMRESET failed &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;errno&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;-32&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  Dec &lt;span style=&#34;color:#ae81ff&#34;&gt;18&lt;/span&gt; 07:34:47 archiso kernel: ata3: COMRESET failed &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;errno&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;-32&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  Dec &lt;span style=&#34;color:#ae81ff&#34;&gt;18&lt;/span&gt; 07:34:47 archiso kernel: ata3: reset failed &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;errno&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;-32&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;, retrying in &lt;span style=&#34;color:#ae81ff&#34;&gt;8&lt;/span&gt; secs
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  Dec &lt;span style=&#34;color:#ae81ff&#34;&gt;18&lt;/span&gt; 07:34:56 archiso kernel: ata3: SATA link down &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;SStatus &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt; SControl 300&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;These messages indicates that even the COMRESET at the SATA link initialization failed.
But at least something tries to connect here at all.
There must be something else which keeps the drive from talking to the controller&amp;hellip;&lt;/p&gt;
&lt;h2 id=&#34;power-up-in-standby-puis&#34;&gt;Power Up In Standby (PUIS)&lt;/h2&gt;
&lt;p&gt;Ahh the internet says there is another power down feature for SATA disks.
It&amp;rsquo;s called &lt;a href=&#34;https://en.wikipedia.org/wiki/Power-up_in_standby&#34;&gt;Power Up in Standby&lt;/a&gt; and it means that the drive is set into a mode where it does not power up when it&amp;rsquo;s plugged in
no matter what state the SSU pin is in.
Alright so another thing to fix then we&amp;rsquo;re good to go. Some SATA drives have a jumper to set the PUIS mode, I actually found an old one in my stash
and with the jumper set, the drive stays quiet when power is attached.
Sadly the drives I want to use in the server don&amp;rsquo;t have jumper pins to set PUIS.
But you can also read this feature via software (like &lt;a href=&#34;https://en.wikipedia.org/wiki/Hdparm&#34;&gt;hdparm&lt;/a&gt;).&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;hdparm -I /dev/sdX | grep -i -B &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt; power-up
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     *    SMART feature set
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          Power-Up In Standby feature set 
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The missing * at the beginning of line indicates, that this feature is not set!!&lt;/p&gt;
&lt;p&gt;With the following commands one can control the PUIS feature flag:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;disable PUIS: &lt;code&gt;sudo sg_sat_set_features -f 0x86 /dev/sdX --verbose&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;enable PUIS: &lt;code&gt;sudo sg_sat_set_features -f 0x06 /dev/sdX --verbose&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I tested it with the old drive and as expected it has the same effect as the jumper setting
but the feature could neither be enabled nor disabled on the drives I want to use.&lt;/p&gt;
&lt;h2 id=&#34;power-disable-pwdis&#34;&gt;Power disable (PWDIS)&lt;/h2&gt;
&lt;p&gt;Well believe it or not but since SATA Rev 3.2+ there is another power feature called &lt;strong&gt;Power disable&lt;/strong&gt; (PWDIS).
Like staggered spinup it ist controlled via a pin on the SATA power connector
in this case Pin 3 which was one of three 3.3V pin in earlier SATA revisions.
See &lt;a href=&#34;https://www.tomshardware.com/news/hdd-sata-power-disable-feature,36146.html&#34;&gt;tom&amp;rsquo;s HARDWARE&lt;/a&gt;
for further details. &lt;br&gt;
I verified that this pin is not connected to the other two 3.3V pins (like on older disks)
and then I started the whole endeavour again.
I taped the pin, I soldered it to ground, I shorted it to ground after the disk was connected.
Then I did all that in various combinations with both the SSU and the PWDIS pin. &lt;br&gt;
The only measurable effect was some magic smoke leaving the backplane indicating that one of the activity LEDs has left our solar system.
All four drives still not spinning up.&lt;/p&gt;
&lt;h2 id=&#34;the-cable-again&#34;&gt;The cable, again&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;https://blog.domainmess.org/pictures/satanstuff/hp_cable_open.jpg&#34;&gt;&lt;img src=&#39;https://blog.domainmess.org/pictures/satanstuff/hp_cable_open.jpg#floatright&#39; width=200px alt=&#34;SFF-8087 connector of a two lane HP cable&#34;&gt;&lt;/a&gt;
&lt;a href=&#34;https://blog.domainmess.org/pictures/satanstuff/shit_cable_open.jpg&#34;&gt;&lt;img src=&#39;https://blog.domainmess.org/pictures/satanstuff/shit_cable_open.jpg#floatright&#39; width=200px alt=&#34;SFF-8087 connector of a four lane noname cable&#34;&gt;&lt;/a&gt;
Still my mind told me that after all it is most likely that the cable must be the culprit.
I searched for replacement in all offices and workshops I could think of and got a bunch of HP branded 2x SATA -&amp;gt; SAS adapter cables.
With this the drives spun up and are recognized by the host system.
Oh how crazy is that, was it the wrong cable after all?
Well with the HP cable I could only use the first two drives but that&amp;rsquo;s at least something.
I used the machine for more then a year with this setup till I ran out of storage.
Anyway if two lanes work, there must be a solution for four SATA lanes.
I wanted to understand what the difference between the working and the non-working cable is and
so I ripped one of each type open.&lt;/p&gt;
&lt;p&gt;These pictures show the PCB of a noname 4 lane cable (left) and a 2 lane HP cable (right).
As you can see the layout is the same.
In the center there are the sideband pins and on the each side there is a SATA dataline pair surrounded by GND.
The HP cable had the sideband connected, I desoldered them, nothing changed.
Also all wires had connection from one end to another.&lt;/p&gt;
&lt;p&gt;As to be expected, no further noticeable difference between them.&lt;/p&gt;
&lt;h2 id=&#34;the-controller&#34;&gt;The controller&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;https://blog.domainmess.org/pictures/satanstuff/controller.jpg&#34;&gt;&lt;img src=&#39;https://blog.domainmess.org/pictures/satanstuff/controller.jpg#floatright&#39; width=180px&gt;&lt;/a&gt;
The project was in such a horrible state that the occasionally heavy drinking started to become occasionally more often!
At last on the list was the controller, although I seriously doubted that it could be the root cause.
Nevertheless I checked my options. &lt;br&gt;
As mentioned above I use a &lt;a href=&#34;https://web.archive.org/web/20210309194840/https://www.marvell.com/content/dam/marvell/en/public-collateral/storage/marvell-storage-88se9215-datasheet-2018-12.pdf&#34;&gt;Marvell 88SE9215&lt;/a&gt;
which has no raid capabilities or something like that.
The &lt;a href=&#34;https://aur.archlinux.org/packages/marvell-msu/&#34;&gt;tooling&lt;/a&gt; provided by Marvell can only handle their raid controllers and did not even recognize mine.
So I spent a night or two going through everything the AHCI driver exposes via sysfs about that controller.
Then I read the source code of the AHCI driver and found a &lt;a href=&#34;https://github.com/torvalds/linux/blob/7cd4ecd9177b94af783b8e21de7c65b41a871342/drivers/ata/ahci.c#L635&#34;&gt;Marvell specific option&lt;/a&gt;
Additionally there is &lt;a href=&#34;https://github.com/torvalds/linux/blob/7cd4ecd9177b94af783b8e21de7c65b41a871342/drivers/net/phy/marvell.c&#34;&gt;another driver&lt;/a&gt;
for these controllers which I could try, but honestly I didn&amp;rsquo;t even want to anymore.&lt;/p&gt;
&lt;h2 id=&#34;the-rapture&#34;&gt;The rapture&lt;/h2&gt;
&lt;p&gt;While waiting for the next best time to checkout some other combinations of parameters I talked to a lot of people about this mess.&lt;br&gt;
Most of them avoided successfully to get dragged into this, some other lend me hardware for testing.
My partner then told me that she likes the idea of fixing such a problem with money and what would be my options on that.
So answered more &lt;del&gt;or less&lt;/del&gt; sarcastically &amp;ldquo;Well, I could get a cable from a considerable brand which costs 4 times as much&amp;rdquo;
- &amp;ldquo;Then you should try that!&amp;rdquo;&lt;/p&gt;
&lt;p&gt;So I paid 45€ (!) for a SATA-&amp;gt;SAS cable with all the schibberish I already told you about, plugged it in and it just worked. And it still does&amp;hellip;&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Booting Ubuntu 20.04 live via http</title>
      <link>https://blog.domainmess.org/post/ubuntu_http/</link>
      <pubDate>Wed, 28 Jul 2021 23:39:21 +0200</pubDate>
      <guid>https://blog.domainmess.org/post/ubuntu_http/</guid>
      <description>PXE boot concepts are often complicated chains of many stages. Init ramdisks contaning casper 1.445 can load a ISO over http as rootfs.&lt;p&gt;Most Linux distros offer an &lt;a href=&#34;https://en.wikipedia.org/wiki/Optical_disc_image&#34;&gt;ISO&lt;/a&gt; file which could either be burned on CD or copied to an USB stick.
Although [grub2] can handle such ISO files directly, &lt;a href=&#34;https://wiki.syslinux.org/wiki/index.php?title=The_Syslinux_Project&#34;&gt;SYSLINUX&lt;/a&gt; can&amp;rsquo;t and
it&amp;rsquo;s part PXELINUX still used in a lot of &lt;a href=&#34;https://en.wikipedia.org/wiki/Preboot_Execution_Environment&#34;&gt;PXE&lt;/a&gt; environments.&lt;/p&gt;
&lt;p&gt;The idea behind PXE is that a small program is stored on the network card which obtains an IP address and then loads a system over the network (eg. &lt;a href=&#34;https://en.wikipedia.org/wiki/Trivial_File_Transfer_Protocol&#34;&gt;FTP&lt;/a&gt;)
As second stage PXELINUX is often used as bootloader which then loads a linux kernel and an initramfs.
Once they are booted there is a whole lot of possible further bootpaths.
Ubuntu uses the &lt;a href=&#34;https://code.launchpad.net/ubuntu/+source/casper&#34;&gt;casper scripts&lt;/a&gt;
to handle the actual boot sequence.
Since casper version 1.445 which is packaged in Ubuntu 20.04 (Focal Fossa) it is capable to mount the rootfs not only via SMB/CIFS and NFS
but it&amp;rsquo;s also possible to specify a http link to a ISO file which is then loaded and mounted as root filesystem.&lt;/p&gt;
&lt;p&gt;I saw a lot of PXE setups which load the kernel and mount the root filesystem via NFS and for those which load the kernel via HTTP I wanted to eliminate NFS as a second necessary protocol.
I had to experiment a bit to get this working, cause the &lt;a href=&#34;https://web.archive.org/web/20201121060416/http://manpages.ubuntu.com/manpages/focal/man7/casper.7.html&#34;&gt;manpage of casper&lt;/a&gt;
suggested false default.
But here is the PXELINUX configuration which worked eventually:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;/srv/tftp/pxelinux.cfg/default&lt;/code&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;LABEL rescue-live-system
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        MENU LABEL Rescue Live System
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        KERNEL http://fileserver.local/rescuei.iso-mounted/casper/vmlinuz
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        APPEND initrd&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;http://fileserver.local/rescue.iso-mounted/casper/initrd.lz boot&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;casper ip&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;dhcp netboot&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;url url&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;http://fileserver.local/rescue.iso console&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;tty0 console&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;ttyS1,115200
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;First lets go through the casper options:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;boot=casper&lt;/code&gt; tells that casper should be used inside the initrd (under &lt;code&gt;/scripts/casper&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ip=dhcp&lt;/code&gt; although the &lt;a href=&#34;https://web.archive.org/web/20201121060416/http://manpages.ubuntu.com/manpages/focal/man7/casper.7.html&#34;&gt;manpage of casper&lt;/a&gt; says DHCP is default, this option is mandatory&lt;/li&gt;
&lt;li&gt;&lt;code&gt;netboot=url&lt;/code&gt; instead of smb or nfs we want to netboot from a HTTP url&lt;/li&gt;
&lt;li&gt;&lt;code&gt;url=http://fileserver.local/rescue.iso&lt;/code&gt; well the path to the ISO which is booted.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a href=&#34;https://blog.domainmess.org/pictures/ubuntu_http/iso_tree.png&#34;&gt;&lt;img src=&#34;https://blog.domainmess.org/pictures/ubuntu_http/iso_tree.png#floatleft&#34; width=29% &gt;&lt;/a&gt;
If you want to server the files from a local fileserver you need to extract the kernel and the initrd file from the iso and serve them seperatly.
To do that just mount the ISO and copy the files:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;mount -o loop ubuntu-20.10-desktop-amd64.iso /mnt
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;cp -av /mnt/casper/&lt;span style=&#34;color:#f92672&#34;&gt;{&lt;/span&gt;initrd,vmlinux&lt;span style=&#34;color:#f92672&#34;&gt;}&lt;/span&gt; /var/www/path/to/fileserver/
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;umount -l /mnt
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;br&gt;
If you have internet access you can also boot an ubuntu image directly from ubuntu.com.
But &lt;strong&gt;be careful since there is no HTTPS support!&lt;/strong&gt;&lt;/p&gt;
&lt;h4 id=&#34;useful-links&#34;&gt;Useful links&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Howto from Ubuntu.com &lt;a href=&#34;https://web.archive.org/web/20210126035729/https://discourse.ubuntu.com/t/netbooting-the-live-server-installer/14510&#34;&gt;https://discourse.ubuntu.com/t/netbooting-the-live-server-installer/14510&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    
    <item>
      <title>Shiet Protection</title>
      <link>https://blog.domainmess.org/post/shiet_protection/</link>
      <pubDate>Wed, 23 Jun 2021 15:40:21 +0200</pubDate>
      <guid>https://blog.domainmess.org/post/shiet_protection/</guid>
      <description>Excel files can protect sheets/cells to prevent accidental editing. This protection can be &amp;ldquo;secured&amp;rdquo; by a password. This article describes how to remove that protection with basic Linux tools.&lt;p&gt;A friend of mine called me and ask if I know how to remove the write protection of a Excel file.
No, I&amp;rsquo;ve never heard of such a thing so she explained that she was using a template form
which she can fill out but can not edit the predefined cells or the sheets themselves.&lt;/p&gt;
&lt;p&gt;Since the file was readable and not encrypted, I thought &amp;lsquo;how hard can it be?!&amp;rsquo;,
there must be a way to edit this thing without rebuilding it in a new Excel file.&lt;/p&gt;
&lt;p&gt;After a short internet research I found multiple approaches:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Open it with LibreOffice and reexport it as a new xlsx file.&lt;/li&gt;
&lt;li&gt;Open it with Google Sheets and reexport it as a new xlsx file.&lt;/li&gt;
&lt;li&gt;Manually edit the files with a text editor&lt;/li&gt;
&lt;li&gt;Lots of shady online tools&lt;/li&gt;
&lt;li&gt;Brute forcing the password with Visual Basic Scripts&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;First I tried opening the file in LibreOffice but sadly I couldn&amp;rsquo;t remove the write protection.
LibreOffice was also asking for a password.
Then another friend found a LibreOffice version in a Fedora 32 which seems to ignore this password setting
but after he exported the file as .xlsx again most references where broken and the manual fixing of those would probably take hours. &lt;br&gt;
&lt;a href=&#34;https://blog.domainmess.org/pictures/shiet_protection/libreoffice_password.png&#34;&gt;&lt;img src=&#34;https://blog.domainmess.org/pictures/shiet_protection/libreoffice_password.png#floatleft&#34; width=&#34;38%&#34; height=&#34;23%&#34;&gt;&lt;/a&gt;
Then we tried the same thing with Google Sheets.
The application also ignores the password setting and simple loads all sheets fully editable
but sadly when reexporting the files, all references are broken.&lt;/p&gt;
&lt;p&gt;At this time I felt rather triggered!&lt;/p&gt;
&lt;p&gt;To describe that feature briefly: One can set a protection on sheets and cells which keeps users from editing them accidentally.
That&amp;rsquo;s reasonable and even useful. &lt;br&gt;
But then one could also set a password which is needed to unlock these cells and there is absolutely &lt;em&gt;no&lt;/em&gt; technical mechanism ensuring that this password is checked.
It completely depends on the implementation of the program which is used to work with that sheet.
If it just doesn&amp;rsquo;t parse the password setting there is nothing preventing the editing.
What kind of a functionality is that?!&lt;/p&gt;
&lt;p&gt;Maybe it&amp;rsquo;s better to go one layer beneath.
XLSX files are basically zipped directories of XML files.
So first I extracted the document to be able to read its internals:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;highway17 ~/W/excel&amp;gt; cp -av write_protected_excel_shiet.xlsx write_protected_excel_shiet.zip
&amp;#39;write_protected_excel_shiet.xlsx&amp;#39; -&amp;gt; &amp;#39;write_protected_excel_shiet.zip&amp;#39;
highway17 ~/W/excel&amp;gt; unzip write_protected_excel_shiet.zip -d write_protected_excel_shiet.unzipped
Archive:  write_protected_excel_shiet.zip
  inflating: write_protected_excel_shiet.unzipped/[Content_Types].xml  
  inflating: write_protected_excel_shiet.unzipped/_rels/.rels  
  inflating: write_protected_excel_shiet.unzipped/xl/workbook.xml  
  inflating: write_protected_excel_shiet.unzipped/xl/_rels/workbook.xml.rels  
  inflating: write_protected_excel_shiet.unzipped/xl/styles.xml  
  inflating: write_protected_excel_shiet.unzipped/xl/worksheets/sheet1.xml  
  inflating: write_protected_excel_shiet.unzipped/xl/worksheets/sheet2.xml  
  ...
  inflating: write_protected_excel_shiet.unzipped/xl/worksheets/sheet12.xml  
 extracting: write_protected_excel_shiet.unzipped/xl/media/image1.png  
  inflating: write_protected_excel_shiet.unzipped/xl/worksheets/_rels/sheet11.xml.rels  
  ...
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Some guides in the internet describe that the &lt;code&gt;sheetProtection&lt;/code&gt; setting should be in the &lt;em&gt;workbook.xml&lt;/em&gt; but I found two other Protection settings.
In the &lt;code&gt;xl/styles.xml&lt;/code&gt; file there are some xml tags which included &lt;code&gt;applyProtection=&lt;/code&gt;.
Some set to &lt;code&gt;1&lt;/code&gt;, some to &lt;code&gt;0&lt;/code&gt;.
So as a first try I set them all to zero with&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;sed -i &amp;#39;s/applyProtection=&amp;#34;1&amp;#34;/applyProtection=&amp;#34;0&amp;#34;/g&amp;#39;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Afterwards LibreOffice rendered the file totally scrambled and Excel refused to open it.
I was thinking about some checksum which verifies if the file might be corrupted but I couldn&amp;rsquo;t find anything about it.&lt;/p&gt;
&lt;p&gt;So I search in the other files and found things like this in the &lt;code&gt;xl/worksheets/sheetN.xml&lt;/code&gt; files:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;highway17 ~/W/e/w/x/worksheets&amp;gt; grep -rio &amp;#39;&amp;lt;[^&amp;gt;]*Protection[^&amp;gt;]*&amp;#39; *
sheet1.xml:&amp;lt;sheetProtection selectLockedCells=&amp;#34;1&amp;#34; selectUnlockedCells=&amp;#34;1&amp;#34;/
sheet2.xml:&amp;lt;sheetProtection password=&amp;#34;90AE&amp;#34; sheet=&amp;#34;1&amp;#34; objects=&amp;#34;1&amp;#34; scenarios=&amp;#34;1&amp;#34; selectLockedCells=&amp;#34;1&amp;#34;/
sheet3.xml:&amp;lt;sheetProtection password=&amp;#34;90AE&amp;#34; sheet=&amp;#34;1&amp;#34; objects=&amp;#34;1&amp;#34; scenarios=&amp;#34;1&amp;#34; selectLockedCells=&amp;#34;1&amp;#34;/
sheet4.xml:&amp;lt;sheetProtection password=&amp;#34;90AE&amp;#34; sheet=&amp;#34;1&amp;#34; objects=&amp;#34;1&amp;#34; scenarios=&amp;#34;1&amp;#34; selectLockedCells=&amp;#34;1&amp;#34;/
sheet5.xml:&amp;lt;sheetProtection password=&amp;#34;90AE&amp;#34; sheet=&amp;#34;1&amp;#34; objects=&amp;#34;1&amp;#34; scenarios=&amp;#34;1&amp;#34; selectLockedCells=&amp;#34;1&amp;#34;/
sheet6.xml:&amp;lt;sheetProtection password=&amp;#34;90AE&amp;#34; sheet=&amp;#34;1&amp;#34; objects=&amp;#34;1&amp;#34; scenarios=&amp;#34;1&amp;#34; selectLockedCells=&amp;#34;1&amp;#34;/
sheet7.xml:&amp;lt;sheetProtection password=&amp;#34;90AE&amp;#34; sheet=&amp;#34;1&amp;#34; objects=&amp;#34;1&amp;#34; scenarios=&amp;#34;1&amp;#34; selectLockedCells=&amp;#34;1&amp;#34;/
sheet8.xml:&amp;lt;sheetProtection password=&amp;#34;90AE&amp;#34; sheet=&amp;#34;1&amp;#34; objects=&amp;#34;1&amp;#34; scenarios=&amp;#34;1&amp;#34; selectLockedCells=&amp;#34;1&amp;#34;/
sheet9.xml:&amp;lt;sheetProtection password=&amp;#34;90AE&amp;#34; sheet=&amp;#34;1&amp;#34; objects=&amp;#34;1&amp;#34; scenarios=&amp;#34;1&amp;#34; selectLockedCells=&amp;#34;1&amp;#34;/
sheet10.xml:&amp;lt;sheetProtection sheet=&amp;#34;1&amp;#34; objects=&amp;#34;1&amp;#34; scenarios=&amp;#34;1&amp;#34; selectLockedCells=&amp;#34;1&amp;#34; autoFilter=&amp;#34;0&amp;#34; selectUnlockedCells=&amp;#34;1&amp;#34;/
sheet11.xml:&amp;lt;sheetProtection sheet=&amp;#34;1&amp;#34; objects=&amp;#34;1&amp;#34; scenarios=&amp;#34;1&amp;#34; selectLockedCells=&amp;#34;1&amp;#34; selectUnlockedCells=&amp;#34;1&amp;#34;/
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The password isn&amp;rsquo;t there in plaintext of course.
Some hashing must be in use but I didn&amp;rsquo;t investigate much further since I want to fully remove the password instead of recovering it.
However I just removed all these &amp;ldquo;sheetProtection&amp;rdquo; tags and zipped the whole thing together again.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;egrep -lRZ &amp;#39;&amp;lt;sheetProtect[^&amp;gt;]*&amp;#39; . | xargs -0 -l sed -i &amp;#39;s/&amp;lt;sheetProtection[^&amp;gt;]*//g&amp;#39;
cd ../../..
zip -r unlocked.xlsx ./*
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;That worked!&lt;/strong&gt;
I could open the file with LibreOffice, the forms were in order, everything was unprotected and editable and last but not least Excel was able to open the files with working references.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Search and destroy corrupt pages in Postgres databases</title>
      <link>https://blog.domainmess.org/post/postgresdd/</link>
      <pubDate>Tue, 22 Jun 2021 13:04:41 +0200</pubDate>
      <guid>https://blog.domainmess.org/post/postgresdd/</guid>
      <description>Postgres can get in a sitation where there are corrupt datasets in the DB which are neither readable nor deleteable. This article describes how to identify such blocks and zero them with basic linux utils&lt;p&gt;At work I found a very slow and rather huge Postgres database.
Over 750GB of Bareos backup information with such incredible slow I/O that the jobs sometime timeout.
So I started to clean the thing up and realized that the problem wasn&amp;rsquo;t just the amount of data but obviously the DB was corrupt.&lt;/p&gt;
&lt;h2 id=&#34;the-corrupt-database&#34;&gt;The corrupt database&lt;/h2&gt;
&lt;p&gt;During my attempts to clean the database I tried some Bareos cleanup job which all failed.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;root@bareos-director-live:~# systemd-run -t bareos-dbcheck -b -f
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Query failed: SELECT FileId,Name from File WHERE Name LIKE &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;%/&amp;#39;&lt;/span&gt;: ERR&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;PANIC:  corrupted item lengths: total 22664, available space &lt;span style=&#34;color:#ae81ff&#34;&gt;7912&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;SSL SYSCALL error: EOF detected
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Then I logged into the Postgres DB directly and manually started a VACUUM task to see what exactly fails.
These should normally run automatically as AUTOVACUUM but I the only error report from them which I could find was `autovacuum: found orphan temp table &amp;ldquo;pg_temp_20&amp;rdquo;.&lt;br&gt;
Attempting an manual VACUUM FULL which rewrites all data and discards obsolete entries was unsuccessful:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;bareos_catalog=# VACUUM FULL;
WARNING:  concurrent delete in progress within table &amp;#34;file&amp;#34;
server closed the connection unexpectedly
        This probably means the server terminated abnormally
        before or while processing the request.
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Okay the working threat just crashes when doing a VACUUM, that explains why the Bareos cleanup jobs cannot finish and probably also explains why the database is so big.
Space with old data just cannot be claimed again and is therefore never overwritten.&lt;/p&gt;
&lt;p&gt;So I tried to figure out where exactly the corrupt data lies.
Therefore I ran the VACCUUM on every single table in the database and voilà:
the &amp;lsquo;file&amp;rsquo; table seems to be the culprit.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;bareos_catalog=# VACUUM VERBOSE file;
INFO:  vacuuming &amp;#34;public.file&amp;#34;
INFO:  scanned index &amp;#34;file_pkey&amp;#34; to remove 89478200 row versions
DETAIL:  CPU 33.06s/183.07u sec elapsed 298.52 sec
...
INFO:  scanned index &amp;#34;file_pjidpart_idx&amp;#34; to remove 89478227 row versions
DETAIL:  CPU 1.54s/2.08u sec elapsed 13.91 sec
INFO:  &amp;#34;file&amp;#34;: removed 89478227 row versions in 2349497 pages
DETAIL:  CPU 32.93s/17.48u sec elapsed 873.81 sec
PANIC:  corrupted item lengths: total 22664, available space 7912
server closed the connection unexpectedly
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;attempting-to-fix-it-with-postgres-tools&#34;&gt;Attempting to fix it with Postgres tools&lt;/h2&gt;
&lt;p&gt;Somewhere in this table there seems to be an entry which says it is longer than it can be.&lt;/p&gt;
&lt;p&gt;I tried to dump the whole database and hoped that I would be able to reimport it, but no:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;root@bareos-dbm-live01:~# sudo -u postgres pg_dump --user bareos_catalog bareos_catalog &amp;gt; /var/lib/postgresql/dump.sql
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Password: *************************
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;pg_dump: error: Dumping the contents of table &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;file&amp;#34;&lt;/span&gt; failed: PQgetResult&lt;span style=&#34;color:#f92672&#34;&gt;()&lt;/span&gt; failed.
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;pg_dump: error: Error message from server: PANIC:  corrupted item lengths: total 22664, available space &lt;span style=&#34;color:#ae81ff&#34;&gt;7912&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;pg_dump: error: The command was: COPY public.file &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;fileid, fileindex, jobid, pathid, deltaseq, markid, fhinfo, fhnode, lstat, md5, name&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt; TO stdout;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;I search the web for an solution and &lt;a href=&#34;https://web.archive.org/web/20210625112636/https://pgsql-general.postgresql.narkive.com/3hBds3f0/vacuumdb-vacuuming-of-database-xy-failed-panic-corrupted-item-pointer-19227&#34;&gt;found out&lt;/a&gt; that one approach is to set the option &lt;code&gt;zero_damaged_pages = true&lt;/code&gt;
and REINDEX the table afterwards. &lt;br&gt;
Dataloss was okay for me at this time, as long as just one entry from the file tables would be lost.
The Bareos backups which rely on this database would be still restorable.&lt;/p&gt;
&lt;p&gt;But of course it ain&amp;rsquo;t that simple:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;bareos_catalog=# REINDEX table file;
WARNING:  concurrent delete in progress within table &amp;#34;file&amp;#34;
ERROR:  could not access status of transaction 125829127
DETAIL:  Could not open file &amp;#34;pg_subtrans/0780&amp;#34;: No such file or directory.
CONTEXT:  while checking uniqueness of tuple (23963062,6) in relation &amp;#34;file&amp;#34;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now this looks like Postgres searches for data in a non existing file, ugh. Tried to touch that file, made it even worse.
Well but at least we&amp;rsquo;ve got some information from this.
The CONTEXT line explains that the error occures when working on a specific tuple (a dataset in the database).&lt;/p&gt;
&lt;h2 id=&#34;investigating-the-bad-datasets&#34;&gt;Investigating the bad datasets&lt;/h2&gt;
&lt;p&gt;So maybe we can work on that thing directly, read it or delete it.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;bareos_catalog=# select * from file where ctid=&amp;#39;(23963062,6)&amp;#39;;
ERROR:  invalid memory alloc request size 18446744073709551613
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Nope! Don&amp;rsquo;t have that much memory installed right now and I don&amp;rsquo;t think the tuple should be that big.
Although it is possible to read the first few columns of the tuple like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;bareos_catalog&lt;span style=&#34;color:#f92672&#34;&gt;=#&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;SELECT&lt;/span&gt; ctid,fileid,fileindex,jobid,pathid,deltaseq,markid &lt;span style=&#34;color:#66d9ef&#34;&gt;FROM&lt;/span&gt; file &lt;span style=&#34;color:#66d9ef&#34;&gt;WHERE&lt;/span&gt; ctid&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;(23963062,6)&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     ctid     &lt;span style=&#34;color:#f92672&#34;&gt;|&lt;/span&gt;       fileid        &lt;span style=&#34;color:#f92672&#34;&gt;|&lt;/span&gt; fileindex  &lt;span style=&#34;color:#f92672&#34;&gt;|&lt;/span&gt;   jobid    &lt;span style=&#34;color:#f92672&#34;&gt;|&lt;/span&gt;   pathid   &lt;span style=&#34;color:#f92672&#34;&gt;|&lt;/span&gt; deltaseq &lt;span style=&#34;color:#f92672&#34;&gt;|&lt;/span&gt;   markid
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;--------------+---------------------+------------+------------+------------+----------+------------
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt; (&lt;span style=&#34;color:#ae81ff&#34;&gt;23963062&lt;/span&gt;,&lt;span style=&#34;color:#ae81ff&#34;&gt;6&lt;/span&gt;) &lt;span style=&#34;color:#f92672&#34;&gt;|&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;7885913182697562177&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;|&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;1109424715&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;|&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;1664625506&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;|&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;1682055211&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;|&lt;/span&gt;    &lt;span style=&#34;color:#ae81ff&#34;&gt;25968&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;|&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;1092632864&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;row&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;But as soon as I tried to read the next column &lt;code&gt;fhinfo&lt;/code&gt; I get an abnormal long response and all following columns are unreadable.
Also the pointer to the tuple which resides before the corrupt one (23963062,5) works fine.&lt;/p&gt;
&lt;p&gt;Then I tried to read all the tuples in the page.
The page no. is the 23963062 and the digit after the comma is the tuple.
I found out that there are dozens of tuples with the same type of curruption and also one which complains about
&lt;code&gt;ERROR:  duplicate key value violates unique constraint &amp;quot;file_pkey&amp;quot;&lt;/code&gt;.
Reading data from other pages was possible.
Maybe we have to accept that this whole page is lost&amp;hellip;&lt;/p&gt;
&lt;h3 id=&#34;tracking-down-the-bad-pages-on-disk&#34;&gt;Tracking down the bad pages on disk&lt;/h3&gt;
&lt;p&gt;Now I really was on new territory. I found two guides which describe more or less the same way to zapp out an entire page from a corrupt Postgres DB. &lt;br&gt;
&lt;a href=&#34;https://web.archive.org/web/20210625115146/https://www.endpoint.com/blog/2010/06/01/tracking-down-database-corruption-with&#34;&gt;https://www.endpoint.com/blog/2010/06/01/tracking-down-database-corruption-with&lt;/a&gt; &lt;br&gt;
&lt;a href=&#34;https://web.archive.org/web/20160429111804/http://www.postgresql.org/message-id/1184245756.24101.178.camel@coppola.muc.ecircle.de&#34;&gt;https://www.postgresql.org/message-id/1184245756.24101.178.camel@coppola.muc.ecircle.de&lt;/a&gt; &lt;br&gt;
Respect for these howtos, and thaks a lot for sharing!&lt;/p&gt;
&lt;p&gt;First it must be clarified in which file the corrupt page resides.
Therefore we need to get the OID of the database, the RELFILENODE of the table and the blocksize to calculate the offset:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;bareos_catalog&lt;span style=&#34;color:#f92672&#34;&gt;=#&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;select&lt;/span&gt; oid &lt;span style=&#34;color:#66d9ef&#34;&gt;from&lt;/span&gt; pg_database &lt;span style=&#34;color:#66d9ef&#34;&gt;where&lt;/span&gt; datname &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;bareos_catalog&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  oid
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;-------
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;16387&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;row&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;bareos_catalog&lt;span style=&#34;color:#f92672&#34;&gt;=#&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;select&lt;/span&gt; relfilenode &lt;span style=&#34;color:#66d9ef&#34;&gt;from&lt;/span&gt; pg_class &lt;span style=&#34;color:#66d9ef&#34;&gt;where&lt;/span&gt; relname &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;file&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; relfilenode
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;-------------
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;       &lt;span style=&#34;color:#ae81ff&#34;&gt;16402&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;row&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;postgres&lt;span style=&#34;color:#f92672&#34;&gt;=#&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;SELECT&lt;/span&gt; current_setting(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;block_size&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; current_setting
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;-----------------
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;8192&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;row&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;With this information the file can be located under &lt;code&gt;/var/lib/postgresql/9.6/main/base/16387/16402&lt;/code&gt;
but since the table is several hundred GB in size, the table is splitted into multiple files.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;root@syseleven.managementbki1.backupng.live.dbm:/var/lib/postgresql/9.6/main# ls -1 base/16387/16402&lt;span style=&#34;color:#ae81ff&#34;&gt;\*&lt;/span&gt; | wc -l
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;359&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;So we still need to figure out in which sub file the page resides. Let&amp;rsquo;s start calculating&lt;/p&gt;
&lt;p&gt;Byte offset of the page is the page no. multiplied with the block size: &lt;code&gt;23963062 * 8192 = 196305403904&lt;/code&gt; &lt;br&gt;
Now each split file of the table has the size of 1 GB (I think I read that somewhere).
So we&amp;rsquo;re search for the no. of the file in which out page offset lies.&lt;br&gt;
That is the page no. multiplied with the block size devided by 1GB: &lt;code&gt;23963062 * 8192 / 1024 / 1024 / 1024 = 182&lt;/code&gt; &lt;br&gt;
The page should be located in the 182nd file; now we&amp;rsquo;re searching for the byte offset inside that file. &lt;br&gt;
To get that I just substracted 182GB from the overall offset: &lt;code&gt;23963062 * 8192 - ( 182 * 1024 * 1024 * 1024 ) = 884391936&lt;/code&gt; &lt;br&gt;
And last but not least we calculate the offset inside that file in page no. instead of bytes by deviding the offset by the block size: &lt;code&gt;884391936 / 8192 = 107958&lt;/code&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;&lt;strong&gt;Now before you do anything of this, make sure your database is stopped an you have a backup.&lt;/strong&gt; Things can still get much worse.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;We can build a dd command with that no. to read out the corrupt page.
If you know what data is to be expected here, you can verify that you&amp;rsquo;re on the correct page. I didn&amp;rsquo;t.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;dd &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;base/16387/16402.182 bs&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;8192&lt;/span&gt; count&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt; skip&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;107958&lt;/span&gt; of&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;test.dd
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;xxd test.dd | head
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;000001d0: &lt;span style=&#34;color:#ae81ff&#34;&gt;0000&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0000&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0700&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;8007&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0080&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;6941&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;2041&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;2049&lt;/span&gt;  ..........iA A I
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;000001e0: &lt;span style=&#34;color:#ae81ff&#34;&gt;4567&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;2041&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;2041&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;2041&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;2041&lt;/span&gt; 202d &lt;span style=&#34;color:#ae81ff&#34;&gt;4220&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;4241&lt;/span&gt;  Eg A A A A -B BA
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;000001f0: &lt;span style=&#34;color:#ae81ff&#34;&gt;4120&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;4220&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;4264&lt;/span&gt; 706d 4b7a &lt;span style=&#34;color:#ae81ff&#34;&gt;2042&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;6347&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;6765&lt;/span&gt;  A B BdpmKz BcGge
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;00000200: &lt;span style=&#34;color:#ae81ff&#34;&gt;6320&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;4264&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;7065&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;7868&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;2041&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;2041&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;2043&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;5954&lt;/span&gt;  c Bdpexh A A CYT
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;00000210: &lt;span style=&#34;color:#ae81ff&#34;&gt;6448&lt;/span&gt; 776a &lt;span style=&#34;color:#ae81ff&#34;&gt;5737&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;6943&lt;/span&gt; 7a4a &lt;span style=&#34;color:#ae81ff&#34;&gt;5870&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;3941&lt;/span&gt; 4f48  dHwjW7iCzJXp9AOH
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;00000220: &lt;span style=&#34;color:#ae81ff&#34;&gt;4448&lt;/span&gt; 4b4b &lt;span style=&#34;color:#ae81ff&#34;&gt;3668&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;3231&lt;/span&gt; 6a70 &lt;span style=&#34;color:#ae81ff&#34;&gt;3558&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;7174&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;4537&lt;/span&gt;  DHKK6h21jp5XqtE7
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;00000230: 5a48 &lt;span style=&#34;color:#ae81ff&#34;&gt;7255&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;5059&lt;/span&gt; 416e &lt;span style=&#34;color:#ae81ff&#34;&gt;6738&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;1363&lt;/span&gt; 6f6e &lt;span style=&#34;color:#ae81ff&#34;&gt;7465&lt;/span&gt;  ZHrUPYAng8.conte
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;00000240: 6e74 &lt;span style=&#34;color:#ae81ff&#34;&gt;7302&lt;/span&gt; a455 ee02 520a c003 &lt;span style=&#34;color:#ae81ff&#34;&gt;0000&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0000&lt;/span&gt;  nts..U..R.......
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;00000250: &lt;span style=&#34;color:#ae81ff&#34;&gt;0000&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0000&lt;/span&gt; 6d01 b5a5 3b00 0b00 &lt;span style=&#34;color:#ae81ff&#34;&gt;0209&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;1800&lt;/span&gt;  ....m...;.......
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;00000260: d8fd 5fcd &lt;span style=&#34;color:#ae81ff&#34;&gt;0100&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0000&lt;/span&gt; ef52 &lt;span style=&#34;color:#ae81ff&#34;&gt;0000&lt;/span&gt; d6e9 &lt;span style=&#34;color:#ae81ff&#34;&gt;0000&lt;/span&gt;  .._......R......
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;...
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;I just overwrote the whole page with zeros.&lt;/p&gt;
&lt;h2 id=&#34;deleting-the-corrupt-pages&#34;&gt;Deleting the corrupt pages&lt;/h2&gt;
&lt;p&gt;Yes that means dataloss but there&amp;rsquo;s no way to repair the corrupt tuples and most probaly the data in the page is already obsolete but could not be reclaimed.&lt;/p&gt;
&lt;p&gt;As mentioned in the other guides: &lt;strong&gt;notice the conv=notrunc to prevent dd from truncating the rest of the file!&lt;/strong&gt;&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;dd if=/dev/zero conv=notrunc of=base/16387/16402.182 bs=8192 count=1 seek=107958
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;I read the page again and saw 8K of zeros in there. Looks good to me.
Time to look confident and starting Postgres again.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;bareos_catalog=# select * from file WHERE ctid=&amp;#39;(23963062,6)&amp;#39;;
 fileid | fileindex | jobid | pathid | deltaseq | markid | fhinfo | fhnode | lstat | md5 | name
--------+-----------+-------+--------+----------+--------+--------+--------+-------+-----+------
(0 rows)
bareos_catalog=# VACUUM VERBOSE file;
INFO:  vacuuming &amp;#34;public.file&amp;#34;
WARNING:  relation &amp;#34;file&amp;#34; page 23963062 is uninitialized --- fixing
INFO:  scanned index &amp;#34;file_pkey&amp;#34; to remove 178956713 row versions
DETAIL:  CPU 36.52s/189.18u sec elapsed 324.00 sec
....
INFO:  &amp;#34;file&amp;#34;: found 863859297 removable, 21859469 nonremovable row versions in 25139106 out of 46748205 pages
DETAIL:  0 dead row versions cannot be removed yet.
There were 287140903 unused item pointers.
Skipped 0 pages due to buffer pins.
1 page is entirely empty.
...
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;Success!&lt;/strong&gt;  No error when reading the page.
And the VACUUM recognized it as uninitialized.
It was possible to remove a few hundred GBs of data from that database afterwards which was sleeping there due to the fact that VACUUM wasn&amp;rsquo;t working correctly.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Building Arch Linux packages under Ubuntu</title>
      <link>https://blog.domainmess.org/post/arch_buildhost_on_ubuntu/</link>
      <pubDate>Mon, 28 Dec 2020 17:22:02 +0100</pubDate>
      <guid>https://blog.domainmess.org/post/arch_buildhost_on_ubuntu/</guid>
      <description>A few times I had the need to build Arch Linux AUR packages which took a long time on my notebook. I had access to some faster hosts but they were all running Ubuntu (16.04 and later). To keep this in mind I write down how to create a Arch Linux build chroot inside an Ubuntu host.
Bootstrapping Arch Linux First we need to get the Arch Linux base filesystem and extract it to a directory.&lt;p&gt;A few times I had the need to build Arch Linux AUR packages which took a long time on my notebook.
I had access to some faster hosts but they were all running Ubuntu (16.04 and later).
To keep this in mind I write down how to create a Arch Linux build chroot inside an Ubuntu host.&lt;/p&gt;
&lt;h3 id=&#34;bootstrapping-arch-linux&#34;&gt;Bootstrapping Arch Linux&lt;/h3&gt;
&lt;p&gt;First we need to get the Arch Linux base filesystem and extract it to a directory.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;cd /var/lib/machines/
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;wget http://mirrors.dotsrc.org/archlinux/iso/2020.12.01/archlinux-bootstrap-2020.12.01-x86_64.tar.gz
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;btrfs subvolume create archlinux-builder
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;tar -zxvf archlinux-bootstrap-2020.12.01-x86_64.tar.gz 
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;mv root.x86_64/* archlinux-builder
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;rmdir root.x86_64
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Afterwards we can configure the DNS settings and chroot to it&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;cd archlinux-builder
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;cp /etc/resolv.conf etc
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;bin/arch-chroot .
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Finally we can configure pacman inside the chroot and install/build software under a separate user&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# select a mirror&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;vim /etc/pacman.d/mirrorlist
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;vim /etc/pacman.conf
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;pacman-key --init
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;pacman-key --refresh-keys
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;pacman -Syu
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;pacman -S --needed base-devel git
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;pacman -S --needed git base-devel
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;git clone https://aur.archlinux.org/yay.git
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;useradd builder
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;echo &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;builder  ALL=(ALL) NOPASSWD:ALL&amp;#34;&lt;/span&gt; | sudo tee /etc/sudoers.d/builder
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;chown builder: -R yay
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;cd yay
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;su builder
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;makepkg -si
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Now we can build Arch Linux AUR packages inside that chroot with makepkg or yay. &lt;br&gt;
I usually save the freshly configured state of such a chroot with&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# either with BTRFS&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;btrfs subvolume snapshot archlinux-builder archlinux-builder-fresh
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# or with systemds machinectl&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;machinectl export-tar archlinux-builder archlinux-builder-fresh.tar
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;links&#34;&gt;Links&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://wiki.archlinux.org/title/Install_Arch_Linux_from_existing_Linux#From_a_host_running_another_Linux_distribution&#34;&gt;Install Arch Linux from existing Linux (Arch Linux wiki)&lt;/a&gt;&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Lichtverschmutzer</title>
      <link>https://blog.domainmess.org/post/lichtverschutzer/</link>
      <pubDate>Wed, 02 Dec 2020 11:30:08 +0100</pubDate>
      <guid>https://blog.domainmess.org/post/lichtverschutzer/</guid>
      <description>We disassembled a large equipment cabinet in our storehouse to use its space and I got a lot of pneumatic gear out of it. Since I don&amp;rsquo;t have any kind of compressed air systems at home I did what I do most: I used it to build a desk lamp. I removed all the filter stuff from the chassis to conduct a USB cable through and screwed a IKEA LED light arm on top.&lt;p&gt;We disassembled a large equipment cabinet in our storehouse to use its space and I got a lot of pneumatic gear out of it. Since I don&amp;rsquo;t have any kind of compressed air systems at home
I did what I do most: I used it to build a desk lamp.
I removed all the filter stuff from the chassis to conduct a USB cable through and screwed a IKEA LED light arm on top.
Voilà another post soviet futuristic light source.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://blog.domainmess.org/pictures/lichtverschmutzer/lamp_off_side.jpg&#34;&gt;&lt;img src=&#34;https://blog.domainmess.org/pictures/lichtverschmutzer/lamp_off_side_small.jpg#floatleft&#34; width=29% &gt;&lt;/a&gt;
&lt;a href=&#34;https://blog.domainmess.org/pictures/lichtverschmutzer/lamp_on.jpg&#34;&gt;&lt;img src=&#34;https://blog.domainmess.org/pictures/lichtverschmutzer/lamp_on_small.jpg#floatleft&#34; width=29% &gt;&lt;/a&gt;
&lt;a href=&#34;https://blog.domainmess.org/pictures/lichtverschmutzer/barometer.jpg&#34;&gt;&lt;img src=&#34;https://blog.domainmess.org/pictures/lichtverschmutzer/barometer_small.jpg#floatleft&#34; width=29% &gt;&lt;/a&gt;&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Lichtverschmutzer Enterprise Edition</title>
      <link>https://blog.domainmess.org/post/lichtverschutzer_enterprise/</link>
      <pubDate>Sun, 29 Nov 2020 22:30:08 +0100</pubDate>
      <guid>https://blog.domainmess.org/post/lichtverschutzer_enterprise/</guid>
      <description>I had another air filter with a barometer left over. Again I took all the filter things out of it to make room for a cable coming in on one of the intakes and I added the arm of a floor lamp on the top of the filter.
For this one I ordered a 12V warm white 1W LED and put it on a heatsink with thermal glue. The heatsink just fit into the round chassis on the end of the arm and is hold in place by a screw.&lt;p&gt;&lt;a href=&#34;https://blog.domainmess.org/pictures/lichtverschmutzer_enterprise/led.jpg&#34;&gt;&lt;img src=&#34;https://blog.domainmess.org/pictures/lichtverschmutzer_enterprise/led_small.jpg#floatleft&#34; width=10% &gt;&lt;/a&gt;
I had another air filter with a barometer left over.
Again I took all the filter things out of it to make room for a cable coming in on one of the
intakes and I added the arm of a floor lamp on the top of the filter.&lt;/p&gt;
&lt;p&gt;For this one I ordered a 12V warm white 1W LED and put it on a heatsink with thermal glue.
The heatsink just fit into the round chassis on the end of the arm and is hold in place by a screw.
This one has a external power supply.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://blog.domainmess.org/pictures/lichtverschmutzer_enterprise/lamp_on.jpg&#34;&gt;&lt;img src=&#34;https://blog.domainmess.org/pictures/lichtverschmutzer_enterprise/lamp_on_small.jpg#floatleft&#34; width=29% &gt;&lt;/a&gt;
&lt;a href=&#34;https://blog.domainmess.org/pictures/lichtverschmutzer_enterprise/lamp_off.jpg&#34;&gt;&lt;img src=&#34;https://blog.domainmess.org/pictures/lichtverschmutzer_enterprise/lamp_off_small.jpg#floatleft&#34; width=29% &gt;&lt;/a&gt;
&lt;a href=&#34;https://blog.domainmess.org/pictures/lichtverschmutzer_enterprise/barometer.jpg&#34;&gt;&lt;img src=&#34;https://blog.domainmess.org/pictures/lichtverschmutzer_enterprise/barometer_small.jpg#floatleft&#34; width=29% &gt;&lt;/a&gt;&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>DNS Resolution on Laptops</title>
      <link>https://blog.domainmess.org/post/dns_resolution/</link>
      <pubDate>Thu, 26 Nov 2020 19:49:40 +0100</pubDate>
      <guid>https://blog.domainmess.org/post/dns_resolution/</guid>
      <description>The story of struggeling with the always wrong DNS server on my laptop and the behaviour of systemd-resolved with static and dhcp announced DNS servers.&lt;p&gt;This topic bugged me for a very long time!
In Germany there a quite a lot ISPs which censor specific content either due law enforcements or to assert their own interests.
Since years I wanted to use DNS Servers which I chose myself so I nailed down my laptop to a fixed DNS server.&lt;br&gt;
However every time when I wanted to use a network which either use DNS spoofing for
a captive portal or which has some local domains I had to manually change the DNS settings on my laptop.
That can get quite annoying also because afterwards I always have to revert the change. &lt;br&gt;
So for quite a time researching about local DNS resolution settings was my hobby during longer train rides
and I figured out the following requirements for my setup:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;use a static DNS server (always)&lt;/li&gt;
&lt;li&gt;fallback to the DNS server announced via DHCP&lt;/li&gt;
&lt;li&gt;&lt;em&gt;optional: fallback to other DNS servers&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;possibility to add local DNS entries&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;After playing around with &lt;code&gt;dnsmasq&lt;/code&gt; and having a rather bad time with &lt;code&gt;resolveconf&lt;/code&gt; I ended up using &lt;code&gt;systemd-resolved&lt;/code&gt; in combination with &lt;code&gt;systemd-networkd&lt;/code&gt; which I already used for my &lt;a href=&#34;https://blog.domainmess.org/post/wpa_supplicant.conf/&#34;&gt;Simple wireless setup&lt;/a&gt;&lt;/p&gt;
&lt;h1 id=&#34;basic-configuration&#34;&gt;Basic configuration&lt;/h1&gt;
&lt;p&gt;So I just stepped through the requirements listed above and configured them into &lt;code&gt;/etc/systemd/resolved.conf&lt;/code&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[&lt;span style=&#34;color:#ae81ff&#34;&gt;Resolve]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;DNS=46.246.46.246&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;FallbackDNS=1.1.1.1 8.8.4.4 8.8.8.8 2001:4860:4860::8888 2001:4860:4860::8844&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;Cache=yes&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The server set as &lt;code&gt;DNS=&lt;/code&gt; is my static DNS server which I trust in this example. The &lt;code&gt;FallbackDNS=&lt;/code&gt; servers are other public DNS servers which probably have better availability.
systemd-resolved automatically gets the DNS servers announced via DHCP from systemd-networkd and uses them as normal DNS servers.&lt;br&gt;
Pinging google.se will result in the following DNS requests:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-tcpdump&#34; data-lang=&#34;tcpdump&#34;&gt;01:48:38.670451 IP 10.123.9.194.43043 &amp;gt; 46.246.46.246.53: 25460+% [1au] A? google.se. (61)
01:48:38.670742 IP 10.123.9.194.50049 &amp;gt; 46.246.46.246.53: 25901+% [1au] AAAA? google.se. (61)
01:48:38.670904 IP 10.123.9.194.59267 &amp;gt; 10.123.9.1.53: 35751+% [1au] A? google.se. (38)
01:48:38.671034 IP 10.123.9.194.49471 &amp;gt; 10.123.9.1.53: 57442+% [1au] AAAA? google.se. (38)
01:48:38.708778 IP 10.123.9.1.53 &amp;gt; 10.123.9.194.59267: 35751 1/0/1 A 216.58.207.67 (54)
01:48:38.708779 IP 10.123.9.1.53 &amp;gt; 10.123.9.194.49471: 57442 1/0/1 AAAA 2a00:1450:4001:81e::2003 (66)
01:48:38.762701 IP 46.246.46.246.53 &amp;gt; 10.123.9.194.43043: 25460 1/0/1 A 172.217.20.35 (54)
01:48:38.762702 IP 46.246.46.246.53 &amp;gt; 10.123.9.194.50049: 25901 1/0/1 AAAA 2a00:1450:400f:80a::2003 (66)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This leads to the result that both servers are asked at the same time and
therefore the local DNS server is faster in nearly every case and
effectively disables the preferred non local DNS server.&lt;/p&gt;
&lt;p&gt;On the other hand, if there would be a fixed order in which the DNS servers would be queried then it can happened that the external is queried first about a local domain, like a captive portal.
It will then respond with NXDOMAIN and no other DNS servers will be queried.&lt;br&gt;
See &lt;a href=&#34;https://github.com/systemd/systemd/issues/5755#issuecomment-297005909&#34;&gt;https://github.com/systemd/systemd/issues/5755#issuecomment-297005909&lt;/a&gt; for details.&lt;/p&gt;
&lt;p&gt;Maybe in the end it&amp;rsquo;s the best way to disable the DHCP DNS servers in the systemd-network config file for interfaces with changing connections and then reenable them for specific domains.
Of course that would mean to maintain lists of domains which should be resolved by DHCP announced DNS servers, which I do not want to do. But it is probably the best way if you don&amp;rsquo;t trust them!&lt;/p&gt;
&lt;p&gt;In the end the setup still misses the requirements from the beginning but it&amp;rsquo;s the best I&amp;rsquo;ve got so far and it&amp;rsquo;s still quite simple.&lt;/p&gt;
&lt;p&gt;Links:&lt;br&gt;
&lt;a href=&#34;https://www.freedesktop.org/software/systemd/man/resolved.conf.html#Options&#34;&gt;https://www.freedesktop.org/software/systemd/man/resolved.conf.html#Options&lt;/a&gt; &lt;br&gt;
&lt;a href=&#34;https://www.freedesktop.org/software/systemd/man/systemd.network.html#%5BNetwork%5D%20Section%20Options&#34;&gt;https://www.freedesktop.org/software/systemd/man/systemd.network.html#%5BNetwork%5D%20Section%20Options&lt;/a&gt; &lt;br&gt;
&lt;a href=&#34;https://www.freedesktop.org/software/systemd/man/systemd.network.html#Domains=&#34;&gt;https://www.freedesktop.org/software/systemd/man/systemd.network.html#Domains=&lt;/a&gt;&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Lichtmaschine</title>
      <link>https://blog.domainmess.org/post/lichtmaschine/</link>
      <pubDate>Tue, 03 Nov 2020 20:12:56 +0100</pubDate>
      <guid>https://blog.domainmess.org/post/lichtmaschine/</guid>
      <description>A desk lamp made from an old alternator and an industrial shade&lt;p&gt;After my wisdom teeth have been drawed I had two times two weeks of being at home, half the day on painkillers *_*&lt;/p&gt;
&lt;p&gt;First I wanted to build a light for bringing my balcony plants through the winter so I decided to go through my metal and electronic trash in search for something I could use to make a full lamp out of an old industrial lampshade from the DDR (&lt;a href=&#34;https://en.wikipedia.org/wiki/East_Germany&#34;&gt;East Germany&lt;/a&gt;)&lt;/p&gt;
&lt;p&gt;I found some wood for a base and an old alternator from my car which seemed suitable for being a weight and revolving stand at the same time.
As arms I used solid copper cables with ~1cm diameter.&lt;/p&gt;
&lt;p&gt;I fixed the alternator into the wooden base with epoxy and screwed the cables on top of it. The strands were scrambled bent into the alternator and a 12V DC power supply attached to two of them so that they can power the LED stripes inside the shade.&lt;/p&gt;
&lt;p&gt;I called this one &amp;ldquo;Lichtmaschine&amp;rdquo; as this is the German word for the alternator in a car but literally it means &amp;rsquo;light machine&amp;rsquo;. It ended up being my desk lamp.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://blog.domainmess.org/pictures/lichtmaschine/01_base.jpg&#34;&gt;&lt;img src=&#34;https://blog.domainmess.org/pictures/lichtmaschine/01_base_small.jpg#floatcenter&#34; width=29% &gt;&lt;/a&gt;
&lt;a href=&#34;https://blog.domainmess.org/pictures/lichtmaschine/02_shade.jpg&#34;&gt;&lt;img src=&#34;https://blog.domainmess.org/pictures/lichtmaschine/02_shade_small.jpg#floatcenter&#34; width=10% &gt;&lt;/a&gt;
&lt;a href=&#34;https://blog.domainmess.org/pictures/lichtmaschine/03_arms.jpg&#34;&gt;&lt;img src=&#34;https://blog.domainmess.org/pictures/lichtmaschine/03_arms_small.jpg#floatcenter&#34; width=10% &gt;&lt;/a&gt;
&lt;a href=&#34;https://blog.domainmess.org/pictures/lichtmaschine/04_arms_shade.jpg&#34;&gt;&lt;img src=&#34;https://blog.domainmess.org/pictures/lichtmaschine/04_arms_shade_small.jpg#floatcenter&#34; width=10% &gt;&lt;/a&gt;
&lt;a href=&#34;https://blog.domainmess.org/pictures/lichtmaschine/05_alternator.jpg&#34;&gt;&lt;img src=&#34;https://blog.domainmess.org/pictures/lichtmaschine/05_alternator_small.jpg#floatcenter&#34; width=29% &gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://blog.domainmess.org/pictures/lichtmaschine/06_finish.jpg&#34;&gt;&lt;img src=&#34;https://blog.domainmess.org/pictures/lichtmaschine/06_finish.jpg#floatcenter&#34; width=100%&gt;&lt;/a&gt;&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Host and container name resolution with LLMNR</title>
      <link>https://blog.domainmess.org/post/nspawn-llmnr/</link>
      <pubDate>Thu, 02 Jul 2020 18:53:02 +0200</pubDate>
      <guid>https://blog.domainmess.org/post/nspawn-llmnr/</guid>
      <description>LLMNR is a rather easy yet unknown protocol to resolve hostnames on a local link. On most modern Linux systems it can be used with systemd-resolved. This article describes the basic components and configs&lt;p&gt;When I use containers, I don&amp;rsquo;t want to fumble around with IPs. Especially not when they change each time a container is created from scratch.
Of course Docker has its way to &lt;a href=&#34;https://docs.docker.com/config/containers/container-networking/#dns-services&#34;&gt;address this problem&lt;/a&gt; but since I use &lt;a href=&#34;https://www.freedesktop.org/software/systemd/man/systemd-nspawn.html&#34;&gt;systemd-nspawn&lt;/a&gt; most of the time I wanted to figure out how to do that on my own.&lt;/p&gt;
&lt;h2 id=&#34;name-resolution-on-linux&#34;&gt;Name resolution on linux&lt;/h2&gt;
&lt;p&gt;On a Linux system there are multiple ways how a program can resolve a name to an address. The most common way is to ask the glibc system library via a call of &lt;a href=&#34;https://man7.org/linux/man-pages/man3/getaddrinfo.3.html&#34;&gt;getaddrinfo()&lt;/a&gt; for example. Another one would be to ask another program via D-Bus interface. &lt;br&gt;
But that library can do way more than just do a usual DNS request. It is backed by a system called Name Service Switch (&lt;a href=&#34;https://man7.org/linux/man-pages/man5/nss.5.html&#34;&gt;NSS&lt;/a&gt;) which performs lookups for many function calls.&lt;br&gt;
NSS has a lot of modular libraries which can be enabled and ordered in &lt;code&gt;/etc/nswitch.conf&lt;/code&gt;.
For example &lt;code&gt;libnss-mdns&lt;/code&gt; would allow doing DNS lookups via a multicastDNS resolver like avahi, &lt;code&gt;libnss-resolve&lt;/code&gt; allows the usage of systemd-resolved and finally &lt;code&gt;libnss-mymachines&lt;/code&gt; can lookup local container names.&lt;br&gt;
So with that we could easily reach our containers by name. But we also want the container to be able to lookup its host.&lt;/p&gt;
&lt;p&gt;While researching I stumbled upon a technology called Link-Local Multicast Name Resolution (&lt;a href=&#34;https://tools.ietf.org/html/rfc4795&#34;&gt;LLMNR&lt;/a&gt;). It allows the Multicast Name Resolution bound to a link and is therefore ideal for this usecase. Its available in systemd-resolved by default and ca be enabled via&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#/etc/systemd/resolved.conf&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[&lt;span style=&#34;color:#ae81ff&#34;&gt;Resolve]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;LLMNR=yes&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;If you cannot or want not use systemd-resolved have a look at &lt;a href=&#34;https://github.com/tklauser/llmnrd&#34;&gt;llmnrd&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;configuration&#34;&gt;Configuration&lt;/h2&gt;
&lt;h3 id=&#34;setting-up-the-host&#34;&gt;Setting up the host&lt;/h3&gt;
&lt;p&gt;On the host system we want to directly lookup local containers. Therefore we install the &lt;code&gt;libnss-mymachines&lt;/code&gt; packages and enabled it in the configuration:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#/etc/nsswitch.conf&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;hosts&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;files mymachines dns&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;It does not matter what is in your &lt;code&gt;/etc/resolv.conf&lt;/code&gt; because NSS will first try to lookup a name in files like &lt;code&gt;/etc/hosts&lt;/code&gt; then asks the mymachines library.&lt;br&gt;
Of course you can reorder the libraries but be aware that each library delays all DNS request which it cannot resolve.&lt;/p&gt;
&lt;h3 id=&#34;setting-up-the-container&#34;&gt;Setting up the container&lt;/h3&gt;
&lt;p&gt;Inside the container we want to configure LLMNR instead but it&amp;rsquo;s the same principle: First install the &lt;code&gt;libnss-resolve&lt;/code&gt; package and then activate it:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#/etc/nsswitch.conf&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;hosts&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;files resolve dns &lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Ensure that systemd-resolved is configured correctly and is up and runnning:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#/etc/systemd/resolved.conf&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[&lt;span style=&#34;color:#ae81ff&#34;&gt;Resolve]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;LLMNR=yes&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;Cache=no&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;MulticastDNS=no&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;sudo systemctl enabe --now systemd-resolved
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;You have to enable LLMNR on the host and inside the container&lt;/strong&gt; so get them both speak to each other. I also disabled multicast DNS and caching inside the container so that they cannot interfere with LLMNR which now discovers automatically any configured addresses of your container, both IPv4 and IPv6 including link-local addressing:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;root@host ~# machinectl
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;MACHINE           CLASS     SERVICE        OS     VERSION ADDRESSES       
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;test-container    container systemd-nspawn ubuntu 18.04   192.168.240.200…
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt; machines listed.
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;root@host ~# ping -c &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt; test-container
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;PING test-container&lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;test-container &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;fe80::2473:aeff:fe41:3bcb%ve-test-container&lt;span style=&#34;color:#f92672&#34;&gt;))&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;56&lt;/span&gt; data bytes
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;64&lt;/span&gt; bytes from test-container &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;fe80::2473:aeff:fe41:3bcb%ve-test-container&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;: icmp_seq&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt; ttl&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;64&lt;/span&gt; time&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;0.054 ms
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;--- test-container ping statistics ---
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt; packets transmitted, &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt; received, 0% packet loss, time 0ms
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;rtt min/avg/max/mdev &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; 0.054/0.054/0.054/0.000 ms
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;root@host ~# ping -4 -c &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt; test-container
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;PING test-container &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;169.254.179.218&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt; 56&lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;84&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt; bytes of data.
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;64&lt;/span&gt; bytes from test-container &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;169.254.179.218&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;: icmp_seq&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt; ttl&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;64&lt;/span&gt; time&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;0.085 ms
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;--- test-container ping statistics ---
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt; packets transmitted, &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt; received, 0% packet loss, time 0ms
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;rtt min/avg/max/mdev &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; 0.085/0.085/0.085/0.000 ms
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Even if the LLMNR configuration is broken and not working, the host can still resolve the containers names via mymachines lib:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;root@host ~# systemctl stop systemd-resolved.service 
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;root@host ~# ping -c &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt; test-container
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;PING test-container&lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;fe80::2473:aeff:fe41:3bcb%ve-test-container&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;56&lt;/span&gt; data bytes
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;64&lt;/span&gt; bytes from fe80::2473:aeff:fe41:3bcb%ve-test-container: icmp_seq&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt; ttl&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;64&lt;/span&gt; time&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;0.058 ms
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;--- test-container ping statistics ---
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt; packets transmitted, &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt; received, 0% packet loss, time 0ms
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;rtt min/avg/max/mdev &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; 0.058/0.058/0.058/0.000 ms
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;alternative-setup&#34;&gt;Alternative setup&lt;/h2&gt;
&lt;p&gt;Instead of using &lt;code&gt;libnss-mymachines&lt;/code&gt; and &lt;code&gt;libnss-resolve&lt;/code&gt; you can also set up systemd-resolved to use LLMNR and the point to it in you /etc/resolv.conf:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;#/etc/resovl.conf
nameserver 127.0.0.53
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The systemd-resolved is listening on that address by default and can resolve your requests for you via different protocols including LLMNR if its enabled in the config:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;root@host ~# systemctl start systemd-resolved.service
root@host ~# echo &amp;#34;nameserver 127.0.0.53&amp;#34; &amp;gt; /etc/resolv.conf
root@host ~# ping -c 1 test-container
PING test-container (169.254.179.218) 56(84) bytes of data.
64 bytes from test-container (169.254.179.218): icmp_seq=1 ttl=64 time=0.068 ms
--- test-container ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.068/0.068/0.068/0.000 ms
&lt;/code&gt;&lt;/pre&gt;</description>
    </item>
    
    <item>
      <title>FOSDEM 2020</title>
      <link>https://blog.domainmess.org/post/fosdem_2020/</link>
      <pubDate>Sun, 09 Feb 2020 23:57:18 +0100</pubDate>
      <guid>https://blog.domainmess.org/post/fosdem_2020/</guid>
      <description>This year I visited Brussels with some colleagues to attend the FOSDEM Conference for the first time https://fosdem.org
Conference and Organisation The conference itself takes place in the Université Liberal Brussels (ULB) which is a campus of more or less rotten buildings and can be visited without a ticket or fee. There are many many talks over two days which average on about 30 minutes and are held in 29 different rooms parallel.&lt;p&gt;This year I visited Brussels with some colleagues to attend the FOSDEM Conference for the first time
&lt;a href=&#34;https://fosdem.org&#34;&gt;https://fosdem.org&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&#34;conference-and-organisation&#34;&gt;Conference and Organisation&lt;/h2&gt;
&lt;p&gt;The conference itself takes place in the Université Liberal Brussels (ULB) which is a campus of more or less rotten buildings and can be visited without a ticket or fee.
There are many many talks over two days which average on about 30 minutes and are held in 29 different rooms parallel. The rooms are rather small and the conference is very frequented, so sometimes its not possible to get in the room in time, but there is a video stream+recording of every talk and the wifi can handle them pretty well. Also there are a lot of friendly helping organizers and volunteers so when one is awake enough to handle the crowds the conference becomes quite easy.
Hint: Even if the Belgium beer is very good that does not mean you can drink more of it without consequences.&lt;/p&gt;
&lt;h2 id=&#34;linux-and-memory-management&#34;&gt;Linux and Memory Management&lt;/h2&gt;
&lt;p&gt;The Linux memory management is a topic which comes up very often, especially when dividing physical memory between different virtual machines. Also there is a lot of superficial knowledge about it and people often speak of memory as if it would be a few bytes which are either full or empty and that&amp;rsquo;s it.
Well the reality is way more complex and I am struggling for a few years now to get a better understanding of how one can measure, analyze and configure memory usage in Linux. So I was quite happy to see the talk of Chris Down who told us about the tools and techniques of Facebook to thrash memory.
&lt;a href=&#34;https://fosdem.org/2020/schedule/event/containers_memory_management/&#34;&gt;https://fosdem.org/2020/schedule/event/containers_memory_management/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Strongly related is the question &amp;ldquo;To swap or not swap&amp;rdquo; which I have discussed multiple times in the last few years, always with different outcomes. Chris wrote a long article about SWAP and why it is still needed in modern systems.
&lt;a href=&#34;https://chrisdown.name/2018/01/02/in-defence-of-swap.html&#34;&gt;https://chrisdown.name/2018/01/02/in-defence-of-swap.html&lt;/a&gt; / bit.ly/whyswap&lt;/p&gt;
&lt;p&gt;So I have to say that I still have to learn a lot about memory management and I am absolutely sure that this knowledge can become crucial in analysing and preventing incidents.
Every time I dive into this topic I realise that memory is not a barrel which just fills up but a managed system with complex and interdependent rules. This system must be managed as such and therefore understood to keep it working correctly. When OOM killer runs and destroys a process, the cause is already lost and the system was mismanaged.&lt;/p&gt;
&lt;h2 id=&#34;virtualization-and-systemd&#34;&gt;Virtualization and Systemd&lt;/h2&gt;
&lt;p&gt;So we come to the question how we can ensure that a computer system managed correctly and the resources are shared wisely. I think we can all agree that the time when a Linux system was a kernel which then uses a lot of shell scripts to startup manually configured applications are over.
A modern system consists of a lot of management and surveillance software and of course it is virtually divided into pieces which do different kinds of work.
In this context I want to highlight systemd one more time because there is still a lot to learn about it for me. Systemd is capable of doing a lot of stuff way more than just replacing the init V system.
Nowadays with systemd a linux system is aware that it is not just an OS running on a computer but it has a hierarchy of subsystems (Devices, Processes, Services, Namespaces, Containers).
In contrast to docker and vagrant, systemd comes with many modern linux distributions and is highly integrated into the OS and an operator can use it as a modular system to jail applications, let them depend on hardware changes or manage their resources (see also Linux and Memory Management)
I attended a talk about systemds security features and its ability to abstract the kernel and limit resources and syscalls:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://fosdem.org/2020/schedule/event/ussftbasd/&#34;&gt;https://fosdem.org/2020/schedule/event/ussftbasd/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/keszybz/systemd-security-talk/blob/master/jesie%C5%84-systemd-security.pdf&#34;&gt;https://github.com/keszybz/systemd-security-talk/blob/master/jesie%C5%84-systemd-security.pdf&lt;/a&gt;
They also recommends this documentation&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://systemd.io/&#34;&gt;https://systemd.io/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I think of systemd as a well designed and well documented structure of a modern Linux which finally enables us to configure our system from the kernel up to the application with modules which know about each other, all in the same style. And eventually we can get rid of wiggly, half-baked solutions like VirtuozzoLinux or proprietary appliance systems.&lt;/p&gt;
&lt;h2 id=&#34;micro--and-unikernels&#34;&gt;Micro- and Unikernels&lt;/h2&gt;
&lt;p&gt;On Sunday at FOSDEM I wanted to look out to some future stuff (beyond Kubernetes).
In the autumn of 2018 I attended the MirageOS hack retreat in Marrakesh, Marocco (mirageos.io).
Because I already thought of Kubernetes and docker as over complex bloated feature creep software I really enjoined the radical approach of compiling just the code which is needed into a unikernel for smaller footprint, speed and better security. Think of it as a statically linked application which comes as a bootable image.
I was happy to see a half a day Micro-/Unikernel track at FOSDEM and realized that there are a lot of projects in this area.
I especially want to emphasize the two following talks&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://fosdem.org/2020/schedule/event/uk_hipperos/&#34;&gt;https://fosdem.org/2020/schedule/event/uk_hipperos/&lt;/a&gt; - a realtime, multicore, hierarchical kernel for embedded systems&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://fosdem.org/2020/schedule/event/uk_unicraft/&#34;&gt;https://fosdem.org/2020/schedule/event/uk_unicraft/&lt;/a&gt; - a toolchain to build various unikernels&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Unicraft is something which definitely looks like a good starting point to get in touch with Unikernels because it supports a lot of common tools and languages (mirageOS was kinda hard for me because it is written in OCaml).
Anyhow, I believe that Unikernels will be the next big thing after Kubernetes and other cloud approaches become too complicated to be maintainable anymore and because of the million lines of code they waste with abstraction too slow and too inflexible.&lt;/p&gt;
&lt;p&gt;So in the end this FOSDEM visited encouraged me in my strategy to&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;learn more about kernel code to understand why a computer behaves the way it does&lt;/li&gt;
&lt;li&gt;using Linux systems as a cluster of software which is aware of and integrable into each other&lt;/li&gt;
&lt;li&gt;building large scale applications with the smallest (carbon) footprint possible&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Clouds are made out of tiny water drops not fuel tanks.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Installing Ubuntu 18.04 from Archlinux on APU Board</title>
      <link>https://blog.domainmess.org/post/arch_ubuntu_install/</link>
      <pubDate>Thu, 26 Dec 2019 15:04:42 +0100</pubDate>
      <guid>https://blog.domainmess.org/post/arch_ubuntu_install/</guid>
      <description>I decided to use my second APU2c4 board as my new Nextcloud/Mailserver. Since this thing should be reliable, especially reboot safe because I have to travel a few hundred kilometers to get hardware access in the datacenter, I decided to use Ubuntu as OS. Sadly the Ubuntu standard installer ISO is not configured to be used only via serial console. Although there are some hints in the web how to change this I never got and Ubuntu USB stick working for installation so I decided to install Ubuntu without its installer (don&amp;rsquo;t like it anyway) from another livelinux.&lt;p&gt;I decided to use my second APU2c4 board as my new &lt;a href=&#34;../mailserver_setup&#34;&gt;Nextcloud/Mailserver&lt;/a&gt;.
Since this thing should be reliable, especially reboot safe because I have to travel a few hundred kilometers to get hardware
access in the datacenter, I decided to use Ubuntu as OS.
Sadly the Ubuntu standard installer ISO is not configured to be used only via serial console.
Although there are some &lt;a href=&#34;https://trick77.com/installing-ubuntu-server-16-04-pc-engines-apu-apu2/&#34;&gt;hints&lt;/a&gt;
in the web how to change this I never got and Ubuntu USB stick working for installation
so I decided to install Ubuntu without its installer (don&amp;rsquo;t like it anyway) from another livelinux.&lt;/p&gt;
&lt;h1 id=&#34;boot-archlinux&#34;&gt;Boot Archlinux&lt;/h1&gt;
&lt;p&gt;To get started a Linux USB stick which can start a live system.
In this example &lt;a href=&#34;https://www.archlinux.org/download/&#34;&gt;Arch Linux&lt;/a&gt; is used,
&lt;a href=&#34;https://wiki.debian.org/DebianReleases&#34;&gt;Debian&lt;/a&gt; should work as well. &lt;br&gt;
If the stick is plugged into the APU Board and the serial cable is connected one can use minicom to start the OS&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://blog.domainmess.org/pictures//arch_install_ubuntu/115200.jpg&#34;&gt;&lt;img src=&#34;https://blog.domainmess.org/pictures/arch_install_ubuntu/115200.jpg&#34; width=&#34;398&#34; height=&#34;283&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# connect via serial to the APU&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;sudo minicom -D /dev/ttyUSB0
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Then select a baudrate of &lt;code&gt;38400&lt;/code&gt; to use the Archlinux bootloader. You can do that in a running minicom with &lt;code&gt;Ctrl+a p d&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://blog.domainmess.org/pictures/arch_install_ubuntu/minicom.png&#34;&gt;&lt;img src=&#34;https://blog.domainmess.org/pictures/arch_install_ubuntu/minicom.png&#34; width=&#34;398&#34; height=&#34;283&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Afterward select &amp;ldquo;Boot Archlinux&amp;rdquo; and press Tab to edit the bootloader line and append &lt;code&gt;console=ttyS0,115200&lt;/code&gt;.
Sure you can use every baudrate you want, I use 115200 whenever possible because in the end you use that
serial line more than expected and you&amp;rsquo;re happy if things don&amp;rsquo;t take that much time.&lt;/p&gt;
&lt;h1 id=&#34;partitioning&#34;&gt;Partitioning&lt;/h1&gt;
&lt;p&gt;Once the livesystem is started we can layout our desired partitions. I use parted for this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# example&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;root@archiso:~# parted
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;GNU Parted 3.2
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Using /dev/sdX
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Welcome to GNU Parted! Type &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;help&amp;#39;&lt;/span&gt; to view a list of commands.
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;parted&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;select&lt;/span&gt; /dev/sdX
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Using /dev/sdX
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;parted&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# create a partion table&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;parted&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt; mktable msdos
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# create a partion&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;parted&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt; mkpart primary btrfs 0% 100%
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;parted&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt; print
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Model: ATA SATA SSD &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;scsi&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Disk /dev/sda: 16.0GB
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Sector size &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;logical/physical&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;: 512B/512B
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Partition Table: msdos
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Disk Flags: 
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Number  Start   End     Size    Type     File system  Flags
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;      1049kB  16.0GB  16.0GB  primary  btrfs
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;I tried another layout before with GPT partition table and a extra partition for /boot and another one
for swap but I always ended up with a corrupt /boot filesystem after I installed the OS so
I decided to use just on Btrfs and do everything else in there.&lt;/p&gt;
&lt;p&gt;Afterwards we need to create a filesystem, parted doesn&amp;rsquo;t do that for us even it might be implied. Just use &lt;code&gt;mkfs.btrfs /dev/sdX1&lt;/code&gt;  and mount it with &lt;code&gt;mount /dev/sda1 /mnt&lt;/code&gt;&lt;/p&gt;
&lt;h1 id=&#34;install-ubuntu&#34;&gt;Install Ubuntu&lt;/h1&gt;
&lt;p&gt;To install Ubuntu we need debootstrap, a tool to generate chroots and basic system files.
So ensure you got a working internet connection and install it&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# install debootstrap&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;pacman -Sy debootstrap
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# use it to generate a ubuntu bionic filesystem in /mnt&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;debootstrap --components&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;main,universe --include ssh,vim,systemd,linux-generic,grub2-common,grub-pc,btrfs-progs --arch&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;amd64 bionic /mnt http://de.archive.ubuntu.com/ubuntu
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# chroot to that directory&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;arch-chroot /mnt
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;You are now inside your future ubuntu installation! You can start to configure it as you wish. There is to say that I had to add some PATHs:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;root@archiso:~# ls
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;-bash: ls: command not found
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;root@archiso:~# PATH&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;$PATH:/sbin:/bin
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;root@archiso:~# ls /
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;bin   etc         initrd.img.old  media  proc  sbin      sys  var
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;boot  home        lib             mnt    root  srv       tmp  vmlinuz
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;dev   initrd.img  lib64           opt    run   swapfile  usr  vmlinuz.old
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This only occurred when I chrooted from Arch to Ubuntu and wasn&amp;rsquo;t a problem in the final installation of Ubuntu.&lt;/p&gt;
&lt;h1 id=&#34;configure-ubuntu&#34;&gt;Configure Ubuntu&lt;/h1&gt;
&lt;p&gt;I decided to only do some very basic config in this session because the host will be configured once the Ubuntu can boot by itself.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# configure timezone&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;dpkg-reconfigure tzdata
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# configure locales, sometimes apt need them&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;localedef -i en_US -c -f UTF-8 en_US.UTF-8
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# set a root password&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;passwd
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# (or) add a username&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;useradd foobar
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;passwd foobar
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# set a hostname, otherwise your ubuntu will get used to the name archiso :-)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;hostname
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;vim /etc/hosts
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;apt install btrfs-progs
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;btrfs filesystem label / system
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;You need to generate a fstab file manually. I recommend using the UUIDs instead of /dev/sdX which can be obtained with &lt;code&gt;lsblk --output name,uuid,type,mountpoint,label&lt;/code&gt; or a btrfs label if used. In the end save a file like this to /etc/fstab:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# device-spec               mount-point     fs-type      options                       dump pass
/dev/disk/by-label/system   /               btrfs        rw,relatime,nofail,subvol=/,  0    0
&lt;/code&gt;&lt;/pre&gt;&lt;h1 id=&#34;configure-grub&#34;&gt;Configure GRUB&lt;/h1&gt;
&lt;p&gt;Even a basic ubuntu system now exists on the APU, there is still no boot process defined. We install the GRUB Bootloader on our disk by running&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;grub-install /dev/sdX
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;and ensure that &lt;code&gt;/boot/grub/i386-pc/btrfs.mod&lt;/code&gt; exists. Also have a lookout for &lt;code&gt;vmlinuz&lt;/code&gt; and &lt;code&gt;initrd.img&lt;/code&gt; in /boot. If somethings missing ensure that &lt;code&gt;linux-image-generic&lt;/code&gt; and &lt;code&gt;grub-pc-bin&lt;/code&gt; are installed correctly&lt;/p&gt;
&lt;p&gt;If your /boot folder looks good edit &lt;code&gt;/etc/default/grub&lt;/code&gt; so that your system also uses the serial console&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# disable the quiet boot&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;GRUB_CMDLINE_LINUX_DEFAULT&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# tell the linux kernel to use the serial for console output&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;GRUB_CMDLINE_LINUX&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;console=ttyS0,115200 acpi=off&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# tell grub to use the serial&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;GRUB_TERMINAL&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;serial
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;GRUB_SERIAL_COMMAND&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;serial --unit=0 --speed=115200&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;and run &lt;code&gt;update-grub&lt;/code&gt; to update GRUBs config files.&lt;/p&gt;
&lt;p&gt;Now your are ready to reboot into your new installed Ubuntu system.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Simple Mailserver Setup</title>
      <link>https://blog.domainmess.org/post/mailserver_setup/</link>
      <pubDate>Thu, 24 Oct 2019 17:02:35 +0200</pubDate>
      <guid>https://blog.domainmess.org/post/mailserver_setup/</guid>
      <description>Preamble This is a classic one. I run my own mailserver since I&amp;rsquo;m legally allowed to rent rootservers and twice a decade this stuff had to be rebuilt somehow. I ran a setup with postfix + dbmail + spamassasin for a long time but since dbmail is completly dead and it&amp;rsquo;s a hassle to get the share libraries straight on anything newer that Ubuntu 14.04 I must switch to something more convenient and better supported.&lt;h1 id=&#34;preamble&#34;&gt;Preamble&lt;/h1&gt;
&lt;p&gt;This is a classic one. I run my own mailserver since I&amp;rsquo;m legally allowed to rent rootservers and twice a decade this stuff had to be rebuilt somehow.
I ran a setup with postfix + dbmail + spamassasin for a long time but since dbmail is completly dead and it&amp;rsquo;s a hassle to get the share libraries straight on anything newer that Ubuntu 14.04 I must switch to something more convenient and better supported.&lt;/p&gt;
&lt;p&gt;For the new mailserver I wanted to change a few things in the software stack and setup organisation. First I decided to build it following these principles:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;keep it simple&lt;/strong&gt; Mailservers are complex enough&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;config management&lt;/strong&gt; For the whole setup. no more &amp;lsquo;oh shit where is this special config tweak&amp;rsquo;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;reduce overhead&lt;/strong&gt; No special additions like admin webinterface/containerization etc. which have to be maintained&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Then I thought about the technical specs. The mailserver must support the following features:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;smtp+imap+sieve&lt;/strong&gt; Basic feature to use email.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;webinterface&lt;/strong&gt; For all situation on the run&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;password change&lt;/strong&gt; Users must be able to change their password without an admin&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Eventually I came up with the following decisions&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;postfix+dovecot+btrfs&lt;/strong&gt; Stable software, no database just a filesystem&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;no spamfilter&lt;/strong&gt; Since I receive less than 2 spam mails per month with a decent configured mailserver&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Ansible+git&lt;/strong&gt; Use Ansible for config management and setup and git to store the Ansible stuff&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;nextcloud+rainloop&lt;/strong&gt; A already running nextcloud will be used with Rainloop Plugin&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I then decided to use dovecot as a dbmail replacement as it is well maintained and well-hung. So lets get started!&lt;/p&gt;
&lt;h1 id=&#34;setup&#34;&gt;Setup&lt;/h1&gt;
&lt;p&gt;As soon as we have set the MX record for our domain to our mailserver we should ensure that we can receive mails there. Thats postfix&amp;rsquo; job and it has a whole lot of configs. I found a good &lt;a href=&#34;https://thomas-leister.de/mailserver-unter-ubuntu-16.04/&#34;&gt;tutorial&lt;/a&gt; and reduced it for my purposes. The whole config with Ansible&amp;quot; automation can be found &lt;a href=&#34;#&#34;&gt;here&lt;/a&gt; but let us go throught the most important stuff.&lt;/p&gt;
&lt;h2 id=&#34;postfix&#34;&gt;Postfix&lt;/h2&gt;
&lt;p&gt;First the virtual user and domain setup:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# /etc/postfix/main.cf
virtual_transport = lmtp:unix:private/dovecot-lmtp
virtual_mailbox_domains = domain.tld another.tld
virtual_mailbox_maps = texthash:/etc/postfix/accounts
local_recipient_maps = $virtual_mailbox_maps
virtual_alias_maps = texthash:/etc/postfix/aliases
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Mails for virtual mailboxes should be transferred via a unix socket to dovecot using the LMTP protocol. The domains which postfix should feel responsible for are configured via Ansible&amp;quot; directly into the main.cf cause they are just a few.&lt;br&gt;
The addresses/accounts for which postfix should accept mail are written by Ansible&amp;quot; to &lt;code&gt;/etc/postfix/accounts&lt;/code&gt; and their aliases added to &lt;code&gt;/etc/postfix/aliases&lt;/code&gt;. I use &lt;code&gt;texthash&lt;/code&gt; as fileformat although its slower but for a few entrys that should not matter at all and so I don&amp;rsquo;t have to run &lt;code&gt;postmap&lt;/code&gt; everytime they change. Keep it simple.The account and alias file look like:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# /etc/postfix/accounts
example@domain.tld  stub
eg@another.tld  stub
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The second column of the file is not used and the &amp;lsquo;stub&amp;rsquo; is just there to keep the file format. So it&amp;rsquo;s basically a list of accountnames. The same list will later be nessesary for dovecot acoount lookups but Ansible&amp;quot; just pastes the this for every server in its format, so no additional work needs to be done.\&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# /etc/postfix/aliases
# aliases for example@domain.tld
@domain.tld example@domain.tld
# aliases for eg@another.tld
edgaer_the_pimp@another.tld eg@another.tld
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;There is an catch all alias for *@domain.tld to the account of &lt;a href=&#34;mailto:example@domain.tld&#34;&gt;example@domain.tld&lt;/a&gt; and a second address for the account &lt;a href=&#34;mailto:eg@another.tld&#34;&gt;eg@another.tld&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Then there is the whole security stuff. That is the crucial part of the postfix config. Here we decide whether to block a lot of spam even without parsen the message or accidentally create an open relay.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# /etc/postfix/main.cf
disable_vrfy_command = yes
smtpd_helo_required = yes
smtpd_data_restrictions = reject_unauth_pipelining
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We don&amp;rsquo;t want spammer to be able to lookup the catch all config using the &lt;code&gt;VRFY&lt;/code&gt; command so we just disable it. &lt;br&gt;
Also we require a civilized greeting and force clients to a use SMTP without shortcuts.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# /etc/postfix/main.cf
smtpd_client_restrictions =
  permit_mynetworks,
  reject_unknown_client_hostname,
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now we come to the restriction of the various SMTP commands. We always allow our local network like localhost (&lt;a href=&#34;foo.bar&#34;&gt;permit_mynetworks&lt;/a&gt;) and reject clients with broken DNS&amp;lt;-&amp;gt;reverse DNS (&lt;a href=&#34;http://www.postfix.org/postconf.5.html#reject_unknown_client_hostname&#34;&gt;reject_unknown_client_hostname&lt;/a&gt;)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# /etc/postfix/main.cf
smtpd_helo_restrictions =
  permit_mynetworks,
  reject_invalid_helo_hostname,
  reject_non_fqdn_helo_hostname,
  reject_unknown_helo_hostname,
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We also want the remote client to give a valid and resolveable FQDN in the &lt;code&gt;HELO&lt;/code&gt;. With the DNS based filters postfix drops 500-600 Connections per month with log messages like this:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# mail.log
/var/log/mail.log.4.gz:Oct  4 05:55:39 novaprospekt postfix/smtpd[21911]: warning: hostname 26.189.237.221.broad.cd.sc.dynamic.163data.com.cn does not resolve to address 221.237.189.26: Name or service not known
/var/log/mail.log.4.gz:Oct  6 00:02:03 novaprospekt postfix/smtpd[32514]: warning: hostname nl1.nlkoddos.com does not resolve to address 93.174.92.223: Name or service not known
/var/log/mail.log.4.gz:Oct  6 00:30:53 novaprospekt postfix/smtpd[485]: warning: hostname mail4.sailof.com does not resolve to address 104.250.108.101
/var/log/mail.log.4.gz:Oct  6 03:41:56 novaprospekt postfix/smtpd[4261]: warning: hostname hosting-by.directwebhost.org does not resolve to address 45.227.253.131: Name or service not known
&lt;/code&gt;&lt;/pre&gt;&lt;pre&gt;&lt;code&gt;# /etc/postfix/main.cf
smtpd_sender_restrictions =
        permit_mynetworks,
        permit_sasl_authenticated,
        reject_non_fqdn_sender,
        check_sender_access texthash:/etc/postfix/check_sender_domain
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In the sender address restriction we additionally allow connections which have authenticated via username &amp;amp; password and for everyone else we add another filter&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# /etc/postfix/check_sender_domain
domain.tld       REJECT You&#39;re not one of us!
another.tld      REJECT You&#39;re not one of us!
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That rejects every connection from a remote host which tries to send mail with one of our own domains as sender.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# /etc/postfix/main.cf
smtpd_recipient_restrictions =
        permit_mynetworks,
        permit_sasl_authenticated,
        reject_unauth_destination
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Finally we only accept mails for domains we defined in our config (&lt;a href=&#34;http://www.postfix.org/postconf.5.html#reject_unauth_destination&#34;&gt;reject_unauth_destination&lt;/a&gt;). That prevents an open relay.&lt;/p&gt;
&lt;p&gt;Another trick from the tutorial mentioned above is to create seperate rules for Mail client (like Webinterface or Thunderbird) and use them only on submission port 587.
They are very simple&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# /etc/postfix/main.cf
# Restrictions for MUAs (used by submission)
mua_relay_restrictions =
  permit_sasl_authenticated,
  reject
mua_sender_restrictions =
  permit_sasl_authenticated,
  reject
mua_client_restrictions =
  permit_sasl_authenticated,
  reject
mua_recipient_restrictions=
  permit_sasl_authenticated,
  reject
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;but need an extra config snippet in the master.cf&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# /etc/postfix/master.cf
submission inet  n       -       n       -       -       smtpd
  -o smtpd_tls_security_level=encrypt
  -o smtpd_sasl_auth_enable=yes
  -o smtpd_sasl_type=dovecot
  -o smtpd_sasl_path=private/auth
  -o smtpd_sasl_security_options=noanonymous
  -o smtpd_sasl_local_domain=$myhostname
  -o smtpd_client_restrictions=$mua_client_restrictions
  -o smtpd_sender_restrictions=$mua_sender_restrictions
  -o smtpd_relay_restrictions=$mua_relay_restrictions
  -o smtpd_recipient_restrictions=$mua_recipient_restrictions
  -o smtpd_helo_required=no
  -o smtpd_helo_restrictions=
  -o cleanup_service_name=submission-header-cleanup
# remove specific headers for privacy reasons
submission-header-cleanup unix n - n    -       0       cleanup
    -o header_checks=regexp:/etc/postfix/submission_header_cleanup
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here we can also see the setting for the authentication. Postfix connects to a socket which dovecot provieds so that we don&amp;rsquo;t need to configure the authentication in postfix.&lt;/p&gt;
&lt;p&gt;The last important feature in the postfix config is the removal of a few client headers that is added by some MUAs. Especially the IP of the client must not be leaked in my understanding of privacy.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# /etc/postfix/submission_header_cleanup
/^Received:/            IGNORE
/^X-Originating-IP:/    IGNORE
/^X-Mailer:/            IGNORE
/^User-Agent:/          IGNORE
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;dovecot&#34;&gt;Dovecot&lt;/h2&gt;
&lt;p&gt;Afterwards we want to hand over the mail to dovecot to store it in the appropriate acoount and make it available via IMAP for clients. The dovecot config is pretty much straight forward and the whole, commented config can be found &lt;a href=&#34;#&#34;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# /etc/dovecot/dovecot.conf
service auth {
    ### Auth socket für Postfix
    unix_listener /var/spool/postfix/private/auth {
        mode = 0660
        user = postfix
        group = postfix
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here is the socket on which postfix can check the user credentials.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# /etc/dovecot/dovecot.conf
userdb {
    driver = static
    args = /etc/dovecot/userdb
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And thats the user account list, very similar to the one which is used by postfix.&lt;/p&gt;
&lt;p&gt;One interesting solution I&amp;rsquo;m slightly proud of is the user password handling. I wanted that users are able to change their password without any administrative action. Back in the days I wrote a roundcube plugin to do this directly in the dbmail MySQL database but without both dbmail and roundcube a new solution has to be found.
I decided just to reuse their nextcloud account information and wrote a small SQL for that:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# /etc/dovecot/nextcloud_passwd_sql.conf
driver = mysql
connect = host=localhost dbname=nextcloud user=nextcloud-dovecot password=supersecret port=3306
password_query = SELECT REPLACE( password, &#39;2|&#39;, &#39;{ARGON2I}&#39;) password FROM oc_users WHERE uid_lower=REGEXP_REPLACE(&#39;%u&#39;, &#39;@.*&#39;, &#39;&#39;);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The query replaces the nextcloud specific hash prefix with the one dovecot uses and search for a nextcloud username
which matches the local-part of the account email address in dovecot.
The corresponding user table from nextcloud looks like:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# mysql&amp;gt; select * from nextcloud.oc_users;
+---------+-------------+----------------------------------------------------------------------------------------------------+-----------+
| uid     | displayname | password                                                                                           | uid_lower |
+---------+-------------+----------------------------------------------------------------------------------------------------+-----------+
| Example | NULL        | 2|$argon2i$v=19$m=32768,t=4,p=1$oS3RHai8LRX8gqOMCX095w$eFEEHBaVOh56whmB6hJgggHeVydrJpKMOi7T2hj5vfI | example   |
| eg      | NULL        | 2|$argon2i$v=19$m=32768,t=4,p=1$seluAwz5IZJskkOrFlevNw$KEim1FMtlLqIFb20Co1d/bK+7xj23irip9/GLiXPNpY | eg        |
+---------+-------------+----------------------------------------------------------------------------------------------------+-----------+
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;and the dovecot userdb file which is provided via Ansible&amp;quot; looks like:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# /etc/dovecot/userdb
example@domain.tld:::::::
eg@another.tld:::::::
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The final tidbit was to use the Rainloop IMAP Webinterface, installed as a nextcloud plugin, with autologin.
The benefit of using Rainloop as a Nextcloud plugin is that no extra Vhost configuration is nessesary,
updates come automatically via Nextcloud plugin management, all contacts stored in Nextcloud are automatically
available in Rainloop and last but no least,
if the user files the email address in the Nextcloud account the Rainloop webinterface logs in automatically. &lt;br&gt;
Well at least it will when this Pull Request is merged :-P &lt;a href=&#34;https://github.com/pierre-alain-b/rainloop-nextcloud/pull/111&#34;&gt;https://github.com/pierre-alain-b/rainloop-nextcloud/pull/111&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://blog.domainmess.org/pictures/mailserver_setup/user_email.png&#34;&gt;&lt;img src=&#34;https://blog.domainmess.org/pictures/mailserver_setup/user_email.png#floatleft&#34;&gt;&lt;/a&gt;
&lt;a href=&#34;https://blog.domainmess.org/pictures/mailserver_setup/autologin.png&#34;&gt;&lt;img src=&#34;https://blog.domainmess.org/pictures/mailserver_setup/autologin.png#floatcenter&#34; width=&#34;398&#34; height=&#34;283&#34;&gt;&lt;/a&gt;
&lt;a href=&#34;https://blog.domainmess.org/pictures/mailserver_setup/webinterface.png&#34;&gt;&lt;img src=&#34;https://blog.domainmess.org/pictures/mailserver_setup/webinterface.png#floatnone&#34; width=&#34;398&#34; height=&#34;283&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&#34;update&#34;&gt;Update&lt;/h2&gt;
&lt;p&gt;A friend of mine was forced to use outlook which though the following error:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;Jun 12 22:50:29 dovecot: imap-login: Error: Diffie-Hellman key exchange requested, but no DH parameters provided. Set ssh_dh=&amp;lt;/path/to/dh.pem
Jun 12 22:50:29 dovecot: imap-login: Disconnected (no auth attempts in 0 secs): user=&amp;lt;&amp;gt;, rip=92.XX.YY.ZZ, lip=185.XX.YY.ZZ, TLS handshaking: SSL_accept() failed: error:141EC044:SSL routines:tls_construct_server_key_exchange:internal error, session=&amp;lt;EWRFXXXXXXXXXXXXX&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;the Diffie Hellman Key file was missing. I created it with &lt;code&gt;openssl dhparam 4096 &amp;gt; /etc/dovecot/dh.pem&lt;/code&gt;, took like half an hour.\
Also don&amp;rsquo;t get confused about the &amp;ldquo;ssh_dh&amp;rdquo; it&amp;rsquo;s a typo and &lt;a href=&#34;https://github.com/dovecot/core/commit/79f6fd2e5ebce8e64cee9dbbd7b5941ad236d5f2&#34;&gt;fixed&lt;/a&gt; in the meantime&lt;/p&gt;
&lt;h2 id=&#34;reference&#34;&gt;Reference:&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;https://web.archive.org/web/20191029132311/https://thomas-leister.de/en/mailserver-debian-stretch/&#34;&gt;https://thomas-leister.de/en/mailserver-debian-stretch/ on archive.org&lt;/a&gt;&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Hyperconverged Garden</title>
      <link>https://blog.domainmess.org/post/bladecenter_fan/</link>
      <pubDate>Wed, 29 May 2019 21:31:27 +0200</pubDate>
      <guid>https://blog.domainmess.org/post/bladecenter_fan/</guid>
      <description>&amp;ldquo;I&amp;rsquo;m a huge fan&amp;rdquo; With this words on it this totally broken Bladecenter fan was lying for something like a year in our office. Well actually I&amp;rsquo;m not a fan of Bladecenters at all so I decided to make something useful out of this&lt;p&gt;&lt;strong&gt;&amp;ldquo;I&amp;rsquo;m a huge fan&amp;rdquo;&lt;/strong&gt; With this words on it this totally broken Bladecenter fan was lying for something like a year in our office.
Well actually I&amp;rsquo;m not a fan of Bladecenters at all so I decided to make something useful out of this&lt;/p&gt;
&lt;p&gt;
  &lt;img src=&#34;https://blog.domainmess.org/pictures/bladecenter_fan/fan.jpg&#34;&gt;

&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Dell Latitude 2nd HDD slot</title>
      <link>https://blog.domainmess.org/post/dell_cd_tray/</link>
      <pubDate>Wed, 29 May 2019 20:08:16 +0200</pubDate>
      <guid>https://blog.domainmess.org/post/dell_cd_tray/</guid>
      <description>Once I bought a Lenovo Thinkpad Edge, can&amp;rsquo;t remember the exact number, but I selected the small CPU and it was so slow, that I smashed it one day so that the display was broken. What a relief! Afterwards my flatmate gave me a Dell Latitude E4300 which I used approximately from 2014 to 2018 and besides it was also very old I was very happy with it. This thing was unbreakable and a good companion!&lt;p&gt;&lt;a href=&#34;https://blog.domainmess.org/pictures/dell_cd_tray/overview.jpg&#34;&gt;&lt;img src=&#34;https://blog.domainmess.org/pictures/dell_cd_tray/overview_small.jpg#floatleft&#34; width=&#34;250&#34;&gt;&lt;/a&gt;
&lt;a href=&#34;https://blog.domainmess.org/pictures/dell_cd_tray/eject.jpg&#34;&gt;&lt;img src=&#34;https://blog.domainmess.org/pictures/dell_cd_tray/eject_small.jpg#floatright&#34; width=&#34;225&#34; &gt;&lt;/a&gt;
Once I bought a Lenovo Thinkpad Edge, can&amp;rsquo;t remember the exact number, but I selected the small CPU and it was so slow, that I smashed it one day so that the display was broken. What a relief!
Afterwards my flatmate gave me a Dell Latitude E4300 which I used approximately from 2014 to 2018 and besides it was also very old I was very happy with it. This thing was unbreakable and a good companion!&lt;/p&gt;
&lt;p&gt;Cause I didn&amp;rsquo;t had the money to buy big SSDs at that time I had only 120GB SSD in the only SATA slot. But the thing had a DVD tray which I never used so it was very obviously to remove this and replace it with a HDD for slow and cheap storage. But I could afford that either, all I could by was a 1TB 2,5&amp;quot; HDD (7mm) which fit in the slot.
So I decided to build the HDD tray myself.&lt;/p&gt;
&lt;p&gt;I pulled out the DVD tray and removed everything inside and just kept the cover and groundplate. The HDD fit in the hight exactly but the connector was a [https://de.wikipedia.org/wiki/Serial_ATA#Slimline_SATA](SATA Slimline connector) which is quite common for CD/DVD trays. Since buying adapters would have been already way to convenient I tried to build one.&lt;/p&gt;
&lt;p&gt;Because I don&amp;rsquo;t wanted to solder SATA cables and connector I cut out the datapin connector from the Slimline connector from DVD tray and used a SATA extension cable which has a male connector to replace it.
They didn&amp;rsquo;t fit really good so I had to cut them down a bit and fixed them with as much hot glue as possible. Then I always had to fumble the whole thing inside the DVD tray to test if the connector fits. Without seeing anything inside this was a very annoying hour.&lt;/p&gt;
&lt;p&gt;But finally I had a working Slimline connector, soldered powercables to it and glued everything together so that I can connect the harddrive. In comparison to the Slimline connector this was easy even if the SATA cable was very rigid.&lt;/p&gt;
&lt;p&gt;Then I tried the whole thing and voila, the SATA disk spun up and was recognized by the system. Well done, I thought. But &lt;strong&gt;damn&lt;/strong&gt; the SATA cable had to be turned in order to get the connector into the right orientation and it turn out that width of the cable didn&amp;rsquo;t fit hight of the tray&amp;hellip;&lt;/p&gt;
&lt;p&gt;So I pulled i out again and made a cut right in the middle of the cables isolation between the wires pair. Of coarse I practised this before with another SATA cable. And finally the whole glue blob fit inside into the tray :-)&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://blog.domainmess.org/pictures/dell_cd_tray/slimline.jpg&#34;&gt;&lt;img src=&#34;https://blog.domainmess.org/pictures/dell_cd_tray/slimline_small.jpg#floatcenter&#34; width=&#34;400&#34;&gt;&lt;/a&gt;
&lt;a href=&#34;https://blog.domainmess.org/pictures/dell_cd_tray/sata.jpg&#34;&gt;&lt;img src=&#34;https://blog.domainmess.org/pictures/dell_cd_tray/sata_small.jpg#floatcenter&#34; width=&#34;400&#34;&gt;&lt;/a&gt;
&lt;a href=&#34;https://blog.domainmess.org/pictures/dell_cd_tray/front.jpg&#34;&gt;&lt;img src=&#34;https://blog.domainmess.org/pictures/dell_cd_tray/front_small.jpg#floatcenter&#34; width=&#34;225&#34;&gt;&lt;/a&gt;&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Homeserver</title>
      <link>https://blog.domainmess.org/post/homeserver/</link>
      <pubDate>Thu, 10 Jan 2019 02:27:38 +0100</pubDate>
      <guid>https://blog.domainmess.org/post/homeserver/</guid>
      <description>Storage server with APU2c4 Board, btrfs and systemd-nspawn&lt;p&gt;Homeserver. Standard. Something with a bit of space for backups, entertainment and for sure to be a seedbox.
I decided to build on based on an apu2c4 board cause they don&amp;rsquo;t need much power and have good reliability.
Sadly the have only one SATA port so another an additional controller is needed to get a RAID running.
Plan was to get at least 8TB netto capacity with 1 parity (like RAID).&lt;/p&gt;
&lt;p&gt;But lets start from the beginning. I got a small 19&amp;quot; office rack in which I wanted to migrate all my home computers.
Sadly it only has around 45cm usable depth cause it most probably was meant for office networks so I needed very short cases.
After a while of searching for something that fits an has 3,5&amp;quot; HDD Trays with a backplane I found &lt;a href=&#34;https://web.archive.org/web/20180829075329/https://www.inter-tech.de/products/ipc/storage-cases/2u-2404s&#34;&gt;this one&lt;/a&gt;
Case was good so far, the backplane and the miniSAS connector still give me a headache, but &lt;a href=&#34;https://blog.domainmess.org/post/satanstuff/&#34;&gt;that&amp;rsquo;s another story&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;However the case fit into the rack and I was able to fumble a small power supply and the APU Board inside with a bit mechanical adaption.
In German one would call it &amp;ldquo;hemdsärmelig&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;Afterwards I got stuck for a few day while I was trying to get the APU Board running without Seabios just with a self compiled Coreboot which directly has GRUB OS as payload.
But that is again, another story.&lt;/p&gt;
&lt;p&gt;So the hardware which is being used is:
&lt;a href=&#34;https://blog.domainmess.org/pictures/homeserver/overview.jpg&#34;&gt;&lt;img src=&#34;https://blog.domainmess.org/pictures/homeserver/overview.jpg#floatright&#34; width=40% &gt;&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;1x Intertech 2U 2404S&lt;/li&gt;
&lt;li&gt;1x &lt;a href=&#34;https://web.archive.orghttps://pcengines.ch/apu2e4.htm&#34;&gt;APU 2c4 Board&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;1x 16GB mSATA SSD&lt;/li&gt;
&lt;li&gt;4x &lt;a href=&#34;&#34;&gt;Seagate Barracuda 4TB ST4000DM004&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Anyway the first intention was to have a working storage server I setup the following software baremetal:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Arch Linux&lt;/li&gt;
&lt;li&gt;16GB SSD with btrfs as systemdisk&lt;/li&gt;
&lt;li&gt;2x 4TB with btrfs mirror&lt;/li&gt;
&lt;li&gt;smartmontools&lt;/li&gt;
&lt;li&gt;samba for fileaccess
&lt;a href=&#34;https://blog.domainmess.org/pictures/homeserver/board_detail.jpg&#34;&gt;&lt;img src=&#34;https://blog.domainmess.org/pictures/homeserver/board_detail.jpg#floatright&#34; width=10% &gt;&lt;/a&gt;
&lt;a href=&#34;https://blog.domainmess.org/pictures/homeserver/psu.jpg&#34;&gt;&lt;img src=&#34;https://blog.domainmess.org/pictures/homeserver/psu.jpg#floatright&#34; width=14% &gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;avahi for local discovery&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;No crypto! Because I still have my last homeserver around which I am not able to access anymore,
but that&amp;rsquo;s a whole different story about which I won&amp;rsquo;t blog.
So for now the thing works.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Update&lt;/strong&gt;
During the process of deciding for HDD to use, I read a lot about &lt;a href=&#34;https://en.wikipedia.org/wiki/Shingled_magnetic_recording&#34;&gt;Shingled Magnetic Recording&lt;/a&gt; (SMR)
and decided &lt;em&gt;not&lt;/em&gt; to buy HDDs working this way, just because I mistrust new technology and the writing performance isn&amp;rsquo;t great.
I decided to buy the Seagate Barracuda disks because they were confusingly cheap and I already wondered at that time why they have so much cache (256MB).
According to &lt;a href=&#34;https://web.archive.org/web/20210308084151/https://blocksandfiles.com/2020/04/15/seagate-2-4-and-8tb-barracuda-and-desktop-hdd-smr/&#34;&gt;this blogpost&lt;/a&gt; the drives actually are using SMR, although it&amp;rsquo;s not mentioned. -10 for Seagate!&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Update&lt;/strong&gt;
In the meantime Seagate has released &lt;a href=&#34;https://web.archive.org/web/20220105160314/https://www.seagate.com/internal-hard-drives/cmr-smr-list/&#34;&gt;a list&lt;/a&gt; of their disks and which technology they are using.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Netjail</title>
      <link>https://blog.domainmess.org/post/netjail/</link>
      <pubDate>Mon, 19 Nov 2018 10:11:23 +0000</pubDate>
      <guid>https://blog.domainmess.org/post/netjail/</guid>
      <description>Introducing netjail Long time ago I felt the need to force a single application to use a specific network connection. Or to be more specific I needed to ensure that my torrent client cannot escape the VPN connection. Today the internet is full of scripts and tools to realize that under any kind of OS and many people just use container virtualization like docker or LXC.
Anyway I started to write a bash script which should be able to cage an application into an extra network namespace in which only a OpenVPN connection is available.&lt;h1 id=&#34;introducing-netjail&#34;&gt;Introducing netjail&lt;/h1&gt;
&lt;p&gt;Long time ago I felt the need to force a single application to use a specific network connection. Or to be more specific I needed to ensure that my torrent client cannot escape the VPN connection. Today the internet is full of scripts and tools to realize that under any kind of OS and many people just use container virtualization like docker or LXC.&lt;br&gt;
Anyway I started to write a bash script which should be able to cage an application into an extra network namespace in which only a OpenVPN connection is available. At first I wrote down a special routing+iptables felony but then I realized, that I just can move an existing TUN Interface to another namespace. It&amp;rsquo;s called &lt;code&gt;netjail&lt;/code&gt; [1] &lt;br&gt;
Here is an example:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;ip netns add netjail
ip link set tun0 netns netjail
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The tricky thing is that it&amp;rsquo;s necessary to reconfigure the IPs and routes after that because the interface looses all its config when it changes the networknamespace. Normally OpenVPN configures the Interfaces it creates automatically but for special cases like this it can call bash scripts and pass them more or less every configuration parameter.
So I just added few lines of bash inspired by [2] which can be called by OpenVPN during initialisation.
They move the interface inside netjails network namespace and configure it there [3].&lt;/p&gt;
&lt;p&gt;Last but not least, the script is able to directly start an application inside this new namespace. This application can only use the OpenVPN connection to talk to the outside. If OpenVPN dies, the application is offline.&lt;/p&gt;
&lt;p&gt;Its also possible to use the script to prepare network namespaces for container usage or to push an OpenVPN interface to an already existing namespace.&lt;/p&gt;
&lt;p&gt;Links: &lt;br&gt;
[1] &lt;a href=&#34;https://github.com/benibr/netjail&#34;&gt;https://github.com/benibr/netjail&lt;/a&gt; &lt;br&gt;
[2] &lt;a href=&#34;http://www.naju.se/articles/openvpn-netns.html&#34;&gt;http://www.naju.se/articles/openvpn-netns.html&lt;/a&gt; &lt;br&gt;
[3] &lt;a href=&#34;https://linux.die.net/man/8/openvpn&#34;&gt;https://linux.die.net/man/8/openvpn&lt;/a&gt; \&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>HP Micro Flowerpot</title>
      <link>https://blog.domainmess.org/post/flowerpot/</link>
      <pubDate>Sat, 15 Sep 2018 20:41:13 +0200</pubDate>
      <guid>https://blog.domainmess.org/post/flowerpot/</guid>
      <description>A friend of mine gave me the case of an old HP Gen8 Microserver, chassis only without the board or power supply. Since the HDD cage has no real backplane but a SAS (SFF-8087) Plug directly attached to the HDD Slots and I didn&amp;rsquo;t have SAS controller at that time, the case wasn&amp;rsquo;t useful for me.
Cause I want to install 19&amp;quot; rackmountable hardware only at home I finally decided to do something useful with that crappy HP case and reused it for the first plant in my new apartment :-)&lt;p&gt;A friend of mine gave me the case of an old HP Gen8 Microserver, chassis only without the board or power supply. Since the HDD cage has no real backplane but a SAS (SFF-8087) Plug directly attached to the HDD Slots and I didn&amp;rsquo;t have SAS controller at that time, the case wasn&amp;rsquo;t useful for me.&lt;/p&gt;
&lt;p&gt;Cause I want to install 19&amp;quot; rackmountable hardware only at home I finally decided to do something useful
with that crappy HP case and reused it for the first plant in my new apartment :-)&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://blog.domainmess.org/pictures/flowerpot/front.jpg&#34;&gt;&lt;img src=&#34;https://blog.domainmess.org/pictures/flowerpot/front.jpg#floatcenter&#34; width=29% &gt;&lt;/a&gt;
&lt;a href=&#34;https://blog.domainmess.org/pictures/flowerpot/open.jpg&#34;&gt;&lt;img src=&#34;https://blog.domainmess.org/pictures/flowerpot/open.jpg#floatcenter&#34; width=29% &gt;&lt;/a&gt;
&lt;a href=&#34;https://blog.domainmess.org/pictures/flowerpot/back.jpg&#34;&gt;&lt;img src=&#34;https://blog.domainmess.org/pictures/flowerpot/back.jpg#floatcenter&#34; width=29% &gt;&lt;/a&gt;&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Notifications under i3</title>
      <link>https://blog.domainmess.org/post/i3_notifications/</link>
      <pubDate>Sat, 05 May 2018 22:12:00 +0200</pubDate>
      <guid>https://blog.domainmess.org/post/i3_notifications/</guid>
      <description>I usually use systemd user services to get some simple tasks done on my workstations like backups of my homefolder or changing my wallpaper any hour. For some of them I want to get some notifications if they succeed or fail and since I don&amp;rsquo;t use some kind of Desktop Environment like GNOME I had to choose the components myself. Right now I glued together X.org, LightDM and i3 windowmanager under ArchLinux and I wanted something that shows me some kind of a noticeable popup and not just a line of text somewhere.&lt;p&gt;I usually use systemd user services to get some simple tasks done on my workstations like backups of my homefolder or changing my wallpaper any hour.
For some of them I want to get some notifications if they succeed or fail and since I don&amp;rsquo;t use some kind of Desktop Environment like GNOME I had to choose the components myself.
Right now I glued together X.org, LightDM and i3 windowmanager under ArchLinux and I wanted something that shows me some kind of a noticeable popup and not just a line of text somewhere. Also a Logo or Picture would be nice to have.&lt;/p&gt;
&lt;p&gt;First I realized that &lt;code&gt;notify-send&lt;/code&gt; is a standard tool to generate notifications from a shell script and pass them to some running daemon which shows the messages.
I quickly looked through the usage text and tried the basic functionality:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt; notify-send --urgency normal --icon wheather-storm &amp;quot;Backup failed&amp;quot; &amp;quot;Could not connect to backup host.&amp;quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The first text is the title, the second the actual message. Sadly nothing happened cause I didn&amp;rsquo;t have any notification daemon ready yet. Therefore I search the &lt;a href=&#34;https://wiki.archlinux.org/index.php/Desktop_notifications#Standalone&#34;&gt;ArchLinux Wiki&lt;/a&gt; and tried a few of the listed ones. My requirements where:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;useable out-of-the-box&lt;/li&gt;
&lt;li&gt;simple to config&lt;/li&gt;
&lt;li&gt;somehow pretty graphical popup&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Finally I decided to use &lt;em&gt;mate-notification-daemon&lt;/em&gt;, a fork of the notification-daemon from the GNOME Project.
It is available on ArchLinux repositories and comes with a small tool (&lt;code&gt;mate-notification-properties&lt;/code&gt;) to configure the
&lt;em&gt;/usr/share/mate-notification-daemon/mate-notification-properties.ui&lt;/em&gt; XML File.
I found a list of the available icons one can use on &lt;a href=&#34;https://specifications.freedesktop.org/icon-naming-spec/icon-naming-spec-latest.html&#34;&gt;freedesktop.org&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;
  &lt;img src=&#34;https://blog.domainmess.org/post/notifications1.png&#34; alt=&#34;Example Notification&#34;&gt;

&lt;/p&gt;
&lt;p&gt;Links:
Mirror of &lt;a href=&#34;https://blog.domainmess.org/freedesktop_org_notification_icons.html&#34;&gt;freedesktop.org/icon-naming-spec/icon-naming-spec-latest.html&lt;/a&gt;&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Simple Wireless Setup</title>
      <link>https://blog.domainmess.org/post/wpa_supplicant.conf/</link>
      <pubDate>Tue, 24 Apr 2018 21:17:57 +0200</pubDate>
      <guid>https://blog.domainmess.org/post/wpa_supplicant.conf/</guid>
      <description>After using Networkmanager and Wicd for a few years each I craved for a less complicated networking setup on my laptop. I did some research and found that nothing out there fits my need so I decided just to use the minimal basic setup.
systemd_networkd I created a simple network file to use systemd to do the DHCP:
[Match] Name=wlan0 [Network] DHCP=yes [DHCP] RouteMetric=10 The Name tells systemd on which interfaces the config should be applied.&lt;p&gt;After using Networkmanager and Wicd for a few years each I craved for a less complicated networking setup on my laptop.
I did some research and found that nothing out there fits my need so I decided just to use the minimal basic setup.&lt;/p&gt;
&lt;h3 id=&#34;systemd_networkd&#34;&gt;systemd_networkd&lt;/h3&gt;
&lt;p&gt;I created a simple network file to use systemd to do the DHCP:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[Match]
Name=wlan0

[Network]
DHCP=yes

[DHCP]
RouteMetric=10
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The &lt;em&gt;Name&lt;/em&gt; tells systemd on which interfaces the config should be applied. &lt;em&gt;wlp*&lt;/em&gt;  would also be valid
The &lt;em&gt;DHCP&lt;/em&gt; Parameter should be self explaining. &lt;em&gt;ipv4&lt;/em&gt; would also be valid.
The &lt;em&gt;RouteMetric&lt;/em&gt; tells systemd that any route announced by the DHCP Server should get this specific metric. I use a lower metric for any routes on my wired interfaces to force traffic to go through the cable if possible.&lt;/p&gt;
&lt;h3 id=&#34;wpa_supplicant&#34;&gt;wpa_supplicant&lt;/h3&gt;
&lt;p&gt;Ofcourse wpa_supplicant is necessary on Linux to use any kind of Wireless network.
I use &lt;a href=&#34;https://aur.archlinux.org/packages/wpa_supplicant_gui/&#34;&gt;wpa_gui&lt;/a&gt; for the lazy hours to create the config for me. Writing/Editing the config manually is still needed sometimes&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=network
update_config=1
ap_scan=1

network={
	ssid=&amp;quot;karlsruhe.freifunk.net&amp;quot;
	key_mgmt=NONE
	auth_alg=OPEN
  #disabled=1
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is as simple as possible. &lt;em&gt;ctrl_interface&lt;/em&gt;  defines the socket on which wpa_ui or something similar can connect to wpa_supplicant
&lt;em&gt;update_config&lt;/em&gt; allows wpa_supplicant to overwrite the configfile if necessary.
&lt;em&gt;ap_scan&lt;/em&gt; tells wpa_supplicant to decide which network to connect to. It would be also possible to let the driver to that (ap_scan=0)&lt;/p&gt;
&lt;p&gt;After a while I found out that wpa_gui creates the network config snippet with the &lt;em&gt;disabled=1&lt;/em&gt; parameter by default. This prevents wpa_supplicant from connecting to the network automatically if while by scanning.
For most networks I disable this parameter manually.&lt;/p&gt;
&lt;h4 id=&#34;useful-links&#34;&gt;Useful Links:&lt;/h4&gt;
&lt;p&gt;&lt;a href=&#34;https://linux.die.net/man/5/wpa_supplicant.conf&#34;&gt;wpa_supplicant.conf (5)&lt;/a&gt;&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Introducing</title>
      <link>https://blog.domainmess.org/post/introducing/</link>
      <pubDate>Mon, 09 Apr 2018 20:56:21 +0200</pubDate>
      <guid>https://blog.domainmess.org/post/introducing/</guid>
      <description>blog.domainmess.org This will be a random collection of stuff I do or should not do or already did. I just felt the need for some form of publication which I can control myself without depending on any kind of company.
This is a static page proudly served with nginx created with hugo and nofancy theme.&lt;h2 id=&#34;blogdomainmessorg&#34;&gt;blog.domainmess.org&lt;/h2&gt;
&lt;img src=&#34;https://blog.domainmess.org/pictures/introducing/introducing1.jpg&#34; width=100%&gt;
&lt;p&gt;This will be a random collection of stuff I do or should not do or already did.
I just felt the need for some form of publication which I can control myself without depending on any kind of company.&lt;br&gt;
This is a static page proudly served with &lt;a href=&#34;http://nginx.org/&#34;&gt;nginx&lt;/a&gt; created with &lt;a href=&#34;https://gohugo.io&#34;&gt;hugo&lt;/a&gt; and &lt;a href=&#34;https://themes.gohugo.io/nofancy/&#34;&gt;nofancy&lt;/a&gt; theme.&lt;/p&gt;
</description>
    </item>
    
  </channel>
</rss>
