Saturday, 31. December 2022 Week 52
Sunday, 25. December 2022 Week 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: nato.sigint.ch

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

# curl nato.sigint.ch
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
Sunday, 7. August 2022 Week 31
Wednesday, 6. July 2022 Week 27

Add node to MongoDB cluster

To add a new node to an existing MongoDB cluster, login to the mongo shell on the primary node and run the following command:

rs.add({host:"mongodb3.example.net:27017"})

Similar to remove a node from the cluster, use:

rs.remove("mongodb3.example.net:27017")
Sunday, 19. June 2022 Week 24

Custom nginx error pages

For quite some time I've been using custom nginx error pages on this site.
My approach so far was to generate a bunch of static HTML with the various error messages and then configure them for each corresponding HTTP status codes in nginx.
As there are quite a number of HTTP errors, I used a little shell script to generate the whole config and HTML, in the end I had a huge file with snippets like the one below.

error_page 429 @custom_error_429;
location @custom_error_429 {
	internal;
	more_set_headers 'Content-Type: text/html';
	echo '<html>...</html>';
}

Now while implementing custom error pages for a different project, I tried to see if there is an easier way to do this.
Some searching lead to the One NGINX error page to rule them all article which describes an alternative approach leveraging the nginx SSI module to generate the error pages on the fly.

Instead of generating and defining a specific error page for each error, a single error page is used for all errors.

error_page 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414
           415 416 417 418 421 422 423 424 425 426 428 429 431 451 500
           501 502 503 504 505 506 507 508 510 511 /error.html;

location = /error.html {
	ssi on;
	internal;
	root /var/www/default;
}

nginx provides the status code as variable to our error page, but we also need the error message to make it more userfriendly.
For this we define a mapping of status codes to the error messages.

map $status $status_text {
  400 'Bad Request';
  401 'Unauthorized';
  402 'Payment Required';
  403 'Forbidden';
  404 'Not Found';
  405 'Method Not Allowed';
  406 'Not Acceptable';
  407 'Proxy Authentication Required';
  408 'Request Timeout';
  409 'Conflict';
  410 'Gone';
  411 'Length Required';
  412 'Precondition Failed';
  413 'Payload Too Large';
  414 'URI Too Long';
  415 'Unsupported Media Type';
  416 'Range Not Satisfiable';
  417 'Expectation Failed';
  418 'I\'m a teapot';
  421 'Misdirected Request';
  422 'Unprocessable Entity';
  423 'Locked';
  424 'Failed Dependency';
  425 'Too Early';
  426 'Upgrade Required';
  428 'Precondition Required';
  429 'Too Many Requests';
  431 'Request Header Fields Too Large';
  451 'Unavailable For Legal Reasons';
  500 'Internal Server Error';
  501 'Not Implemented';
  502 'Bad Gateway';
  503 'Service Unavailable';
  504 'Gateway Timeout';
  505 'HTTP Version Not Supported';
  506 'Variant Also Negotiates';
  507 'Insufficient Storage';
  508 'Loop Detected';
  510 'Not Extended';
  511 'Network Authentication Required';
  default 'Something went wrong';
}

Now we have the status and the status_text variables available in our error.html page.

<html><body>
<h1><!--# echo var="status" default="" --> 
<!--# echo var="status_text" default="Something went wrong" --></h1>
</body></html>
Wednesday, 15. June 2022 Week 24

nitter

nitter provides a free and open source alternative front-end to Twitter. It talks with the API and does not show any JavaScript or ads (thus no 'forced-login' overlay after reading 5 tweets or similar nastiness).
The source code for it is available on GitHub.

It does a direct mapping of the profile URLs, thus https://twitter.com/sheeshee becomes https://nitter.net/sheeshee

Saturday, 4. June 2022 Week 22
Thursday, 2. June 2022 Week 22

Happy 20th Birthday x-log

On June 2nd 2002 I published the first (test) entry in this weblog. The first entry has disappeared since (thus making the second entry the first one in the archive of June 2002).

Screenshot of the first (test) entry

Compared to 20 years ago, the about page no longer needs to explain what a weblog is.
Interesting though that the linked definition of a weblog from back then already did foresee the rise and fall in popularity of weblogs which happend during the last two decades.
To me it seems in the last 1-2 years there has been an increase again in activity around personal weblogs; curious to see if this revival trend continues.

Also the weblog here has changed quite a bit. Initially its content was more on the pure web-logging side (commenting on interesting links I encountered during my daily Internet surfing) mixed with some kind of a journal/commentary of my day-to-day life. Later on it moved more towards a 'knowledge dump' on technical topics mixed with some music discoveries and random personal post from festivals and travels. And lately it has been rather sparse again with posts, still mostly on technical topics around coding, networking, security mixed with some personal posts commenting on the current world situation.
The frequency of posts also followed the changes in content where early on there sometimes were multiple posts per day, nowadays there can be multiple months without any post and there were even entire years where nothing new was posted; let's see how this goes in the future :-)

From the list of linked Blogs in 2002, only deep-resonance aka mk is still active, special shout-out to Markus for the continuous persistence.
To the next twenty years :-)

Saturday, 26. March 2022 Week 12

mt-set-time

A while ago I wrote a little tool to set the time on MikroTik devices. It takes the current time from the local machine and does set it on the device through the API (while respecting the timezone configured on it).
I mostly use it to set the proper time when the device time was completely off (when setting up a new device or when it has been powered off for a long time). Afterwards NTP should take care of keeping the time in sync.

The tool is now available on GitHub together with installation and usage instructions: mt-set-time

Tuesday, 15. March 2022 Week 11
Sunday, 27. February 2022 Week 8
Saturday, 26. February 2022 Week 8

Non à la guerre! Nein zum Krieg!

Today I went to Bern to the rally for peace.
My motivation was to show support for the people suffering in this war and to send a signal to our swiss government that the population wants clear participation in sanctions (while remaining neutral, the two in my view are not exclusive!).

Swiss media reported that this was the largest rally for peace in Switzerland since the rallies against the war in Iraq in 2003. That I can link to my own blog entry regarding the rally for peace from 19 years ago, makes me sad.
Clearly we as human species did not progress enough on this topic :-(

Besides showing up to the rally, I also did donate to the ICRC to provide humanitarian aid and I do encourage you to do the same.

Sunday, 20. February 2022 Week 7
Saturday, 29. January 2022 Week 4

vtysock

After switching my Debian hosts from Quagga to FRRouting, I noticed that running vtysh has become quite a bit slower especially when making multiple calls to it from my status/monitoring scripts.
This has also been observed by other users of FRRouting (there's an open issue in their bugtracker: #7799).

The Prometheus frr_exporter works around this by directly sending commands to the UNIX sockets of the FRR daemons (PR).

To use the same approach in my monitoring scripts, I wrote a small utility which acts as a drop-in replacement for vtysh and sends the commands directly to the UNIX sockets of the FRR daemons: vtysock
By skipping the parsing and validation checks done in vtysh, vtysock can achieve a significant speed improvement when executing commands.

Sunday, 23. January 2022 Week 3

Force SSH to use IPv6

In situations where IPv6 connectivity performs better than IPv4, you might want to force SSH to use IPv6. In interactive mode this can be achieved with the -6 commandline parameter.
But in situations where you can't modify the commandline parameters a different approach is needed (for example in rsync backup scripts which use SSH as underlying transport layer).

We can use the ssh_config file to encforce that IPv6 is used for a specific host:

Host myipv6host
	AddressFamily inet6

This instructs all SSH commands to use IPv6 when connecting to myipv6host.

The same approach also works to force usage of Legacy IP by specyfing inet as address family.

Wednesday, 19. January 2022 Week 3

Google Analytics removed

After running it for a bit more than a decade, I've now removed again the Google Analytics tracking from this site. It does not feel appropriate anymore on a personal website.
At the moment no alternative statistics solution is in place yet, but I could imagine setting up a self-hosted solution like Matomo or Plausible in the future.

Wednesday, 5. January 2022 Week 1

Wordle

Wordle seems to be the trending topic these days.
It's a word game similar to the french Motus game show (resp. the american Lingo game show).

Wordle 200 4/6

⬜⬜⬜🟩⬜
⬜⬜🟨🟩⬜
⬜⬜⬜🟩🟩
🟩🟩🟩🟩🟩

Saturday, 1. January 2022 Week 0

Y2K22

Turns out that signed 32-bit numbers can be exhausted long before Y2038, when you use them to store time in YYMMDDHHMM format. (via)