Sunday, 30. April 2023Week 17
.: Why Personal Blogging Still Rules

Resonating article from Mike Grindle about personal blogging and how it fits into todays Internet: Why Personal Blogging Still Rules

Before the social media craze or publishing platforms, and long before ‘content creator’ was a job title, blogs served as one of the primary forms of online expression and communication.

Everything on your blog was made to look and feel the way you wanted. If it didn’t, you rolled your sleeves up and coded that stuff in like the webmaster you were. And if the masses didn’t like it, who cared? They had no obligations to you, and you had none to them.

Hiding beneath the drivel that is Google’s search results, and all the trackers, cookies, ads and curated feeds that come with them, personal blogs and sites of all shapes and sizes are still there. They’re thriving even in a kind of interconnected web beneath the web.

The blogs on this small or “indie” web come in many shapes and sizes. […] But at their core, they all have one characteristic in common: they’re there because their owners wanted to carve out their space on the internet.

Your blog doesn’t have to be big and fancy. It doesn’t have to outrank everyone on Google, make money or “convert leads” to be important. It can be something that exists for its own sake, as your place to express yourself in whatever manner you please.


14:42 | Misc | Permalink
Sunday, 23. April 2023Week 16
.: exec-hookd

To automate some of the deployment steps on my personal server, I needed a tool which can be triggered by a webhook and does execute some pre-defined commands.

A classic solution for this would be to have a simple PHP script with a call to system(...). But I don't have PHP installed on the server itself and wanted this to be more lightweight than a full Apache+PHP installation.

Thus exec-hookd was born. It is a small Go daemon which listens to HTTP POST requests and runs pre-defined commands when a matching path is requested.

Its configuration lives in a small JSON file, which lists the port to listen on and the paths together with their commands to execute:

  "Port": 8059,
  "HookList": [
      "Path": "/myhook",
      "Exec": [
          "Cmd": "/usr/bin/somecmd",
          "Args": [
          "Timeout": "5s"

The commands are called with a timeout after which they are stopped to avoid that things hang around forever.

22:32 | Linux | Permalink
Sunday, 16. April 2023Week 15
.: Nice git log alias

Ralf tooted a nice and tidy git log output alias for the console:

alias glg="git log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit"
13:55 | Coding | Permalink
Saturday, 18. March 2023Week 11
.: Docker registry facade with nginx

Found this inspiring blog post about how to use your own domain for Docker images. (via HN)

It explains how to use your own domain with redirects such that the Docker registry hosting the images can be changed easily. Your domain is only used for issueing HTTP redirects, so that the actual data storage and transfer happens directly with the Docker registry.

The blog post comes with a sample implementation for Caddy. As my server is running nginx, I used the following config snippet to achieve the same result:

server {
	listen 443 ssl;
	listen [::]:443 ssl;


	access_log	/var/log/nginx/;
	error_log	/var/log/nginx/;

	ssl_certificate		/etc/letsencrypt/live/;
	ssl_certificate_key	/etc/letsencrypt/live/;

	location / {
		return 403;

	location = /v2 {
		add_header Cache-Control 'max-age=300, must-revalidate';
		return 307$request_uri;
	location = /v2/ {
		add_header Cache-Control 'max-age=300, must-revalidate';
		return 307$request_uri;
	location = /v2/xway {
		add_header Cache-Control 'max-age=300, must-revalidate';
		return 307$request_uri;
	location /v2/xway/ {
		add_header Cache-Control 'max-age=300, must-revalidate';
		return 307$request_uri;

Quickly tested it with some docker pull commands and already integrated it into the build process of dnsupd.

10:36 | Linux | Permalink
Thursday, 26. January 2023Week 04
.: STRAYA 🇦🇺

Here's a bit older mashup. Happy Australia Day!

05:43 | Music | Permalink
Wednesday, 18. January 2023Week 03

Let's Encrypt recently introduced support for ACME-CAA.

I've now extended my existing CAA DNS entries with the ACME-CAA properties:

% dig +short -t CAA
0 issue "; accounturi=; validationmethods=http-01"
0 issue "; accounturi=; validationmethods=http-01"

The effect of this is that Let's Encrypt will only grant a signed TLS certificate if the request comes from one of my two accounts (authenticated with the corresponding private key).
If the certificate request comes from a different account, no TLS certificate will be granted.
This protects against man-in-the-middle attacks, specifically against attacks where someone between Let's Encrypt and my server would be trying to impersonate my server to obtain a signed TLS certificate.

In case you're wondering where to get the accounturi value from, it can be found in your account file:

% cat /etc/letsencrypt/accounts/*/regr.json
{"body": {}, "uri": ""}

23:06 | Networking | Permalink
Tuesday, 10. January 2023Week 02
.: JSON Feed

Added a JSON Feed to this blog (in additon to the existing RSS and Atom feeds):

To build the proper JSON file, I used this Jekyll template and the JSON Feed validator.

21:51 | Webdesign | Permalink
Tuesday, 3. January 2023Week 01
.: Get last 24h of logs with AWK

For a temporary log analysis task, I wanted to get the last 24h of logs from a Postfix logfile.
To achieve this I came up with the following AWK oneliner (which fails in spectacular ways around new years):

awk -F '[ :]+' 'BEGIN{m=split("Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec",d,"|"); for(o=1;o<=m;o++){months[d[o]]=sprintf("%02d",o)}} mktime(strftime("%Y")" "months[$1]" "sprintf("%02d",$2+1)" "$3" "$4" "$5) > systime()'

This is then used in a cronjob to get a pflogsumm summary of the last 24h:

cat /var/log/mail.log | awk -F '[ :]+' 'BEGIN{m=split("Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec",d,"|"); for(o=1;o<=m;o++){months[d[o]]=sprintf("%02d",o)}} mktime(strftime("%Y")" "months[$1]" "sprintf("%02d",$2+1)" "$3" "$4" "$5) > systime()' | pflogsumm
14:40 | Linux | Permalink
Saturday, 31. December 2022Week 52
.: Happy New Year 2023

As usual, Sydney is a bit ahead of us. Great memories, long time ago :-)

13:59 | Misc | Permalink
Sunday, 25. December 2022Week 51
.: Alpha Bravo Charlie

While closing an old account I had to communicate using the infamous NATO/ICAO phonetic alphabet (US banks like to exchange the 20+ character long IBANs via poor-quality call-center phonelines).

As it has been a while since I last used it, I created a handy table to quickly lookup the code words:

Special feature: when queried by curl (eg. without a text/html Accept header) it returns the table as plaintext :-)

# curl
A Alpha      S Sierra
B Bravo      T Tango
C Charlie    U Uniform
D Delta      V Victor
E Echo       W Whiskey
F Foxtrot    X X-ray
G Golf       Y Yankee
H Hotel      Z Zulu
I India      0 Zero
J Juliett    1 One
K Kilo       2 Two
L Lima       3 Three
M Mike       4 Four
N November   5 Five
O Oscar      6 Six
P Papa       7 Seven
Q Quebec     8 Eight
R Romeo      9 Niner

22:11 | Misc | Permalink