Sunday, 16. April 2023 Week 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"
Saturday, 18. March 2023 Week 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;

	server_name	docker.x-way.org;

	access_log	/var/log/nginx/docker.x-way.org.access.log;
	error_log	/var/log/nginx/docker.x-way.org.error.log;

	ssl_certificate		/etc/letsencrypt/live/docker.x-way.org/fullchain.pem;
	ssl_certificate_key	/etc/letsencrypt/live/docker.x-way.org/privkey.pem;

	location / {
		return 403;
	}

	location = /v2 {
		add_header Cache-Control 'max-age=300, must-revalidate';
		return 307 https://registry.hub.docker.com$request_uri;
	}
	location = /v2/ {
		add_header Cache-Control 'max-age=300, must-revalidate';
		return 307 https://registry.hub.docker.com$request_uri;
	}
	location = /v2/xway {
		add_header Cache-Control 'max-age=300, must-revalidate';
		return 307 https://registry.hub.docker.com$request_uri;
	}
	location /v2/xway/ {
		add_header Cache-Control 'max-age=300, must-revalidate';
		return 307 https://registry.hub.docker.com$request_uri;
	}
}

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

Thursday, 26. January 2023 Week 4
Wednesday, 18. January 2023 Week 3

ACME-CAA

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 x-way.org
0 issue "letsencrypt.org; accounturi=https://acme-v02.api.letsencrypt.org/acme/acct/68891730; validationmethods=http-01"
0 issue "letsencrypt.org; accounturi=https://acme-v02.api.letsencrypt.org/acme/acct/605777876; 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.

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

% cat /etc/letsencrypt/accounts/acme-v02.api.letsencrypt.org/directory/*/regr.json
{"body": {}, "uri": "https://acme-v02.api.letsencrypt.org/acme/acct/605777876"}
Tuesday, 10. January 2023 Week 2
Tuesday, 3. January 2023 Week 1

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
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")