Funkenflug aus flammenden Synapsen.

Adding your Yubikey's SSH keys to your agent automatically

Sometimes, systemd makes things reasonably easy:

First of all, we want a new udev rule we can latch onto:

% cat /etc/udev/rules.d/98-yubikey5.rules 
SUBSYSTEMS=="usb", ACTION=="add", ATTRS{idVendor}=="1050", SYMLINK+="yubikey", 

This will create /dev/yubikey when a USB device from Vendor 0x1050, Yubico, is plugged in. Use udevadm control --reload to enable the new rule.

Now, we can have a user-level systemd unit that is started by this device:

% systemctl --user cat yubissh.service 
# /home/(me)/.config/systemd/user/yubissh.service
Description=Autoload Yubikey SSH keys


ExecStart = ssh-add -s /usr/lib/x86_64-linux-gnu/
ExecStop  = ssh-add -e /usr/lib/x86_64-linux-gnu/


Enable this with systemctl --user daemon-reload && systemctl --user enable yubissh.service and you should be good to go. (Don't forgot you need some sort of ssh-askpass binary, too!)

I dent, you dent, we all dent for syslog.

This was a "fun" one to figure out… we run a (actually several) shared PHP-FPM setups at work for our customers. While they're not big or sensitive enough to warrant per-user process segregation, we'd still like them to get their own php error logs, so we can tell them they need to fix their own messes.

This is possible, but a bit… batteries not included, let's say. I have about six points in the following where either the semantics are unclear but currently work the way I want them to, or the features I use are so obscure that PHP might drop them.

Step 1: use syslog.

Starting from PHP 7.3, you can set syslog.ident, the prefix of syslog messages. It's configurable at PHP_INI_SYSTEM level, i.e. basically in php.ini. I won't go into detail on how to point the syslog to a remote logging server or something like that, partially because I don't understand rsyslog enough, it can't possibly be as bad as it feels to me.

Step 2: but that doesn't work, does it?

We have several users connecting into the same php-fpm processes, which share a common php.ini. Are we out of luck? As it turns out, no. Well-hidden in the docs, we find that you can have php.ini sections that only apply to certain directories or hostnames:

syslog.ident = "user1php"

syslog.ident = "user2php"

Step 3: but you'll have a monolithic, often-changing php.ini now!

Turns out, no. There is an environment variable PHP_INI_SCAN_DIR, again so documented you only find it if you know it exists, that points at a directory full of .ini files and applies all of them. You will have to augment your systemd service file to use it:


Step 4: but that doesn't work, does it?

You're right. phpinfo() will tell you all the settings get there, but you won't see the prefixes you want in the syslog. This is because even though you can set syslog.ident on a per-directory basis, it's only used once, when openlog is called. (This might be implicitly when syslog() is called for the first time.)

So, we need more help, by way of auto_prepend_file. Prepending something to every file at parse time is exactly what we need to make sure the proper syslog.ident is applied:

         constant("LOG_" . strtoupper(ini_get('syslog.facility'))));

Yes, that constant(…) construct looks ugly and is probably not the best way to do it. In practice, you could probably hardcode the value you want there anyway. You probably don't strictly need the closelog() either.

And yes, this is semantically very odd: as per docs,

[t]he [autoprepended] file is included as if it was called with the require function

and it doesn't itself need to be within the scope given by the [PATH=] section, it just needs to be covered by open_basedir and include_path. This is something I'm pretty worried about, because it looks like the intended behaviour is under-defined, so if it breaks it's just "why did you use such a border case anyway".

Step 5: Is this going anywhere useful?

We're almost there. It'll look good when you test it. It'll fall over in production and direct all logs to a small number of files. The problem will mysteriously go away as you try to debug it, and come back when you're not looking.

The problem is: opcache. PHP keeps some files parsed and precompiled to bytecode for performance reasons. Since our autoprepended file is getting hit for literally every request, it will never leave the cache unless you change the source file. Unfortunately, though, bytecompiling it will apparently resolve the ini_gets since it thinks they're constants. I can't blame opcache here, after all, it's the literally same file, just included from different paths.

Fortunately, there is the (at time of writing still named thusly) opcache.blacklist_filename, with which you can tell PHP to never cache bytecode for the autoprepended file.

Step 6: Profit??

Now you should get your nice stream of syslog messages with the right prefixes. Splitting that off into different files is left as an exercise for the reader. ;-)

This is not the error page you aren't looking for

Tired of manually managing redirects because users can't spell? Proxy all 404 pages to your local link shortener, and let that sort it out.

ErrorDocument 404 /.404/%{sha1:%{SERVER_NAME}%{REQUEST_URI}}?%{QUERY_STRING}
RewriteRule ^/.404/(.*)$ http://sho.rt/$1 [P]

(Needs to be a [P] in order to not have a redirect to a 404 in case of non-existing page.)

In case I ever need this again, part 57

Long delays when using xdg-open or firefox --new-tab can be caused by a stale /tmp/firefox_$USER directory. Remove (as root, apparently, or maybe I had a leftover permissions issue there) and you should be good to go.

Because I'm going to need this again: fixing firefox/nss token certificate bug

Documenting this here because Mozilla's docs are bullshit. I have no idea how much kool-aid is needed to actually try and develop extensions for this crock of shit…

For some time now, you can't seem to save settings you make in the security devices settings. (To be exact: you can see them added to the NSS database, but on restarting your thunderbird/firefox, your NSS database is overwritten with one only containing the default entries. Removing permissions fro the relevant database files in the profile directory only leads to the software ignoring them.)

Anyway, so find a elevated javascript console (in thunderbird, that's Ctrl-Shift-J) and paste

Components.classes[";1"].getService(Components.interfaces.nsIPKCS11).addModule("p11autoproxy", "/usr/lib64/", 0, 0); 
Components.classes[";1"].getService(Components.interfaces.nsIPK11TokenDB).findTokenByName("PIV_II (PIV Card Holder pin)").login(true);

Obviously, the name might be different for you – if you manually add the device through the GUI, it's the string listed as "Label".

Next on the list: find out how to either force this early enough in the startup process or to automatically re-select the certs to use for signatures for certain accounts.

Everyday I sing the blues…

Return to work at 8pm because customer had filed a "needs to be fixed urgently" bug earlier today, and I had to request further info to reproduce and hadn't heard back by the end of my work day (which is around 3pm).

Nope, nuttin', other than being a #dienstleistungsheld. Wobei, es könnte weitaus schlimmer sein.

Pump up the retro.

My mind is currently stuck on MARRS. Hey, don't judge me, I grew up with animations of sat solar sails unfolding, and the occasional newspaper piece on where Voyager 2 currently was. I remember being on vacation at my grandma's place when Challenger exploded, the booster rockets making the thing look like a perverse caterpillar made of steam and dead astronauts.


I guess in retrospect, you can say it was obvious that I'd end up in IT, with its tiny automation steps unfolding, trying to build order in a world that is mad chaotic.

What could possible go wrong at that point?

— ölf's turn 1 —
ölf activates the dogma of Metalworking1.
... ölf draws and scores Archery1, Masonry1, City States1, Oars1, Domestication1, and The Wheel1.
... ölf achieves Monument!
... ölf draws Writing1.