<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:base="https://iay.org.uk/">
  <id>tag:iay.org.uk,2003-05-12:/blog</id>
  <title>Technology Stir Fry</title>
  <updated>2024-09-03T11:18:30Z</updated>
  <link rel="alternate" href="/blog/" type="text/html"/>
  <link rel="self" href="https://iay.org.uk/blog/atom.xml" type="application/atom+xml"/>
  <author>
    <name>iay</name>
    <uri>https://iay.org.uk/about</uri>
  </author>
  <entry>
    <id>tag:iay.org.uk,2024-05-28:/blog/2024/05/28/signing-mail-2024/</id>
    <title type="html">Signing Mail, 2024 Edition</title>
    <published>2024-05-28T14:19:55Z</published>
    <updated>2024-05-28T14:19:55Z</updated>
    <link rel="alternate" href="https://iay.org.uk/blog/2024/05/28/signing-mail-2024/" type="text/html"/>
    <content type="html">&lt;p&gt;I have been using &lt;a href="https://en.wikipedia.org/wiki/S/MIME"&gt;S/MIME&lt;/a&gt; to sign e-mail for well over a decade now.
Because certificates don’t last for ever, I need to renew mine
every couple of years. This gives me an opportunity to experience
the current state of that market and of client software.&lt;/p&gt;

&lt;p&gt;This has seldom been a pleasant experience, and it has sometimes
been downright awful (see &lt;a href="/blog/2019/07/29/signing-mail/"&gt;2019&lt;/a&gt;, &lt;a href="/blog/2022/06/16/signing-mail-2022/"&gt;2022&lt;/a&gt;). This iteration wasn’t
great, but there are some small signs of improvement.&lt;/p&gt;

&lt;p&gt;I should make clear a couple of important qualifications which may mean
that my experience isn’t applicable to your situation:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;I’m looking at this from the point of view of an individual
without access to some sort of corporate-level certificate
provision.&lt;/li&gt;
  &lt;li&gt;I no longer even consider the PGP/GPG ecosystem for mail
authentication, although I do still use it for artifact signing.
There are enough systems in between myself and recipients these
days that it is next to impossible to get even clear-signed
text blocks through the system sufficiently unscathed for the
signature to be verifiable. Broken signatures are not useful.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I mentioned &lt;a href="/blog/2022/06/16/signing-mail-2022/"&gt;last time&lt;/a&gt; that the process then depended on the
long-standing capability of certain browsers to create an RSA
keypair and use that in requesting an S/MIME certificate from a
certification authority through the CA’s web site.
This approach caused a large share of the problems in previous years
because collecting the certificate, linking it to the private key in the
browser and then exporting it to other clients was just full of
flakiness, bugs and bad user interface design.&lt;/p&gt;

&lt;p&gt;The browsers that had that ability are, I think, now fully extinct.
The good news is that this means that all those problems went away.
The bad news is that the alteratives aren’t great:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;The option that I suspect most people will use is to allow the
CA’s web site to create your RSA keypair and let you download it
from them. I find it surprising that this is offered without any
mention of the fact that &lt;em&gt;the CA therefore knows your private key.&lt;/em&gt;
In the world of TLS certificates, the key being at any time
out of your sole control would be grounds to revoke
your certificate immediately. Somehow, that rule apparently
doesn’t apply here. Needless to say, I don’t feel that I can
take this route with a straight face.&lt;/li&gt;
  &lt;li&gt;The second option, by analogy with the TLS certificate market,
is for the customer to create their own keypair, construct
an appropriate Certificate Signing Request (&lt;a href="https://en.wikipedia.org/wiki/Certificate_signing_request"&gt;CSR&lt;/a&gt;) and
submit that for signing. This obviously requires more
technical knowledge and is probably something most individuals
looking for S/MIME certificates won’t feel capable of doing.
It is nevertheless the route I took.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Unfortunately, at least on the site of the CA I was working with,
there seemed to be no documentation at all of what an appropriate
CSR should look like. In the end, this is what I did:&lt;/p&gt;

&lt;div class="language-bash highlighter-rouge"&gt;&lt;div class="highlight"&gt;&lt;pre class="highlight"&gt;&lt;code&gt;&lt;span class="nb"&gt;touch &lt;/span&gt;smime.key
&lt;span class="nb"&gt;chmod &lt;/span&gt;600 smime.key
openssl genrsa 3072 &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt;smime.key
openssl req &lt;span class="nt"&gt;-new&lt;/span&gt; &lt;span class="nt"&gt;-config&lt;/span&gt; smime.cnf &lt;span class="nt"&gt;-key&lt;/span&gt; smime.key &lt;span class="nt"&gt;-out&lt;/span&gt; smime.csr
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The critical part of this is &lt;code&gt;smime.cnf&lt;/code&gt;:&lt;/p&gt;

&lt;div class="language-config highlighter-rouge"&gt;&lt;div class="highlight"&gt;&lt;pre class="highlight"&gt;&lt;code&gt;[&lt;span class="n"&gt;req&lt;/span&gt;]
&lt;span class="n"&gt;default_bits&lt;/span&gt; = &lt;span class="m"&gt;3072&lt;/span&gt;
&lt;span class="n"&gt;distinguished_name&lt;/span&gt; = &lt;span class="n"&gt;dn&lt;/span&gt;
&lt;span class="n"&gt;prompt&lt;/span&gt; = &lt;span class="n"&gt;no&lt;/span&gt;

[&lt;span class="n"&gt;dn&lt;/span&gt;]
&lt;span class="n"&gt;C&lt;/span&gt;=&lt;span class="n"&gt;GB&lt;/span&gt;
&lt;span class="n"&gt;ST&lt;/span&gt;=&lt;span class="n"&gt;Scotland&lt;/span&gt;
&lt;span class="n"&gt;L&lt;/span&gt;=&lt;span class="n"&gt;Edinburgh&lt;/span&gt;
&lt;span class="n"&gt;O&lt;/span&gt;=&lt;span class="n"&gt;Ian&lt;/span&gt; &lt;span class="n"&gt;A&lt;/span&gt;. &lt;span class="n"&gt;Young&lt;/span&gt;
&lt;span class="n"&gt;CN&lt;/span&gt;=&lt;span class="n"&gt;ian&lt;/span&gt;@&lt;span class="n"&gt;iay&lt;/span&gt;.&lt;span class="n"&gt;org&lt;/span&gt;.&lt;span class="n"&gt;uk&lt;/span&gt;
&lt;span class="n"&gt;emailAddress&lt;/span&gt;=&lt;span class="n"&gt;ian&lt;/span&gt;@&lt;span class="n"&gt;iay&lt;/span&gt;.&lt;span class="n"&gt;org&lt;/span&gt;.&lt;span class="n"&gt;uk&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;As it turned out, the certificate product I was purchasing discarded all of
the components of the distinguished name other than the &lt;code&gt;emailAddress&lt;/code&gt;,
so that could probably have been simplified.&lt;/p&gt;

&lt;p&gt;Once I uploaded the CSR to the certification authority’s web site, I was
able to download the new certificate in one of two ways:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;I could get a &lt;a href="https://en.wikipedia.org/wiki/PKCS_12"&gt;PKCS#12&lt;/a&gt; file (sometimes called a PFX file, particularly
in Microsoft environments). This would be ideal for configuring client
software, but there’s a catch: &lt;em&gt;this requires you to upload your
private key&lt;/em&gt;. Yes, again, there’s an option that asks you to lose
control of your private key without mentioning that in many
situations this would be an unacceptable security risk. As with
the “easy” option for key generation, I didn’t feel that I could do this.&lt;/li&gt;
  &lt;li&gt;The second option is to have a &lt;a href="https://en.wikipedia.org/wiki/PKCS_7"&gt;PKCS#7&lt;/a&gt; file generated, and that’s
of course what I selected.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A PKCS#7 file is just a bag of certificates (i.e., public data).
The end entity certificate (for &lt;code&gt;ian@iay.org.uk&lt;/code&gt; in this case) is
usually first, followed by the other certificates required to build
a verification chain up to a trust root. This will be a familiar
concept to anyone who has worked with X.509 certificates for transport
layer security, as will the inevitable format conversion dance that
followed on from downloading the file.&lt;/p&gt;

&lt;p&gt;I had expected the download to be either:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;A PEM-encoded PKCS#7 bundle with the usual textual &lt;code&gt;BEGIN&lt;/code&gt;
and &lt;code&gt;END&lt;/code&gt; lines, or&lt;/li&gt;
  &lt;li&gt;A DER-encoded (binary) PKCS#7 bundle.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;What I actually got was a text file containing a single very
long line. You could think of this as the PEM variant with the
header and trailer lines stripped off, or as a Base64-encoded
form of the DER variant. I chose the latter viewpoint and
converted it to something useful like this:&lt;/p&gt;

&lt;div class="language-bash highlighter-rouge"&gt;&lt;div class="highlight"&gt;&lt;pre class="highlight"&gt;&lt;code&gt;&lt;span class="nb"&gt;base64&lt;/span&gt; &lt;span class="nt"&gt;--decode&lt;/span&gt; &amp;lt;smime.p7b &lt;span class="o"&gt;&amp;gt;&lt;/span&gt;certs.der
openssl pkcs7 &lt;span class="nt"&gt;-in&lt;/span&gt; certs.der &lt;span class="nt"&gt;-inform&lt;/span&gt; der &lt;span class="nt"&gt;-print_certs&lt;/span&gt; &lt;span class="nt"&gt;-out&lt;/span&gt; certs.pem
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Now I had a series of certificates in the textual PEM format
in &lt;code&gt;certs.pem&lt;/code&gt;, but to conifgure my mail clients I
needed to further convert that to a PKCS#12 file so that I
could incorporate the private (&lt;em&gt;still&lt;/em&gt; private) key:&lt;/p&gt;

&lt;div class="language-bash highlighter-rouge"&gt;&lt;div class="highlight"&gt;&lt;pre class="highlight"&gt;&lt;code&gt;openssl pkcs12 &lt;span class="nt"&gt;-export&lt;/span&gt; &lt;span class="nt"&gt;-in&lt;/span&gt; certs.pem &lt;span class="nt"&gt;-inkey&lt;/span&gt; smime.key &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-out&lt;/span&gt; smime.p12 &lt;span class="nt"&gt;-chain&lt;/span&gt; &lt;span class="nt"&gt;-untrusted&lt;/span&gt; certs.pem &lt;span class="nt"&gt;-legacy&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The &lt;code&gt;-legacy&lt;/code&gt; option changes the default encryption algorithm
and was necessary to make the resulting PKCS#12 file acceptable
to the Apple mail clients I use.&lt;/p&gt;

&lt;p&gt;Once you have a PKCS#12 file, of course your troubles are over!
I jest, of course: in practice, mail clients hide the configuration
of signing certificates in the weirdest places. For Apple’s
Mail under macOS, for example, you register the certificate
in the separate Keychain Access utility and then hope that
Mail notices when you enable signing in the main application.&lt;/p&gt;

&lt;p&gt;One place things have improved a little since my previous
iteration is in Apple’s mobile operating systems. Under both
iOS and iPadOS, installing a new signing certificate was
a bit of a pain: now, if you can locate your &lt;code&gt;.p12&lt;/code&gt; file
in the Files application, you can just tap it and get
an instruction to install the new “profile” in Settings.&lt;/p&gt;

&lt;p&gt;In conclusion: on one hand, the bad news is that signing
your e-mail is still quite problematic, sufficiently so
that I wouldn’t expect most people to bother even if they
knew it was possible.
On the other hand, some of the old cruft has been stripped
away in the last couple of years, and someone who is
capable of understanding TLS certificates should be
able to apply that knowledge to S/MIME certificates directly,
and that’s &lt;em&gt;good.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;On the &lt;a href="https://en.wikipedia.org/wiki/The_Mote_in_God%27s_Eye#Moties"&gt;gripping hand&lt;/a&gt;, if you go through this process you
get more than one opportunity to commit the cardinal sin of
compromising your private key material by handing it over to
a supplier. This is &lt;em&gt;bad.&lt;/em&gt;&lt;/p&gt;</content>
  </entry>
  <entry>
    <id>tag:iay.org.uk,2024-02-09:/blog/2024/02/09/docker-and-lxc/</id>
    <title type="html">Docker and LXC</title>
    <published>2024-02-09T20:51:49Z</published>
    <updated>2024-02-09T20:51:49Z</updated>
    <link rel="alternate" href="https://iay.org.uk/blog/2024/02/09/docker-and-lxc/" type="text/html"/>
    <content type="html">&lt;p&gt;My long-standing virtualisation platform of choice has been &lt;a href="https://www.vmware.com"&gt;VMware&lt;/a&gt;’s;
for many years I’ve had a couple of machines running &lt;a href="https://en.wikipedia.org/wiki/VMware_ESXi"&gt;ESXi&lt;/a&gt; hosting my virtual machines
and I use their Fusion product on my Macs.
With the &lt;a href="https://www.broadcom.com/company/news/financial-releases/61541"&gt;acquisition&lt;/a&gt; of that business by Broadcom and the ongoing
&lt;a href="https://news.vmware.com/company/vmware-by-broadcom-business-transformation"&gt;“business transformation”&lt;/a&gt;, though, I’ve moved
the server side of things over to &lt;a href="https://proxmox.com/en/proxmox-virtual-environment/overview"&gt;Proxmox Virtual Environment&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Proxmox is a more open virtualisation product built around Debian Linux.
It is a little less featureful than the VMware suite in some ways, but
it has what I need in my very not-Enterprise use case, and I’m
less concerned that a new “business
transformation” might suddenly compromise my access to it.&lt;/p&gt;

&lt;p&gt;As well as running virtual machines, Proxmox has a very usable interface to
&lt;a href="https://en.wikipedia.org/wiki/LXC"&gt;Linux containers (LXC)&lt;/a&gt;, a technology which I’d been aware of from my
use of Docker but which I’ve not previously had the opportunity to look into
in its own right. Having a new tool for the
toolbox is always a joy, though, so I’ve been digging into this other form
of virtualisation recently.&lt;/p&gt;

&lt;p&gt;Linux containers are built on the same Linux kernel technologies that
underlie Docker, Podman and Kubernetes: &lt;a href="https://en.wikipedia.org/wiki/Cgroups"&gt;cgroups&lt;/a&gt;, &lt;a href="https://en.wikipedia.org/wiki/Linux_namespaces"&gt;namespaces&lt;/a&gt;
and an isolated filesystem that (usually) looks a lot like a Linux
installation. There are differences, though:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;In an “application” container (Docker, etc.), setting up networking
is the job of the container engine, not the container. In a
“system” container (LXC) the container sees a raw
(virtual) network interface and is responsible for its setup,
in the same way as a virtual machine would be.&lt;/li&gt;
  &lt;li&gt;In an application container, things like environmental variables
are passed in to the container’s entrypoint, which is often the only
thing that runs. In a system container, there are fewer assumptions
and you can do whatever you like but very little is done for you.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id="simple-container"&gt;Simple container&lt;/h2&gt;

&lt;p&gt;As an example, let’s look inside a simple application container:&lt;/p&gt;

&lt;div class="language-bash highlighter-rouge"&gt;&lt;div class="highlight"&gt;&lt;pre class="highlight"&gt;&lt;code&gt;% docker run &lt;span class="nt"&gt;--rm&lt;/span&gt; &lt;span class="nt"&gt;-it&lt;/span&gt; alpine:latest
/ &lt;span class="c"&gt;# ps gax&lt;/span&gt;
PID   USER     TIME  COMMAND
    1 root      0:00 /bin/sh
    7 root      0:00 ps gax
/ &lt;span class="c"&gt;# ip a&lt;/span&gt;
...
21: eth0@if22: &amp;lt;BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN&amp;gt; mtu 65535 ...
    &lt;span class="nb"&gt;link&lt;/span&gt;/ether 02:42:ac:11:00:03 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.3/16 brd 172.17.255.255 scope global eth0
/ &lt;span class="c"&gt;# df -h /&lt;/span&gt;
Filesystem                Size      Used Available Use% Mounted on
overlay                  58.4G     22.4G     32.9G  41% /
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Here, the process with PID 1 is the container’s entrypoint, the shell. An Ethernet
interface is ready for use, and I have 33GB of space on my root drive.
Those are all lies, of course, but they are the kind of lies a containerised
application needs to hear.&lt;/p&gt;

&lt;p&gt;What about LXC? A container is just a bunch of files invoked in some kind of
context, so maybe we can just export that bunch of files and fire it up in Proxmox
as a system container? Turns out that is exactly true:&lt;/p&gt;

&lt;div class="language-bash highlighter-rouge"&gt;&lt;div class="highlight"&gt;&lt;pre class="highlight"&gt;&lt;code&gt;% docker container create &lt;span class="nt"&gt;--name&lt;/span&gt; example1 alpine:latest
% docker container &lt;span class="nb"&gt;export&lt;/span&gt; &lt;span class="nt"&gt;--output&lt;/span&gt; example1.tar example1
% docker container &lt;span class="nb"&gt;rm &lt;/span&gt;example1
% &lt;span class="nb"&gt;gzip &lt;/span&gt;example1.tar
% scp example1.tar.gz root@pve02:/var/lib/vz/template/cache/
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;code&gt;pve02&lt;/code&gt; is one of my Proxmox nodes;
the &lt;code&gt;/var/lib/vz/template/cache/&lt;/code&gt; directory is a location where Proxmox
stores templates from which you can create containers using its
graphical user interface. Creating such
a container from the template that used to be a Docker image and
firing it up gives us a login prompt, after which we can have a poke
around:&lt;/p&gt;

&lt;div class="language-bash highlighter-rouge"&gt;&lt;div class="highlight"&gt;&lt;pre class="highlight"&gt;&lt;code&gt;example1:~# ps gax
PID   USER     TIME  COMMAND
    1 root      0:00 /sbin/init
   25 root      0:00 /bin/login &lt;span class="nt"&gt;--&lt;/span&gt; root
   26 root      0:00 /sbin/getty 38400 tty2
   27 root      0:00 &lt;span class="nt"&gt;-ash&lt;/span&gt;
   28 root      0:00 ps gax
example1:~# ip a
...
2: eth0@if482: &amp;lt;BROADCAST,MULTICAST,M-DOWN&amp;gt; mtu 1500 ...
    &lt;span class="nb"&gt;link&lt;/span&gt;/ether bc:24:11:fa:87:94 brd ff:ff:ff:ff:ff:ff
example1:~# &lt;span class="nb"&gt;df&lt;/span&gt; &lt;span class="nt"&gt;-h&lt;/span&gt; /
Filesystem                Size      Used Available Use% Mounted on
/dev/mapper/pve-vm--106--disk--0
                          7.8G      7.7M      7.4G   0% /
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The lies are different this time.
PID 1 is now an explicit &lt;code&gt;init&lt;/code&gt; process created by the environment,
and that has spun up the login process which leads to our shell.
There’s a network interface, but it’s unconfigured. The root filesystem
is a mounted virtual disk now, and a tiny 8MB of that is in use by our Alpine
Linux userspace.&lt;/p&gt;

&lt;p&gt;At this point, because this is &lt;a href="https://www.alpinelinux.org"&gt;Alpine Linux&lt;/a&gt; and even the tiniest
container bundles &lt;a href="https://www.busybox.net"&gt;BusyBox&lt;/a&gt;, you can create an appropriate
&lt;code&gt;/etc/network/interfaces&lt;/code&gt;, type &lt;code&gt;ifup eth0&lt;/code&gt; and be off to the races.
Things will be a little trickier with images based on
other distributions, but the principle still applies.&lt;/p&gt;

&lt;h2 id="complex-container"&gt;Complex container&lt;/h2&gt;

&lt;p&gt;In the above, I glossed over the fact that although I got a shell out
of both container technologies, the mechanism was entirely different.
That’s more obvious if the Docker container is supposed to be doing
something other than running a shell, which will almost always be the
case. The technique above will &lt;em&gt;always&lt;/em&gt; give you a shell (if it works at
all); the original image’s &lt;code&gt;ENTRYPOINT&lt;/code&gt;, &lt;code&gt;CMD&lt;/code&gt;, &lt;code&gt;ENV&lt;/code&gt; and so on are all
ignored.&lt;/p&gt;

&lt;p&gt;To see what can be done in real use cases, let’s move on to my motivating
example for looking into this at all. &lt;a href="https://netboot.xyz"&gt;&lt;code&gt;netboot.xyz&lt;/code&gt;&lt;/a&gt; is a neat
thing to have hosted in your network if you’re trying different Linux
distributions or just installing a lot of virtual machines. You
&lt;em&gt;can&lt;/em&gt; deploy it as a &lt;a href="https://netboot.xyz/docs/docker"&gt;Docker container&lt;/a&gt; but it’s better for
it to have its own independent IP address so that you can put that into your
DHCP server’s configuration. Deploying as an LXC container is ideal,
but that’s not something they provide.&lt;/p&gt;

&lt;p&gt;Instead, we can take the Docker image, add some missing components to
turn that into a fully functional LXC template using &lt;code&gt;docker buildx&lt;/code&gt;,
then deploy a container from that template. Here’s the &lt;code&gt;Dockerfile&lt;/code&gt;:&lt;/p&gt;

&lt;div class="language-Dockerfile highlighter-rouge"&gt;&lt;div class="highlight"&gt;&lt;pre class="highlight"&gt;&lt;code&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; netbootxyz/netbootxyz:latest&lt;/span&gt;

&lt;span class="k"&gt;RUN &lt;/span&gt;apk add &lt;span class="nt"&gt;--no-cache&lt;/span&gt; openrc ifupdown-ng

&lt;span class="k"&gt;ADD&lt;/span&gt;&lt;span class="s"&gt; netbootxyz /etc/init.d/&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;rc-update add netbootxyz default
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This &lt;code&gt;Dockerfile&lt;/code&gt; installs two packages: &lt;code&gt;openrc&lt;/code&gt; is &lt;a href="https://docs.alpinelinux.org/user-handbook/0.1a/Working/openrc.html"&gt;Alpine’s init system&lt;/a&gt;;
&lt;code&gt;ifupdown-ng&lt;/code&gt; is a more advanced network interface package than that provided
by BusyBox: it’s there to provide compatibility with Proxmox’s LXC network
configuration UI.&lt;/p&gt;

&lt;p&gt;We’re also adding a &lt;code&gt;netbootxyz&lt;/code&gt; service to the system’s &lt;code&gt;default&lt;/code&gt; run level.
The configuration file (which needs to be executable) looks like this:&lt;/p&gt;

&lt;div class="language-shell highlighter-rouge"&gt;&lt;div class="highlight"&gt;&lt;pre class="highlight"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/sbin/openrc-run&lt;/span&gt;

&lt;span class="nb"&gt;command&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"/start.sh"&lt;/span&gt;
&lt;span class="nv"&gt;command_background&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"true"&lt;/span&gt;
&lt;span class="nv"&gt;pidfile&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"/run/netbootxyz.pid"&lt;/span&gt;

&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;TFTPD_OPTS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;NGINX_PORT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;80
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;WEB_APP_PORT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;3000

depend&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        need net
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The &lt;code&gt;export&lt;/code&gt; statements provide the environmental variables required by
the container image’s &lt;code&gt;/start.sh&lt;/code&gt; entrypoint, which we’re defining here
as a service dependent on the availability of networking. Because
&lt;code&gt;netbootxyz&lt;/code&gt; is part of the default run level, its dependency will
be brought up before it whenever the system starts.&lt;/p&gt;

&lt;p&gt;Building the new template is simple:&lt;/p&gt;

&lt;div class="language-bash highlighter-rouge"&gt;&lt;div class="highlight"&gt;&lt;pre class="highlight"&gt;&lt;code&gt;% docker buildx build &lt;span class="nt"&gt;--output&lt;/span&gt; &lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;tar&lt;/span&gt;,dest&lt;span class="o"&gt;=&lt;/span&gt;example2.tar &lt;span class="nb"&gt;.&lt;/span&gt;
% &lt;span class="nb"&gt;gzip &lt;/span&gt;example2.tar
% scp example2.tar.gz root@pve02:/var/lib/vz/template/cache/
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Deploying this template from the Proxmox UI and providing a static IP address
results in the following:&lt;/p&gt;

&lt;div class="language-bash highlighter-rouge"&gt;&lt;div class="highlight"&gt;&lt;pre class="highlight"&gt;&lt;code&gt;example2:~# ps gax
PID   USER     TIME  COMMAND
    1 root      0:00 /sbin/init
  348 root      0:00 &lt;span class="o"&gt;{&lt;/span&gt;start.sh&lt;span class="o"&gt;}&lt;/span&gt; /bin/bash /start.sh
  357 root      0:00 /sbin/getty 38400 tty2
  384 root      0:00 &lt;span class="o"&gt;{&lt;/span&gt;supervisord&lt;span class="o"&gt;}&lt;/span&gt; /usr/bin/python3 /usr/bin/supervisord ...
  386 root      0:00 /usr/sbin/syslog-ng &lt;span class="nt"&gt;--foreground&lt;/span&gt; &lt;span class="nt"&gt;--no-caps&lt;/span&gt;
  387 root      0:00 nginx: master process /usr/sbin/nginx ...
  388 nbxyz     0:00 /usr/bin/node app.js
  389 root      0:00 /usr/sbin/in.tftpd &lt;span class="nt"&gt;-Lvvv&lt;/span&gt; &lt;span class="nt"&gt;--user&lt;/span&gt; nbxyz &lt;span class="nt"&gt;--secure&lt;/span&gt; /config/menus
  391 nbxyz     0:00 nginx: worker process
  392 nbxyz     0:00 nginx: worker process
  393 nbxyz     0:00 nginx: worker process
  394 nbxyz     0:00 nginx: worker process
  406 root      0:00 &lt;span class="nb"&gt;tail&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; /var/log/messages
  412 root      0:00 /bin/login &lt;span class="nt"&gt;--&lt;/span&gt; root
  413 root      0:00 &lt;span class="nt"&gt;-ash&lt;/span&gt;
  414 root      0:00 ps gax
example2:~# ip a
...
2: eth0@if486: &amp;lt;BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN&amp;gt; mtu 1500 ...
    &lt;span class="nb"&gt;link&lt;/span&gt;/ether bc:24:11:82:48:d1 brd ff:ff:ff:ff:ff:ff
    inet 192.168.117.1/24 scope global eth0
       valid_lft forever preferred_lft forever
...
example2:~# &lt;span class="nb"&gt;df&lt;/span&gt; &lt;span class="nt"&gt;-h&lt;/span&gt; /
Filesystem                Size      Used Available Use% Mounted on
/dev/mapper/pve-vm--106--disk--0
                          7.8G    182.3M      7.2G   2% /
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;You can see from this that the network interface has been configured with
the supplied static address, and that the full &lt;code&gt;netboot.xyz&lt;/code&gt; stack is
running:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;PID 348 is the service startup script, running as a daemon.&lt;/li&gt;
  &lt;li&gt;That has invoked a &lt;code&gt;supervisord&lt;/code&gt; process (PID 384) to start the component services:
    &lt;ul&gt;
      &lt;li&gt;&lt;code&gt;syslog-ng&lt;/code&gt;&lt;/li&gt;
      &lt;li&gt;&lt;code&gt;tftpd&lt;/code&gt;&lt;/li&gt;
      &lt;li&gt;a Node.js application for the user interface&lt;/li&gt;
      &lt;li&gt;
&lt;code&gt;nginx&lt;/code&gt; and its worker processes to serve asset requests&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id="conclusions"&gt;Conclusions&lt;/h2&gt;

&lt;p&gt;Containers are variations on a bunch of files in an isolated runtime context.
It’s possible — and even fairly straightforward — to convert a container image
intended for one runtime for use in another by tweaking the set of
files in use; they’re just files. &lt;code&gt;docker buildx&lt;/code&gt; is, pretty much by definition,
one way of performing manipulations of this kind.&lt;/p&gt;

&lt;p&gt;Proxmox is a pretty nice platform to deploy both virtual machines and
system containers (application containers too, with the proviso that
the recommendation from Proxmox is to run your application container
runtime inside a virtual machine). The resulting containers are tiny,
start very quickly and are easy to move around a Proxmox cluster if
needed, without dragging a virtual machine around with them.&lt;/p&gt;</content>
  </entry>
  <entry>
    <id>tag:iay.org.uk,2023-10-27:/blog/2023/10/27/key-server-shuffle/</id>
    <title type="html">Key Server Shuffle</title>
    <published>2023-10-27T13:16:44Z</published>
    <updated>2023-10-27T13:16:44Z</updated>
    <link rel="alternate" href="https://iay.org.uk/blog/2023/10/27/key-server-shuffle/" type="text/html"/>
    <content type="html">&lt;p&gt;Every so often, I find myself interacting with the
PGP/GPG ecosystem. This usually results in me
&lt;a href="/blog/2021/07/05/sks-key-servers-gone/"&gt;bemoaning&lt;/a&gt;
the latest step in its slow drift towards complete
irrelevance.&lt;/p&gt;

&lt;p&gt;Imagine my surprise when this week’s addition of a new
signing subkey on my &lt;a href="/identity/pgp/"&gt;main key&lt;/a&gt; ended up
finding that although the key server I had been using
(&lt;code&gt;pgp.re&lt;/code&gt;) had become defunct, quite a few &lt;em&gt;new&lt;/em&gt; key
servers seem to have sprung up, and there’s actually a
reasonable number again.&lt;/p&gt;

&lt;p&gt;I’ve pushed my most recent key update to the following:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
&lt;code&gt;keys.openpgp.org&lt;/code&gt; (a privacy-centric island)&lt;/li&gt;
  &lt;li&gt;
&lt;code&gt;pgp.mit.edu&lt;/code&gt; (“old faithful”)&lt;/li&gt;
  &lt;li&gt;&lt;code&gt;keyserver.ubuntu.com&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code&gt;sks.pgpkeys.eu&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These servers all seem to be fairly consistently available and
moreover are again (mostly) participating in a functional
&lt;a href="https://spider.pgpkeys.eu"&gt;distribution network&lt;/a&gt;. I’m not sure
how the previous GDPR-related issues have been resolved,
but it’s nice to have this back.&lt;/p&gt;</content>
  </entry>
  <entry>
    <id>tag:iay.org.uk,2023-09-21:/blog/2023/09/21/unchromed/</id>
    <title type="html">Unchromed</title>
    <published>2023-09-21T11:54:12Z</published>
    <updated>2023-09-21T11:54:12Z</updated>
    <link rel="alternate" href="https://iay.org.uk/blog/2023/09/21/unchromed/" type="text/html"/>
    <content type="html">&lt;p&gt;It has been a long time since “&lt;a href="https://en.wikipedia.org/wiki/Don't_be_evil" title="Wikipedia: Don't be evil"&gt;Don’t be evil&lt;/a&gt;” was part of Google’s
corporate philosophy. We could probably argue about whether they
ever really believed in that idea, how long their belief lasted,
and what about the environment they exist in was so corrosive
to it. That discussion would probably include a lot of
talking points along the lines of “well, actually, corporations
are required by law to be evil in order to maximise shareholder value”
and — at least in recent years — a lot of audible scoffing on my part.&lt;/p&gt;

&lt;p&gt;I recently reached the point at which I wasn’t prepared to keep
having that argument even with myself. I got pretty close
a couple of years ago when &lt;a href="https://en.wikipedia.org/wiki/Federated_Learning_of_Cohorts" title="Wikipedia: Federated Learning of Cohorts"&gt;FLoC&lt;/a&gt; came along
(see &lt;em&gt;&lt;a href="/blog/2021/05/10/no-floc-here" title="A previous, related rant"&gt;No FLoC Here&lt;/a&gt;&lt;/em&gt;). The latest round in the exhausting
saga of Google forcing surveillance advertising onto end users
is the so-called &lt;a href="https://en.wikipedia.org/wiki/Privacy_Sandbox" title="Wikipedia: Privacy Sandbox"&gt;Privacy Sandbox&lt;/a&gt;, in which Google’s preferred
model for targeted web advertising is baked into the world’s
&lt;a href="https://en.wikipedia.org/wiki/Usage_share_of_web_browsers" title="Wikipedia: Usage share of web browsers"&gt;dominant browser&lt;/a&gt;, which they not coincidentally control.&lt;/p&gt;

&lt;p&gt;I recommend the &lt;a href="https://arstechnica.com/gadgets/2023/09/googles-widely-opposed-ad-platform-the-privacy-sandbox-launches-in-chrome/"&gt;Ars Technica article&lt;/a&gt; if you want depth,
but here’s the lede:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Don’t let Chrome’s big redesign distract you from the fact that
Chrome’s invasive new ad platform, ridiculously branded the
“Privacy Sandbox,” is also getting a widespread rollout in
Chrome today. If you haven’t been following this, this feature
will track the web pages you visit and generate a list of advertising
topics that it will share with web pages whenever they ask,
and it’s built directly into the Chrome browser.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;No end user asked for this. No end user benefits from this.
The selected user interface (and messaging: “Privacy Sandbox”,
&lt;em&gt;my eye&lt;/em&gt;) mean that people who use Chrome will most often end up
with this enabled by default and never find out how to turn it
off. This benefits Google’s customers, who are not me and,
probably, not you.&lt;/p&gt;

&lt;p&gt;As a &lt;a href="https://i.pinimg.com/originals/de/8b/67/de8b6733b613ab387590cfcde4a376e7.png" title="I are programmer: obligatory cat meme"&gt;sophisticated technical user&lt;/a&gt; I could of course disable this and
be on my way. And check it hasn’t been re-enabled every few days
“by accident”. And make sure there’s no new &lt;a href="https://arstechnica.com/gadgets/2023/07/googles-web-integrity-api-sounds-like-drm-for-the-web/" title="Ars Technica: Google’s nightmare “Web Integrity API” wants a DRM gatekeeper for the web"&gt;wizard wheeze&lt;/a&gt; introduced that
needs to be defended against. But, as I said above, this adversarial
approach to a critical tool is just &lt;em&gt;exhausting&lt;/em&gt; and at this point
I’m done with it.&lt;/p&gt;

&lt;p&gt;So, for what it’s worth, Chrome is now gone from all of my systems
and won’t come back as long as there are less-abusive alternatives.&lt;/p&gt;

&lt;p&gt;I’ve been primarily a &lt;a href="https://www.apple.com/safari/"&gt;Safari&lt;/a&gt; user for some years now, and
although it has some flaws I’ve been pretty happy with it from
a privacy perspective. Apple may not be as perfect as they
would like everyone to think, but they’re not bad. Well, as
long as you set &lt;a href="https://duckduckgo.com"&gt;DuckDuckGo&lt;/a&gt; as your default search engine
anyway.&lt;/p&gt;

&lt;p&gt;You can’t live with just Safari, though, which is of course the
reason I was regularly using Chrome in the first place. There
are still a wide variety of web sites which just don’t work
perfectly on the world’s &lt;em&gt;second&lt;/em&gt; most dominant browser.
For that second, utility, browser I’ve returned after a
long hiatus to good old &lt;a href="https://www.mozilla.org/en-GB/firefox/browsers/"&gt;Firefox&lt;/a&gt;. I don’t love it,
but it works with most things that balk at Safari and
it gets extra points for a &lt;a href="https://en.wikipedia.org/wiki/Firefox_logo#/media/File:Mozilla_Firefox_cosplay_(4951164105).jpg" title="Wikipedia: A woman cosplaying the Firefox mascot depicted in the browser's logo"&gt;nice logo&lt;/a&gt;.&lt;/p&gt;</content>
  </entry>
  <entry>
    <id>tag:iay.org.uk,2023-05-12:/blog/2023/05/12/porcelain/</id>
    <title type="html">Porcelain</title>
    <published>2023-05-12T22:57:25Z</published>
    <updated>2023-05-12T22:57:25Z</updated>
    <link rel="alternate" href="https://iay.org.uk/blog/2023/05/12/porcelain/" type="text/html"/>
    <content type="html">&lt;p&gt;It was twenty years ago today, &lt;a href="https://en.wikipedia.org/wiki/Sgt._Pepper%27s_Lonely_Hearts_Club_Band" title="Wikipedia: Sgt. Pepper's Lonely Hearts Club Band"&gt;Sgt. Pepper&lt;/a&gt; told the band to play…&lt;/p&gt;

&lt;p&gt;No. Wait. That’s not right; let me start again.&lt;/p&gt;

&lt;p&gt;My very &lt;a href="/blog/2003/05/resolutions" title="Technology Stir Fry: Resolutions"&gt;first post&lt;/a&gt; to this “weblog” (as the
term still was then) was exactly twenty years ago. The &lt;a href="/colophon"&gt;colophon&lt;/a&gt;
has some of the story of how the implementation has changed over the years, but
today I thought it would be more interesting to look and see what if anything I have
learned from two decades writing here. There are not many things in your life you end up
devoting effort to over that span of time, after all.&lt;/p&gt;

&lt;p&gt;Some statistics, just for fun: there are 260 posts here excluding this one
but including the &lt;a href="/there/blog"&gt;&lt;code&gt;iay@there&lt;/code&gt;&lt;/a&gt; side-blog I ran for a few months
in 2004&lt;sup id="fnref:legs"&gt;&lt;a href="#fn:legs" class="footnote" rel="footnote" role="doc-noteref"&gt;1&lt;/a&gt;&lt;/sup&gt;. That’s an average of a bit over one post a month, but you can see from the
&lt;a href="/blog/archive"&gt;Archives page&lt;/a&gt; that my output has been rather uneven: I’m not at all sure what
happened to silence me in 2015–2016, as most people would claim it’s usually
pretty difficult to get me to shut up.&lt;/p&gt;

&lt;p&gt;Looking at the posts on the main blog &lt;a href="/blog/tags"&gt;by tag&lt;/a&gt;, I wasn’t surprised to find that the
biggest cluster of subjects has been around digital identity, cryptography, and
security more generally. That’s been my principal line of work for most of
this time, after all.&lt;/p&gt;

&lt;p&gt;If you include both blogs, though, “&lt;a href="/blog/tag/virtual-iay/"&gt;virtual reality&lt;/a&gt;” actually wins out. That might
be a little surprising unless you’re aware of my brief career as a
professional &lt;a href="/blog/2006/03/global_kids_isl/"&gt;construction worker&lt;/a&gt; in the &lt;a href="https://secondlife.com"&gt;Second Life&lt;/a&gt; virtuality.&lt;/p&gt;

&lt;p&gt;Over the years several communities have, I believe, found
this blog useful. The most surprising to me, certainly at the time,
was the result of the spectacular success of a pair of articles I wrote in 2003
about my experiments with 8-bit microcontrollers. They were
so popular — presumably because they were just in the right place
at the right time — that the advertisements I ran on
&lt;a href="/blog/2003/07/pic16c745765_mi/"&gt;PIC16C745/765: microcontrollers with USB&lt;/a&gt; and
&lt;a href="/blog/2003/07/my_very_first_u"&gt;My Very First USB Peripheral&lt;/a&gt;
were enough to pay my hosting fees for that year, which was nice.
They are are the only pages I’ve ever run advertisements on, and
I no longer serve up anything I’d need to host a cookie banner for,
not even analytics.&lt;/p&gt;

&lt;p&gt;In the early days, before the scourge of &lt;a href="/blog/tag/spam/" title="Technology Stir Fry: spam tag"&gt;spam&lt;/a&gt; inevitably spread to
the world of blogs, this one had both &lt;a href="https://en.wikipedia.org/wiki/Trackback" title="Wikipedia: Trackback"&gt;trackback&lt;/a&gt; and comment functionality.
Equally inevitably, I gave up what would otherwise have become a full-time
moderation job here so that I could devote time to my paid work.
There are some crackers in there if you root around; they’re still visible because I imported
everything from the database-backed versions of the blog when I &lt;a href="/blog/2018/02/08/nanoced/"&gt;Nanoced&lt;/a&gt;
it into a static site. My favourite, I think, is the one where a
commenter asks if he can buy my &lt;a href="/blog/2006/07/cuddly_headcrab/" title="Technology Stir Fry: Cuddly Headcrab"&gt;cuddly headcrab&lt;/a&gt;. I was not able to
oblige him, alas.&lt;/p&gt;

&lt;p&gt;So, twenty years. Has it been worth it? Yes, absolutely. I &lt;em&gt;enjoy&lt;/em&gt; writing
long form, and working with words in general. I do get to write from
&lt;a href="https://docs.ukfederation.org.uk/fts/FTS-1.1.pdf" title="UK federation: Federation Technical Specifications"&gt;time&lt;/a&gt; to &lt;a href="/blog/2018/08/28/rfc8409/" title="RFC 8409; Young, I (ed.)"&gt;time&lt;/a&gt; for my paying work, and that’s enjoyable as an
&lt;a href="http://www.midwinter.com/lurk/guide/082.html" title="There's a rule here: ALWAYS a Babylon 5 reference."&gt;exercise of vital powers&lt;/a&gt; but it’s not really the same as self-directed
writing.&lt;/p&gt;

&lt;p&gt;So, writing has been worth it, but what about writing &lt;em&gt;here,&lt;/em&gt; at &lt;code&gt;iay.org.uk&lt;/code&gt;?
Has the palaver
of hosting my own site, learning Movable Type, Drupal, Nanoc, all that stuff… has
&lt;em&gt;that&lt;/em&gt; paid off? One of my answers should be obvious if you’ve glanced at the
&lt;a href="/" title="Technology Stir Fry"&gt;site title&lt;/a&gt;: as well as sometimes being a pain, digging into
the technology has also been &lt;em&gt;fun.&lt;/em&gt; So again, yes.&lt;/p&gt;

&lt;p&gt;I’ll finish with a second and more serious answer to the same question, which I will
shamelessly steal from John Scalzi (who has been
blogging at &lt;a href="https://whatever.scalzi.com/" title="Whatever: Furiously Reasonable"&gt;Whatever&lt;/a&gt; for twenty-&lt;em&gt;four&lt;/em&gt; years as I write this):&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;I’ve had Scalzi.com since March of 1998, which has been enough time for at least
four generations of online social networking sites. They come and go; my site
remains. And it will remain when the hip kids roll their eyes at whatever
pathetic dinosaurs still remain on Facebook (hint: that’s already happening).
Online, that’s as good as permanence gets.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Scalzi &lt;a href="https://whatever.scalzi.com/2011/06/29/mastering-ones-own-domain-an-no-this-is-not-a-seinfeld-reference/"&gt;wrote this&lt;/a&gt; in 2011: long before the &lt;a href="/blog/2022/12/01/unfollowed/" title="This place is best shunned and left uninhabited."&gt;recent unpleasantness&lt;/a&gt; on Twitter,
back in the early days when Twitter was becoming the &lt;a href="https://www.youtube.com/watch?v=ha-uagjJQ9k" title="Men in Black II - Old Busted Hotness"&gt;New Hotness&lt;/a&gt; people were talking about.
We may not be at the sad end of that particular mayfly’s lifecycle just yet,
but who would &lt;em&gt;start&lt;/em&gt; using it right now?&lt;/p&gt;

&lt;p&gt;None of us are here for the &lt;a href="https://longnow.org" title="The Long Now Foundation is a nonprofit established in 01996 to foster long-term thinking."&gt;long term&lt;/a&gt;, but I think it’s wise to treat
all online services — &lt;em&gt;other people’s computers&lt;/em&gt; — as entirely &lt;a href="https://en.wikipedia.org/wiki/Mayfly" title="Wikipedia: Mayfly (Ephemeroptera)"&gt;ephemeral&lt;/a&gt;.
Whether a service survives for more than a handful of years is out of my control,
and the last year has certainly demonstrated that what motivates the owners of such
services does not necessarily align with what would be best for me.&lt;/p&gt;

&lt;p&gt;Fortunately, many of the things I love about social media (the wellspring of ideas, the active
conversation and, honestly, the cat pictures) don’t require persistence. They require
active interest; they require being the thing that people think is the New Hotness. Until we all move
on to the new place we’re all hearing about.&lt;/p&gt;

&lt;div class="footnotes" role="doc-endnotes"&gt;
  &lt;ol&gt;
    &lt;li id="fn:legs"&gt;
      &lt;p&gt;Kids today wouldn’t believe it, but back in my day, people in the metaverse
&lt;em&gt;had legs&lt;/em&gt;. &lt;a href="#fnref:legs" class="reversefootnote" role="doc-backlink"&gt;↩&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
  &lt;/ol&gt;
&lt;/div&gt;</content>
  </entry>
  <entry>
    <id>tag:iay.org.uk,2023-05-09:/blog/2023/05/09/infosec-exchange/</id>
    <title type="html">infosec.exchange</title>
    <published>2023-05-09T15:54:37Z</published>
    <updated>2023-05-09T15:54:37Z</updated>
    <link rel="alternate" href="https://iay.org.uk/blog/2023/05/09/infosec-exchange/" type="text/html"/>
    <content type="html">&lt;p&gt;I started looking at &lt;a href="https://en.wikipedia.org/wiki/Mastodon_(software)" title="Wikipedia: Mastodon (software)"&gt;Mastodon&lt;/a&gt; a bit more than a year ago, when
the prospect of &lt;a href="https://tvtropes.org/pmwiki/pmwiki.php/Literature/TheNewManagement"&gt;New Management&lt;/a&gt; at Twitter was becoming
a looming disturbance in the timeline and although no-one really
knew exactly what to expect, “something good” was clearly unlikely&lt;sup id="fnref:1"&gt;&lt;a href="#fn:1" class="footnote" rel="footnote" role="doc-noteref"&gt;1&lt;/a&gt;&lt;/sup&gt;.
As described in &lt;a href="/blog/2022/04/27/tweets-and-toots"&gt;Tweets and Toots&lt;/a&gt;, I set up at
&lt;a href="https://mastodon.social/about"&gt;&lt;code&gt;mastodon.social&lt;/code&gt;&lt;/a&gt; because I really didn’t have a
good answer to the question of which community I felt part of.&lt;/p&gt;

&lt;p&gt;In December 2022, I posted &lt;a href="/blog/2022/12/01/unfollowed"&gt;Why I Unfollowed You&lt;/a&gt; to
mark my progressive disengagement from Muskland, and really
haven’t spent a lot of time there since. A couple of weeks
later I pinned what I regard as my &lt;a href="https://twitter.com/iay/status/1603684326935351296"&gt;tombstone post&lt;/a&gt; and
which still represents my position:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;This place is best shunned and left uninhabited.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I’ve enjoyed the time I have spent on Mastodon a lot more than
my latter-day experience with the Hellsite. It’s less exhausting and
stressful, and even the &lt;a href="https://mastodon.social/tags/catsofmastodon" title="Cats of Mastodon"&gt;cat pictures&lt;/a&gt; are better, to my mind. Or
are those statements redundant?&lt;/p&gt;

&lt;p&gt;I’m not finding myself &lt;em&gt;posting&lt;/em&gt; that much more on Mastodon —
most of my posts are essentially pointers to long-form posts
here — but I do find myself &lt;em&gt;boosting&lt;/em&gt; a lot more than I
retweeted. Boosts don’t incorporate commentary in the way
that quote-tweets can, so the semantics are simply and only “I think
people who follow me might find this interesting” and I don’t
find it particularly scary to hit a button with that label.&lt;/p&gt;

&lt;p&gt;It turns out that the question of whether Mastodon should &lt;em&gt;also&lt;/em&gt; provide an
easy way to do the equivalent of a quote-tweet is a
contentious one. Not having that in the experience was a
&lt;a href="https://mastodon.social/@Gargron/99662106175542726"&gt;conscious choice&lt;/a&gt; and while I’m not certain that the sky
would fall if it was introduced, it’s a cultural thing now
and I don’t think there’s a pressing need for in-line argumentation.&lt;/p&gt;

&lt;p&gt;The one change I am making today is to move from my original
instance, the flagship &lt;code&gt;mastodon.social&lt;/code&gt;, to the smaller
&lt;code&gt;infosec.exchange&lt;/code&gt;. So, I am now &lt;a href="https://infosec.exchange/web/@iay"&gt;&lt;code&gt;@iay@infosec.exchange&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The new instance is quite a &lt;em&gt;lot&lt;/em&gt; smaller: as I write this,
&lt;code&gt;mastodon.social&lt;/code&gt; has 878K users, of which around 220K are
in some sense “active” (there are enough users on
the instance that it’s no longer open access). &lt;code&gt;infosec.exchange&lt;/code&gt;
has closer to 30K users in total. This makes a &lt;em&gt;big&lt;/em&gt; difference
to the “local” timeline: it’s an unusable firehose on &lt;code&gt;mastodon.social&lt;/code&gt;
and while there’s probably a way to filter it down to a reasonable
level the smaller instance just feels… friendlier, somehow.
The denizens of &lt;code&gt;infosec.exchange&lt;/code&gt; don’t feel like my family, necessarily,
and they’re not even all in the same line of work as I am (my Mastodon
bio describes me as “Infosec-adjacent”), but they’re definitely &lt;em&gt;my tribe.&lt;/em&gt;
The things they are talking about are the things I talk about.&lt;/p&gt;

&lt;p&gt;As well as feeling more at home, and having a manageable local timeline,
I’m also sympathetic to the idea that large instances (and implicitly
a &lt;em&gt;small number&lt;/em&gt; of large instances) is just a bad direction. Obviously
that feeling is informed by the limiting case of conventional
monolithic social media: the incentives for site owners are just
too misaligned with those of the would-be socialites and
&lt;a href="https://pluralistic.net/2023/01/21/potemkin-ai/#hey-guys"&gt;enshittification&lt;/a&gt; is, if not actually inevitable, at least
hard to avoid.&lt;/p&gt;

&lt;p&gt;The move itself was very smooth, perhaps because I waited for a day when
neither instance was being &lt;a href="https://en.wikipedia.org/wiki/Denial-of-service_attack"&gt;DDOS&lt;/a&gt;ed by people who don’t want us to have
nice things. If you’re thinking of doing this for any reason, my only
word of advice would be to change your original profile to be exactly the way
you want it &lt;em&gt;before&lt;/em&gt; flipping the “send my followers over there” switch,
as there are some things you can’t do with an active redirect in place.&lt;/p&gt;

&lt;div class="footnotes" role="doc-endnotes"&gt;
  &lt;ol&gt;
    &lt;li id="fn:1"&gt;
      &lt;p&gt;“called it” &lt;a href="#fnref:1" class="reversefootnote" role="doc-backlink"&gt;↩&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
  &lt;/ol&gt;
&lt;/div&gt;</content>
  </entry>
  <entry>
    <id>tag:iay.org.uk,2022-12-29:/blog/2022/12/29/new-rule/</id>
    <title type="html">New Rule</title>
    <published>2022-12-29T16:09:10Z</published>
    <updated>2022-12-29T16:09:10Z</updated>
    <link rel="alternate" href="https://iay.org.uk/blog/2022/12/29/new-rule/" type="text/html"/>
    <content type="html">&lt;p&gt;Alongside “don’t drink coffee too late at night” I have a new
rule to make sure I get a good night’s sleep:
“never fire up &lt;a href="https://www.wireshark.org" title="Wireshark network protocol analyser."&gt;Wireshark&lt;/a&gt; after 10pm”.&lt;/p&gt;
&lt;p&gt;I’m moving some network functionality — specifically, local
DNS servers, I run &lt;a href="https://en.wikipedia.org/wiki/Split-horizon_DNS" title="Wikipedia: Split-horizon DNS"&gt;split-horizon DNS&lt;/a&gt; — from two old Raspberry
Pi machines onto something
more modern. The question arose of how I’d know when I was
done: how would I know when there are no more requests being
made to the old machines?&lt;/p&gt;

&lt;p&gt;I had a “bright idea” and made the mistake of firing up a Wireshark
network analyser to quickly answer this question. I got more than
I bargained for, as there were a &lt;em&gt;lot&lt;/em&gt; of DNS queries I couldn’t
see a reason for. The most common one looked like this:&lt;/p&gt;

&lt;p&gt;&lt;img src="../pcap1a.png" alt="Packet capture showing www.microsoft.com query every 15 seconds."&gt;&lt;/p&gt;

&lt;p&gt;Some host on the network is performing a query for &lt;code&gt;www.microsoft.com&lt;/code&gt;
every 15 seconds, regular as clockwork.&lt;/p&gt;

&lt;p&gt;Well, that’s on &lt;em&gt;one&lt;/em&gt; server. I have two: this is what the other one was seeing:&lt;/p&gt;

&lt;p&gt;&lt;img src="../pcap2a.png" alt="Packet capture showing query from two sources every 15 seconds."&gt;&lt;/p&gt;

&lt;p&gt;That’s another &lt;em&gt;two&lt;/em&gt; sources of these queries, each also ticking away
every 15 seconds.&lt;/p&gt;

&lt;p&gt;These three hosts turn out to be the nodes in my WiFi mesh network.
The manufacturer, Tenda, have arranged for each node to acquire an
IP address on the network and use that to query for the address of
&lt;code&gt;www.microsoft.com&lt;/code&gt; every 15 seconds. That’s 17,280 queries a day.&lt;/p&gt;

&lt;p&gt;Why? I found &lt;a href="https://www.ispreview.co.uk/talk/threads/tenda-mw12.38419/#post-277217"&gt;this post&lt;/a&gt; suggesting that the idea here is to
establish whether there’s internet connectivity. Why each and every
node in a WiFi mesh needs to know more than which RJ45 to send
the packets out of is a mystery to me. It’s also amusing to think that as
I have local servers all these queries are being swallowed
by them and aren’t establishing
second-by-second connectivity at all; it’s all just wasted
effort.&lt;/p&gt;

&lt;p&gt;Never fire up Wireshark after 10pm.&lt;/p&gt;</content>
  </entry>
  <entry>
    <id>tag:iay.org.uk,2022-12-07:/blog/2022/12/07/docker-in-docker-host-resolution/</id>
    <title type="html">Docker-in-Docker and host resolution errors</title>
    <published>2022-12-07T10:37:32Z</published>
    <updated>2022-12-07T10:37:32Z</updated>
    <link rel="alternate" href="https://iay.org.uk/blog/2022/12/07/docker-in-docker-host-resolution/" type="text/html"/>
    <content type="html">&lt;p&gt;This article documents a particularly niche issue I ran into which took a
while to debug and resolve. I’ve posted it for the benefit of search engines,
so that the next person to run into these exact conditions might save
a few hours. You’re welcome.&lt;/p&gt;

&lt;p&gt;This is probably interesting only to someone in my
exact situation, so most people should find some &lt;a href="https://mastodon.social/tags/catsofmastodon" title="Cats of Mastodon"&gt;cat pictures&lt;/a&gt; to look
at instead.
If you’ve been directed here by a search engine because you’re tearing
your hair out, though, read on.&lt;/p&gt;
&lt;p&gt;The very niche situation I alluded to breaks down to this:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;A private &lt;a href="https://about.gitlab.com"&gt;GitLab&lt;/a&gt; instance, running a continuous integration job.&lt;/li&gt;
  &lt;li&gt;The job is &lt;code&gt;docker build&lt;/code&gt;ing something based on a recent Linux base image
(in my case, Rocky Linux 9).&lt;/li&gt;
  &lt;li&gt;The runner is executing on a slightly older Linux implementation
(in my case, Ubuntu 20.04 LTS).&lt;/li&gt;
  &lt;li&gt;We’re using Docker-in-Docker mode to avoid giving the job access to the
host’s Docker socket.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The failure looks like this:&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-text"&gt;---&amp;gt; Running in faab08d66352
+ dnf -y install httpd mod_ssl
Rocky Linux 9 - BaseOS                          0.0  B/s |   0  B     00:00    
Errors during downloading metadata for repository 'baseos':
  - Curl error (6): Couldn't resolve host name for https://mirrors.rockylinux.org/mirrorlist?arch=x86_64&amp;amp;repo=BaseOS-9 [getaddrinfo() thread failed to start]&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You might &lt;em&gt;think&lt;/em&gt; that the most likely cause of an issue like this would be DNS.
After all, &lt;a href="https://imgflip.com/i/63yh6t"&gt;it’s always DNS&lt;/a&gt;, right? Not in this case (and it wasn’t IPv4 vs. IPv6 either,
which was my other initial thought). Search engines brought up suggestions to restart my
router. I rolled my eyes.&lt;/p&gt;

&lt;p&gt;Eventually I happened across
&lt;a href="https://medium.com/nttlabs/ubuntu-21-10-and-fedora-35-do-not-work-on-docker-20-10-9-1cd439d9921"&gt;ubuntu:21.10 and fedora:35 do not work on the latest Docker (20.10.9)&lt;/a&gt; by
&lt;a href="https://github.com/AkihiroSuda"&gt;Akihiro Suda&lt;/a&gt;, one of the maintainers of the various components used by Docker.
He explains the root of the problem, which is a change in user-mode behaviour in
the &lt;code&gt;glibc&lt;/code&gt; shipped with newer Linux distributions (Fedora 35, Red Hat Enterprise Linux 9
and derivates like Rocky Linux 9, Ubuntu 22.04). The way older versions of Docker
(20.10.9 and earlier) handle the new &lt;code&gt;clone3&lt;/code&gt; system call means that it’s
treated as a permissions violation rather than a “not implemented” call which
would have resulted in fallback behaviour appropriate to the host operating system.&lt;/p&gt;

&lt;p&gt;As an aside, I think this is only the second time I’ve hit any kind of kernel
mismatch problem while using Docker. That’s an impressive compatibility record
given that I’ve been using it for eight years now.&lt;/p&gt;

&lt;p&gt;Akihiro’s recommendation:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;The right solution is to upgrade Docker to 20.10.10 or later.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This didn’t help me because all my Docker nodes were &lt;em&gt;already&lt;/em&gt; running 20.10.21.
However, I saw that
the problem was only showing up on those nodes running Ubuntu 20.04 LTS:
the node running Ubuntu 22.04 LTS wasn’t seeing the problem, so I felt I was
probably on the right track.&lt;/p&gt;

&lt;p&gt;The wrinkle in my case turned out to be that my GitLab continuous integration pipeline
included the following:&lt;/p&gt;

&lt;div class="language-yaml highlighter-rouge"&gt;&lt;div class="highlight"&gt;&lt;pre class="highlight"&gt;&lt;code&gt;&lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;docker:20.10.6&lt;/span&gt;
&lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;docker:20.10.6-dind&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This is configuring a “helper service” &lt;em&gt;containing its own copy of the Docker
daemon&lt;/em&gt; for use in the build. This “Docker in Docker” arrangement allows
conventional &lt;code&gt;docker build&lt;/code&gt; operations to be performed within the CI job
&lt;em&gt;without&lt;/em&gt; granting the build container access to the host’s Docker daemon.
(The build does still need to be run “privileged”, which is still slightly
scary, but those are the tools available.)&lt;/p&gt;

&lt;p&gt;I deduce that the same interpretation of errant system calls is performed
within the &lt;code&gt;dind&lt;/code&gt; container as needs to be performed by “normal” Docker.
This is a little surprising when you think about all the turtles being
stacked on top of each other here, but also makes sense: how else &lt;em&gt;could&lt;/em&gt;
it work?&lt;/p&gt;

&lt;p&gt;Updating the &lt;code&gt;dind&lt;/code&gt; helper service to a more recent version of course
addresses the original issue. One option is to use &lt;code&gt;docker:20.10-dind&lt;/code&gt; to
get maintenance updates without the exciting functional changes that
might greet a user of the &lt;code&gt;latest&lt;/code&gt; tag.&lt;/p&gt;</content>
  </entry>
  <entry>
    <id>tag:iay.org.uk,2022-12-01:/blog/2022/12/01/unfollowed/</id>
    <title type="html">Why I Unfollowed You</title>
    <published>2022-12-01T23:20:18Z</published>
    <updated>2022-12-01T23:20:18Z</updated>
    <link rel="alternate" href="https://iay.org.uk/blog/2022/12/01/unfollowed/" type="text/html"/>
    <content type="html">&lt;p&gt;So, I used to follow you on Twitter, but now I don’t. What’s up with that?&lt;/p&gt;
&lt;p&gt;The first thing to say is: it’s not personal. Unless it is, of course, personal: but
in that case you already &lt;a href="https://helloiamabear.com/2017/01/30/an-open-letter-to-the-deer/" title="An open letter to the deer across the river."&gt;know what you did&lt;/a&gt;. You monster.&lt;/p&gt;

&lt;p&gt;It’s obviously much more likely — given your upstanding character and sunny
disposition — that you have fallen foul of my progressive campaign to free myself
from dependence on The Bad Place. Did I say that out loud? I meant to say Twitter.&lt;/p&gt;

&lt;p&gt;I like doomscrolling as much as the next fellow, of course. But since April when I
&lt;a href="/blog/2022/04/27/tweets-and-toots/" title="Technology Stir Fry: Tweets and Toots"&gt;last discussed&lt;/a&gt; matters of so-called “social” media, things on The Hellsite have
gone about as badly as they could have, consequent to its purchase by the
world’s richest &lt;a href="https://www.boringcompany.com/not-a-flamethrower" title="No, seriously. A flamethrower."&gt;tunneling equipment and flamethrower&lt;/a&gt; magnate. The ratio of
outrage to useful information is going in the wrong direction fast, and the &lt;em&gt;quality&lt;/em&gt;
of doomscrolling available has plummeted as a result. It’s just &lt;em&gt;exhausting&lt;/em&gt; watching
all those strangers argue past each other.&lt;/p&gt;

&lt;p&gt;My best guess at this stage is that the Bluebird of Unhappiness is doomed to circle
the black hole of its new owner’s ego until it is either entirely crushed by the
tidal forces, or he gets bored and wanders off to assist some other large
corporation turn back into a struggling start-up. I think we have a responsibility
to future civilisations to signpost the resulting floating rubble as a hazard to
navigation; the message should be that
&lt;a href="https://en.wikipedia.org/wiki/Long-term_nuclear_waste_warning_messages" title="Wikipedia: Long term nuclear waste warning messages"&gt;this place is not a place of honor… this place is best shunned and left uninhabited&lt;/a&gt;.
Social media implemented in that fashion, with those incentives,
was &lt;em&gt;not humanity’s best idea.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Sorry, where was I? Oh yes, why I unfollowed you. Well my &lt;em&gt;hope&lt;/em&gt; is that the reason for
that was that I decided to follow you somewhere else instead! For example, if you have
a &lt;a href="https://joinmastodon.org"&gt;Mastodon&lt;/a&gt; or other &lt;a href="https://fediverse.info"&gt;Fediverse&lt;/a&gt; account, you’ll be picking up followers there
as you lose them elsewhere. If you followed me on The Twitters, I invite you to do
the same: unfollow me now, with gusto, and make my acquaintance anew at
&lt;a href="https://infosec.exchange/@iay" title="Me over there."&gt;&lt;code&gt;@iay@mastodon.social&lt;/code&gt;&lt;/a&gt;. I might actually post a bit more now that the
environment I’m posting into is not actively horrible.&lt;/p&gt;

&lt;p&gt;As well as relocating my primary doomscrolling location, I’ve started getting back into
that retro technology we all used to use before microblogging was a thing. That means
&lt;a href="https://en.wikipedia.org/wiki/RSS" title="Wikipedia: RSS - Really Simple Syndication"&gt;RSS&lt;/a&gt; and such, so if you have a real old-fashioned steam-powered blog-type blog,
I’m probably subscribed to that already. Either that or my friend &lt;a href="https://github.com/huginn/huginn" title="Huginn is a system for building agents that perform automated tasks for you online."&gt;Huginn&lt;/a&gt; is watching
over you for me, and I’ll wake up to your wisdom fresh every morning in my daily digest,
to enjoy with my &lt;a href="https://www.youtube.com/watch?v=UALN1ZoN6bA" title="Not my house. Not his house, either."&gt;delicious morning cup of coffee&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Doesn’t that sound nicer?&lt;/p&gt;</content>
  </entry>
  <entry>
    <id>tag:iay.org.uk,2022-08-12:/blog/2022/08/12/still-aggregating/</id>
    <title type="html">Still Aggregating</title>
    <published>2022-08-12T10:09:04Z</published>
    <updated>2022-08-12T10:09:04Z</updated>
    <link rel="alternate" href="https://iay.org.uk/blog/2022/08/12/still-aggregating/" type="text/html"/>
    <content type="html">
&lt;p&gt;
&lt;a style="margin: 0px 10px 10px 0px;" href="/blog/2012/08/ukf-flows.png"&gt;&lt;img src="/blog/2012/08/ukf-flows-thumb.png" width="220" height="154" alt=""&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;This morning, I was having a conversation with a colleague about the &lt;a href="https://www.ukfederation.org.uk/" title="UK Access Management Federation for Education and Research"&gt;UK federation&lt;/a&gt;’s
metadata publication system. We needed to reference the order of operations
and I remembered that I had once published an article about this system, along with a diagram
illustrating just the point under consideration.&lt;/p&gt;

&lt;p&gt;Pulling up the article in question, I was slightly surprised to find that the
&lt;a href="/blog/2012/08/uk-federation-metadata-aggregation/"&gt;original article&lt;/a&gt; was published exactly ten years ago today.&lt;/p&gt;

&lt;p&gt;The original architecture of this system was deliberately flexible, because we didn’t really
know for sure the environment we’d be operating in. It’s gratifying, therefore, to see
that the basic design has held up well enough that we can still use the article as
an informal reference.&lt;/p&gt;

&lt;p&gt;In detail, of course, things are different now than we anticipated and the
deployed system has aspects which are simpler than a decade ago, as well as others
which have required some elaboration. At present, for example, &lt;a href="https://edugain.org/"&gt;eduGAIN&lt;/a&gt; has been
successful enough that it is currently the only active source of metadata other than that
registered by the UK federation itself. On the other side, we produce a number of
additional outputs today that we hadn’t really considered at the time, the most important
of those probably being that we now publish &lt;a href="https://www.ukfederation.org.uk/content/Documents/MDQ"&gt;per-entity metadata&lt;/a&gt; as well as the
aggregate metadata illustrated.&lt;/p&gt;

&lt;p&gt;Another major change – one that happened in 2013, about a year after the article
was published – was that we started publishing the tooling itself in a
&lt;a href="https://github.com/ukf/ukf-meta/"&gt;GitHub repository&lt;/a&gt; for the benefit of other organisations working in
the same area. I remember the big challenge there being that the original repository
(which dated back to 2004) contained customer data; the version we published
had to be filtered using &lt;code&gt;git filter-branch&lt;/code&gt; for privacy (see the &lt;a href="https://github.com/ukf/ukf-meta-meta/"&gt;ukf-meta-meta&lt;/a&gt;
repository for the gory details). We’ve since rebased our development so that
our internal repository matches the published one except that we don’t expose
development work in progress. I’m really glad not to be reliant on &lt;code&gt;filter-branch&lt;/code&gt;
any more, and I’m sure any reader who has dipped a toe into those waters
will sympathise.&lt;/p&gt;

&lt;p&gt;Anyway: Happy birthday, &lt;a href="/blog/2012/08/ukf-flows.png"&gt;helpful diagram&lt;/a&gt;!&lt;/p&gt;</content>
  </entry>
</feed>

