Before I proceed to manufacture the PCBs for the home automation I decided to invest in a solder plate and try a very small project: Temperature sensors that consists of a DS18B20 1-wire temperature sensor and a 2-pin SMD push connector.

First step was to make sure that the solder plate is actually grounded properly.

ground check
1 Ohm is acceptable

After that a layman’s temperature calibration run. Comparing the temperature using my multi-meter’s temperature probe and the internally measured value of the solder plate.

temp check
Close enough

The PCBs were designed with eagle and manufactured by AISLER. They look good, were reasonably priced and came with a stencil.

On to solder paste application. The setup consists of a piece of wood with two pieces of PCB with the same thickness as the target PCB and the stencil taped in place after alignment. You can see in the image that the stencil is far from perfectly parallel to the hole line. The effect of slightly offsetting the solder paste will be visible soon.

Solder paste application setup on a wooden board and a dry fit of the parts

Flipped the stencil over and put a drop of solder paste.

solder paste
Before application of the solder paste

Using a metal scraper to apply.

solder paste applied
Solder paste applied.

The above mentioned error is visible, but I hope that it does not cause issues later and the amount of solder paste looks good. Next step is placing the parts.

parts placed
Using tweezers to place the parts

Now let’s heat it up. Since I’m using the solder plate for the first time I did not take enough pictures to capture the whole reflow solder profile. I’ve set the temperatures manually and have waited using a timer. The relatively slow solder plate ensures the ramping is not too fast. The cooling after reaching maximum heat is a little bit slow, but will be improved once I’ve the ventilation in place that is definitely required for larger projects. The fan is already in place, so I’ll have to add an enclosure only.

Solder paste shortly after it started melting

Wait until it’s cooled.

The the solder joints look acceptable

Considering the fact that the connector does not match 100% with the footprint (the 8D process will show what went wrong) the solder joint is acceptable. The temperature sensor looks good to me. (Feedback welcome). After the first one was successful I finished the series by soldering the remaining 2 parts.

mini series
The complete series of 3 parts is finished

PCBs routed and sanded. I did a quick electrical test. With only 2 connections it could easily be done with the multi-meter. So the next step was to integrate the new sensor in the existing Loxone home automation system.

system test
The newly produced sensor is connected to the live system

The sensor was successfully detected and provided a reasonable temperature.

The software displays a reasonable temperature value

In addition I’ve placed one of the sensors outside and it also show values that made sense.

I’ll order more PCBs and run a second batch and after that I’ll be out of excuses for producing the bigger PCBs for my light switches.

Finally, I had the chance to polish the source code a bit for releasability, after having a bunch of smaller improvements sitting in the git tree for quite a while.

Rearrange the effect processing order through drag’n’drop (click for full-size)

Release 4.1.0 brings:

  • Turntable colors to quickly find the right controls/or audio data
  • Effect queues can now be rearranged using drag’n’drop
  • Old icons have been replaced with stock versions
  • Workaround for duplicated events in wrap pointer mode as under some conditions X11 may generate motion events when warping
  • Fix position of loading dialog on startup
  • Miscellaneous clean-ups

As always you can find the sources in the download section; pre-built packages for Ubuntu 20.10 are available in the terminatorX PPA.

I finally got around to looking into why my rsync automation fails with my new Lineage OS 17.1 device. The old instructions worked like charm. Sshd will start, but the shell user will receive a permission denied after successful authentication.

It turns out that sshd is unhappy with the file ownership or modes for /data. Now I didn’t want to mess with those nor did I want to move the ssh directory to another place so I cheated and told sshd to relax by adding:

StrictModes no

to sshd_config. Probably sshd dislikes that /data is owned by system and not shell nor root – allowing the system user to erase the ssh directory. Seems like one security concept is ruining another…

A hogshead

(abbreviated "Hhd", plural "Hhds") is a large cask of liquid (or, less often, of a food commodity). More specifically, it refers to a specified volume, measured in either imperial or US customary measures, primarily applied to alcoholic beverages, such as wine, ale, or cider. — Hogshead – Wikipedia

It must have been in 1999 when a group of four friends (including myself) started to think about buying a whisky cask. A whisky cask full of whisky of course. We agreed to buy the cask from the Springbank distillery in Campbeltown, Scotland, because it was, at that time (and probably still is), one of the few distilleries which were malting their barley themselves as well as performing their own bottling.

Hogshead 2003

Our hogshead in 2003

The cask we bought was a hogshead which in our case meant 242 litres of 100 proof Springbank whisky, distilled in November 2000 (see picture). The hogshead we went with was a Sherry refill cask and our whisky was the second whisky in this Sherry cask (that is what the B stands for in the picture). The price included the whisky and the cask itself and 10 years in Springbank’s warehouse. One important information at this point, which we ignored or which we did not care, is that the whisky in the cask in the warehouse is not yet taxed. Once you want to get the whisky out of the warehouse and bottled it will be taxed. A lot.

Cask Owners Privilege Card

Cask Owners Privilege Card

Now that we owned a whisky cask in Scotland we made plans to visit it (of course). The first visit was in July 2003 from which we still have the first picture of our cask as well as some notes from the stillman.

Stillman notes 2003

Stillman notes 2003

In addition to the visit and the picture we were able to get one sample bottle of our whisky and for the first time we were able to taste it. At that time it still tasted very alcoholic and was not as smooth as it is now. At that time our whisky has been less than three years in its cask and has not had enough time to mature. Having matured less than three years our whisky could not even be called a scotch yet.

First bottles

First bottles (left:2003 right:2007)

Our next visit to the Springbank distillery was in 2007. We did a distillery tour and were also able to visit our cask again. We were also able to get another sample bottle from our whisky.

Springbank 2007 Springbank 2007 Springbank 2007 Springbank 2007 Springbank 2007 Springbank 2007

In 2008 we ordered the first 8 bottles of our whisky and they soon arrived:

2008 8 bottles

2008 8 bottles

In 2010 the whisky had its 10 years to mature in the cask and we started discussions with the distillery to get one part of our whisky bottled. The minimum number of bottles to start the bottling is 120. The remaining whisky should stay in the cask for 5 more years. After selecting a label and how the bottles would be transported to us, 120 bottles of single cask Springbank cask strength arrived at my door in March 2011.

Delivery 2011 Delivery 2011 Delivery 2011 Delivery 2011

After 5 more years in the warehouse we decided to bottle the remaining whisky and in April 2016 156 bottles of our remaining single cask Springbank in cask strength were shipped. After 10 years the whisky had 54.8% vol alcohol and after 15 years it went down to 51.8% vol alcohol.

Delivery 2016 Delivery 2016 Delivery 2016 Delivery 2016

The delivery of the last bottles included the hogshead which is still in front of my house. Standing in the rain in front of my house the original labelling started to appear and it seems to origin from Dublin.

Celebration Cream

No 121
L.G.&Sons Ltd
u 747
CAP. 250 CONT 253
N 267

The whisky we got is really good, especially the bottling after 15 years. Being cask strength means you usually have to add a few drops of water.

Overall it was a really fun experience, especially to how many different people you have to talk to get everything shipped to our place. I am happy that I was asked to join this group in 1999 and want to thank everyone involved.

When I started to include container migration into Podman using CRIU over a year ago I did not really think about SELinux. I was able to checkpoint a running container and I was also able to restore it later I never looked at the process labels of the restored containers. But I really should have.

After my initial implementation of container checkpoint and restore for Podman I started to work on live container migration for Podman in October last year (2018). I opened the corresponding pull request end of January 2019. I immediately started to get SELinux related failures from the CI.

Amongst other SELinux denials the main SELinux related problem was a blocked connectto.

avc: denied { connectto } for pid=23569 comm="top" path=002F6372746F6F6C732D70722D3233363139 scontext=system_u:system_r:container_t:s0:c245,c463 tcontext=unconfined_u:system_r:container_runtime_t:s0-s0:c0.c1023 tclass=unix_stream_socket permissive=0

This is actually a really interesting denial, because it gives away details about how CRIU works. This denial was caused by a container running top (podman run -d alpine top) which I tried to checkpoint.

To understand why a denial like this is reported by top it helps to understand how CRIU works. To be able to access all resources of the process CRIU tries to checkpoint (or dump), CRIU injects parasite code into the process. The parasite code allows CRIU to act from within the process’s address space. Once the parasite is injected and running it connects to the main CRIU process and is ready to receive commands.

The parasite’s attempt to connect to the main CRIU process is exactly the step SELinux is blocking. Looking at the denial it seems that a process top running as system_u:system_r:container_t:s0:c245,c463 is trying to connectto a socket labeled as unconfined_u:system_r:container_runtime_t:s0-s0:c0.c1023, which is indeed suspicious: something running in a container tries to connect to something running on the outside of the container. Knowing that this is CRIU and knowing how CRIU works it is, however, required that the parasite code connects to the main process using connectto.

Fortunately SELinux has the necessary interface to solve this: setsockcreatecon(3). Using setsockcreatecon(3) it is possible to specify the context of newly created sockets. So all we have to do is get the context of the process to checkpoint and tell SELinux to label newly created sockets accordingly (8eb4309). Once understood that was easy. Unfortunately this is also where the whole thing got really complicated.

The CRIU RPM package in Fedora is built without SELinux support, because CRIU’s SELinux support until now was limited and not tested. CRIU’s SELinux support used to be: If the process context does not start with unconfined_ CRIU just refuses to dump the process and exits. Being unaware of SELinux a process restored with CRIU was no longer running with the context it was started but with the context of CRIU during the restore. So if a container was running with a context like system_u:system_r:container_t:s0:c248,c716 during checkpointing it was running with the wrong context after restore: unconfined_u:system_r:container_runtime_t:s0, which is the context of the container runtime and not of the actual container process.

So first I had to fix CRIU’s SELinux handling to be able to use setsockcreatecon(3). Fortunately, once I understood the problem, it was pretty easy to fix CRIU’s SELinux process labeling. Most of the LSM code in CRIU was written by Tycho in 2015 with focus on AppArmor which luckily uses the same interfaces as SELinux. So all I had to do is remove the restrictions on which SELinux context CRIU is willing to operate on and make sure that CRIU stores the information about the process context in its image files 796da06.

Once the next CRIU release with these patches included is available I have to add BuildRequires: libselinux-devel to the RPM to build Fedora’s CRIU package with SELinux support. This, however, means that CRIU users on Fedora might see SELinux errors they have not seen before. CRIU now needs SELinux policies which allow CRIU to change the SELinux context of a running process. For the Podman use case which started all of this there has been the corresponding change in container-selinux to allow container_runtime_t to dyntransition to container domains.

For CRIU use cases outside of containers additional policies have been created which are also used by the new CRIU ZDTM test case selinux00. A new boolean exists which allows CRIU to use “setcon to dyntrans to any process type which is part of domain attribute”. So with setsebool -P unconfined_dyntrans_all 1 it should be possible to use CRIU on Fedora just like before.

After I included all those patches and policies into Podman’s CI almost all checkpoint/restore related tests were successful. Except one test which was testing if it is possible to checkpoint and restore a container with established TCP connections. In this test case a container with Redis is started, a connection to Redis is opened and the container is checkpointed and restored. This was still failing in CI which was interesting as this seemed unrelated to SELinux.

Trying to reproduce the test case locally I actually saw the following SELinux errors during restore:

audit: SELINUX_ERR op=security_bounded_transition seresult=denied oldcontext=unconfined_u:system_r:container_runtime_t:s0 newcontext=system_u:system_r:container_t:s0:c218,c449

This was unusual as it did not look like something that could be fixed with a policy.

The reason my test case for checkpointing and restoring containers with established TCP connections failed was not the fact that it is testing established TCP connections, but the fact that it is a multithreaded process. Looking at the SELinux kernel code I found following comment in security/selinux/hooks.c:

/* Only allow single threaded processes to change context */

This line is unchanged since 2008 so it seemed unlikely that it would be possible to change SELinux in such a way that it would be possible to label each thread separately. My first attempt to solve this was to change the process label with setcon(3) before CRIU forks the first time. This kind of worked but at the same time created lots of SELinux denials (over 50), because during restore CRIU changes itself and the forks it creates into the process it wants to restore. So instead of changing the process label just before forking the first time I switched to setting the process label just before CRIU creates all threads (e86c2e9).

Setting the context just before creating the threads resulted in only two SELinux denials. The first is about CRIU accessing the log file during restore which is not critical and the other denial happens when CRIU tries to influence the PID of the threads it wants to create via /proc/sys/kernel/ns_last_pid. As CRIU is now running in the SELinux context of the to be restored container and to avoid allowing the container to access all files which are labeled as sysctl_kernel_t, Fedora’s selinux-policy contains a patch to label /proc/sys/kernel/ns_last_pid as sysctl_kernel_ns_last_pid_t.

So with the latest CRIU and selinux-policy installed and the following addition to my local SELinux policy (kernel_rw_kernel_ns_lastpid_sysctl(container_domain)) I can now checkpoint and restore a Podman container (even multi-threaded) with the correct SELinux process context after a restore and no further SELinux denials blocking the checkpointing or restoring of the container. There are a few SELinux denials which are mainly related to not being able to write to the log files. Those denials, however, do not interfere with the checkpoint and restoring.

For some time (two or three years) I was aware that CRIU was never verified to work correctly with SELinux but I always ignored it and I should have just fixed it a long time ago. Without the CRIU integration into Podman, however, I would have not been able to test my changes as I was able to do.

I would like to thank Radostin for his feedback and ideas when I was stuck and his overview of the necessary CRIU changes, Dan for his help in adapting the container-selinux package to CRIU’s needs and Lukas for the necessary changes to Fedora’s selinux-policy package to make CRIU work with SELinux on Fedora. All these combined efforts made it possible to have the necessary policies and code changes ready to support container migration with Podman.