Don't understand german? Read or subscribe to my english-only feed.

HTU Bigband Konzert am 04.06.2024

May 28th, 2024

Plakat für das HTU Bigband-Konzert am 04.06.2024

Am Dienstag den 4. Juni spielen wir ab 19:30 Uhr unser nächstes HTU-Bigband-Konzert. Das Konzert findet im Innenhof der TU Graz (Alte Technik, Rechbauerstraße 12, 8010 Graz) statt, bei Schlechtwetter geht es an der gleichen Adresse in den wunderbaren Hörsaal 2. Wir sind über 25 Musikerinnen und Musiker und haben ein anspruchsvolles Programm – von Swing, über Soul, Funk und Latin bis Pop ist alles dabei. Es gibt über 2 Stunden Musik vom Feinsten, und das Ganze bei freiem Eintritt.

Das Event gibt es auch auf Facebook und Instagram zum “Liken” und Weiterverteilen.

Ich freue mich schon tierisch darauf und würde mich über bekannte Gesichter freuen. Ich hoffe man sieht und hört sich! :-)

Being a Debian Developer since 15 years

May 28th, 2024

15 years ago I became an official Debian Developer. Incredible how time flies.

Vortrag: We got hacked: Lektionen aus realen Security-Vorfällen @ GLT24

April 7th, 2024

Auf den Grazer Linuxtagen 2024 (GLT24) war ich als Referent mit einem Vortrag zum Thema “We got hacked: Lektionen aus realen Security-Vorfällen” vertreten. In meinem Vortrag gibt es einen Einblick in reale Security-Incidents und welche Lektionen sich aus solchen Vorfällen mitnehmen lassen.

Es gibt den Vortrag dank des fantastischen c3voc-Teams bereits als Videomitschnitt online. Meine Vortragsfolien (2.1MB, PDF) stehen ebenfalls online zur Verfügung. Viel Spaß beim Anschauen!

Mein Lesejahr 2023

January 3rd, 2024

Foto der hier vorgestellten Bücher

Ich habe auch 2023 keine Bookdumps geschrieben (zu viel Aufwand), darum gibt es auch diesmal wieder (siehe Lesejahr 2022 für die letzte Ausgabe) eine Art Best-Of der von mir 2023 fertig gelesenen Bücher, also jene die ich besonders lesenswert fand bzw. empfehlen möchte (die Reihenfolge entspricht dem Foto und stellt keinerlei Reihung oder dergleichen dar):

  • Das glücklichste Volk: Sieben Jahre bei den Pirahã-Indianern am Amazonas, Daniel L. Everett. Diese Buch ist eine Empfehlung von Khaled Hakami, der u.a. im Erklär-mir-die-Welt-Podcast zum Thema Erklär mir Jäger und Sammle zu Gast war. Das Buch ist eine große Empfehlung speziell für all jene Leute, die sich für andere Kulturen interessieren. Es ist eines der horizonterweiterndsten Bücher, das ich in den letzten Jahren gelesen habe.
  • Kleine Probleme, Nele Pollatschek. Der letzte Tag des Jahres, eine To-do-Liste, unerledigte Dinge und die Sehnsucht nach Ordnung. Die Autorin schreibt aus Sicht von Lars, Familienvater und Endvierziger ein unterhaltsames Buch.
  • Gentleman über Bord, Herbert Clyde Lewis. Ein Roman aus dem Jahr 1937, in dem der Protagonist Henry bei einer Schiffsreise bei einem Missgeschick über Bord geht, und die restliche Besatzung des Schiffes jede Menge Ausreden für sich (er)findet, um das Verschwinden des Passagiers Henry zu entschuldigen. Bedeutungstief und zeitlos.
  • The Undoing Project: A Friendship That Changed Our Minds, Michael Lewis. Ein Buch das die Freundschaft und Lebensweg von Daniel Kahneman (bekannt u.a. für das Buch “Thinking, Fast and Slow”) und Amos Tversk beleuchtet, jene Herren die u.a. für die Prospect Theory bekannt sind. Ich wurde auf das Buch über die wunderbare Rezension von Kathrin Passig aufmerksam, und mir hat das Buch voll zugesagt (auch wenn ein Lesebuddy zurecht anmerkte, dass man kein Problem mit amerikanischen Journalisten als Autor wie auch ein bisserl Drama haben sollte, mich hat beides nicht gestört). Für mich war das Buch insgesamt sehr gut gemacht, es gab einige interessante Stellen und diente mir als Erinnerung, dass ich die Werke von Kahneman (wieder) mal (fertig)lesen sollte.
  • Mir geht’s gut, wenn nicht heute, dann morgen, Dirk Stermann. Eine wunderbare Mischung aus ernsten Themen und Schmäh.
  • Vati, Monika Helfer. Eine Fortsetzung ihrer eigenen Familiengeschichte, ich mag die schlichte und trotzdem berührende Sprache.
  • Eigentum, Wolf Haas. Ich habe Haas erst 2022 für mich entdeckt, er ist einer meiner Lieblingsautoren und ich bin seither auf dem Weg alles von ihm zu lesen. Auch Eigentum ist ein wunderschönes Buch, in dem Haas von seiner sterbenden Mutter schreibt. Sprachkünstler, Hilfsausdruck!
  • Arbeit und Struktur, Wolfgang Herrndorf. Los ging es mit dem Schließen einer Bildungslücke: Tschick vom selbigen Autor hat mich dermaßen reingezogen, dass ich auch endlich mal dessen Arbeit und Struktur angefangen habe, ein Buch das Clemens J. Setz im Podcast “Das Lesen der Anderen” empfohlen hat. Das Buch ist die Autobiografie der letzten Lebensjahre des Autors. Ursprünglich als Blog aufgesetzt nachdem der Autor die Diagnose Hirntumor bekommen hat, wurde sein digitales Tagebuch dann in Papier- und Buchform gebracht. Man möge sich von dem vielleicht etwas sperrigen Titel nicht aufhalten lassen. Ein beeindruckendes, bewegendes und großartiges Buch.
  • Die Herrenausstatterin, Mariana Leky. Ich bin ein Fan von Mariana Leky und habe über die letzten Jahre regelmäßig Bücher von ihr gelesen, so auch dieses wunderbare Buch über eine Dreiecksgeschichte.

Ich freue mich übrigens über Feedback, wenn jemand von euch ein Buch aufgrund dieses Beitrags hier gelesen oder selbst Lese-Empfehlungen für mich hat.

Postfix failing with “no shared cipher”

September 25th, 2023

I’m one of the few folks left who run and maintain mail servers. Recently I had major troubles receiving mails from the mail servers used by a bank, and when asking my favourite search engine, I’m clearly not the only one who ran into such an issue. Actually, I should have checked off the issue and not become a customer at that bank, but the tech nerd in me couldn’t resist getting to the bottom of the problem. Since I got it working and this might be useful for others, here we are. :)

I was trying to get an online banking account set up, but the corresponding account creation mail didn’t arrive me, at all. Looking at my mail server logs, my postfix mail server didn’t accept the mail due to:

postfix/smtpd[3319640]: warning: TLS library problem: error:1417A0C1:SSL routines:tls_post_process_client_hello:no shared cipher:../ssl/statem/statem_srvr.c:2283:
postfix/smtpd[3319640]: lost connection after STARTTLS from mx01.arz.at[193.110.182.61]

Huh, what’s going on here?! Let’s increase the TLS loglevel (setting smtpd_tls_loglevel = 2) and retry. But how can I retry receiving yet another mail? Luckily, on the registration website of the bank there was a URL available, that let me request a one-time password. This triggered another mail, so I did that and managed to grab this in the logs:

postfix/smtpd[3320018]: initializing the server-side TLS engine
postfix/tlsmgr[3320020]: open smtpd TLS cache btree:/var/lib/postfix/smtpd_scache
postfix/tlsmgr[3320020]: tlsmgr_cache_run_event: start TLS smtpd session cache cleanup
postfix/smtpd[3320018]: connect from mx01.arz.at[193.110.182.61]
postfix/smtpd[3320018]: setting up TLS connection from mx01.arz.at[193.110.182.61]
postfix/smtpd[3320018]: mx01.arz.at[193.110.182.61]: TLS cipher list "aNULL:-aNULL:HIGH:MEDIUM:+RC4:@STRENGTH"
postfix/smtpd[3320018]: SSL_accept:before SSL initialization
postfix/smtpd[3320018]: SSL_accept:before SSL initialization
postfix/smtpd[3320018]: SSL3 alert write:fatal:handshake failure
postfix/smtpd[3320018]: SSL_accept:error in error
postfix/smtpd[3320018]: SSL_accept error from mx01.arz.at[193.110.182.61]: -1
postfix/smtpd[3320018]: warning: TLS library problem: error:1417A0C1:SSL routines:tls_post_process_client_hello:no shared cipher:../ssl/statem/statem_srvr.c:2283:
postfix/smtpd[3320018]: lost connection after STARTTLS from mx01.arz.at[193.110.182.61]
postfix/smtpd[3320018]: disconnect from mx01.arz.at[193.110.182.61] ehlo=1 starttls=0/1 commands=1/2
postfix/smtpd[3320018]: connect from mx01.arz.at[193.110.182.61]
postfix/smtpd[3320018]: disconnect from mx01.arz.at[193.110.182.61] ehlo=1 quit=1 commands=2

Ok, so this TLS cipher list “aNULL:-aNULL:HIGH:MEDIUM:+RC4:@STRENGTH” looked like the tls_medium_cipherlist setting in postfix, but which ciphers might we expect? Let’s see what their SMTP server would speak to us:

% testssl --cipher-per-proto -t=smtp mx01.arz.at:25
[...]
Hexcode  Cipher Suite Name (OpenSSL)       KeyExch.   Encryption  Bits     Cipher Suite Name (IANA/RFC)
-----------------------------------------------------------------------------------------------------------------------------
SSLv2
SSLv3
TLS 1
TLS 1.1
TLS 1.2
 xc030   ECDHE-RSA-AES256-GCM-SHA384       ECDH 256   AESGCM      256      TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
 xc028   ECDHE-RSA-AES256-SHA384           ECDH 256   AES         256      TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
 xc014   ECDHE-RSA-AES256-SHA              ECDH 256   AES         256      TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
 x9d     AES256-GCM-SHA384                 RSA        AESGCM      256      TLS_RSA_WITH_AES_256_GCM_SHA384
 x3d     AES256-SHA256                     RSA        AES         256      TLS_RSA_WITH_AES_256_CBC_SHA256
 x35     AES256-SHA                        RSA        AES         256      TLS_RSA_WITH_AES_256_CBC_SHA
 xc02f   ECDHE-RSA-AES128-GCM-SHA256       ECDH 256   AESGCM      128      TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
 xc027   ECDHE-RSA-AES128-SHA256           ECDH 256   AES         128      TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
 xc013   ECDHE-RSA-AES128-SHA              ECDH 256   AES         128      TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
 x9c     AES128-GCM-SHA256                 RSA        AESGCM      128      TLS_RSA_WITH_AES_128_GCM_SHA256
 x3c     AES128-SHA256                     RSA        AES         128      TLS_RSA_WITH_AES_128_CBC_SHA256
 x2f     AES128-SHA                        RSA        AES         128      TLS_RSA_WITH_AES_128_CBC_SHA
TLS 1.3

Looks like a very small subset of ciphers, and they don’t seem to be talking TLS v1.3 at all? Not great. :(

A nice web service to verify the situation from another point of view is checktls, which also confirmed this:

[000.705] 	<-- 	220 2.0.0 Ready to start TLS
[000.705] 		STARTTLS command works on this server
[001.260] 		Connection converted to SSL
		SSLVersion in use: TLSv1_2
		Cipher in use: ECDHE-RSA-AES256-GCM-SHA384
		Perfect Forward Secrecy: yes
		Session Algorithm in use: Curve P-256 DHE(256 bits)
		Certificate #1 of 3 (sent by MX):
		Cert VALIDATED: ok
		Cert Hostname VERIFIED (mx01.arz.at = *.arz.at | DNS:*.arz.at | DNS:arz.at)
[...]
[001.517] 		TLS successfully started on this server

I got distracted by some other work, and when coming back to this problem, the one-time password procedure no longer worked, as the password reset URL was no longer valid. :( I managed to find the underlying URL, and with some web developer tools tinkering I could still use the website to let me trigger sending further one-time password mails, phew.

Let’s continue, so my mail server was running Debian/bullseye with postfix v3.5.18-0+deb11u1 and openssl v1.1.1n-0+deb11u5, let’s see what it offers:

% testssl --cipher-per-proto -t=smtp mail.example.com:25
[...]
Hexcode  Cipher Suite Name (OpenSSL)       KeyExch.   Encryption  Bits     Cipher Suite Name (IANA/RFC)
-----------------------------------------------------------------------------------------------------------------------------
SSLv2
SSLv3
TLS 1
 xc00a   ECDHE-ECDSA-AES256-SHA            ECDH 253   AES         256      TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
 xc019   AECDH-AES256-SHA                  ECDH 253   AES         256      TLS_ECDH_anon_WITH_AES_256_CBC_SHA
 x3a     ADH-AES256-SHA                    DH 2048    AES         256      TLS_DH_anon_WITH_AES_256_CBC_SHA
 x89     ADH-CAMELLIA256-SHA               DH 2048    Camellia    256      TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA
 xc009   ECDHE-ECDSA-AES128-SHA            ECDH 253   AES         128      TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
 xc018   AECDH-AES128-SHA                  ECDH 253   AES         128      TLS_ECDH_anon_WITH_AES_128_CBC_SHA
 x34     ADH-AES128-SHA                    DH 2048    AES         128      TLS_DH_anon_WITH_AES_128_CBC_SHA
 x9b     ADH-SEED-SHA                      DH 2048    SEED        128      TLS_DH_anon_WITH_SEED_CBC_SHA
 x46     ADH-CAMELLIA128-SHA               DH 2048    Camellia    128      TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA
TLS 1.1
 xc00a   ECDHE-ECDSA-AES256-SHA            ECDH 253   AES         256      TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
 xc019   AECDH-AES256-SHA                  ECDH 253   AES         256      TLS_ECDH_anon_WITH_AES_256_CBC_SHA
 x3a     ADH-AES256-SHA                    DH 2048    AES         256      TLS_DH_anon_WITH_AES_256_CBC_SHA
 x89     ADH-CAMELLIA256-SHA               DH 2048    Camellia    256      TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA
 xc009   ECDHE-ECDSA-AES128-SHA            ECDH 253   AES         128      TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
 xc018   AECDH-AES128-SHA                  ECDH 253   AES         128      TLS_ECDH_anon_WITH_AES_128_CBC_SHA
 x34     ADH-AES128-SHA                    DH 2048    AES         128      TLS_DH_anon_WITH_AES_128_CBC_SHA
 x9b     ADH-SEED-SHA                      DH 2048    SEED        128      TLS_DH_anon_WITH_SEED_CBC_SHA
 x46     ADH-CAMELLIA128-SHA               DH 2048    Camellia    128      TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA
TLS 1.2
 xc02c   ECDHE-ECDSA-AES256-GCM-SHA384     ECDH 253   AESGCM      256      TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
 xc024   ECDHE-ECDSA-AES256-SHA384         ECDH 253   AES         256      TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384
 xc00a   ECDHE-ECDSA-AES256-SHA            ECDH 253   AES         256      TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
 xcca9   ECDHE-ECDSA-CHACHA20-POLY1305     ECDH 253   ChaCha20    256      TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256
 xc0af   ECDHE-ECDSA-AES256-CCM8           ECDH 253   AESCCM8     256      TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8
 xc0ad   ECDHE-ECDSA-AES256-CCM            ECDH 253   AESCCM      256      TLS_ECDHE_ECDSA_WITH_AES_256_CCM
 xc073   ECDHE-ECDSA-CAMELLIA256-SHA384    ECDH 253   Camellia    256      TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384
 xc019   AECDH-AES256-SHA                  ECDH 253   AES         256      TLS_ECDH_anon_WITH_AES_256_CBC_SHA
 xa7     ADH-AES256-GCM-SHA384             DH 2048    AESGCM      256      TLS_DH_anon_WITH_AES_256_GCM_SHA384
 x6d     ADH-AES256-SHA256                 DH 2048    AES         256      TLS_DH_anon_WITH_AES_256_CBC_SHA256
 x3a     ADH-AES256-SHA                    DH 2048    AES         256      TLS_DH_anon_WITH_AES_256_CBC_SHA
 xc5     ADH-CAMELLIA256-SHA256            DH 2048    Camellia    256      TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA256
 x89     ADH-CAMELLIA256-SHA               DH 2048    Camellia    256      TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA
 xc05d   ECDHE-ECDSA-ARIA256-GCM-SHA384    ECDH 253   ARIAGCM     256      TLS_ECDHE_ECDSA_WITH_ARIA_256_GCM_SHA384
 xc02b   ECDHE-ECDSA-AES128-GCM-SHA256     ECDH 253   AESGCM      128      TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
 xc023   ECDHE-ECDSA-AES128-SHA256         ECDH 253   AES         128      TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
 xc009   ECDHE-ECDSA-AES128-SHA            ECDH 253   AES         128      TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
 xc0ae   ECDHE-ECDSA-AES128-CCM8           ECDH 253   AESCCM8     128      TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8
 xc0ac   ECDHE-ECDSA-AES128-CCM            ECDH 253   AESCCM      128      TLS_ECDHE_ECDSA_WITH_AES_128_CCM
 xc072   ECDHE-ECDSA-CAMELLIA128-SHA256    ECDH 253   Camellia    128      TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256
 xc018   AECDH-AES128-SHA                  ECDH 253   AES         128      TLS_ECDH_anon_WITH_AES_128_CBC_SHA
 xa6     ADH-AES128-GCM-SHA256             DH 2048    AESGCM      128      TLS_DH_anon_WITH_AES_128_GCM_SHA256
 x6c     ADH-AES128-SHA256                 DH 2048    AES         128      TLS_DH_anon_WITH_AES_128_CBC_SHA256
 x34     ADH-AES128-SHA                    DH 2048    AES         128      TLS_DH_anon_WITH_AES_128_CBC_SHA
 xbf     ADH-CAMELLIA128-SHA256            DH 2048    Camellia    128      TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA256
 x9b     ADH-SEED-SHA                      DH 2048    SEED        128      TLS_DH_anon_WITH_SEED_CBC_SHA
 x46     ADH-CAMELLIA128-SHA               DH 2048    Camellia    128      TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA
 xc05c   ECDHE-ECDSA-ARIA128-GCM-SHA256    ECDH 253   ARIAGCM     128      TLS_ECDHE_ECDSA_WITH_ARIA_128_GCM_SHA256
TLS 1.3
 x1302   TLS_AES_256_GCM_SHA384            ECDH 253   AESGCM      256      TLS_AES_256_GCM_SHA384
 x1303   TLS_CHACHA20_POLY1305_SHA256      ECDH 253   ChaCha20    256      TLS_CHACHA20_POLY1305_SHA256
 x1301   TLS_AES_128_GCM_SHA256            ECDH 253   AESGCM      128      TLS_AES_128_GCM_SHA256

Not so bad, but sadly no overlap with any of the ciphers that mx01.arz.at offers.

What about disabling STARTTLS for the mx01.arz.at (+ mx02.arz.at being another one used by the relevant domain) mail servers when talking to mine? Let’s try that:

% sudo postconf -nf smtpd_discard_ehlo_keyword_address_maps
smtpd_discard_ehlo_keyword_address_maps =
    hash:/etc/postfix/smtpd_discard_ehlo_keywords

% cat /etc/postfix/smtpd_discard_ehlo_keywords
# *disable* starttls for mx01.arz.at / mx02.arz.at:
193.110.182.61 starttls
193.110.182.62 starttls

But the remote mail server doesn’t seem to send mails without TLS:

postfix/smtpd[4151799]: connect from mx01.arz.at[193.110.182.61]
postfix/smtpd[4151799]: discarding EHLO keywords: STARTTLS
postfix/smtpd[4151799]: disconnect from mx01.arz.at[193.110.182.61] ehlo=1 quit=1 commands=2

Let’s verify this further, but without fiddling with the main mail server too much. We can add a dedicated service to postfix (see serverfault), and run it in verbose mode, to get more detailled logging:

% sudo postconf -Mf
[...]
10025      inet  n       -       -       -       -       smtpd
    -o syslog_name=postfix/smtpd/badstarttls
    -o smtpd_tls_security_level=none
    -o smtpd_helo_required=yes
    -o smtpd_helo_restrictions=pcre:/etc/postfix/helo_badstarttls_allow,reject
    -v

[...]

% cat /etc/postfix/helo_badstarttls_allow
/mx01.arz.at/ OK
/mx02.arz.at/ OK
/193.110.182.61/ OK
/193.110.182.62/ OK

We redirect the traffic from mx01.arz.at + mx02.arz.at towards our new postfix service, listening on port 10025:

% sudo iptables -t nat -A PREROUTING -p tcp -s 193.110.182.61 --dport 25 -j REDIRECT --to-port 10025
% sudo iptables -t nat -A PREROUTING -p tcp -s 193.110.182.62 --dport 25 -j REDIRECT --to-port 10025

With this setup we get very detailed logging, and it seems to confirm our suspicion that the mail server doesn’t want to talk unencrypted with us:

[...]
postfix/smtpd/badstarttls/smtpd[3491900]: connect from mx01.arz.at[193.110.182.61]
[...]
postfix/smtpd/badstarttls/smtpd[3491901]: disconnect from mx01.arz.at[193.110.182.61] ehlo=1 quit=1 commands=2
postfix/smtpd/badstarttls/smtpd[3491901]: master_notify: status 1
postfix/smtpd/badstarttls/smtpd[3491901]: connection closed
[...]

Let’s step back and revert those changes, back to our original postfix setup. Might the problem be related to our Let’s Encrypt certificate? Let’s see what we have:

% echo QUIT | openssl s_client -connect mail.example.com:25 -starttls
[...]
issuer=C = US, O = Let's Encrypt, CN = R3

---
No client certificate CA names sent
Peer signing digest: SHA384
Peer signature type: ECDSA
Server Temp Key: X25519, 253 bits
---
SSL handshake has read 4455 bytes and written 427 bytes
Verification: OK
---
New, TLSv1.3, Cipher is TLS_AES_256_GCM_SHA384
Server public key is 384 bit
[...]

We have an ECDSA based certificate, what about switching to RSA instead? Thanks to the wonderful dehydrated, this is as easy as:

% echo KEY_ALGO=rsa > certs/mail.example.com/config
% ./dehydrated -c --domain mail.example.com --force
% sudo systemctl reload postfix

With switching to RSA type key we get:

% echo QUIT | openssl s_client -connect mail.example.com:25 -starttls smtp
CONNECTED(00000003)
[...]
issuer=C = US, O = Let's Encrypt, CN = R3

---
No client certificate CA names sent
Peer signing digest: SHA256
Peer signature type: RSA-PSS
Server Temp Key: X25519, 253 bits
---
SSL handshake has read 5295 bytes and written 427 bytes
Verification: OK
---
New, TLSv1.3, Cipher is TLS_AES_256_GCM_SHA384
Server public key is 4096 bit

Which ciphers do we offer now? Let’s check:

% testssl --cipher-per-proto -t=smtp mail.example.com:25
[...]
Hexcode  Cipher Suite Name (OpenSSL)       KeyExch.   Encryption  Bits     Cipher Suite Name (IANA/RFC)
-----------------------------------------------------------------------------------------------------------------------------
SSLv2
SSLv3
TLS 1
 xc014   ECDHE-RSA-AES256-SHA              ECDH 253   AES         256      TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
 x39     DHE-RSA-AES256-SHA                DH 2048    AES         256      TLS_DHE_RSA_WITH_AES_256_CBC_SHA
 x88     DHE-RSA-CAMELLIA256-SHA           DH 2048    Camellia    256      TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA
 xc019   AECDH-AES256-SHA                  ECDH 253   AES         256      TLS_ECDH_anon_WITH_AES_256_CBC_SHA
 x3a     ADH-AES256-SHA                    DH 2048    AES         256      TLS_DH_anon_WITH_AES_256_CBC_SHA
 x89     ADH-CAMELLIA256-SHA               DH 2048    Camellia    256      TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA
 x35     AES256-SHA                        RSA        AES         256      TLS_RSA_WITH_AES_256_CBC_SHA
 x84     CAMELLIA256-SHA                   RSA        Camellia    256      TLS_RSA_WITH_CAMELLIA_256_CBC_SHA
 xc013   ECDHE-RSA-AES128-SHA              ECDH 253   AES         128      TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
 x33     DHE-RSA-AES128-SHA                DH 2048    AES         128      TLS_DHE_RSA_WITH_AES_128_CBC_SHA
 x9a     DHE-RSA-SEED-SHA                  DH 2048    SEED        128      TLS_DHE_RSA_WITH_SEED_CBC_SHA
 x45     DHE-RSA-CAMELLIA128-SHA           DH 2048    Camellia    128      TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA
 xc018   AECDH-AES128-SHA                  ECDH 253   AES         128      TLS_ECDH_anon_WITH_AES_128_CBC_SHA
 x34     ADH-AES128-SHA                    DH 2048    AES         128      TLS_DH_anon_WITH_AES_128_CBC_SHA
 x9b     ADH-SEED-SHA                      DH 2048    SEED        128      TLS_DH_anon_WITH_SEED_CBC_SHA
 x46     ADH-CAMELLIA128-SHA               DH 2048    Camellia    128      TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA
 x2f     AES128-SHA                        RSA        AES         128      TLS_RSA_WITH_AES_128_CBC_SHA
 x96     SEED-SHA                          RSA        SEED        128      TLS_RSA_WITH_SEED_CBC_SHA
 x41     CAMELLIA128-SHA                   RSA        Camellia    128      TLS_RSA_WITH_CAMELLIA_128_CBC_SHA
TLS 1.1
 xc014   ECDHE-RSA-AES256-SHA              ECDH 253   AES         256      TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
 x39     DHE-RSA-AES256-SHA                DH 2048    AES         256      TLS_DHE_RSA_WITH_AES_256_CBC_SHA
 x88     DHE-RSA-CAMELLIA256-SHA           DH 2048    Camellia    256      TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA
 xc019   AECDH-AES256-SHA                  ECDH 253   AES         256      TLS_ECDH_anon_WITH_AES_256_CBC_SHA
 x3a     ADH-AES256-SHA                    DH 2048    AES         256      TLS_DH_anon_WITH_AES_256_CBC_SHA
 x89     ADH-CAMELLIA256-SHA               DH 2048    Camellia    256      TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA
 x35     AES256-SHA                        RSA        AES         256      TLS_RSA_WITH_AES_256_CBC_SHA
 x84     CAMELLIA256-SHA                   RSA        Camellia    256      TLS_RSA_WITH_CAMELLIA_256_CBC_SHA
 xc013   ECDHE-RSA-AES128-SHA              ECDH 253   AES         128      TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
 x33     DHE-RSA-AES128-SHA                DH 2048    AES         128      TLS_DHE_RSA_WITH_AES_128_CBC_SHA
 x9a     DHE-RSA-SEED-SHA                  DH 2048    SEED        128      TLS_DHE_RSA_WITH_SEED_CBC_SHA
 x45     DHE-RSA-CAMELLIA128-SHA           DH 2048    Camellia    128      TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA
 xc018   AECDH-AES128-SHA                  ECDH 253   AES         128      TLS_ECDH_anon_WITH_AES_128_CBC_SHA
 x34     ADH-AES128-SHA                    DH 2048    AES         128      TLS_DH_anon_WITH_AES_128_CBC_SHA
 x9b     ADH-SEED-SHA                      DH 2048    SEED        128      TLS_DH_anon_WITH_SEED_CBC_SHA
 x46     ADH-CAMELLIA128-SHA               DH 2048    Camellia    128      TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA
 x2f     AES128-SHA                        RSA        AES         128      TLS_RSA_WITH_AES_128_CBC_SHA
 x96     SEED-SHA                          RSA        SEED        128      TLS_RSA_WITH_SEED_CBC_SHA
 x41     CAMELLIA128-SHA                   RSA        Camellia    128      TLS_RSA_WITH_CAMELLIA_128_CBC_SHA
TLS 1.2
 xc030   ECDHE-RSA-AES256-GCM-SHA384       ECDH 253   AESGCM      256      TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
 xc028   ECDHE-RSA-AES256-SHA384           ECDH 253   AES         256      TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
 xc014   ECDHE-RSA-AES256-SHA              ECDH 253   AES         256      TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
 x9f     DHE-RSA-AES256-GCM-SHA384         DH 2048    AESGCM      256      TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
 xcca8   ECDHE-RSA-CHACHA20-POLY1305       ECDH 253   ChaCha20    256      TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256
 xccaa   DHE-RSA-CHACHA20-POLY1305         DH 2048    ChaCha20    256      TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256
 xc0a3   DHE-RSA-AES256-CCM8               DH 2048    AESCCM8     256      TLS_DHE_RSA_WITH_AES_256_CCM_8
 xc09f   DHE-RSA-AES256-CCM                DH 2048    AESCCM      256      TLS_DHE_RSA_WITH_AES_256_CCM
 x6b     DHE-RSA-AES256-SHA256             DH 2048    AES         256      TLS_DHE_RSA_WITH_AES_256_CBC_SHA256
 x39     DHE-RSA-AES256-SHA                DH 2048    AES         256      TLS_DHE_RSA_WITH_AES_256_CBC_SHA
 xc077   ECDHE-RSA-CAMELLIA256-SHA384      ECDH 253   Camellia    256      TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384
 xc4     DHE-RSA-CAMELLIA256-SHA256        DH 2048    Camellia    256      TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256
 x88     DHE-RSA-CAMELLIA256-SHA           DH 2048    Camellia    256      TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA
 xc019   AECDH-AES256-SHA                  ECDH 253   AES         256      TLS_ECDH_anon_WITH_AES_256_CBC_SHA
 xa7     ADH-AES256-GCM-SHA384             DH 2048    AESGCM      256      TLS_DH_anon_WITH_AES_256_GCM_SHA384
 x6d     ADH-AES256-SHA256                 DH 2048    AES         256      TLS_DH_anon_WITH_AES_256_CBC_SHA256
 x3a     ADH-AES256-SHA                    DH 2048    AES         256      TLS_DH_anon_WITH_AES_256_CBC_SHA
 xc5     ADH-CAMELLIA256-SHA256            DH 2048    Camellia    256      TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA256
 x89     ADH-CAMELLIA256-SHA               DH 2048    Camellia    256      TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA
 x9d     AES256-GCM-SHA384                 RSA        AESGCM      256      TLS_RSA_WITH_AES_256_GCM_SHA384
 xc0a1   AES256-CCM8                       RSA        AESCCM8     256      TLS_RSA_WITH_AES_256_CCM_8
 xc09d   AES256-CCM                        RSA        AESCCM      256      TLS_RSA_WITH_AES_256_CCM
 x3d     AES256-SHA256                     RSA        AES         256      TLS_RSA_WITH_AES_256_CBC_SHA256
 x35     AES256-SHA                        RSA        AES         256      TLS_RSA_WITH_AES_256_CBC_SHA
 xc0     CAMELLIA256-SHA256                RSA        Camellia    256      TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256
 x84     CAMELLIA256-SHA                   RSA        Camellia    256      TLS_RSA_WITH_CAMELLIA_256_CBC_SHA
 xc051   ARIA256-GCM-SHA384                RSA        ARIAGCM     256      TLS_RSA_WITH_ARIA_256_GCM_SHA384
 xc053   DHE-RSA-ARIA256-GCM-SHA384        DH 2048    ARIAGCM     256      TLS_DHE_RSA_WITH_ARIA_256_GCM_SHA384
 xc061   ECDHE-ARIA256-GCM-SHA384          ECDH 253   ARIAGCM     256      TLS_ECDHE_RSA_WITH_ARIA_256_GCM_SHA384
 xc02f   ECDHE-RSA-AES128-GCM-SHA256       ECDH 253   AESGCM      128      TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
 xc027   ECDHE-RSA-AES128-SHA256           ECDH 253   AES         128      TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
 xc013   ECDHE-RSA-AES128-SHA              ECDH 253   AES         128      TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
 x9e     DHE-RSA-AES128-GCM-SHA256         DH 2048    AESGCM      128      TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
 xc0a2   DHE-RSA-AES128-CCM8               DH 2048    AESCCM8     128      TLS_DHE_RSA_WITH_AES_128_CCM_8
 xc09e   DHE-RSA-AES128-CCM                DH 2048    AESCCM      128      TLS_DHE_RSA_WITH_AES_128_CCM
 xc0a0   AES128-CCM8                       RSA        AESCCM8     128      TLS_RSA_WITH_AES_128_CCM_8
 xc09c   AES128-CCM                        RSA        AESCCM      128      TLS_RSA_WITH_AES_128_CCM
 x67     DHE-RSA-AES128-SHA256             DH 2048    AES         128      TLS_DHE_RSA_WITH_AES_128_CBC_SHA256
 x33     DHE-RSA-AES128-SHA                DH 2048    AES         128      TLS_DHE_RSA_WITH_AES_128_CBC_SHA
 xc076   ECDHE-RSA-CAMELLIA128-SHA256      ECDH 253   Camellia    128      TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256
 xbe     DHE-RSA-CAMELLIA128-SHA256        DH 2048    Camellia    128      TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256
 x9a     DHE-RSA-SEED-SHA                  DH 2048    SEED        128      TLS_DHE_RSA_WITH_SEED_CBC_SHA
 x45     DHE-RSA-CAMELLIA128-SHA           DH 2048    Camellia    128      TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA
 xc018   AECDH-AES128-SHA                  ECDH 253   AES         128      TLS_ECDH_anon_WITH_AES_128_CBC_SHA
 xa6     ADH-AES128-GCM-SHA256             DH 2048    AESGCM      128      TLS_DH_anon_WITH_AES_128_GCM_SHA256
 x6c     ADH-AES128-SHA256                 DH 2048    AES         128      TLS_DH_anon_WITH_AES_128_CBC_SHA256
 x34     ADH-AES128-SHA                    DH 2048    AES         128      TLS_DH_anon_WITH_AES_128_CBC_SHA
 xbf     ADH-CAMELLIA128-SHA256            DH 2048    Camellia    128      TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA256
 x9b     ADH-SEED-SHA                      DH 2048    SEED        128      TLS_DH_anon_WITH_SEED_CBC_SHA
 x46     ADH-CAMELLIA128-SHA               DH 2048    Camellia    128      TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA
 x9c     AES128-GCM-SHA256                 RSA        AESGCM      128      TLS_RSA_WITH_AES_128_GCM_SHA256
 x3c     AES128-SHA256                     RSA        AES         128      TLS_RSA_WITH_AES_128_CBC_SHA256
 x2f     AES128-SHA                        RSA        AES         128      TLS_RSA_WITH_AES_128_CBC_SHA
 xba     CAMELLIA128-SHA256                RSA        Camellia    128      TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256
 x96     SEED-SHA                          RSA        SEED        128      TLS_RSA_WITH_SEED_CBC_SHA
 x41     CAMELLIA128-SHA                   RSA        Camellia    128      TLS_RSA_WITH_CAMELLIA_128_CBC_SHA
 xc050   ARIA128-GCM-SHA256                RSA        ARIAGCM     128      TLS_RSA_WITH_ARIA_128_GCM_SHA256
 xc052   DHE-RSA-ARIA128-GCM-SHA256        DH 2048    ARIAGCM     128      TLS_DHE_RSA_WITH_ARIA_128_GCM_SHA256
 xc060   ECDHE-ARIA128-GCM-SHA256          ECDH 253   ARIAGCM     128      TLS_ECDHE_RSA_WITH_ARIA_128_GCM_SHA256
TLS 1.3
 x1302   TLS_AES_256_GCM_SHA384            ECDH 253   AESGCM      256      TLS_AES_256_GCM_SHA384
 x1303   TLS_CHACHA20_POLY1305_SHA256      ECDH 253   ChaCha20    256      TLS_CHACHA20_POLY1305_SHA256
 x1301   TLS_AES_128_GCM_SHA256            ECDH 253   AESGCM      128      TLS_AES_128_GCM_SHA256

With switching our SSL certificate to RSA, we gained around 51 new cipher options, amongst them being ones that also mx01.arz.at claimed to support.

FTR, the result from above is what you get with the default settings for postfix v3.5.18, being:

smtpd_tls_ciphers = medium
smtpd_tls_mandatory_ciphers = medium
smtpd_tls_mandatory_exclude_ciphers =
smtpd_tls_mandatory_protocols = !SSLv2, !SSLv3

But the delay between triggering the password reset mail and getting a mail server connect was getting bigger and bigger. Therefore while waiting for the next mail to arrive, I decided to capture the network traffic, to be able to look further into this if it should continue to be failing:

% sudo tshark -n -i eth0 -s 65535 -w arz.pcap -f "host 193.110.182.61 or host 193.110.182.62"

A few hours later the mail server connected again, and the mail went through!

postfix/smtpd[4162835]: connect from mx01.arz.at[193.110.182.61]
postfix/smtpd[4162835]: Anonymous TLS connection established from mx01.arz.at[193.110.182.61]: TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)
postfix/smtpd[4162835]: E50D6401E6: client=mx01.arz.at[193.110.182.61]
postfix/smtpd[4162835]: disconnect from mx01.arz.at[193.110.182.61] ehlo=2 starttls=1 mail=1 rcpt=1 data=1 quit=1 commands=7

Now also having the captured network traffic, we can check the details there:

[...]
% tshark -o smtp.decryption:true -r arz.pcap
    1 0.000000000 193.110.182.61 → 203.0.113.42 TCP 74 24699 → 25 [SYN] Seq=0 Win=29200 Len=0 MSS=1460 SACK_PERM=1 TSval=2261106119 TSecr=0 WS=128
    2 0.000042827 203.0.113.42 → 193.110.182.61 TCP 74 25 → 24699 [SYN, ACK] Seq=0 Ack=1 Win=65160 Len=0 MSS=1460 SACK_PERM=1 TSval=3233422181 TSecr=2261106119 WS=128
    3 0.020719269 193.110.182.61 → 203.0.113.42 TCP 66 24699 → 25 [ACK] Seq=1 Ack=1 Win=29312 Len=0 TSval=2261106139 TSecr=3233422181
    4 0.022883259 203.0.113.42 → 193.110.182.61 SMTP 96 S: 220 mail.example.com ESMTP
    5 0.043682626 193.110.182.61 → 203.0.113.42 TCP 66 24699 → 25 [ACK] Seq=1 Ack=31 Win=29312 Len=0 TSval=2261106162 TSecr=3233422203
    6 0.043799047 193.110.182.61 → 203.0.113.42 SMTP 84 C: EHLO mx01.arz.at
    7 0.043811363 203.0.113.42 → 193.110.182.61 TCP 66 25 → 24699 [ACK] Seq=31 Ack=19 Win=65280 Len=0 TSval=3233422224 TSecr=2261106162
    8 0.043898412 203.0.113.42 → 193.110.182.61 SMTP 253 S: 250-mail.example.com | PIPELINING | SIZE 20240000 | VRFY | ETRN | AUTH PLAIN | AUTH=PLAIN | ENHANCEDSTATUSCODES | 8BITMIME | DSN | SMTPUTF8 | CHUNKING
    9 0.064625499 193.110.182.61 → 203.0.113.42 SMTP 72 C: QUIT
   10 0.064750257 203.0.113.42 → 193.110.182.61 SMTP 81 S: 221 2.0.0 Bye
   11 0.064760200 203.0.113.42 → 193.110.182.61 TCP 66 25 → 24699 [FIN, ACK] Seq=233 Ack=25 Win=65280 Len=0 TSval=3233422245 TSecr=2261106183
   12 0.085573715 193.110.182.61 → 203.0.113.42 TCP 66 24699 → 25 [FIN, ACK] Seq=25 Ack=234 Win=30336 Len=0 TSval=2261106204 TSecr=3233422245
   13 0.085610229 203.0.113.42 → 193.110.182.61 TCP 66 25 → 24699 [ACK] Seq=234 Ack=26 Win=65280 Len=0 TSval=3233422266 TSecr=2261106204
   14 1799.888108373 193.110.182.61 → 203.0.113.42 TCP 74 10330 → 25 [SYN] Seq=0 Win=29200 Len=0 MSS=1460 SACK_PERM=1 TSval=2262906007 TSecr=0 WS=128
   15 1799.888161311 203.0.113.42 → 193.110.182.61 TCP 74 25 → 10330 [SYN, ACK] Seq=0 Ack=1 Win=65160 Len=0 MSS=1460 SACK_PERM=1 TSval=3235222069 TSecr=2262906007 WS=128
   16 1799.909030335 193.110.182.61 → 203.0.113.42 TCP 66 10330 → 25 [ACK] Seq=1 Ack=1 Win=29312 Len=0 TSval=2262906028 TSecr=3235222069
   17 1799.956621011 203.0.113.42 → 193.110.182.61 SMTP 96 S: 220 mail.example.com ESMTP
   18 1799.977229656 193.110.182.61 → 203.0.113.42 TCP 66 10330 → 25 [ACK] Seq=1 Ack=31 Win=29312 Len=0 TSval=2262906096 TSecr=3235222137
   19 1799.977229698 193.110.182.61 → 203.0.113.42 SMTP 84 C: EHLO mx01.arz.at
   20 1799.977266759 203.0.113.42 → 193.110.182.61 TCP 66 25 → 10330 [ACK] Seq=31 Ack=19 Win=65280 Len=0 TSval=3235222158 TSecr=2262906096
   21 1799.977351663 203.0.113.42 → 193.110.182.61 SMTP 267 S: 250-mail.example.com | PIPELINING | SIZE 20240000 | VRFY | ETRN | STARTTLS | AUTH PLAIN | AUTH=PLAIN | ENHANCEDSTATUSCODES | 8BITMIME | DSN | SMTPUTF8 | CHUNKING
   22 1800.011494861 193.110.182.61 → 203.0.113.42 SMTP 76 C: STARTTLS
   23 1800.011589267 203.0.113.42 → 193.110.182.61 SMTP 96 S: 220 2.0.0 Ready to start TLS
   24 1800.032812294 193.110.182.61 → 203.0.113.42 TLSv1 223 Client Hello
   25 1800.032987264 203.0.113.42 → 193.110.182.61 TLSv1.2 2962 Server Hello
   26 1800.032995513 203.0.113.42 → 193.110.182.61 TCP 1266 25 → 10330 [PSH, ACK] Seq=3158 Ack=186 Win=65152 Len=1200 TSval=3235222214 TSecr=2262906151 [TCP segment of a reassembled PDU]
   27 1800.053546755 193.110.182.61 → 203.0.113.42 TCP 66 10330 → 25 [ACK] Seq=186 Ack=3158 Win=36096 Len=0 TSval=2262906172 TSecr=3235222214
   28 1800.092852469 193.110.182.61 → 203.0.113.42 TCP 66 10330 → 25 [ACK] Seq=186 Ack=4358 Win=39040 Len=0 TSval=2262906212 TSecr=3235222214
   29 1800.092892905 203.0.113.42 → 193.110.182.61 TLSv1.2 900 Certificate, Server Key Exchange, Server Hello Done
   30 1800.113546769 193.110.182.61 → 203.0.113.42 TCP 66 10330 → 25 [ACK] Seq=186 Ack=5192 Win=41856 Len=0 TSval=2262906232 TSecr=3235222273
   31 1800.114763363 193.110.182.61 → 203.0.113.42 TLSv1.2 192 Client Key Exchange, Change Cipher Spec, Encrypted Handshake Message
   32 1800.115000416 203.0.113.42 → 193.110.182.61 TLSv1.2 117 Change Cipher Spec, Encrypted Handshake Message
   33 1800.136070200 193.110.182.61 → 203.0.113.42 TLSv1.2 113 Application Data
   34 1800.136155526 203.0.113.42 → 193.110.182.61 TLSv1.2 282 Application Data
   35 1800.158854473 193.110.182.61 → 203.0.113.42 TLSv1.2 162 Application Data
   36 1800.159254794 203.0.113.42 → 193.110.182.61 TLSv1.2 109 Application Data
   37 1800.180286407 193.110.182.61 → 203.0.113.42 TLSv1.2 144 Application Data
   38 1800.223005960 203.0.113.42 → 193.110.182.61 TCP 66 25 → 10330 [ACK] Seq=5502 Ack=533 Win=65152 Len=0 TSval=3235222404 TSecr=2262906299
   39 1802.230300244 203.0.113.42 → 193.110.182.61 TLSv1.2 146 Application Data
   40 1802.251994333 193.110.182.61 → 203.0.113.42 TCP 2962 [TCP segment of a reassembled PDU]
   41 1802.252034015 203.0.113.42 → 193.110.182.61 TCP 66 25 → 10330 [ACK] Seq=5582 Ack=3429 Win=63616 Len=0 TSval=3235224433 TSecr=2262908371
   42 1802.252279083 193.110.182.61 → 203.0.113.42 TLSv1.2 1295 Application Data
   43 1802.252288316 203.0.113.42 → 193.110.182.61 TCP 66 25 → 10330 [ACK] Seq=5582 Ack=4658 Win=64128 Len=0 TSval=3235224433 TSecr=2262908371
   44 1802.272816060 193.110.182.61 → 203.0.113.42 TLSv1.2 833 Application Data, Application Data
   45 1802.272827542 203.0.113.42 → 193.110.182.61 TCP 66 25 → 10330 [ACK] Seq=5582 Ack=5425 Win=64128 Len=0 TSval=3235224453 TSecr=2262908392
   46 1802.338807683 203.0.113.42 → 193.110.182.61 TLSv1.2 131 Application Data
   47 1802.398968611 193.110.182.61 → 203.0.113.42 TCP 66 10330 → 25 [ACK] Seq=5425 Ack=5647 Win=44800 Len=0 TSval=2262908518 TSecr=3235224519
   48 1863.257457500 193.110.182.61 → 203.0.113.42 TLSv1.2 101 Application Data
   49 1863.257495688 203.0.113.42 → 193.110.182.61 TCP 66 25 → 10330 [ACK] Seq=5647 Ack=5460 Win=64128 Len=0 TSval=3235285438 TSecr=2262969376
   50 1863.257654942 203.0.113.42 → 193.110.182.61 TLSv1.2 110 Application Data
   51 1863.257721010 203.0.113.42 → 193.110.182.61 TLSv1.2 97 Encrypted Alert
   52 1863.278242216 193.110.182.61 → 203.0.113.42 TCP 66 10330 → 25 [ACK] Seq=5460 Ack=5691 Win=44800 Len=0 TSval=2262969397 TSecr=3235285438
   53 1863.278464176 193.110.182.61 → 203.0.113.42 TCP 66 10330 → 25 [RST, ACK] Seq=5460 Ack=5723 Win=44800 Len=0 TSval=2262969397 TSecr=3235285438
% tshark -O tls -r arz.pcap
[...]
Transport Layer Security
    TLSv1 Record Layer: Handshake Protocol: Client Hello
        Content Type: Handshake (22)
        Version: TLS 1.0 (0x0301)
        Length: 152
        Handshake Protocol: Client Hello
            Handshake Type: Client Hello (1)
            Length: 148
            Version: TLS 1.2 (0x0303)
            Random: 4575d1e7c93c09a564edc00b8b56ea6f5d826f8cfe78eb980c451a70a9c5123f
                GMT Unix Time: Dec  5, 2006 21:09:11.000000000 CET
                Random Bytes: c93c09a564edc00b8b56ea6f5d826f8cfe78eb980c451a70a9c5123f
            Session ID Length: 0
            Cipher Suites Length: 26
            Cipher Suites (13 suites)
                Cipher Suite: TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (0xc030)
                Cipher Suite: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (0xc02f)
                Cipher Suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 (0xc028)
                Cipher Suite: TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 (0xc027)
                Cipher Suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA (0xc014)
                Cipher Suite: TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA (0xc013)
                Cipher Suite: TLS_RSA_WITH_AES_256_GCM_SHA384 (0x009d)
                Cipher Suite: TLS_RSA_WITH_AES_128_GCM_SHA256 (0x009c)
                Cipher Suite: TLS_RSA_WITH_AES_256_CBC_SHA256 (0x003d)
                Cipher Suite: TLS_RSA_WITH_AES_128_CBC_SHA256 (0x003c)
                Cipher Suite: TLS_RSA_WITH_AES_256_CBC_SHA (0x0035)
                Cipher Suite: TLS_RSA_WITH_AES_128_CBC_SHA (0x002f)
                Cipher Suite: TLS_EMPTY_RENEGOTIATION_INFO_SCSV (0x00ff)
[...]
Transport Layer Security
    TLSv1.2 Record Layer: Handshake Protocol: Server Hello
        Content Type: Handshake (22)
        Version: TLS 1.2 (0x0303)
        Length: 89
        Handshake Protocol: Server Hello
            Handshake Type: Server Hello (2)
            Length: 85
            Version: TLS 1.2 (0x0303)
            Random: cf2ed24e3300e95e5f56023bf8b4e5904b862bb2ed8a5796444f574e47524401
                GMT Unix Time: Feb 23, 2080 23:16:46.000000000 CET
                Random Bytes: 3300e95e5f56023bf8b4e5904b862bb2ed8a5796444f574e47524401
            Session ID Length: 32
            Session ID: 63d041b126ecebf857d685abd9d4593c46a3672e1ad76228f3eacf2164f86fb9
            Cipher Suite: TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (0xc030)
[...]

In this network dump we see what cipher suites are offered, and the TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 here is the Cipher Suite Name in IANA/RFC speak. Whis corresponds to the ECDHE-RSA-AES256-GCM-SHA384 in openssl speak (see Mozilla’s Mozilla’s cipher suite correspondence table), which we also saw in the postfix log.

Mission accomplished! :)

Now, if we’re interested in avoiding certain ciphers and increase security level, we can e.g. get rid of the SEED, CAMELLIA and all anonymous ciphers, and could accept only TLS v1.2 + v1.3, by further adjusting postfix’s main.cf:

smtpd_tls_ciphers = high
smtpd_tls_exclude_ciphers = aNULL CAMELLIA
smtpd_tls_mandatory_ciphers = high
smtpd_tls_mandatory_protocols = TLSv1.2 TLSv1.3
smtpd_tls_protocols = TLSv1.2 TLSv1.3

Which would then gives us:

% testssl --cipher-per-proto -t=smtp mail.example.com:25
[...]

Hexcode  Cipher Suite Name (OpenSSL)       KeyExch.   Encryption  Bits     Cipher Suite Name (IANA/RFC)
-----------------------------------------------------------------------------------------------------------------------------
SSLv2
SSLv3
TLS 1
TLS 1.1
TLS 1.2
 xc030   ECDHE-RSA-AES256-GCM-SHA384       ECDH 253   AESGCM      256      TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
 xc028   ECDHE-RSA-AES256-SHA384           ECDH 253   AES         256      TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
 xc014   ECDHE-RSA-AES256-SHA              ECDH 253   AES         256      TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
 x9f     DHE-RSA-AES256-GCM-SHA384         DH 2048    AESGCM      256      TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
 xcca8   ECDHE-RSA-CHACHA20-POLY1305       ECDH 253   ChaCha20    256      TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256
 xccaa   DHE-RSA-CHACHA20-POLY1305         DH 2048    ChaCha20    256      TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256
 xc0a3   DHE-RSA-AES256-CCM8               DH 2048    AESCCM8     256      TLS_DHE_RSA_WITH_AES_256_CCM_8
 xc09f   DHE-RSA-AES256-CCM                DH 2048    AESCCM      256      TLS_DHE_RSA_WITH_AES_256_CCM
 x6b     DHE-RSA-AES256-SHA256             DH 2048    AES         256      TLS_DHE_RSA_WITH_AES_256_CBC_SHA256
 x39     DHE-RSA-AES256-SHA                DH 2048    AES         256      TLS_DHE_RSA_WITH_AES_256_CBC_SHA
 x9d     AES256-GCM-SHA384                 RSA        AESGCM      256      TLS_RSA_WITH_AES_256_GCM_SHA384
 xc0a1   AES256-CCM8                       RSA        AESCCM8     256      TLS_RSA_WITH_AES_256_CCM_8
 xc09d   AES256-CCM                        RSA        AESCCM      256      TLS_RSA_WITH_AES_256_CCM
 x3d     AES256-SHA256                     RSA        AES         256      TLS_RSA_WITH_AES_256_CBC_SHA256
 x35     AES256-SHA                        RSA        AES         256      TLS_RSA_WITH_AES_256_CBC_SHA
 xc051   ARIA256-GCM-SHA384                RSA        ARIAGCM     256      TLS_RSA_WITH_ARIA_256_GCM_SHA384
 xc053   DHE-RSA-ARIA256-GCM-SHA384        DH 2048    ARIAGCM     256      TLS_DHE_RSA_WITH_ARIA_256_GCM_SHA384
 xc061   ECDHE-ARIA256-GCM-SHA384          ECDH 253   ARIAGCM     256      TLS_ECDHE_RSA_WITH_ARIA_256_GCM_SHA384
 xc02f   ECDHE-RSA-AES128-GCM-SHA256       ECDH 253   AESGCM      128      TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
 xc027   ECDHE-RSA-AES128-SHA256           ECDH 253   AES         128      TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
 xc013   ECDHE-RSA-AES128-SHA              ECDH 253   AES         128      TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
 x9e     DHE-RSA-AES128-GCM-SHA256         DH 2048    AESGCM      128      TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
 xc0a2   DHE-RSA-AES128-CCM8               DH 2048    AESCCM8     128      TLS_DHE_RSA_WITH_AES_128_CCM_8
 xc09e   DHE-RSA-AES128-CCM                DH 2048    AESCCM      128      TLS_DHE_RSA_WITH_AES_128_CCM
 xc0a0   AES128-CCM8                       RSA        AESCCM8     128      TLS_RSA_WITH_AES_128_CCM_8
 xc09c   AES128-CCM                        RSA        AESCCM      128      TLS_RSA_WITH_AES_128_CCM
 x67     DHE-RSA-AES128-SHA256             DH 2048    AES         128      TLS_DHE_RSA_WITH_AES_128_CBC_SHA256
 x33     DHE-RSA-AES128-SHA                DH 2048    AES         128      TLS_DHE_RSA_WITH_AES_128_CBC_SHA
 x9c     AES128-GCM-SHA256                 RSA        AESGCM      128      TLS_RSA_WITH_AES_128_GCM_SHA256
 x3c     AES128-SHA256                     RSA        AES         128      TLS_RSA_WITH_AES_128_CBC_SHA256
 x2f     AES128-SHA                        RSA        AES         128      TLS_RSA_WITH_AES_128_CBC_SHA
 xc050   ARIA128-GCM-SHA256                RSA        ARIAGCM     128      TLS_RSA_WITH_ARIA_128_GCM_SHA256
 xc052   DHE-RSA-ARIA128-GCM-SHA256        DH 2048    ARIAGCM     128      TLS_DHE_RSA_WITH_ARIA_128_GCM_SHA256
 xc060   ECDHE-ARIA128-GCM-SHA256          ECDH 253   ARIAGCM     128      TLS_ECDHE_RSA_WITH_ARIA_128_GCM_SHA256
TLS 1.3
 x1302   TLS_AES_256_GCM_SHA384            ECDH 253   AESGCM      256      TLS_AES_256_GCM_SHA384
 x1303   TLS_CHACHA20_POLY1305_SHA256      ECDH 253   ChaCha20    256      TLS_CHACHA20_POLY1305_SHA256
 x1301   TLS_AES_128_GCM_SHA256            ECDH 253   AESGCM      128      TLS_AES_128_GCM_SHA256

Don’t forget to also adjust the smpt_tls_* accordingly (for your sending side). For further information see the Postfix TLS Support documentation. Also check out options like tls_ssl_options (setting it to e.g. NO_COMPRESSION) and tls_preempt_cipherlist (setting it to yes would prefer the servers’ order of ciphers over clients).

Conclusions:

  • no matter what you change in your mail server settings, be aware that the type of your SSL certificate also matters for what ciphers are offered and used
  • there are mail servers out there that don’t support SSL certificates with ECDSA, using RSA for those ensure better compatibility (nowadays postfix supports parallel usage of ECDSA and RSA keys BTW, check out the smtpd_tls_eccert_file + smtpd_tls_eckey_file options)
  • testssl is a very useful tool, especially with its –cipher-per-proto -t=smtp option to check SMTP servers
  • if you’re uncertain what’s going on, consider capturing network data (tshark/tcpdump/… are your friends)
  • review your postfix configuration and logs every now and then :)

What to expect from Debian/bookworm #newinbookworm

June 11th, 2023

Bookworm Banner, Copyright 2022 Juliette Taka

Debian v12 with codename bookworm was released as new stable release on 10th of June 2023. Similar to what we had with #newinbullseye and previous releases, now it’s time for #newinbookworm!

I was the driving force at several of my customers to be well prepared for bookworm. As usual with major upgrades, there are some things to be aware of, and hereby I’m starting my public notes on bookworm that might be worth also for other folks. My focus is primarily on server systems and looking at things from a sysadmin perspective.

Further readings

As usual start at the official Debian release notes, make sure to especially go through What’s new in Debian 12 + Issues to be aware of for bookworm.

Package versions

As a starting point, let’s look at some selected packages and their versions in bullseye vs. bookworm as of 2023-02-10 (mainly having amd64 in mind):

Package bullseye/v11 bookworm/v12
ansible 2.10.7 2.14.3
apache 2.4.56 2.4.57
apt 2.2.4 2.6.1
bash 5.1 5.2.15
ceph 14.2.21 16.2.11
docker 20.10.5 20.10.24
dovecot 2.3.13 2.3.19
dpkg 1.20.12 1.21.22
emacs 27.1 28.2
gcc 10.2.1 12.2.0
git 2.30.2 2.39.2
golang 1.15 1.19
libc 2.31 2.36
linux kernel 5.10 6.1
llvm 11.0 14.0
lxc 4.0.6 5.0.2
mariadb 10.5 10.11
nginx 1.18.0 1.22.1
nodejs 12.22 18.13
openjdk 11.0.18 + 17.0.6 17.0.6
openssh 8.4p1 9.2p1
openssl 1.1.1n 3.0.8-1
perl 5.32.1 5.36.0
php 7.4+76 8.2+93
podman 3.0.1 4.3.1
postfix 3.5.18 3.7.5
postgres 13 15
puppet 5.5.22 7.23.0
python2 2.7.18 – (gone!)
python3 3.9.2 3.11.2
qemu/kvm 5.2 7.2
ruby 2.7+2 3.1
rust 1.48.0 1.63.0
samba 4.13.13 4.17.8
systemd 247.3 252.6
unattended-upgrades 2.8 2.9.1
util-linux 2.36.1 2.38.1
vagrant 2.2.14 2.3.4
vim 8.2.2434 9.0.1378
zsh 5.8 5.9

Linux Kernel

The bookworm release ships a Linux kernel based on version 6.1, whereas bullseye shipped kernel 5.10. As usual there are plenty of changes in the kernel area, including better hardware support, and this might warrant a separate blog entry, but to highlight some changes:

See Kernelnewbies.org for further changes between kernel versions.

Configuration management

puppet‘s upstream sadly still doesn’t provide packages for bookworm (see PA-4995), though Debian provides puppet-agent and puppetserver packages, and even puppetdb is back again, see release notes for further information.

ansible is also available and made it with version 2.14 into bookworm.

Prometheus stack

Prometheus server was updated from v2.24.1 to v2.42.0 and all the exporters that got shipped with bullseye are still around (in more recent versions of course).

Virtualization

docker (v20.10.24), ganeti (v3.0.2-3), libvirt (v9.0.0-4), lxc (v5.0.2-1), podman (v4.3.1), openstack (Zed), qemu/kvm (v7.2), xen (v4.17.1) are all still around.

Vagrant is available in version 2.3.4, also Vagrant upstream provides their packages for bookworm already.

If you’re relying on VirtualBox, be aware that upstream doesn’t provide packages for bookworm yet (see ticket 21524), but thankfully version 7.0.8-dfsg-2 is available from Debian/unstable (as of 2023-06-10) (VirtualBox isn’t shipped with stable releases since quite some time due to lack of cooperation from upstream on security support for older releases, see #794466).

rsync

rsync was updated from v3.2.3 to v3.2.7, and we got a few new options:

  • --fsync: fsync every written file
  • --old-dirs: works like –dirs when talking to old rsync
  • --old-args: disable the modern arg-protection idiom
  • --secluded-args, -s: use the protocol to safely send the args (replaces –protect-args option)
  • --trust-sender: trust the remote sender’s file list

OpenSSH

OpenSSH was updated from v8.4p1 to v9.2p1, so if you’re interested in all the changes, check out the release notes between those version (8.5, 8.6, 8.7, 8.8, 8.9, 9.0, 9.1 + 9.2). Let’s highlight some notable new features:

  • new system for restricting forwarding and use of keys added to ssh-agent(1), see SSH agent restriction for details)
  • switched scp(1) from using the legacy scp/rcp protocol to using the SFTP protocol by default (see release notes for v9.0 for details
  • ssh(1): when prompting the user to accept a new hostkey, display any other host names/addresses already associated with the key
  • ssh(1): allow UserKnownHostsFile=none to indicate that no known_hosts file should be used to identify host keys
  • ssh(1): add a ssh_config KnownHostsCommand option that allows the client to obtain known_hosts data from a command in addition to the usual files
  • ssh(1), sshd(8): add a RequiredRSASize directive to set a minimum RSA key length
  • ssh(1): add a “host” line to the output of ssh -G showing the original hostname argument
  • ssh-keygen -A (generate all default host key types) will no longer generate DSA keys
  • ssh-keyscan(1): allow scanning of complete CIDR address ranges, e.g. ssh-keyscan 192.168.0.0/24

One important change you might wanna be aware of is that as of OpenSSH v8.8, RSA signatures using the SHA-1 hash algorithm got disabled by default, but RSA/SHA-256/512 AKA RSA-SHA2 gets used instead. OpenSSH has supported RFC8332 RSA/SHA-256/512 signatures since release 7.2 and existing ssh-rsa keys will automatically use the stronger algorithm where possible. A good overview is also available at SSH: Signature Algorithm ssh-rsa Error.

Now tools/libraries not supporting RSA-SHA2 fail to connect to OpenSSH as present in bookworm. For example python3-paramiko v2.7.2-1 as present in bullseye doesn’t support RSA-SHA2. It tries to connect using the deprecated RSA-SHA-1, which is no longer offered by default with OpenSSH as present in bookworm, and then fails. Support for RSA/SHA-256/512 signatures in Paramiko was requested e.g. at #1734, and eventually got added to Paramiko and in the end the change made it into Paramiko versions >=2.9.0. Paramiko in bookworm works fine, and a backport by rebuilding the python3-paramiko package from bookworm for bullseye solves the problem (BTDT).

Misc unsorted

  • new non-free-firmware component/repository (see Debian Wiki for details)
  • support only the merged-usr root filesystem layout (see Debian Wiki for details)
  • the asterisk package didn’t make it into bookworm (see #1031046)
  • e2fsprogs: the breaking change related to metadata_csum_seed and orphan_file (see #1031325) was reverted with v1.47.0-2 for bookworm (also see #1031622 + #1030939)
  • rsnapshot is back again (see #986709)
  • crmadmin of pacemaker no longer interprets the timeout option (-t/–timeout) in milliseconds (as it used to be until v2.0.5), but as of v2.1.0 (and v2.1.5 is present in bookworm) it now interprets the argument as second by default

Thanks to everyone involved in the release, happy upgrading to bookworm, and let’s continue with working towards Debian/trixie. :)

HTU Bigband Konzert am 27.06.2023

June 2nd, 2023

Plakat für das HTU Bigband-Konzert am 27.06.2023

Die HTU Bigband ist zurück! Am 27. Juni 2023 findet im Innenhof der TU Graz (Alte Technik, Rechbauerstraße 12, 8010 Graz) das nächste Konzert statt (bei Schlechtwetter geht es in den Hörsaal 2, der ebenfalls an der gleichen Adresse ist). Mit einem fulminanten Programm von Swing, über Soul, Funk, Latin bis Pop ist alles dabei – es gibt über 2 Stunden Musik vom Feinsten, und das Ganze bei freiem Eintritt.

Für diejenigen mit Facebook-Account unter euch gibt es auch das passende Facebook-Event.

Ich bin als Schlagzeuger und Percussionist mit von der Partie und würde mich über bekannte Gesichter freuen, ich hoffe man sieht und hört sich! 8-)

Vortrag: Debugging für Sysadmins @ GLT23

April 16th, 2023

Auf den Grazer Linuxtagen 2023 (GLT23) war ich als Referent mit einem Vortrag zum Thema “Debugging für Sysadmins” vertreten. In meinem Vortrag gibt es einen Überblick, welche Tools und Strategien rund ums Debugging in der Toolbox von Sysadmins nicht fehlen dürfen.

Es gibt den Vortrag dank des wunderbaren c3voc-Teams bereits als Videomitschnitt online. Meine Vortragsfolien (1.2MB, PDF) stehen ebenfalls online zur Verfügung. Viel Spaß beim Anschauen!

BTW: weil ich schon mehrfach gefragt wurde, den Vortrag gibt es auch in längerer Workshop-Version, bei Interesse einfach bei mir melden.

Automatically unlocking a LUKS encrypted root filesystem during boot

March 22nd, 2023

Update on 2023-03-23: thanks to Daniel Roschka for mentioning the Mandos and TPM approaches, which might be better alternatives, depending on your options and needs. Peter Palfrader furthermore pointed me towards clevis-initramfs and tang.

A customer of mine runs dedicated servers inside a foreign data-center, remote hands only. In such an environment you might need a disk replacement because you need bigger or faster disks, though also a disk might (start to) fail and you need a replacement. One has to be prepared for such a scenario, but fully wiping your used disk then might not always be an option, especially once disks (start to) fail. On the other hand you don’t want to end up with (partial) data on your disk handed over to someone unexpected.

By encrypting the data on your disks upfront you can prevent against this scenario. But if you have a fleet of servers you might not want to manually jump on servers during boot and unlock crypto volumes manually. It’s especially annoying if it’s about the root filesystem where a solution like dropbear-initramfs needs to be used for remote access during initramfs boot stage. So my task for the customer was to adjust encrypted LUKS devices such that no one needs to manually unlock the encrypted device during server boot (with some specific assumptions about possible attack vectors one has to live with, see the disclaimer at the end).

The documentation about this use-case was rather inconsistent, especially because special rules apply for the root filesystem (no key file usage), we see different behavior between what’s supported by systemd (hello key file again), initramfs-tools and dracut, not to mention the changes between different distributions. Since tests with this tend to be rather annoying (better make sure to have a Grml live system available :)), I’m hereby documenting what worked for us (Debian/bullseye with initramfs-tools and cryptsetup-initramfs).

The system was installed with LVM on-top of an encrypted Software-RAID device, only the /boot partition is unencrypted. But even if you don’t use Software-RAID nor LVM the same instructions apply. The system looks like this:

% mount -t ext4 -l
/dev/mapper/foobar-root_1 on / type ext4 (rw,relatime,errors=remount-ro)

% sudo pvs
  PV                    VG     Fmt  Attr PSize   PFree
  /dev/mapper/md1_crypt foobar lvm2 a--  445.95g 430.12g

% sudo vgs
  VG     #PV #LV #SN Attr   VSize   VFree
  foobar   1   2   0 wz--n- 445.95g 430.12g

% sudo lvs
  LV     VG     Attr       LSize   Pool Origin Data%  Meta%  Move Log Cpy%Sync Convert
  root_1 foobar -wi-ao---- <14.90g

% lsblk
NAME                  MAJ:MIN RM   SIZE RO TYPE  MOUNTPOINT
[...]
sdd                     8:48   0 447.1G  0 disk
├─sdd1                  8:49   0   571M  0 part  /boot/efi
├─sdd2                  8:50   0   488M  0 part
│ └─md0                 9:0    0   487M  0 raid1 /boot
└─sdd3                  8:51   0 446.1G  0 part
  └─md1                 9:1    0   446G  0 raid1
    └─md1_crypt       253:0    0   446G  0 crypt
      ├─foobar-root_1 253:1    0  14.9G  0 lvm   /
[...]
sdf                     8:80   0 447.1G  0 disk
├─sdf1                  8:81   0   571M  0 part
├─sdf2                  8:82   0   488M  0 part
│ └─md0                 9:0    0   487M  0 raid1 /boot
└─sdf3                  8:83   0 446.1G  0 part
  └─md1                 9:1    0   446G  0 raid1
    └─md1_crypt       253:0    0   446G  0 crypt
      ├─foobar-root_1 253:1    0  14.9G  0 lvm   /

The actual crypsetup configuration is:

% cat /etc/crypttab
md1_crypt UUID=77246138-b666-4151-b01c-5a12db54b28b none luks,discard

Now, to automatically open the crypto device during boot we can instead use:

% cat /etc/crypttab 
md1_crypt UUID=77246138-b666-4151-b01c-5a12db54b28b none luks,discard,keyscript=/etc/initramfs-tools/unlock.sh

# touch /etc/initramfs-tools/unlock.sh
# chmod 0700 /etc/initramfs-tools/unlock.sh
# $EDITOR etc/initramfs-tools/unlock.sh
# cat /etc/initramfs-tools/unlock.sh
#!/bin/sh
echo -n "provide_the_actual_password_here"

# update-initramfs -k all -u
[...]

The server will then boot without prompting for a crypto password.

Note that initramfs-tools by default uses an insecure umask of 0022, resulting in the initrd being accessible to everyone. But if you have the dropbear-initramfs package installed, its `/usr/share/initramfs-tools/conf-hooks.d/dropbear` sets `UMASK=0077`, so the resulting /boot/initrd* file should automatically have proper permissions (0600). The cryptsetup hook warns about a permissive umask configuration during update-initramfs runs, but if you want to be sure, explicitly set it via e.g.:

# cat > /etc/initramfs-tools/conf.d/umask << EOF
# restrictive umask to avoid non-root access to initrd:
UMASK=0077
EOF
# update-initramfs -k all -u

Disclaimer: Of course you need to trust users with access to /etc/initramfs-tools/unlock.sh as well as the initramfs/initrd on your system. Furthermore you should wipe the boot partition (to destroy the keyfile information) before handing over such a disk. But that is a risk my customer can live with, YMMV.

Mein Lesejahr 2022

January 3rd, 2023

Foto der hier vorgestellten Bücher

Ich habe 2022 keine Bookdumps geschrieben, weil es mir einerseits zu viel Aufwand war, andererseits wollte ich mir auch nicht immer bzw. zeitnahe zu jedem Buch eine Meinung bilden (müssen). 2022 war aus verschiedenen Gründen intensiv, daher habe ich meine Lese-Gewohnheit von 2021 nicht ganz halten können, aber schlussendlich sind es doch 82 Bücher (ca. 19k Seiten) geworden.

Im Gegensatz zu den Vorjahren habe ich diesmal nicht auf das Verhältnis von Autorin zu Autor geachtet, und entsprechend sind es leider auch nur 27 Autorinnen zu 55 Autoren geworden. Ich bin leider noch immer ziemlich schlecht beim Abbrechen von Büchern, aber es waren fast alle Bücher gut. Daher hier nur eine kleine Auswahl jener Bücher, die ich besonders lesenswert fand bzw. empfehlen möchte (die Reihenfolge entspricht dem Foto und stellt keinerlei Reihung oder dergleichen dar):

  • Maksym, Dirk Stermann. Ein wichtiges Thema (Aufteilung der Kinderbetreuung) ist hier in eine unterhaltsam zu lesende Autofiktion verpackt. Das Buch hat meinen Humor im Sommerurlaub perfekt getroffen und wer mit kabarettistischem Humor kein Problem hat, sollte hier nicht enttäuscht werden.
  • Müll (Brenner #9), Wolf Haas. Ich hatte zuvor noch kein Buch von Haas gelesen, weil ich einmal den Spruch “wenn man nicht weiß was man lesen soll greift man zu Haas” aufgeschnappt habe und mich damit nicht angesprochen fühlte. Großer Fehler, Hilfsausdruck. Auf Empfehlung von Daniela Strigl hin habe ich mir den neuesten Brenner-Roman von Haas besorgt und fühlte mich total abgeholt. Ich habe darauf hin gleich weitere Bücher von Haas gelesen. Danke für den Stupser, Frau Strigl.
  • Eine runde Sache, Tomer Gardi. Zwei Geschichten in einem Buch die miteinander lose verbunden sind – zuerst eine Odyssee mit einem Schäferhund in gebrochenem Deutsch, dann die Lebensgeschichte des indonesischen Malers Raden Saleh von Java. Danke für die Empfehlung, Insa Wilke.
  • Das blinde Licht, Benjamín Labatut. In vier Geschichten erzählt Benjamín Labatut vom schmalen Grat zwischen Genie und Wahnsinn, von menschlicher Hybris und der zwiespältigen Kraft der Wissenschaft. Ein wunderbares Buch, das ich nur aufs Wärmste weiterempfehlen kann.
  • Die verschissene Zeit, Barbi Marković. Ein wunderbarer popkultureller Ausflug in das Belgrad der Neunziger.
  • Coventry: Essays, Rachel Cusk. Unaufgeregte Beobachtungen des Alltags die zum Denken anregen. Ich bin leider erst im Nachhinein drauf gekommen, dass die deutsche Übersetzung wohl um einige Kapitel gekürzt ist, sprachlich hat mich die deutsche Ausgabe trotzdem absolut abgeholt.
  • Das hier ist Wasser / This is water, David Foster Wallace. Ein 64 Seiten schlankes Buch, das im ersten Teil die deutsche Übersetzung und im zweiten Teil das englische Original beinhaltet. Inspirierende Gedanken rund um Bildung, Denken und Leben.
  • Kummer aller Art, Mariana Leky. Mir war noch Lekys “Was man von hier aus sehen kann” in guter Erinnerung, hatte die Autorin aber irgendwie aus den Augen verloren. Dieses Buch war ein Weihnachtsgeschenk an mich – und wow, was für ein Volltreffer. Ein fantastisches Buch, ich habe mir umgehend weitere Bücher von Mariana Leky besorgt. Klare Leseempfehlung.
  • Was ist der Mensch? Ein Gespräch über die Welt und Gott, Mark Twain. Ein philosophisches Zwiegespräch über den freien Willen des Menschen. Sehr anregend, danke für die Empfehlung, Darsha.
  • Herr Lehmann (Frank Lehmann #1), Sven Regener. Das Buch wurde 2001 veröffentlicht und 2003 verfilmt, hat es aber erst 2022 auf mein Buchregal geschafft. Für mich hat sich in der Sommerzeit mit diesem Buch ein wunderbarer Lesesog ergeben, ich habe daraufhin gleich weitere Bücher von Regener besorgt und gelesen.
  • Reise durch Ruinen, George Orwell. Orwell folgte als Kriegsberichterstatter den alliierten Streitkräften durch Deutschland und Österreich. Naturgemäß keine leichte Kost.
  • On Writing: A Memoir of the Craft, Stephen King. Dank eines Geburtstagsgeschenks (thx, Kathi + Karl!) habe ich 2022 endlich den Kosmos “Stephen King” betreten. Sprachlich hat mich in “Finderlohn“, der deutschen Ausgabe von “Finders Keepers” aber irgendetwas irritiert, ohne es wirklich benennen zu können. Im Zuge des Lesens von “On Writing: A Memoir of the Craft” habe ich stellenweise das englischsprachige Original mit dessen deutscher Übersetzung “Das Leben und das Schreiben” verglichen und festgestellt, dass ich den “englischen King” unvergleichlich lesenswerter empfinde. Dieses Buch gibt einen lesenswerten Einblick in den Werdegang von King und seinem Zugang zum Schreiben. Und ich möchte hier ganz klar für die englische Ausgabe dieses Buches werben.

RIP, Sven Guckes

February 26th, 2022

Die älteste mir zugängliche Mail von Sven Guckes direkt an mich stammt aus dem Jahr 2002, und startet seinerseits mit:

eine dokumentierte loesung – das ist prima! :-)

Natürlich ging es um: Vim. Viele Mails unter anderem zum Kunsthaus Graz, den Chemnitzer Linux-Tagen, den Grazer Linuxtagen (GLT) und seinem Geek Brunch sollten folgen.

Unvergessen bleibt mir unser Ausflug 2003 zu den Chemnitzer Linux-Tagen mit dem von ihm organisierten Bustransfer aus Berlin. Sven hat netterweise meine Freunde Karl, Thorsten und mich in seiner Wohnung in Berlin gehostet. Einzigartig war Svens Berlin-Führung, von der mir speziell sein mehrfaches “ist gleich ums Eck!” gut in Erinnerung geblieben ist. (Wer das nicht kennt: das war Svens Euphemismus für einen Spaziergang von mehreren Kilometern.)

Ich habe Sven dann weiterhin regelmäßig bei den Chemnitzer Linuxtagen, sowie besonders auf den – von mir mitorganisierten – Grazer Linuxtagen getroffen. Sven konnte dabei für Event-Organisatoren schon auch mal eine Herausforderung sein, er war aber trotzdem immer eine Bereicherung. Svens Sonntags-Brunch war ebenso legendär wie seine Feature-Shows (siehe z.B. Vim Feature Show), oder auch seine späteren “show+tell”-Events.

Technisch hatte ich mit Sven viele Anknüpfungspunkte, von centericq und irssi, über mutt und slrn, bis hin zu screen, vim und zsh. Wir haben zum Thema Texttools 2004 sogar gemeinsam Workshops auf den Grazer Linuxtagen und der KDE Community World Summit 2004 gehalten. Sein Enthusiasmus war im besten Sinne des Wortes ansteckend, seine Geduld und sein Umgang mit Newbies kann für uns alle nur ein Vorbild sein. Aber auch mit Nicht-Techies konnte sich Sven wunderbar unterhalten. Sven war neugierig und hilfsbereit, tolerant aber speziell auch verbindend und ein Menschenfreund. Ich habe viele Bekannte und Freunde dank Sven kennengelernt, und wenn ich mir heute alte Bildergalerien durchschaue, wird mir wieder bewusst, wie viel Einfluss Sven auf mich und mein Umfeld hatte.

Mein nach wie vor verwendetes Mailsetup mit mutt ist mittlerweile über 20 Jahre alt, und noch heute finden sich Schnipsel von Sven in meinen Konfigurationsdateien. Sven ist nach wie vor in der muttrc von Grml vertreten, und exakt am Abend des 20.02.2022 habe ich zur muttrc von Grml eine Mail von einem Anwender erhalten, kurz bevor Sven uns leider für immer verlassen hat. :( Meine vimrc hat noch immer jede Menge iab-Einträge, die ich damals gemeinsam mit Sven erstellt habe. Sven hatte großen Einfluss auf zsh-lovers, aber generell auch auf das gesamte Grml-Projekt (siehe dazu übrigens sein wunderbares Zsh-Buch gemeinsam mit Julius Plenz.)

Svens Leidenschaft für freie Software und die Arbeit mit der Kommandozeile haben mich geprägt, er hatte maßgeblichen Einfluss darauf, wer ich heute bin. Er bleibt mir als Lebenskünstler und Freigeist mit rotem Schal in Erinnerung.

Svens letzte Mail an mich endet übrigens so:

joa.. xundheit hat prio!
denn die beste krankheit nutzt nix. ;)

euch allen ebenfalls alles gute.
auf ein wiedersehen bei den glt22!

:wq

Revisiting 2021

January 12th, 2022

*

Uhm yeah, so this shirt didn’t age well. :) Mainly to recall what happened, I’m once again revisiting my previous year (previous edition: 2020).

2021 was quite challenging overall. It started with four weeks of distance learning at school. Luckily at least at school things got back to "some kind of normal" afterwards. The lockdowns turned out to be an excellent opportunity for practising Geocaching though, and that’s what I started to do with my family. It’s a great way to grab some fresh air, get to know new areas, and spend time with family and friends – I plan to continue doing this. :)

We bought a family season ticket for Freibäder (open-air baths) in Graz; this turned out to be a great investment – I enjoyed the open air swimming with family, as well as going for swimming laps on my own very much, and plan to do the same in 2022. Due to the lockdowns and the pandemics, the weekly Badminton sessions sadly didn’t really take place, so I pushed towards the above-mentioned outdoor swimming and also some running; with my family we managed to do some cycling, inline skating and even practiced some boulder climbing.

For obvious reasons plenty of concerts I was looking forward didn’t take place. With my parents we at least managed to attend a concert performance of Puccinis Tosca with Jonas Kaufmann at Schloßbergbühne Kasematten/Graz, and with the kids we saw "Robin Hood" in Oper Graz and "Pippi Langstrumpf" at Studiobühne of Oper Graz. The lack of concerts and rehearsals once again and still severely impacts my playing the drums, including at HTU BigBand Graz. :-/

Grml-wise we managed to publish release 2021.07, codename JauKerl. Debian-wise we got version 11 AKA bullseye released as new stable release in August.

For 2021 I planned to and also managed to minimize buying (new) physical stuff, except for books and other reading stuff. Speaking of reading, 2021 was nice — I managed to finish more than 100 books (see “Mein Lesejahr 2021“), and I’d like to keep the reading pace.

Now let’s hope for better times in 2022!

Mein Lesejahr 2021

January 4th, 2022

Auch 2021 habe ich wieder mittels Bookdumps versucht, kurze Reviews zu den von mir gelesenen Büchern festzuhalten (wobei sich das auf Belletristik- und Sachbücher beschränkt, also grundsätzlich keine Fachbücher und IT-Bücher, bzw. auch keine Kinderbücher :)). Dazu erschienen 2021 folgende Bookdumps:

In Summe habe ich 2021 mindestens 102 Bücher mit insgesamt 24266 Seiten gelesen, das durchschnittliche Buch hatte also 238 Seiten und ich kam auf durchschnittlich >66 Seiten pro Tag. Diesmal hab ich nicht speziell darauf geachtet, wie das Verhältnis von Autorin zu Autor ist, und mit 69 Autoren zu 32 Autorinnen (sowie 1x gemischt) ist es leider auch entsprechend unausgewogen ausgefallen.

Wie schon in “Mein Lesejahr 2020” geschrieben, helfen mir die Reviews beim Erinnern an die gelesenen Bücher sowie beim Austausch mit Lesekollegen. Die Reviews habe ich diesmal bewusst kürzer bzw. unaufwendiger gehalten und auf die vier Quartale aufgeteilt. Trotzdem passt das Verhältnis Aufwand vs. Nutzen für mich noch nicht ganz. Besonders, da ich den Diskurs mittlerweile in persönlichen Gesprächen mit meinen Lesebuddies suche (und dort eine andere Form von Notizen gefragt ist), die Bookdumps nicht bei der Vorab-Auswahl der Bücher helfen und ich auch viele Bücher ohne Lesebuddy lese. Für 2022 könnte ich mir daher das Format eines “Best Of” vorstellen – let’s see.

Was waren 2021 meine Lieblingsbücher? Es waren viele gute Bücher dabei, die folgenden sind mir aber besonders im Gedächtnis geblieben (keine Reihung):

Mein Bücherregal für 2022 ist bereits gut gefüllt, wer aber noch Empfehlungen hat oder Bücher “gemeinsam” mit mir lesen möchte: ich freue mich über Kommentare hier im Blog oder via Mail (bookdump at michael-prokop.at).

Bookdump 04/2021

January 4th, 2022

Foto vom Buchregal

Bücher, die ich in 2021 seit meinem letzten Bookdump gelesen habe:

  • Das Paradies meines Nachbarn, Nava Ebrahimi. In 220 Seiten geht es anhand von drei Hauptfiguren und deren Familie um Migration, (Nicht)Opfersein, Schuld, Doppelmoral, eingebettet in die Geschichte des Golfkriegs zwischen Iran und Irak. Sprachlich beeindruckend, ohne jeglichem Pathos oder Kitsch.
  • Bauer und Bobo, Florian Klenk. Sehr flüssig zu lesende 156 Seiten, die die wichtigen Themen Fleischindustrie, Klimakrise und Landwirtschaft anhand der Geschichte des “Wutbauers” Christian Bachler und des “Bobos” Florian Klenk erzählen. Schön gemacht und lesenswert.
  • Das Buch Blam, Aleksandar Tišma. Diese 238 Seiten handeln vom Holocaust-Überlebenden Miroslav Blam und spielen in den 50er Jahren in Novi Sad. Es geht um um die Schmach der Überlebenden, erzählt in einer beeindruckenden Sprache. Die alte Rechtschreibung war ungewöhnlich zu lesen, und der Schriftsatz des Buches ist für mich leider nicht ansprechend, aber das Thema Deportationen, und die Geschichte der Juden und Serben sind literarisch in wunderbaren Episoden gestaltet. Danke für den Buchtipp, Anita.
  • Die Anomalie, Hervé Le Tellier. Ein Flugzeug landet nach gut drei Monaten ein zweites Mal, der gleiche Flug mit den gleichen Personen an Bord. Das Ergebnis ist ein Doppelleben im wahrsten Sinne des Wortes. Unterhaltsame 345 Seiten, die zum Philosophieren einladen.
  • Die Geister, die ich teilte, Fritz Jergitsch. Auf 215 Seiten gibt es vom Gründer der “Tagespresse” eine lesenswerte Analyse zum Thema Social Media.
  • Kurz – ein Regime, Peter Pilz. Auf 233 Seiten gibt es einen guten Überblick und Einblick in die letzten Jahre der österreichischen Politik rund um die (neue) ÖVP.
  • Radikalisierter Konservatismus, Natascha Strobl. Die 167 Seiten waren für mich leider nicht ganz so erhellend, wie ich es mir gewünscht hätte, auch wenn es insgesamt einen guten Einstieg in das Thema vermitteln dürfte. Speziell aber gegen Ende hin hatte ich den Eindruck, dass das Buch zu einer Deadline fertig werden muss.
  • Die Epistemisierung des Politischen, Alexander Bogner. Das Buch beleuchtet unsere Wissensgesellschaft und ihre Konflikte (wie z.B. Impfdebatte, Corona- und Klimakrise, Verschwörungsideologien, Fake News), sowie den Umgang und die Abwicklung politischer Fragen. Leseempfehlung für diese 131 anregenden Seiten.
  • GRM, Sibylle Berg. Was für ein unglaublich brutales Buch. Ich habe diesen dystopischen Roman nur stückweise verdauen können, und für die 634 Seiten in Summe mehr als ein halbes Jahr gebraucht.
  • Wo sind wir hier eigentlich?, Stefan Apfl, Sebastian Loudon + Alexander Zach . Das österreichische Monatsmagazin DATUM hat 51 Persönlichkeiten aus Politik, Wirtschaft, Wissenschaft und Kunst zu einem Stammtischgespräch eingeladen. Daraus entstand dieses 165 Seiten schlanke Buch, unterteilt in drei Akte (“Woher wir kommen”, “Wo wir stehen” und “Wohin wir gehen”). Ein nicht alltägliches Format, das zum Nachdenken und Diskutieren einlädt.
  • Im Spiegelsaal, Liv Strömquist. Ein grafischer Roman (Graphic Novel) rund um Schönheitsempfinden und Schönheitswahn in 5 Kapiteln auf 168 Seiten, der Gesellschaftskritik mit geschichtlichem Hintergrundwissen in unterhaltsamer Form kombiniert. Störend fand ich das Fehlen von Seitenzahlen, was vermutlich beabsichtigt ist, den Austausch mit Lesepartner:innen aber dementsprechend erschwert.
  • Gebrauchsanweisung für Barcelona, Merten Worthmann. Auf 153 Seiten gibt es einen Einblick in das Leben und die Kultur der Barceloneserinnen und Barceloneser. Die Konflikte der Katalanen werden ganz vorsichtig angeschnitten, ohne aber in die politische Dimension tiefer einzutauchen. Das ist wohl auch eine gute Zusammenfassung des Buches: unterhaltsam geschrieben, aber – zumindest für mich – mit überschaubarem Erkenntnisgewinn.
  • Das Ereignis, Annie Ernaux. Was für ein wortgewaltiges Buch. In unglaublicher Offenheit schreibt die Autorin auf 104 Seiten von ihrer illegalen Abtreibung aus dem Jahr 1963. Schwere Kost, mit klarer Leseempfehlung.
  • Plastikfreie Zone, Sandra Krautwaschl. Das Buch ist mir in einer Bücherbox (beim Generationenpark in Feldkirchen) aufgefallen, und ich konnte nicht widerstehen, das Buch temporär an mich zu nehmen. Die 296 Seiten waren schnell gelesen, und das Buch lädt ein, sich Gedanken über die eigene Umgebung und den Umgang mit Gegenständen zu machen. Meinen Blick auf Plastik hat das Buch geschärft.
  • Lektüre zwischen den Jahren: Tage des Lesens, Gesine Dammel (Hg.). In Anlehnung an Marcel Proust’ Tage des Lesens, sind in diesem Buch auf 153 Seiten die Geschichten von 19 Autorinnen und Autoren gesammelt, die sich rund um Bücher und das Lesen drehen. Das Format des Buches – einerseits Kurzgeschichten, aber mit 14,8*9,5cm auch wunderbar klein und handlich – lädt dazu ein, es in der Jackentasche mit sich mit zu führen. Schöne Lektüre auch für Zwischendurch.
  • Vom Ende der Einsamkeit, Benedict Wells. Nachdem ich auf Benedict Wells gestoßen bin und großen Gefallen an seinen Texten gefunden habe, musste ich mir ein weiteres Buch von ihm besorgen. Diese 357 Seiten – in denen es u.a. um Verlust und Einsamkeit geht – zeigen, was für ein großartiger Geschichtenerzähler Wells ist. Mehr davon.
  • Meetings moderieren, Daniela Ettl. Das Buch gibt es aktuell noch(?) nicht im freien Handel und ich habe dieses 255 Seiten umfassende Buch als Ergänzung zu Danielas Workshops gelesen. Ich durfte einem solchen Workshop von Daniela beiwohnen, und kann ihre Workshops aufs Wärmste empfehlen.
  • Projekt Lightspeed, Joe Miller mit Özlem Türeci und Uğur Şahin. Dieses 350 Seiten umfassende Buch ist hochaktuell, es behandelt den Zeitraum bis Juli 2021 und erschien im September 2021. Es gibt eine Vielzahl an Hintergrundgeschichten und Anekdoten, die ich in dieser Form noch nicht gehört habe, und man bekommt einen guten Eindruck davon, wie viele Faktoren aber auch Personen und Firmen zusammenspielen mussten, dass der BioNTech-Impfstoff den Markt erreichen konnte. Solch einen Einblick hinter die Kulissen würde ich mir auch für andere Medikamente und Impfstoffe wünschen, gerne auch aus einer Gegenperspektive. Klare Leseempfehlung für am Thema Interessierte.
  • Frauenfragen, Mari Lang. Die Autorin stellte Männern Fragen wie “Wie schaffst du es, Kind und Karriere unter einen Hut zu bringen?”, die normalerweise Frauen in der Öffentlichkeit zu hören bekommen. 210 Seiten, die zum Nachdenken und Reflektieren einladen.
  • Pandemien, Jörg Hacker. Diese 123 Seiten liefern einen guten Einstieg und Überblick zum Thema Pandemien, und der Untertitel “Corona und die neuen globalen Infektionskrankheiten” sowie das Erscheinungsjahr 2021 deuten auch die Aktualität des Buches an. Jörg Hacker ist Infektionsbiologe und war Präsident des Robert Koch-Instituts, und der medizinische Schwerpunkt kommt in stellenweiser Faktendichte immer wieder durch. Besonders die Abschnitte zu zoonotischen Erregern und One Health/Public Health/Global Health waren für mich lehrreich, aber auch sonst gab es einen guten Einstieg und Überblick in das Thema.
  • Rolltreppe – oder die Herkunft der Dinge, Nicholson Baker. Auf dieses Buch bin ich über ein Interview von Klaus Nüchtern mit Clemens Setz im Falter 44/21 gestoßen, und ich kann nachvollziehen, warum Setz an diesen 221 Seiten über die ganz gewöhnlichen Gegenstände unseres Alltags Gefallen findet.
  • The Arrival, Shaun Tan. Über die Folge des Podcasts Das Lesen der Anderen mit Clemens Setz bin ich auf dieses Buch gestoßen. Diese 128 Seiten kommen ausschließlich mit Zeichnungen aus, und es ist ein absolut un- und außergewöhnliches Buch.
  • Der Osbick Vogel, Edward Gorey. Auch auf Edward Gorey bin ich wieder durch Clemens Setz gestoßen, und bevor ich das Original – siehe nächster Abschnitt – lesen konnte, durfte ich diese 15 Seiten schlanke und sehr gelungene Übersetzung von Clemens Setz genießen.
  • Amphigorey too, Edward Gorey. Auf der Suche nach Edward Goreys “The Osbick Bird” im Original bin ich auf dieses Buch von 1975/1980 gestoßen, das auf 260 Seiten 20 Geschichten von Gorey versammelt. Der nicht-deutschsprachige Büchermarkt ist in Österreich abseits von Amazon leider nach wie vor schwer zugänglich, aber dieses Buch wurde von Archive.org digitalisiert und lässt sich unter online ausborgen und lesen.
  • Briefe an mein jüngeres Ich, Herausgegeben von Jane Graham. Eine Vielzahl an Prominenten, besonders aber Schauspieler:innen und Musiker:innen und besonders englischsprachige haben einen Brief an sich selbst geschrieben, konkret an ihr 16-jähriges Ich und was sie sich heute sagen würden. Auffallend sind die unterschiedlichen Biographien, aber die sich dabei vielfach überlappenden Themen Alkohol und Drogen. Ein paar sympathische und anregende Briefe finden sich genauso darunter, wie auch egozentrische, eitle und klischeehafte Ausführungen. Die jeweils ca. 3-7 seitigen Briefe auf insgesamt 378 Seiten laden dazu ein, das Buch auch einfach mal zwischendurch zu lesen.
  • Ich reiß mir eine Wimper aus und stech dich damit tot, Josef Winkler. Ich brauchte eine Weile um mich auf den Stil “einzugrooven” und finde die Form und den Stil über den Tod zu schreiben spannend. Die 125 Seiten waren für mich im Moment schwer einzuordnen – was mich vermuten lässt, dass ich noch mehr vom Autor lesen möchte.
  • Unmöglichkeiten sind die schönsten Möglichkeiten, Sabine M. Gruber. Die Autorin, selbst Sängerin im Arnold Schönberg Chor, hat Aussprüche des österreichischen Dirigenten Nikolaus Harnoncourt bei Orchesterproben über viele Jahre aufgezeichnet und auf diesen 114 Seiten veröffentlicht. Als jemand, der den Orchesterbetrieb auch von Innen kennt, konnte ich mir die Aussagen lebhaft vorstellen und musste an mehreren Stellen laut lachen. Harnoncourt erschafft wunderbare Sprachbilder, und an einigen wenigen Stellen gibt es auch lehrreiche Musikgeschichte.
  • Dreißig Minuten, dann ist aber Schluss!, Patricia Cammarata. Auf 308 Seiten liefert die Autorin einen differenzierten Überblick über den Medien-Umgang mit Kindern. Besonders anregend fand ich die Ausführungen zu Claqueure vs. Verteidiger*innen, Nonpology (die Nicht-Entschuldigung), Grooming, Adultismus, Sharenting + Let’s Plays. Es gibt eine Vielzahl an Links zu Websites rund um das Thema (wie z.B. klicksafe.de, saferinternet.at, juuuport.de, mobilsicher.de, jugendschutz.net, spielbar.de, spieleratgeber-nrw.de, tagesschau.de/faktenfinder, correctiv.org, mimikama.at, hoaxmap.org, mediennutzungsvertrag.de, tiefdurchatmen.com + schau-hin.info). Auch wenn ich einige wenige Kleinigkeiten zu bemängeln habe (Signal wird z.B. ohne wirkliche Argumentation oder Begründung schlechter als iMessage gestellt, bei Sprachnachrichten wird nicht erwähnt, dass man typischerweise schneller liest als hört, das Buch hat einen reinen Deutschland-Bezug, z.B. fehlen leider die Rechtslage in Österreich bzw. der Schweiz), kann ich das Buch guten Gewissens allen Eltern als Orientierungshilfe im Mediendschungel empfehlen.
  • Die drei Leben der Hannah Arendt, Ken Krimstein. Eine Graphic Novel mit 243 Seiten, die in Form einer Biographie das Leben Hannah Arendt näher bringt. Ein schöner Einstieg, allerdings eben auch nicht viel mehr – es hätte für mich gerne ausführlicher bzw. detaillierter sein dürfen. Der deutschen Ausgabe hätte eine bessere Übersetzung bzw. ein genaueres Lektorat stellenweise nicht geschadet.
  • Glücklich wie Blei im Getreide, Clemens J. Setz. Fünfundvierzig Nacherzählungen auf 115 Seiten, die mich recht unterschiedlich begeistert haben. Schlussendlich aber dann doch nicht das Lieblingsbuch einer meiner Lieblingsautoren.
  • Dunkelblum, Eva Menasse. Basierend auf dem Massaker von Rechnitz, spielt dieser historische Roman auf 522 Seiten in der fiktionalen Stadt Dunkelblum. Die Verdrängung der eigenen Vergangenheit wird geschickt mit dem Thema Grenzen (z.B. Öffnung des eisernen Vorhangs) verwoben. Nach “Quasikristalle” und “Tiere für Fortgeschrittene” ein weiteres wunderbares Buch von Eva Menasse. Nicht nur sprachlich hat mich das Buch begeistert, unbedingte Leseempfehlung.
  • Opa, was macht ein Physiker?, Siegfried Hess. Das Buch wirkt mittlerweile leider ein wenig aus der Zeit gefallen. Auf den 250 Seiten werden vielfach Klischees bedient, und auch wenn viele interessante Themen angesprochen werden, werden diese mit sehr unterschiedlicher Tiefe bzw. erforderlichem Vorwissen erklärt. Das Zielpublikum ist mir auch nach Lektüre nicht wirklich klar – der streckenweise flapsige Stil trägt dazu leider auch nicht bei. Ein Wikipedia-Besuch anhand des Stichwortverzeichnisses erscheint mir zumindest heutzutage in Summe lohnenswerter.
  • Gedankenspiele über die Faulheit, Daniela Strigl. Die schlanken Gedankenspiele-Bücher aus dem Droschl-Verlag laden zum Nachdenken ein – und der Literaturwissenschaftlerin, Kritikerin und Essayistin Strigl gelingt dies auf diesen schlanken 54 Seiten aus dem Blickwinkel der Literaturwissenschaft.
  • Gedankenspiele über die Gelassenheit, Ilse Helbich. Ein weiteres Buch aus der Gedankenspiele-Bücherreihe des Droschl-Verlag, diesmal von der Publizistin und Schriftstellerin Helbich über die Gelassenheit. Besonders die Anekdoten dieses 42 Seite schlanken Buches fand ich schön.
  • Du wirst mich töten, Uli Brée. Diese 284 Seiten erzählen von einer absurden Beziehung zwischen einer Polizistin und einem Mörder. Es gibt immer wieder überraschende Wendungen, aber streckenweise war mir die Sprache leider zu brachial bzw. nicht mein Stil. Zum Buch gibt es übrigens den kostenlosen Hörbuch-Download, eine feine Sache.

Bookdump 03/2021

October 1st, 2021

Foto vom Buchregal

Bücher, die ich in 2021 seit meinem letzten Bookdump gelesen habe:

  • Roger Federer, David Foster Wallace. Ein 106 Seiten schlankes zweisprachiges Buch, das im ersten Teil die deutsche Übersetzung, und im zweiten Teil das englische Original bietet. Ich kann die Begeisterung Andrea Petkovics für Wallace jetzt durchaus nachvollziehen.
  • Puccini Tosca, Michael Horst. In Vorbereitung auf ein Konzert habe ich mir diese 134 Seiten reingezogen.
  • GrazRand, Adina Camhy, Robin Klengel, Coline Robin, Markus Waitschacher. Die 4 AutorInnen sind die 65,92km lange Grenze um Graz zu Fuß gefolgt und haben dies auf 143 Seiten dokumentiert. Ein sehr plaktatives Beispiel dafür, wie stark unsere Gesellschaft die Themen Verbauung und Autoverkehr priorisiert. Sehr schönes Projekt, danke.
  • Nachts unter der steinernen Brücke, Leo Perutz. Perutz hat an diesem historischen Roman über 25 Jahre lang geschrieben. In den 269 Seiten geht es in 14 Erzählungen rund um die Zeit um 1600, gestaltet in einer fantastischen Sprache.
  • Souverän investieren mit Indexfonds & ETFs, Gerd Kommer. Die fünfte Auflage (Danke an S. fürs Borgen!) hat 411 Seiten, und es geht grundsätzlich um Indexfonds wie ETFs (Exchange-traded Funds), aber auch Einblicke in Themen wie Regression zur Mitte, Diversifikation, Buy-and-hold-Strategie, Efficient Market Theorie (bzw. Markteffizienzhypothese), 72er Regel, Factor-Investing, Faktor-Prämien mit Small-Size- und Value-Effekt und Momentum-Faktor, Humankapital, Low-Cost-Buy-and-Hold-Indexing-Strategie, Rebalancing und den von Kommer geprägten Begriff des Weltportfolios. Kommer schreibt dabei gegen aktiv gemanagte Fonds, und klärt einige Mythen und Falschinformationen auf (speziell rund um Gold- und Immobilien, aber auch Sunk Costs und Crashes). Der Fokus des Buchs liegt auf Deutschland, der Großteil lässt sich aber auch als ÖsterreicherIn verwenden. Speziell die ersten 3/4 des Buches fielen für mich aber in die Kategorie “dieses Lesen ist Arbeit”, erst die letzten 4 Kapitel ab Seite 319 wurden dann praxisrelevanter.
  • Mein Beethoven – Leben mit dem Meister, Rudolf Buchbinder. Auf 221 Seiten beschäftigt sich der Musiker Buchbinder mit den Werken und dem Leben Beethovens. Als LeserIn erfährt man von geschichtlichen Zusammenhängen (speziell rund um Kaiser Napoleon und Erzherzog Rudolph), aber auch persönlichen Beziehungen Beethovens zu den Musikern Johann Sebastian Bach, Carl Czerny, Mozart, Joseph Haydn und Franz Liszt, sowie zu den Schriftstellern Grillparzer und Goethe. Bisher gänzlich unbekannt war mir die Künstlerin Dorothea von Ertmann. Es gibt einen Einblick in Beethovens Familiengeschichte (speziell zu seinem Neffen Karl), und in den Themenkomplex von Interpretation (u.a. Tempobezeichnungen und “geeichte” Metronome, aber auch Manuskripte sowie Notensatz-Fehler in vorzeitigen Veröffentlichungen), Verlegertum (spez. Breitkopf & Härtel), sowie Beethovens Taubheit und Leberzirrhose. Leider wieder ein Buch ohne Personenregister und Index. Auch das Zielpublikum ist mir nicht ganz klar, weil es einerseits durchaus Musiktheorie-Kenntnisse (speziell bezüglich Tempo- und Stilbezeichnungen) und Kenntnis der Musikstücke voraussetzt, andererseits für Musik- und Beethoven-Kenner in Summe zu oberflächlich bleibt. Trotzdem ein schöner Ausflug zu Beethoven und rund ums 18. Jahrhundert.
  • Die Raststätte, Florian Werner. Ein lesenswerter Ausflug auf 159 Seiten an die Autobahnraststätte Garbsen Nord, mit einem Blick auf Sanifair-Toiletten, Lastwagenfahrer, Autobahnpolizei, Flaschensammler, Notfallseelsorger und einen Exkurs in die Botanik mit Jürgen Feder.
  • Die Leichtigkeit des Schweren, Klaus Reichert. Der vierte Band aus den Grazer Vorlesungen zur Kunst des Schreibens handelt auf 105 Seiten von der Kunst des Übersetzens. Dass dabei nicht nur ein Wort in ein anderes übersetzt wird, sondern ein Sprach- und Kultursystem in ein anderes (so auch der Semiotiker Charles Saunders Peirce). In Summe ein ambivalenter Gesamteindruck, aber durchaus interessante Einblicke in die Sprache rund um Adorno, Celan, Joyce, Shakespear,… und die Biographie und Arbeit eines renommierten Übersetzers.
  • Inside Facebook, Sheera Frenkel + Cecilia Kang. Auf 376 Seiten gibt es einen Einblick in die Unternehmenskultur Facebooks und den Inner Circle von Zuckerberg. Es geht um Zuckerbergs enge Perspektive (Money-Quote: “Ich werde nie die Zeit haben, das zu lesen” – die Antwort Zuckerbergs, als er ein Buch übergeben bekommt), seine fehlende Perspektive über die amerikanische Sicht der Dinge hinaus, das fehlende Verständnis für politische und kulturelle Dynamiken, aber auch seine angebliche Skrupellosigkeit zugunsten der Expansion seiner Firma. Es gibt geschichtliches rund um Themen wie den Like-Button und Datenschutz, aber auch sehr traurige Themen wie die Überwachung der eigenen MitarbeiterInnen, Enthüllungen rund um die Präsidentenwahl von Trump und Clinton, die Geschichte hinter dem Open-Graph-Plugin und den damit verbundenen Skandal um Cambridge Analytics, die Ausschreitungen in Myanmar, und wie sehr sich Facebook als Clickbait-Plattform für Populismus etablierte.
  • Der Sandler, Markus Ostermair. 371 sehr starke Seiten mit einem Einblick in das Tabuthema der Obdachlosigkeit. Irgendwann rund ums dritte Viertel des Buches herum war es für mich streckenweise ein wenig langatmig, nichtsdestotrotz ein starkes und lesenswertes Buch.
  • Machen Sie mal zügig die Mitteltüren frei, Susanne Schmidt. 205 schnell zu lesende Seiten, die einen Einblick in die Welt der Berliner Verkehrsbetrieb geben, die laut der Autorin durchaus als mi­so­gyne und patriarchale Arbeitsumgebung verstanden werden darf. Ein netter Einblick in den Alltag einer Busfahrerin in Berlin.
  • Operation Crypto, Res Strehle. Eine 127 Seiten schlanke Aufarbeitung der Machenschaften der Zuger Firma CRYPTO AG. Wer sich für geschichtliche und politische Zusammenhänge interessiert, wird hier bedient. Danke auch für das Personenregister am Ende des Buches.
  • Meine Olympiade, Ilija Trojanow. Passend zu den olympischen Sommerspielen 2020 in Tokyo hat sich dieses Buch auf mein Bücherregal verirrt. Im Laufe von vier Jahren hat Trojanow alle achtzig Olympia-Sommer-Einzeldisziplinen trainiert, mit dem Ziel, halb so gut abzuschneiden, wie die jeweiligen GoldmedaillengewinnerInnen von von 2012 in London. Die 343 Seiten geben einen schönen Einblick in die Welt des Profisports, speziell auch in Sportarten, die weniger öffentliche Aufmerksamkeit erfahren (z.B. Omnium und Keirin). Nebenbei gibt es schöne Begriffe wie Hinterradlutscher.
  • 99 Fragen, Ralph Caspers. Auf 207 Seiten – links jeweils die Fragestellung, rechts Caspers Antworten bzw. Ausführungen dazu – gibt es 99 Fragen, die für Gespräche mit Kindern, bzw. innerhalb der Familie taugen sollen. Der Schreibstil ist großteils sehr flapsig, aber in einigen wenigen Antworten gab es auch Neuigkeiten zu lernen. Insgesamt aber verstecken sich einige wunderbare Kommunikationsstarter darin, und laden dazu ein, vom üblichen “wie war es in der Schule” auch mal abzuweichen. PS: Das Buch aus dem Duden-Verlag ist der Nachweis, dass auch dort das Thema Rechtschreib-/Grammatikfehler noch kein vollständig gelöstes Problem ist. :)
  • Drei Kameradinnen, Shida Bazyar. Es geht um einen Brand, verknüpft mit den Themen Alltags-Rassismus, Othering und Einwanderung. Nicht leicht zu verdauen und anfangs durchaus interessant zu lesen, aber irgendwann waren mir die 350 Seiten dann leider zu ermüdend.
  • Logicomix, Apostolos Doxiadis + Christos H. Papadimitriou. Eine grafische Novelle mit 348 Seiten, die das Leben von u.a. Bertrand Russell, Ludwig Wittgenstein, Alfred North Whitehead leichthändig beleuchtet.
  • Der Buchspazierer, Carsten Henn. Eine schöne Geschichte rund um Bücher und das Lesen auf 224 Seiten.
  • Vom Aufstehen, Helga Schubert. Was für ein Meisterwerk von einem Buch, was für eine Lebensgeschichte. Eine Lebensrückschau, die einen Rückblick auf den DDR-Alltag und das Spannungsverhältnis zur eigenen Mutter umfasst. Eine ganz klare Leseempfehlung für diese 219 Seiten.
  • Die Geschichte von Herrn Sommer, Patrick Süskind. Eine wunderbare, 130 Seiten schlanke Geschichte. Die Leseempfehlung (danke Anita!) kann ich weitergeben.
  • 2001, Angela Lehner. Ich war von Angela Lehners “Vater unser” 2019 begeistert, daher waren diese 383 Seiten Pflichtprogramm für mich. Der Coming-of-age-Roman rund um die Generation Y hat mich in keinster Weise enttäuscht und war sehr unterhaltsam. Leseempfehlung.
  • Ein Leben voller Abzweigungen, Robert Fröwein. Der Autor befragt Taxi- bzw. Uber-Fahrer bei ihrer Arbeit zu dieser. Der Titel zu diesen 189 Seiten hat viel Potenzial versprochen, für mich aber leider nicht gehalten.
  • Literatur lesen, Terry Eagleton. In der deutschsprachigen Versionen bei Reclam erschienen, als solche aber leider nicht mehr verfügbar, daher entweder in einer Bibliothek ausborgen oder zum englischsprachigen Original (How to Read Literature) greifen. Die 253 Seiten haben mich der britischen Literatur und deren Bedeutungsebenen ein Stück näher gebracht und meinen Blick für die Interpretation von Texten ein wenig geschärft, besonders das letzte Kapitel “Werturteile” fand ich erkenntnisreich.
  • Beethoven, Erich Valentin. Diese ca. 133 Seiten schlanke Bildbiographie erschien im Jahr 1957 und ist leider ebenfalls nur mehr auf dem Gebraucht-Markt bzw. in Bibliotheken zu bekommen. Das Alter merkt man dem Buch auf vielen Ebenen an, das hat aber durchaus seinen Charme (inklusive schöner Sätze wie “Eine goldene Ausnahme war die gute Haushälterin Sali, die ebenso in die Beethoven-Geschichte eingegangen ist wie die »Frau Schnaps«, die »schnellsegelnde Fregatte«.”). Alleinstehend gelesen würde mir mit nur diesem Buch der Blick fürs große Ganze fehlen, aber gemeinsam mit anderen Werken war es eine nette Ergänzung.
  • Machtverfall, Robin Alexander. Auf 378 Seiten gibt es einen Einblick in den politischen Betrieb rund um Angela Merkel. In Dokutainment-Form liest sich das Buch wie ein Politik-Krimi. Das Buch ist 2021 brandaktuell, es startet mit der Wahl von Trump 2017 und geht bis in den April 2021 hinein, behandelt entsprechend die Nachfolge-Suche für Merkel, aber auch die Corona-Politik wird beleuchtet. Gegen Ende hin lässt das Buch für mich ein wenig nach, aber im Kontext der Wahl des deutschen Bundestags am 26. September 2021 war dieses Buch eine sehr gute Lektüre. Für Politikinteressierte ist das Buch absolut empfehlenswert.
  • Marzahn, mon amour, Katja Oskamp. Die Autorin wird in ihrer Midlife-Crisis Fußpflegerin in Berlin-Marzahn, und man darf ihr dabei 143 Seiten lang folgen. Durchwegs sympathisch.
  • Die Wahrheit über das Lügen, Benedict Wells. Zehn Kurzgeschichten auf 244 Seiten, die nur so flutschen. Unterhaltsam, überraschend und abwechslungsreich – und all das in einen wunderbaren Schreibstil verpackt – Leseempfehlung.
  • Das Dämmern der Welt, Werner Herzog. Der japanische Soldat Onoda Hirō bekommt das Ende des zweiten Weltkriegs auf der philippinischen Insel Lubang nicht mit bzw. will es nicht wahrhaben, und kämpft knapp 3 Jahrzehnte noch weiter im Glauben, dass der Weltkrieg noch nicht beendet wurde. Ein gedankenanregender Ausflug in den Dschungel auf 127 Seiten.
  • Alte Meister, Nicolas Mahler. Wieder eine Leihgabe eines Nachbars (danke C.!). Unterhaltsame 158 Seiten, die das Werk Thomas Bernhards in einer grafischen Novelle interpretieren.
  • Der Mann ohne Eigenschaften, Nicolas Mahler. Noch eine Leihgabe eines Nachbars (danke C.!). 156 Seiten, die das unvollendete Werk Robert Musils in einer grafischen Novelle wiedergeben, allerdings ist der Unterhaltungswert speziell in diesem Fall ohne Kennt­nis des Originalwerks überschaubar.

Debian bullseye: changes in util-linux #newinbullseye

July 5th, 2021

Continuing with #newinbullseye. One package that isn’t new but its tools are used by many of us is util-linux, providing many essential system utilities. There is util-linux v2.33.1 in Debian/buster and util-linux v2.36.1 in Debian/bullseye, and as usual there are many new features and options available.

I don’t want to replicate the release notes provided by upstream, instead make sure to check out the Release highlights sections in the following release notes:

Tools that have been taken over from / moved to other packages

Debian’s util-linux source package provides new binary packages: eject (and eject-udeb) and bsdextrautils. The util-linux implementation of /usr/bin/eject is used now, replacing the one previously provided by the eject source package.

Overall, from a util-linux perspective the following shifts took place:

  • col, colcrt, colrm, column: moved from binary package bsdmainutils to bsdextrautils
  • eject: moved to binary package eject
  • hd: moved from binary package bsdmainutils to bsdextrautils
  • hexdump: moved from binary package bsdmainutils to bsdextrautils
  • look: moved from binary package bsdmainutils to bsdextrautils
  • ul: moved from binary package bsdmainutils to bsdextrautils
  • write(.ul): moved from binary package bsdmainutils (named bsd-write) to bsdextrautils

Deprecated / removed tools

Tools that are no longer shipped as of Debian/bullseye:

  • /usr/bin/rename.ul (rename files): use e.g. rename package instead, see #926637 for details regarding the removal
  • /usr/bin/volname (return volume name for a device formatted with an ISO-9660 file system): use blkid -s LABEL -o value $filename instead
  • /usr/lib/eject/dmcrypt-get-device: no replacement available

New tools

Debian’s bsdutils package (which is provided by the util-linux source package) provides a new tool from util-linux:

  • scriptlive: re-execute stdin log by a shell in PTY session

The new tools lsirq + irqtop (to monitor kernel interrupts) sadly didn’t make it into util-linux’s packaging of Debian/bullseye (as without per-CPU data they do not seem mature at this time). The new hardlink tool (to consolidate duplicate files via hardlinks) won’t be shipped, as there’s an existing hardlink package already.

New features/options

agetty + getty:

--show-issue    display issue file and exit

blkdiscard:

--force         disable all checking

blkid:

-D, --no-part-details      don't print info from partition table

blkzone:

Commands:

open         Open a range of zones.
close        Close a range of zones.
finish       Set a range of zones to Full.

Options:

-f, --force            enforce on block devices used by the system

cfdisk:

--lock[=<mode>]      use exclusive device lock (yes, no or nonblock)

dmesg:

--noescape             don't escape unprintable character
-W, --follow-new       wait and print only new messages

fdisk:

-x, --list-details          like --list but with more details
-n, --noauto-pt             don't create default partition table on empty devices
--lock[=<mode>]             use exclusive device lock (yes, no or nonblock)

fstrim:

-I, --listed-in <list>   trim filesystems listed in specified files
--quiet-unsupported      suppress error messages if trim unsupported

lsblk:

Options:

-E, --dedup <column> de-duplicate output by <column> 
                     (for example 'lsblk --dedup WWN' to de-duplicate devices by WWN number, e.g. multi-path devices)
-M, --merge          group parents of sub-trees (usable for RAIDs, Multi-path)
                     see http://karelzak.blogspot.com/2018/11/lsblk-merge.html

New output columns:

FSVER         filesystem version
PARTTYPENAME  partition type name
DAX           dax-capable device

lscpu:

Options:

-B, --bytes             print sizes in bytes rather than in human readable format
-C, --caches[=<list>]   info about caches in extended readable format
    --output-all        print all available columns for -e, -p or -C

Available output columns for -C:

        ALL-SIZE  size of all system caches
           LEVEL  cache level
            NAME  cache name
        ONE-SIZE  size of one cache
            TYPE  cache type
            WAYS  ways of associativity
    ALLOC-POLICY  allocation policy
    WRITE-POLICY  write policy
        PHY-LINE  number of physical cache line per cache t
            SETS  number of sets in the cache; set lines has the same cache index
   COHERENCY-SIZE  minimum amount of data in bytes transferred from memory to cache         

lslogins:

--lastlog <path>     set an alternate path for lastlog

lsns:

-t, --type time      namespace type time is also supported now (next to mnt, net, ipc, user, pid, uts, cgroup)

mkswap:

--lock[=<mode>]      use exclusive device lock (yes, no or nonblock)

more:

Options:

-n, --lines <number>  the number of lines per screenful

New long options (in addition to the listed equivalent short options):

  --silent       - equivalent to -d
  --logical      - equivalent to -f
  --no-pause     - equivalent to -l
  --print-over   - equivalent to -c
  --clean-print  - equivalent to -p
  --squeeze      - equivalent to -s
  --plain        - equivalent to -u

mount:

Options:

--target-prefix <path>  specifies path use for all mountpoints

Source:

ID=<id>                 specifies device by udev hardware ID

mountpoint:

--nofollow     do not follow symlink

nsenter:

-T, --time[=<file>]    enter time namespace

script:

-I, --log-in <file>           log stdin to file
-O, --log-out <file>          log stdout to file (default)
-B, --log-io <file>           log stdin and stdout to file
-T, --log-timing <file>       log timing information to file
-m, --logging-format <name>   force to 'classic' or 'advanced' format
-E, --echo <when>             echo input (auto, always or never)

sfdisk:

--disk-id <dev> [<str>]           print or change disk label ID (UUID)
--relocate <oper> <dev>           move partition header
--move-use-fsync                  use fsync after each write when move data
--lock[=<mode>]                   use exclusive device lock (yes, no or nonblock)

unshare:

-T, --time[=<file>]       unshare time namespace
--map-user=<uid>|<name>   map current user to uid (implies --user)
--map-group=<gid>|<name>  map current group to gid (implies --user)
-c, --map-current-user    map current user to itself (implies --user)
--keep-caps               retain capabilities granted in user namespaces
-R, --root=<dir>          run the command with root directory set to <dir>
-w, --wd=<dir>            change working directory to <dir>
-S, --setuid <uid>        set uid in entered namespace
-G, --setgid <gid>        set gid in entered namespace
--monotonic <offset>      set clock monotonic offset (seconds) in time namespaces
--boottime <offset>       set clock boottime offset (seconds) in time namespaces

wipefs:

--lock[=<mode>] use exclusive device lock (yes, no or nonblock)

Bookdump 02/2021

July 5th, 2021

Foto vom Buchregal

Bücher, die ich in 2021 seit meinem letzten Bookdump gelesen habe:

  • Abenteuerliche Reise durch mein Zimmer, Karl-Markus Gauß. Auf den 221 Seiten begleitet man den Autor bei Geschichten, die es zu den unterschiedlichsten Gegenständen in seiner Wohnung in Salzburg zu erzählen gibt, blickt mit ihm auf die Geschichte seiner Familie wie auch seine Büchersammlung, und bekommt nebenbei geschichtliches Wissen vermittelt. Ein wunderbarer Ausflug.
  • Der Ursprung der Liebe, Liv Strömquist. Wieder eine Leihgabe eines Nachbars (danke C.!). Nach “Der Ursprung der Welt” und “Ich fühl’s nicht” das mittlerweile dritte Buch, das ich von Strömquist gelesen habe. Auch diese 135 Seiten schlanke Graphic Novel war wieder anregend und habe ich gerne gelesen.
  • Die neue (Ab)Normalität, Robert Misik. Ein lesenswerter Essay, der auf 154 Seiten zum Nachdenken einlädt.
  • Alles muss man selber machen, Daniela Strigl. 150 Seiten. Ein interessanter Ausflug in die Literaturszene und Literaturkritik. Und ich weiß jetzt auch, wem wir es zu verdanken haben, dass wir dieses unsägliche “Zurückbleiben, bitte!” bei den Wiener Linien wieder losgeworden sind.
  • Hauskonzert, Igor Levit und Florian Zinnecker. 300 Seiten. Der Titel “Hauskonzert” bezieht sich auf die auf Twitter gestreamten Konzerte von Levit in der Corona-Lockdown-Zeit 2020, und der Schreibstil hat streckenweise auch etwas twitterhaftes. Ein schönes Buch, in dem man mehr über Igor Levit und seinen Werdegang erfährt, und ganz nebenbei noch mehr Lust aufs Hören der erwähnten Werke bekommt (die 32 Beethoven Sonaten, Goldberg- und Diabelli-Variationen, “The People United will never be defeated”, Werke von Thelonious Monk, …). Nur schade, dass die erwähnten Werke und Personen in keinem Index/Register zu finden sind.
  • Hell yeah or no, Derek Sivers. 126 Seiten an Gedanken rund um was es wert ist zu machen, schlechtes loszuwerden und “making things happen”. Der Stil ist für eine Art “Lebensoptimierungs”-Buch vergleichsweise sehr angenehm, und ich habe es als eine wesentlich bessere Version von “Die 4-Stunden Woche” von Timothy Ferriss (siehe mein Review dazu) wahrgenommen. Anregend.
  • Jahr null, Frenk Meeuwsen. Wieder eine Leihgabe eines Nachbars (danke C.!). 237 Seiten in Comic-Formc über seine Entscheidung für das Elternwerden und Vatersein. War mir persönlich zu wenig tiefgehend und zu grafiklastig, die Bücher von Liv Strömquist fand ich diesbezüglich inspirierender und in einer ganz anderen Liga.
  • Das Mädchen mit dem Fingerhut, Michael Köhlmeier. Eine wunderbare Parabel auf die Flüchtlingssituation, in schlanken 140 Seiten .
  • Hamster im hinteren Stromgebiet, Joachim Meyerhoff. 307 Seiten unterhaltsame Literatur. Meyerhoff enttäuscht auch diesmal nicht, ich musste beim Lesen mehrfach laut auflachen, wunderbar.
  • Eurotrash, Christian Kracht. In diesen 210 Seiten macht der Ich-Erzähler mit seiner alkohol- und tablettenabhängigen Mutter einen Ausflug durch die Schweiz. Eine Autofiktion rund um eine Familiengeschichte und Kritik an Schweiz und Deutschland in wunderbarer Sprache. Das Buch ist eine Fortsetzung von Krachts “Faserland”, und ich kann beide Bücher guten Gewissens empfehlen.
  • Daheim, Judith Hermann. Meine Erwartungshaltung an die 189 Seiten waren hoch, da das Buch für die Leipziger Buchmesse 2021 nominiert und in allen Literatursendungen und Rezensionen des Feuilletons hochgelobt wurde. Der Anfang war vielversprechend, sprachlich finden sich immer wieder wunderbare Strecken und das Thema ist gut. Irgendwo rund um die Hälfte hat sich meine Lust auf das Buch leider gedreht, und das Lesen wurde mir mehr Arbeit als Spaß. Vielleicht war ich auch einfach in der falschen Stimmung, aber die leicht inflationäre Verwendung von “ab und an” gegen Ende hin war dann leider nur mehr der i-Punkt für meinen schlussendlich leider doch nicht besonders tollen Gesamteindruck. Hmpf, wirklich schade.
  • Lachen und Sterben, Franz Schuh. Eine wunderbare Sammlung von philosophischen Essays und diversen Anekdoten rund um Österreich, Medien-und Kulturkritik auf 331 Seiten. Anregend.
  • Die Mitternachtsbibliothek, Matt Haig. Nora möchte ihrem Leben ein Ende setzen, landet dabei aber in einer Bibliothek und darf verschiedene Lebenswege, gekoppelt an Entscheidungen in ihrem Leben, neu erleben. Sprachlich OK umgesetzt (stellenweise doch ein wenig rumpelig), aber die wunderbare Idee entschädigt dafür. 318 Seiten mit Gedanken rund um Lebenswillen, Entscheidungen und Blickwinkel.
  • Macbeth Melania, Katharina Tiwald. 143 Seiten einer Mischung aus politischem Roman und Theaterstück, das im Jahr 2017 spielt. Mit diesem zeitlichen Abstand liest es sich ein wenig komisch im Jahr 2021, wenn wir Christian Kern, Reinhold Mitterlehner und Trump eigentlich schon hinter uns gelassen haben. Kurzweilige Lektüre, aber wir wurden von der Wirklichkeit irgendwie schon eingeholt.
  • Die kleinste gemeinsame Wirklichkeit, Mai Thi Nguyen-Kim. Die 365 Seiten lesen sich leicht und flüssig, die Schreibart ließ bei mir gedanklich auch immer wieder den doch recht einmaligen Stil ihrer mailLab YouTube-Videos auftauchen. Der flappsige Stil zielt aber vermutlich eher auf ein junges Publikum ab, daher bietet sich das Buch leider nicht wirklich als Geschenk für so manch ältere Person in meinem Bekanntenkreis an. Das Buch teilt sich inhaltlich in 9 Kapitel auf, anhand derer verschiedene Fragestellungen rund um Wissenschaft behandelt werden: 1) Legalisierung von Drogen, 2) Videospiele und Gewalt, 3) Gender Pay Gap, 4) Big Pharma vs. alternative Medizin, 5) Wie sicher sind Impfungen, 6) Erblichkeit von Intelligenz, 7) Warum denken Frauen und Männer unterschiedlich?, 8) Sind Tierversuche ethisch vertretbar und 9) Die kleinste gemeinsame Wirklichkeit.
    Manche dieser Kapitel nehmen auch direkten Bezug auf die Zeit rund um Corona. Ein wenig schade fand ich dabei, dass Mai nicht auf das häufig missverstandene (Nicht-)Problem von “Langzeit-Folgen” bei Impfungen eingeht (siehe z.B. Martin Moders YouTube-Video bzw. Taschwer im Standard), was zumindest für mich eine der Lektionen aus 2020/2021 war. Schade, dass auch bei diesem Buch wieder ein Index fehlt. Insgesamt hätte das Buch für mich gerne noch ausführlicher und tiefergehend, dafür aber auch kompakter und dichter sein dürfen. Fairerweise liest sich das Buch allerdings so dermaßen flüssig und leicht, dass es eigentlich keine Einstiegshürde oder Gefahr des “beim ersten Kapitel steckenbleiben” gibt. Sehr gelungen – und wünsch ich mir in Zukunft für alle Sachbücher – finde ich die in roter Farbe hervorgehobenen Begriffe, die besonders als Gedankenstütze beim Nachschlagen hilfreich sind. Exemplarisch möchte ich einige dieser rot gedruckten Wörter hier anführen – das vermittelt vielleicht auch gleich noch besser, was man sich inhaltlich von dem Buch erwarten darf:
    MCDA-Prinzip, Verhältnisskala, Prohibition, Reproduzierbarkeit, Researcher Degrees of Freedom, Competitive Reaction Time Task (CRTT), Buss-Perry-Aggressionsfragebogen, Korrelationen, Kausalität, Sozialistationseffekt, Selektionseffekt, Longitudinalstudien/Kohortenstudien, Prädikator, statistische Signifikanz, p-Wert, Publication Bias, p-Hacking, HARKing (Hypothesis After Results Known), Präregistrierung, Effektgröße d, Meta-Analysen, Katharsisthese, Care-Arbeit, Belmont Report, Nürnberger Kodex, Deklaration von Helsinki, Indikation, Publikationsdruck, post hoc ergo propter hoc (danach, also deswegen), cum hoc ergo propter hoc (damit, also deswegen), Placeboeffekt, Noceboeffekt (Nebenwirkungen), klassische Konditionierung, Open Label Placebos, Extinktion, Prevention Paradox, Autoimmunerkrankung, Molekulare Mimikry, Korrelationskoeffizient, Eugenik, Gaußverteilung, Retest-Reliabilität, g-Faktor (general factor), polygen, Flynn-Effekt, Phänotyp (= Genotyp + Umwelt), Effektgröße, Varianz, individualistischer Fehlschluss, Falconer Formel, Methylierung, Big-Five-Persönlichkeitstest, Reverse Bias, Phrenologie, Confirmation Bias, Physiognomik, Dimorphismus, Naturalistische Fehlschluss (Natural Fallacy), Trolley-Problem, translationale Forschung, Draize-Augenreizungstest, Organoiden, Checkpoint-Inhibitoren, 3R-Prinzip (Replace, Reduce, Refine), Cancel-Culture.
  • Der dunkle Spiegel, Barton Gellman. Gellman war Journalist bei der Washington Post und schreibt in diesem sehr gut recherchierten Buch über die Enthüllungen durch Snowden und den Überwachungsstaat. Eine lesenswerte Ergänzung zu “Permanent Record” von Snowden, einerseits weil es einige – mir bisher nicht bekannte – Korrekturen gibt (u.a. zu Greenwald), aber auch die Geschichte von Snowden aus einer weiteren, aber auch größeren Perspektive beleuchtet wird. Sehr beeindruckend, wie es Gellman auf 501 Seiten gelingt, aus einer Vielzahl an Unterlagen, Quellen und Gesprächen eine stringente Erzählung zu konstruieren und aufrecht zu erhalten. Es gibt unglaubliche 78 Seiten Anmerkungen (und leider kapitelweise durchnumeriert, daher mühsam zum Hin- und Herblättern). Sehr fein auch, dass es ein Personen- und Sachregister gibt.

efivars is gone with Debian/bullseye #newinbullseye

June 9th, 2021

Continuing with #newinbullseye, it’s worth being aware of, that efivars is gone with the kernel version shipped as of Debian/bullseye.

Quoting from wiki.debian.org/UEFI:

The Linux kernel gives access to the UEFI configuration variables via a set of files under /sys, using two different interfaces.

The older interface was showing files under /sys/firmware/efi/vars, and this is what was used by default in both Wheezy and Jessie.

The new interface is efivarfs, which will expose things in a slightly different format under /sys/firmware/efi/efivars.
This is the new preferred way of using UEFI configuration variables, and Debian switched to it by default from Stretch onwards.

Now, CONFIG_EFI_VARS is no longer enabled in Debian due to commit 20146398c4 (shipped as such with Debian kernel package versions >=5.10.1-1~exp1).

As a result, the kernel module efivars is no longer available on systems running Debian kernels >=5.10 (which includes Debian/bullseye). Now, when running such a system in EFI mode, chroot-ing into a system and executing e.g. efibootmgr, it might fail with:

# efibootmgr
EFI variables are not supported on this system.

This is caused by /sys/firmware/efi/vars no longer being available, because of the disabled CONFIG_EFI_VARS. To get this working again, you need to make efivarfs available via:

# mount -t efivarfs efivarfs /sys/firmware/efi/efivars

Then efibootmgr and further tools relying on efivars should work again.

FYI: if you’re a user of Grml’s grml-chroot tool, this is going to be handled out of the box for you.

What to expect from Debian/bullseye #newinbullseye

May 27th, 2021

Bullseye Banner, Copyright 2020 Juliette Taka

Debian v11 with codename bullseye is supposed to be released as new stable release soon-ish (let’s hope for June, 2021! :)). Similar to what we had with #newinbuster and previous releases, now it’s time for #newinbullseye!

I was the driving force at several of my customers to be well prepared for bullseye before its freeze, and since then we’re on good track there overall. In my opinion, Debian’s release team did (and still does) a great job – I’m very happy about how unblock requests (not only mine but also ones I kept an eye on) were handled so far.

As usual with major upgrades, there are some things to be aware of, and hereby I’m starting my public notes on bullseye that might be worth also for other folks. My focus is primarily on server systems and looking at things from a sysadmin perspective.

Further readings

Of course start with taking a look at the official Debian release notes, make sure to especially go through What’s new in Debian 11 + Issues to be aware of for bullseye.

Chris published notes on upgrading to Debian bullseye, and also anarcat published upgrade notes for bullseye.

Package versions

As a starting point, let’s look at some selected packages and their versions in buster vs. bullseye as of 2021-05-27 (mainly having amd64 in mind):

Package buster/v10 bullseye/v11
ansible 2.7.7 2.10.8
apache 2.4.38 2.4.46
apt 1.8.2.2 2.2.3
bash 5.0 5.1
ceph 12.2.11 14.2.20
docker 18.09.1 20.10.5
dovecot 2.3.4 2.3.13
dpkg 1.19.7 1.20.9
emacs 26.1 27.1
gcc 8.3.0 10.2.1
git 2.20.1 2.30.2
golang 1.11 1.15
libc 2.28 2.31
linux kernel 4.19 5.10
llvm 7.0 11.0
lxc 3.0.3 4.0.6
mariadb 10.3.27 10.5.10
nginx 1.14.2 1.18.0
nodejs 10.24.0 12.21.0
openjdk 11.0.9.1 11.0.11+9 + 17~19
openssh 7.9p1 8.4p1
openssl 1.1.1d 1.1.1k
perl 5.28.1 5.32.1
php 7.3 7.4+76
postfix 3.4.14 3.5.6
postgres 11 13
puppet 5.5.10 5.5.22
python2 2.7.16 2.7.18
python3 3.7.3 3.9.2
qemu/kvm 3.1 5.2
ruby 2.5.1 2.7+2
rust 1.41.1 1.48.0
samba 4.9.5 4.13.5
systemd 241 247.3
unattended-upgrades 1.11.2 2.8
util-linux 2.33.1 2.36.1
vagrant 2.2.3 2.2.14
vim 8.1.0875 8.2.2434
zsh 5.7.1 5.8

Linux Kernel

The bullseye release will ship a Linux kernel based on v5.10 (v5.10.28 as of 2021-05-27, with v5.10.38 pending in unstable/sid), whereas buster shipped kernel 4.19. As usual there are plenty of changes in the kernel area and this might warrant a separate blog entry, but to highlight some issues:

One surprising change might be that the scrollback buffer (Shift + PageUp) is gone from the Linux console. Make sure to always use screen/tmux or handle output through a pager of your choice if you need all of it and you’re in the console.

The kernel provides BTF support (via CONFIG_DEBUG_INFO_BTF, see #973870), which means it’s no longer necessary to install LLVM, Clang, etc (requiring >100MB of disk space), see Gregg’s excellent blog post regarding the underlying rational. Sadly the libbpf-tools packaging didn’t make it into bullseye (#978727), but if you want to use your own self-made Debian packages, my notes might be useful.

With kernel version 5.4, SUBDIRS support was removed from kbuild, so if an out-of-tree kernel module (like a *-dkms package) fails to compile on bullseye, make sure to use a recent version of it which uses M=… or KBUILD_EXTMOD=… instead.

Unprivileged user namespaces are enabled by default (see #898446 + #987777), so programs can create more restricted sandboxes without the need to run as root or via a setuid-root helper. If you prefer to keep this feature restricted (or tools like web browsers, WebKitGTK, Flatpak,… don’t work), use ‘sysctl -w kernel.unprivileged_userns_clone=0‘.

The /boot/System.map file(s) no longer provide the actual data, you need to switch to the dbg package if you rely on that information:

% cat /boot/System.map-5.10.0-6-amd64 
ffffffffffffffff B The real System.map is in the linux-image-<version>-dbg package

Be aware though, that the *-dbg package requires ~5GB of additional disk space.

Systemd

systemd v247 made it into bullseye (updated from v241). Same as for the kernel this might warrant a separate blog entry, but to mention some highlights:

Systemd in bullseye activates its persistent journal functionality by default (storing its files in /var/log/journal/, see #717388).

systemd-timesyncd is no longer part of the systemd binary package itself, but available as standalone package. This allows usage of ntp, chrony, openntpd,… without having systemd-timesyncd installed (which prevents race conditions like #889290, which was biting me more than once).

journalctl gained new options:

--cursor-file=FILE      Show entries after cursor in FILE and update FILE
--facility=FACILITY...  Show entries with the specified facilities
--image=IMAGE           Operate on files in filesystem image
--namespace=NAMESPACE   Show journal data from specified namespace
--relinquish-var        Stop logging to disk, log to temporary file system
--smart-relinquish-var  Similar, but NOP if log directory is on root mount

systemctl gained new options:

clean UNIT...                       Clean runtime, cache, state, logs or configuration of unit
freeze PATTERN...                   Freeze execution of unit processes
thaw PATTERN...                     Resume execution of a frozen unit
log-level [LEVEL]                   Get/set logging threshold for manager
log-target [TARGET]                 Get/set logging target for manager
service-watchdogs [BOOL]            Get/set service watchdog state

--with-dependencies                 Show unit dependencies with 'status', 'cat', 'list-units', and 'list-unit-files'
 -T --show-transaction              When enqueuing a unit job, show full transaction
 --what=RESOURCES                   Which types of resources to remove
--boot-loader-menu=TIME             Boot into boot loader menu on next boot
--boot-loader-entry=NAME            Boot into a specific boot loader entry on next boot
--timestamp=FORMAT                  Change format of printed timestamps

If you use `systemctl edit …` to adjust overrides, then you’ll now also get the existing configuration file listed as comment, which I consider very helpful.

The MACAddressPolicy behavior with systemd naming schema v241 changed for virtual devices (I plan to write about this in a separate blog post).

There are plenty of new manual pages:

systemd also gained new unit configurations related to security hardening:

Another new unit configuration is SystemCallLog=…, which supports listing the system calls to be logged. This is very useful for for auditing or temporarily when constructing system call filters.

The cgroupv2 change is also documented in the release notes, but to explicitly mention it also here, quoting from /usr/share/doc/systemd/NEWS.Debian.gz:

systemd now defaults to the “unified” cgroup hierarchy (i.e. cgroupv2).
This change reflects the fact that cgroups2 support has matured
substantially in both systemd and in the kernel.
All major container tools nowadays should support cgroupv2.
If you run into problems with cgroupv2, you can switch back to the previous,
hybrid setup by adding “systemd.unified_cgroup_hierarchy=false” to the
kernel command line.
You can read more about the benefits of cgroupv2 at
https://www.kernel.org/doc/html/latest/admin-guide/cgroup-v2.html

Note that cgroup-tools (lssubsys + lscgroup etc) don’t work in cgroup2/unified hierarchy yet (see #959022 for the details).

Configuration management

puppet‘s upstream doesn’t provide packages for bullseye yet (see PA-3624 + MODULES-11060), and sadly neither v6 nor v7 made it into bullseye, so when using the packages from Debian you’re still stuck with v5.5 (also see #950182).

ansible is also available, and while it looked like that only version 2.9.16 would make it into bullseye (see #984557 + #986213), actually version 2.10.8 made it into bullseye.

chef was removed from Debian and is not available with bullseye (due to trademark issues).

Prometheus stack

Prometheus server was updated from v2.7.1 to v2.24.1, and the prometheus service by default applies some systemd hardening now. Also all the usual exporters are still there, but bullseye also gained some new ones:

  • prometheus-elasticsearch-exporter (v1.1.0)
  • prometheus-exporter-exporter (v0.4.0-1)
  • prometheus-hacluster-exporter (v1.2.1-1)
  • prometheus-homeplug-exporter (v0.3.0-2)
  • prometheus-ipmi-exporter (v1.2.0)
  • prometheus-libvirt-exporter (v0.2.0-1)
  • prometheus-mqtt-exporter (v0.1.4-2)
  • prometheus-nginx-vts-exporter (v0.10.3)
  • prometheus-postfix-exporter (v0.2.0-3)
  • prometheus-redis-exporter (v1.16.0-1)
  • prometheus-smokeping-prober (v0.4.1-2)
  • prometheus-tplink-plug-exporter (v0.2.0)

Virtualization

docker (v20.10.5), ganeti (v3.0.1), libvirt (v7.0.0), lxc (v4.0.6), openstack, qemu/kvm (v5.2), xen (v4.14.1),… are all still around, though what’s new and noteworthy is that podman version 3.0.1 (tool for managing OCI containers and pods) made it into bullseye.

If you’re using the docker packages from upstream, be aware that they still don’t seem to understand Debian package version handling. The docker* packages will not be automatically considered for upgrade, as 5:20.10.6~3-0~debian-buster is considered newer than 5:20.10.6~3-0~debian-bullseye:

% apt-cache policy docker-ce
  docker-ce:
    Installed: 5:20.10.6~3-0~debian-buster
    Candidate: 5:20.10.6~3-0~debian-buster
    Version table:
   *** 5:20.10.6~3-0~debian-buster 100
          100 /var/lib/dpkg/status
       5:20.10.6~3-0~debian-bullseye 500
          500 https://download.docker.com/linux/debian bullseye/stable amd64 Packages

Vagrant is available in version 2.2.14, the package from upstream works perfectly fine on bullseye as well. If you’re relying on VirtualBox, be aware that upstream doesn’t provide packages for bullseye yet, but the package from Debian/unstable (v6.1.22 as of 2021-05-27) works fine on bullseye (VirtualBox isn’t shipped with stable releases since quite some time due to lack of cooperation from upstream on security support for older releases, see #794466). If you rely on the virtualbox-guest-additions-iso and its shared folders support, you might be glad to hear that v6.1.22 made it into bullseye (see #988783), properly supporting more recent kernel versions like present in bullseye.

debuginfod

There’s a new service debuginfod.debian.net (see debian-devel-announce and Debian Wiki), which makes the debugging experience way smoother. You no longer need to download the debugging Debian packages (*-dbgsym/*-dbg), but instead can fetch them on demand, by exporting the following variables (before invoking gdb or alike):

% export DEBUGINFOD_PROGRESS=1    # for optional download progress reporting
% export DEBUGINFOD_URLS="https://debuginfod.debian.net"

BTW: if you can’t rely on debuginfod (for whatever reason), I’d like to point your attention towards find-dbgsym-packages from the debian-goodies package.

Vim

Sadly Vim 8.2 once again makes another change for bad defaults (hello “mouse” behavior!). When incsearch is set, it also applies to :substitute. This makes it veeeeeeeeeery annoying when running something like ‘:%s/\s\+$//‘ to get rid of trailing whitespace characters, because if there are no matches it jumps to the beginning of the file and then back, sigh. To get the old behavior back, you can use this:

au CmdLineEnter : let s:incs = &incsearch | set noincsearch
au CmdLineLeave : let &incsearch = s:incs

rsync

rsync was updated from v3.1.3 to v3.2.3. It provides various checksum enhancements (see option --checksum-choice). We got new capabilities (hardlink-specials, atimes, optional protect-args, stop-at, no crtimes) and the addition of zstd and lz4 compression algorithms. And we got new options:

  • --atimes: preserve access (use) times
  • --copy-as=USER: specify user (and optionally group) for the copy
  • --crtimes/-N: for preserving the file’s create time
  • --max-alloc=SIZE: change a limit relating to memory allocation
  • --mkpath:create the destination’s path component
  • --open-noatime: avoid changing the atime on opened files
  • --stop-after=MINS: stop rsync after MINS minutes have elapsed
  • --write-devices: write to devices as files (implies –inplace)

OpenSSH

OpenSSH was updated from v7.9p1 to 8.4p1, so if you’re interested in all the changes, check out the release notes between those version (8.0, 8.1, 8.2, 8.3 + 8.4). Let’s highlight some notable new features:

  • It now defers creation of ~/.ssh until there’s something to write (e.g. the known_hosts file), so the good old admin trick to run ssh localhost and cancel immediately to create ~/.ssh with proper permissions no longer works
  • v8.2 brought FIDO/U2F + FIDO2 resident keys Support
  • The new include sshd_config keyword allows including additional configuration files via glob(3) patterns
  • ssh now allows %n to be expanded in ProxyCommand strings.
  • The scp and sftp command-lines now accept -J option as an alias to ProxyJump.
  • The scp and sftp command-lines allow the -A flag to explicitly enable agent forwarding.

Misc unsorted

A Ceph war story

April 9th, 2021

It all started with the big bang! We nearly lost 33 of 36 disks on a Proxmox/Ceph Cluster; this is the story of how we recovered them.

At the end of 2020, we eventually had a long outstanding maintenance window for taking care of system upgrades at a customer. During this maintenance window, which involved reboots of server systems, the involved Ceph cluster unexpectedly went into a critical state. What was planned to be a few hours of checklist work in the early evening turned out to be an emergency case; let’s call it a nightmare (not only because it included a big part of the night). Since we have learned a few things from our post mortem and RCA, it’s worth sharing those with others. But first things first, let’s step back and clarify what we had to deal with.

The system and its upgrade

One part of the upgrade included 3 Debian servers (we’re calling them server1, server2 and server3 here), running on Proxmox v5 + Debian/stretch with 12 Ceph OSDs each (65.45TB in total), a so-called Proxmox Hyper-Converged Ceph Cluster.

First, we went for upgrading the Proxmox v5/stretch system to Proxmox v6/buster, before updating Ceph Luminous v12.2.13 to the latest v14.2 release, supported by Proxmox v6/buster. The Proxmox upgrade included updating corosync from v2 to v3. As part of this upgrade, we had to apply some configuration changes, like adjust ring0 + ring1 address settings and add a mon_host configuration to the Ceph configuration.

During the first two servers’ reboots, we noticed configuration glitches. After fixing those, we went for a reboot of the third server as well. Then we noticed that several Ceph OSDs were unexpectedly down. The NTP service wasn’t working as expected after the upgrade. The underlying issue is a race condition of ntp with systemd-timesyncd (see #889290). As a result, we had clock skew problems with Ceph, indicating that the Ceph monitors’ clocks aren’t running in sync (which is essential for proper Ceph operation). We initially assumed that our Ceph OSD failure derived from this clock skew problem, so we took care of it. After yet another round of reboots, to ensure the systems are running all with identical and sane configurations and services, we noticed lots of failing OSDs. This time all but three OSDs (19, 21 and 22) were down:

% sudo ceph osd tree
ID CLASS WEIGHT   TYPE NAME      STATUS REWEIGHT PRI-AFF
-1       65.44138 root default
-2       21.81310     host server1
 0   hdd  1.08989         osd.0    down  1.00000 1.00000
 1   hdd  1.08989         osd.1    down  1.00000 1.00000
 2   hdd  1.63539         osd.2    down  1.00000 1.00000
 3   hdd  1.63539         osd.3    down  1.00000 1.00000
 4   hdd  1.63539         osd.4    down  1.00000 1.00000
 5   hdd  1.63539         osd.5    down  1.00000 1.00000
18   hdd  2.18279         osd.18   down  1.00000 1.00000
20   hdd  2.18179         osd.20   down  1.00000 1.00000
28   hdd  2.18179         osd.28   down  1.00000 1.00000
29   hdd  2.18179         osd.29   down  1.00000 1.00000
30   hdd  2.18179         osd.30   down  1.00000 1.00000
31   hdd  2.18179         osd.31   down  1.00000 1.00000
-4       21.81409     host server2
 6   hdd  1.08989         osd.6    down  1.00000 1.00000
 7   hdd  1.08989         osd.7    down  1.00000 1.00000
 8   hdd  1.63539         osd.8    down  1.00000 1.00000
 9   hdd  1.63539         osd.9    down  1.00000 1.00000
10   hdd  1.63539         osd.10   down  1.00000 1.00000
11   hdd  1.63539         osd.11   down  1.00000 1.00000
19   hdd  2.18179         osd.19     up  1.00000 1.00000
21   hdd  2.18279         osd.21     up  1.00000 1.00000
22   hdd  2.18279         osd.22     up  1.00000 1.00000
32   hdd  2.18179         osd.32   down  1.00000 1.00000
33   hdd  2.18179         osd.33   down  1.00000 1.00000
34   hdd  2.18179         osd.34   down  1.00000 1.00000
-3       21.81419     host server3
12   hdd  1.08989         osd.12   down  1.00000 1.00000
13   hdd  1.08989         osd.13   down  1.00000 1.00000
14   hdd  1.63539         osd.14   down  1.00000 1.00000
15   hdd  1.63539         osd.15   down  1.00000 1.00000
16   hdd  1.63539         osd.16   down  1.00000 1.00000
17   hdd  1.63539         osd.17   down  1.00000 1.00000
23   hdd  2.18190         osd.23   down  1.00000 1.00000
24   hdd  2.18279         osd.24   down  1.00000 1.00000
25   hdd  2.18279         osd.25   down  1.00000 1.00000
35   hdd  2.18179         osd.35   down  1.00000 1.00000
36   hdd  2.18179         osd.36   down  1.00000 1.00000
37   hdd  2.18179         osd.37   down  1.00000 1.00000

Our blood pressure increased slightly! Did we just lose all of our cluster? What happened, and how can we get all the other OSDs back?

We stumbled upon this beauty in our logs:

kernel: [   73.697957] XFS (sdl1): SB stripe unit sanity check failed
kernel: [   73.698002] XFS (sdl1): Metadata corruption detected at xfs_sb_read_verify+0x10e/0x180 [xfs], xfs_sb block 0xffffffffffffffff
kernel: [   73.698799] XFS (sdl1): Unmount and run xfs_repair
kernel: [   73.699199] XFS (sdl1): First 128 bytes of corrupted metadata buffer:
kernel: [   73.699677] 00000000: 58 46 53 42 00 00 10 00 00 00 00 00 00 00 62 00  XFSB..........b.
kernel: [   73.700205] 00000010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
kernel: [   73.700836] 00000020: 62 44 2b c0 e6 22 40 d7 84 3d e1 cc 65 88 e9 d8  bD+.."@..=..e...
kernel: [   73.701347] 00000030: 00 00 00 00 00 00 40 08 00 00 00 00 00 00 01 00  ......@.........
kernel: [   73.701770] 00000040: 00 00 00 00 00 00 01 01 00 00 00 00 00 00 01 02  ................
ceph-disk[4240]: mount: /var/lib/ceph/tmp/mnt.jw367Y: mount(2) system call failed: Structure needs cleaning.
ceph-disk[4240]: ceph-disk: Mounting filesystem failed: Command '['/bin/mount', '-t', u'xfs', '-o', 'noatime,inode64', '--', '/dev/disk/by-parttypeuuid/4fbd7e29-9d25-41b8-afd0-062c0ceff05d.cdda39ed-5
ceph/tmp/mnt.jw367Y']' returned non-zero exit status 32
kernel: [   73.702162] 00000050: 00 00 00 01 00 00 18 80 00 00 00 04 00 00 00 00  ................
kernel: [   73.702550] 00000060: 00 00 06 48 bd a5 10 00 08 00 00 02 00 00 00 00  ...H............
kernel: [   73.702975] 00000070: 00 00 00 00 00 00 00 00 0c 0c 0b 01 0d 00 00 19  ................
kernel: [   73.703373] XFS (sdl1): SB validate failed with error -117.

The same issue was present for the other failing OSDs. We hoped, that the data itself was still there, and only the mounting of the XFS partitions failed. The Ceph cluster was initially installed in 2017 with Ceph jewel/10.2 with the OSDs on filestore (nowadays being a legacy approach to storing objects in Ceph). However, we migrated the disks to bluestore since then (with ceph-disk and not yet via ceph-volume what’s being used nowadays). Using ceph-disk introduces these 100MB XFS partitions containing basic metadata for the OSD.

Given that we had three working OSDs left, we decided to investigate how to rebuild the failing ones. Some folks on #ceph (thanks T1, ormandj + peetaur!) were kind enough to share how working XFS partitions looked like for them. After creating a backup (via dd), we tried to re-create such an XFS partition on server1. We noticed that even mounting a freshly created XFS partition failed:

synpromika@server1 ~ % sudo mkfs.xfs -f -i size=2048 -m uuid="4568c300-ad83-4288-963e-badcd99bf54f" /dev/sdc1
meta-data=/dev/sdc1              isize=2048   agcount=4, agsize=6272 blks
         =                       sectsz=4096  attr=2, projid32bit=1
         =                       crc=1        finobt=1, sparse=1, rmapbt=0
         =                       reflink=0
data     =                       bsize=4096   blocks=25088, imaxpct=25
         =                       sunit=128    swidth=64 blks
naming   =version 2              bsize=4096   ascii-ci=0, ftype=1
log      =internal log           bsize=4096   blocks=1608, version=2
         =                       sectsz=4096  sunit=1 blks, lazy-count=1
realtime =none                   extsz=4096   blocks=0, rtextents=0
synpromika@server1 ~ % sudo mount /dev/sdc1 /mnt/ceph-recovery
SB stripe unit sanity check failed
Metadata corruption detected at 0x433840, xfs_sb block 0x0/0x1000
libxfs_writebufr: write verifer failed on xfs_sb bno 0x0/0x1000
cache_node_purge: refcount was 1, not zero (node=0x1d3c400)
SB stripe unit sanity check failed
Metadata corruption detected at 0x433840, xfs_sb block 0x18800/0x1000
libxfs_writebufr: write verifer failed on xfs_sb bno 0x18800/0x1000
SB stripe unit sanity check failed
Metadata corruption detected at 0x433840, xfs_sb block 0x0/0x1000
libxfs_writebufr: write verifer failed on xfs_sb bno 0x0/0x1000
SB stripe unit sanity check failed
Metadata corruption detected at 0x433840, xfs_sb block 0x24c00/0x1000
libxfs_writebufr: write verifer failed on xfs_sb bno 0x24c00/0x1000
SB stripe unit sanity check failed
Metadata corruption detected at 0x433840, xfs_sb block 0xc400/0x1000
libxfs_writebufr: write verifer failed on xfs_sb bno 0xc400/0x1000
releasing dirty buffer (bulk) to free list!releasing dirty buffer (bulk) to free list!releasing dirty buffer (bulk) to free list!releasing dirty buffer (bulk) to free list!found dirty buffer (bulk) on free list!bad magic number
bad magic number
Metadata corruption detected at 0x433840, xfs_sb block 0x0/0x1000
libxfs_writebufr: write verifer failed on xfs_sb bno 0x0/0x1000
releasing dirty buffer (bulk) to free list!mount: /mnt/ceph-recovery: wrong fs type, bad option, bad superblock on /dev/sdc1, missing codepage or helper program, or other error.

Ouch. This very much looked related to the actual issue we’re seeing. So we tried to execute mkfs.xfs with a bunch of different sunit/swidth settings. Using ‘-d sunit=512 -d swidth=512‘ at least worked then, so we decided to force its usage in the creation of our OSD XFS partition. This brought us a working XFS partition. Please note, sunit must not be larger than swidth (more on that later!).

Then we reconstructed how to restore all the metadata for the OSD (activate.monmap, active, block_uuid, bluefs, ceph_fsid, fsid, keyring, kv_backend, magic, mkfs_done, ready, require_osd_release, systemd, type, whoami). To identify the UUID, we can read the data from ‘ceph --format json osd dump‘, like this for all our OSDs (Zsh syntax ftw!):

synpromika@server1 ~ % for f in {0..37} ; printf "osd-$f: %s\n" "$(sudo ceph --format json osd dump | jq -r ".osds[] | select(.osd==$f) | .uuid")"
osd-0: 4568c300-ad83-4288-963e-badcd99bf54f
osd-1: e573a17a-ccde-4719-bdf8-eef66903ca4f
osd-2: 0e1b2626-f248-4e7d-9950-f1a46644754e
osd-3: 1ac6a0a2-20ee-4ed8-9f76-d24e900c800c
[...]

Identifying the corresponding raw device for each OSD UUID is possible via:

synpromika@server1 ~ % UUID="4568c300-ad83-4288-963e-badcd99bf54f"
synpromika@server1 ~ % readlink -f /dev/disk/by-partuuid/"${UUID}"
/dev/sdc1

The OSD’s key ID can be retrieved via:

synpromika@server1 ~ % OSD_ID=0
synpromika@server1 ~ % sudo ceph auth get osd."${OSD_ID}" -f json 2>/dev/null | jq -r '.[] | .key'
AQCKFpZdm0We[...]

Now we also need to identify the underlying block device:

synpromika@server1 ~ % OSD_ID=0
synpromika@server1 ~ % sudo ceph osd metadata osd."${OSD_ID}" -f json | jq -r '.bluestore_bdev_partition_path'    
/dev/sdc2

With all of this, we reconstructed the keyring, fsid, whoami, block + block_uuid files. All the other files inside the XFS metadata partition are identical on each OSD. So after placing and adjusting the corresponding metadata on the XFS partition for Ceph usage, we got a working OSD – hurray! Since we had to fix yet another 32 OSDs, we decided to automate this XFS partitioning and metadata recovery procedure.

We had a network share available on /srv/backup for storing backups of existing partition data. On each server, we tested the procedure with one single OSD before iterating over the list of remaining failing OSDs. We started with a shell script on server1, then adjusted the script for server2 and server3. This is the script, as we executed it on the 3rd server.

Thanks to this, we managed to get the Ceph cluster up and running again. We didn’t want to continue with the Ceph upgrade itself during the night though, as we wanted to know exactly what was going on and why the system behaved like that. Time for RCA!

Root Cause Analysis

So all but three OSDs on server2 failed, and the problem seems to be related to XFS. Therefore, our starting point for the RCA was, to identify what was different on server2, as compared to server1 + server3. My initial assumption was that this was related to some firmware issues with the involved controller (and as it turned out later, I was right!). The disks were attached as JBOD devices to a ServeRAID M5210 controller (with a stripe size of 512). Firmware state:

synpromika@server1 ~ % sudo storcli64 /c0 show all | grep '^Firmware'
Firmware Package Build = 24.16.0-0092
Firmware Version = 4.660.00-8156

synpromika@server2 ~ % sudo storcli64 /c0 show all | grep '^Firmware'
Firmware Package Build = 24.21.0-0112
Firmware Version = 4.680.00-8489

synpromika@server3 ~ % sudo storcli64 /c0 show all | grep '^Firmware'
Firmware Package Build = 24.16.0-0092
Firmware Version = 4.660.00-8156

This looked very promising, as server2 indeed runs with a different firmware version on the controller. But how so? Well, the motherboard of server2 got replaced by a Lenovo/IBM technician in January 2020, as we had a failing memory slot during a memory upgrade. As part of this procedure, the Lenovo/IBM technician installed the latest firmware versions. According to our documentation, some OSDs were rebuilt (due to the filestore->bluestore migration) in March and April 2020. It turned out that precisely those OSDs were the ones that survived the upgrade. So the surviving drives were created with a different firmware version running on the involved controller. All the other OSDs were created with an older controller firmware. But what difference does this make?

Now let’s check firmware changelogs. For the 24.21.0-0097 release we found this:

- Cannot create or mount xfs filesystem using xfsprogs 4.19.x kernel 4.20(SCGCQ02027889)
- xfs_info command run on an XFS file system created on a VD of strip size 1M shows sunit and swidth as 0(SCGCQ02056038)

Our XFS problem certainly was related to the controller’s firmware. We also recalled that our monitoring system reported different sunit settings for the OSDs that were rebuilt in March and April. For example, OSD 21 was recreated and got different sunit settings:

WARN  server2.example.org  Mount options of /var/lib/ceph/osd/ceph-21      WARN - Missing: sunit=1024, Exceeding: sunit=512

We compared the new OSD 21 with an existing one (OSD 25 on server3):

synpromika@server2 ~ % systemctl show var-lib-ceph-osd-ceph\\x2d21.mount | grep sunit
Options=rw,noatime,attr2,inode64,sunit=512,swidth=512,noquota
synpromika@server3 ~ % systemctl show var-lib-ceph-osd-ceph\\x2d25.mount | grep sunit
Options=rw,noatime,attr2,inode64,sunit=1024,swidth=512,noquota

Thanks to our documentation, we could compare execution logs of their creation:

% diff -u ceph-disk-osd-25.log ceph-disk-osd-21.log
-synpromika@server2 ~ % sudo ceph-disk -v prepare --bluestore /dev/sdj --osd-id 25
+synpromika@server3 ~ % sudo ceph-disk -v prepare --bluestore /dev/sdi --osd-id 21
[...]
-command_check_call: Running command: /sbin/mkfs -t xfs -f -i size=2048 -- /dev/sdj1
-meta-data=/dev/sdj1              isize=2048   agcount=4, agsize=6272 blks
[...]
+command_check_call: Running command: /sbin/mkfs -t xfs -f -i size=2048 -- /dev/sdi1
+meta-data=/dev/sdi1              isize=2048   agcount=4, agsize=6336 blks
          =                       sectsz=4096  attr=2, projid32bit=1
          =                       crc=1        finobt=1, sparse=0, rmapbt=0, reflink=0
-data     =                       bsize=4096   blocks=25088, imaxpct=25
-         =                       sunit=128    swidth=64 blks
+data     =                       bsize=4096   blocks=25344, imaxpct=25
+         =                       sunit=64     swidth=64 blks
 naming   =version 2              bsize=4096   ascii-ci=0 ftype=1
 log      =internal log           bsize=4096   blocks=1608, version=2
          =                       sectsz=4096  sunit=1 blks, lazy-count=1
 realtime =none                   extsz=4096   blocks=0, rtextents=0
[...]

So back then, we even tried to track this down but couldn’t make sense of it yet. But now this sounds very much like it is related to the problem we saw with this Ceph/XFS failure. We follow Occam’s razor, assuming the simplest explanation is usually the right one, so let’s check the disk properties and see what differs:

synpromika@server1 ~ % sudo blockdev --getsz --getsize64 --getss --getpbsz --getiomin --getioopt /dev/sdk
4685545472
2398999281664
512
4096
524288
262144

synpromika@server2 ~ % sudo blockdev --getsz --getsize64 --getss --getpbsz --getiomin --getioopt /dev/sdk
4685545472
2398999281664
512
4096
262144
262144

See the difference between server1 and server2 for identical disks? The getiomin option now reports something different for them:

synpromika@server1 ~ % sudo blockdev --getiomin /dev/sdk            
524288
synpromika@server1 ~ % cat /sys/block/sdk/queue/minimum_io_size
524288

synpromika@server2 ~ % sudo blockdev --getiomin /dev/sdk 
262144
synpromika@server2 ~ % cat /sys/block/sdk/queue/minimum_io_size
262144

It doesn’t make sense that the minimum I/O size (iomin, AKA BLKIOMIN) is bigger than the optimal I/O size (ioopt, AKA BLKIOOPT). This leads us to Bug 202127 – cannot mount or create xfs on a 597T device, which matches our findings here. But why did this XFS partition work in the past and fails now with the newer kernel version?

The XFS behaviour change

Now given that we have backups of all the XFS partition, we wanted to track down, a) when this XFS behaviour was introduced, and b) whether, and if so how it would be possible to reuse the XFS partition without having to rebuild it from scratch (e.g. if you would have no working Ceph OSD or backups left).

Let’s look at such a failing XFS partition with the Grml live system:

root@grml ~ # grml-version
grml64-full 2020.06 Release Codename Ausgehfuahangl [2020-06-24]
root@grml ~ # uname -a
Linux grml 5.6.0-2-amd64 #1 SMP Debian 5.6.14-2 (2020-06-09) x86_64 GNU/Linux
root@grml ~ # grml-hostname grml-2020-06
Setting hostname to grml-2020-06: done
root@grml ~ # exec zsh
root@grml-2020-06 ~ # dpkg -l xfsprogs util-linux
Desired=Unknown/Install/Remove/Purge/Hold
| Status=Not/Inst/Conf-files/Unpacked/halF-conf/Half-inst/trig-aWait/Trig-pend
|/ Err?=(none)/Reinst-required (Status,Err: uppercase=bad)
||/ Name           Version      Architecture Description
+++-==============-============-============-=========================================
ii  util-linux     2.35.2-4     amd64        miscellaneous system utilities
ii  xfsprogs       5.6.0-1+b2   amd64        Utilities for managing the XFS filesystem

There it’s failing, no matter which mount option we try:

root@grml-2020-06 ~ # mount ./sdd1.dd /mnt
mount: /mnt: mount(2) system call failed: Structure needs cleaning.
root@grml-2020-06 ~ # dmesg | tail -30
[...]
[   64.788640] XFS (loop1): SB stripe unit sanity check failed
[   64.788671] XFS (loop1): Metadata corruption detected at xfs_sb_read_verify+0x102/0x170 [xfs], xfs_sb block 0xffffffffffffffff
[   64.788671] XFS (loop1): Unmount and run xfs_repair
[   64.788672] XFS (loop1): First 128 bytes of corrupted metadata buffer:
[   64.788673] 00000000: 58 46 53 42 00 00 10 00 00 00 00 00 00 00 62 00  XFSB..........b.
[   64.788674] 00000010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
[   64.788675] 00000020: 32 b6 dc 35 53 b7 44 96 9d 63 30 ab b3 2b 68 36  2..5S.D..c0..+h6
[   64.788675] 00000030: 00 00 00 00 00 00 40 08 00 00 00 00 00 00 01 00  ......@.........
[   64.788675] 00000040: 00 00 00 00 00 00 01 01 00 00 00 00 00 00 01 02  ................
[   64.788676] 00000050: 00 00 00 01 00 00 18 80 00 00 00 04 00 00 00 00  ................
[   64.788677] 00000060: 00 00 06 48 bd a5 10 00 08 00 00 02 00 00 00 00  ...H............
[   64.788677] 00000070: 00 00 00 00 00 00 00 00 0c 0c 0b 01 0d 00 00 19  ................
[   64.788679] XFS (loop1): SB validate failed with error -117.
root@grml-2020-06 ~ # mount -t xfs -o rw,relatime,attr2,inode64,sunit=1024,swidth=512,noquota ./sdd1.dd /mnt/
mount: /mnt: wrong fs type, bad option, bad superblock on /dev/loop1, missing codepage or helper program, or other error.
32 root@grml-2020-06 ~ # dmesg | tail -1
[   66.342976] XFS (loop1): stripe width (512) must be a multiple of the stripe unit (1024)
root@grml-2020-06 ~ # mount -t xfs -o rw,relatime,attr2,inode64,sunit=512,swidth=512,noquota ./sdd1.dd /mnt/
mount: /mnt: mount(2) system call failed: Structure needs cleaning.
32 root@grml-2020-06 ~ # dmesg | tail -14
[   66.342976] XFS (loop1): stripe width (512) must be a multiple of the stripe unit (1024)
[   80.751277] XFS (loop1): SB stripe unit sanity check failed
[   80.751323] XFS (loop1): Metadata corruption detected at xfs_sb_read_verify+0x102/0x170 [xfs], xfs_sb block 0xffffffffffffffff 
[   80.751324] XFS (loop1): Unmount and run xfs_repair
[   80.751325] XFS (loop1): First 128 bytes of corrupted metadata buffer:
[   80.751327] 00000000: 58 46 53 42 00 00 10 00 00 00 00 00 00 00 62 00  XFSB..........b.
[   80.751328] 00000010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
[   80.751330] 00000020: 32 b6 dc 35 53 b7 44 96 9d 63 30 ab b3 2b 68 36  2..5S.D..c0..+h6
[   80.751331] 00000030: 00 00 00 00 00 00 40 08 00 00 00 00 00 00 01 00  ......@.........
[   80.751331] 00000040: 00 00 00 00 00 00 01 01 00 00 00 00 00 00 01 02  ................
[   80.751332] 00000050: 00 00 00 01 00 00 18 80 00 00 00 04 00 00 00 00  ................
[   80.751333] 00000060: 00 00 06 48 bd a5 10 00 08 00 00 02 00 00 00 00  ...H............
[   80.751334] 00000070: 00 00 00 00 00 00 00 00 0c 0c 0b 01 0d 00 00 19  ................
[   80.751338] XFS (loop1): SB validate failed with error -117.

Also xfs_repair doesn’t help either:

root@grml-2020-06 ~ # xfs_info ./sdd1.dd
meta-data=./sdd1.dd              isize=2048   agcount=4, agsize=6272 blks
         =                       sectsz=4096  attr=2, projid32bit=1
         =                       crc=1        finobt=1, sparse=0, rmapbt=0
         =                       reflink=0
data     =                       bsize=4096   blocks=25088, imaxpct=25
         =                       sunit=128    swidth=64 blks
naming   =version 2              bsize=4096   ascii-ci=0, ftype=1
log      =internal log           bsize=4096   blocks=1608, version=2
         =                       sectsz=4096  sunit=1 blks, lazy-count=1
realtime =none                   extsz=4096   blocks=0, rtextents=0

root@grml-2020-06 ~ # xfs_repair ./sdd1.dd
Phase 1 - find and verify superblock...
bad primary superblock - bad stripe width in superblock !!!

attempting to find secondary superblock...
..............................................................................................Sorry, could not find valid secondary superblock
Exiting now.

With the “SB stripe unit sanity check failed” message, we could easily track this down to the following commit fa4ca9c:

% git show fa4ca9c5574605d1e48b7e617705230a0640b6da | cat
commit fa4ca9c5574605d1e48b7e617705230a0640b6da
Author: Dave Chinner <dchinner@redhat.com>
Date:   Tue Jun 5 10:06:16 2018 -0700
    
    xfs: catch bad stripe alignment configurations
    
    When stripe alignments are invalid, data alignment algorithms in the
    allocator may not work correctly. Ensure we catch superblocks with
    invalid stripe alignment setups at mount time. These data alignment
    mismatches are now detected at mount time like this:
    
    XFS (loop0): SB stripe unit sanity check failed
    XFS (loop0): Metadata corruption detected at xfs_sb_read_verify+0xab/0x110, xfs_sb block 0xffffffffffffffff
    XFS (loop0): Unmount and run xfs_repair
    XFS (loop0): First 128 bytes of corrupted metadata buffer:
    0000000091c2de02: 58 46 53 42 00 00 10 00 00 00 00 00 00 00 10 00  XFSB............
    0000000023bff869: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
    00000000cdd8c893: 17 32 37 15 ff ca 46 3d 9a 17 d3 33 04 b5 f1 a2  .27...F=...3....
    000000009fd2844f: 00 00 00 00 00 00 00 04 00 00 00 00 00 00 06 d0  ................
    0000000088e9b0bb: 00 00 00 00 00 00 06 d1 00 00 00 00 00 00 06 d2  ................
    00000000ff233a20: 00 00 00 01 00 00 10 00 00 00 00 01 00 00 00 00  ................
    000000009db0ac8b: 00 00 03 60 e1 34 02 00 08 00 00 02 00 00 00 00  ...`.4..........
    00000000f7022460: 00 00 00 00 00 00 00 00 0c 09 0b 01 0c 00 00 19  ................
    XFS (loop0): SB validate failed with error -117.
    
    And the mount fails.
    
    Signed-off-by: Dave Chinner <dchinner@redhat.com>
    Reviewed-by: Carlos Maiolino <cmaiolino@redhat.com>
    Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
    Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>

diff --git fs/xfs/libxfs/xfs_sb.c fs/xfs/libxfs/xfs_sb.c
index b5dca3c8c84d..c06b6fc92966 100644
--- fs/xfs/libxfs/xfs_sb.c
+++ fs/xfs/libxfs/xfs_sb.c
@@ -278,6 +278,22 @@ xfs_mount_validate_sb(
                return -EFSCORRUPTED;
        }
        
+       if (sbp->sb_unit) {
+               if (!xfs_sb_version_hasdalign(sbp) ||
+                   sbp->sb_unit > sbp->sb_width ||
+                   (sbp->sb_width % sbp->sb_unit) != 0) {
+                       xfs_notice(mp, "SB stripe unit sanity check failed");
+                       return -EFSCORRUPTED;
+               } 
+       } else if (xfs_sb_version_hasdalign(sbp)) { 
+               xfs_notice(mp, "SB stripe alignment sanity check failed");
+               return -EFSCORRUPTED;
+       } else if (sbp->sb_width) {
+               xfs_notice(mp, "SB stripe width sanity check failed");
+               return -EFSCORRUPTED;
+       }
+
+       
        if (xfs_sb_version_hascrc(&mp->m_sb) &&
            sbp->sb_blocksize < XFS_MIN_CRC_BLOCKSIZE) {
                xfs_notice(mp, "v5 SB sanity check failed");

This change is included in kernel versions 4.18-rc1 and newer:

% git describe --contains fa4ca9c5574605d1e48
v4.18-rc1~37^2~14

Now let’s try with an older kernel version (4.9.0), using old Grml 2017.05 release:

root@grml ~ # grml-version
grml64-small 2017.05 Release Codename Freedatensuppe [2017-05-31]
root@grml ~ # uname -a
Linux grml 4.9.0-1-grml-amd64 #1 SMP Debian 4.9.29-1+grml.1 (2017-05-24) x86_64 GNU/Linux
root@grml ~ # lsb_release -a
No LSB modules are available.
Distributor ID: Debian
Description:    Debian GNU/Linux 9.0 (stretch)
Release:        9.0
Codename:       stretch
root@grml ~ # grml-hostname grml-2017-05
Setting hostname to grml-2017-05: done
root@grml ~ # exec zsh
root@grml-2017-05 ~ #

root@grml-2017-05 ~ # xfs_info ./sdd1.dd
xfs_info: ./sdd1.dd is not a mounted XFS filesystem
1 root@grml-2017-05 ~ # xfs_repair ./sdd1.dd
Phase 1 - find and verify superblock...
bad primary superblock - bad stripe width in superblock !!!

attempting to find secondary superblock...
..............................................................................................Sorry, could not find valid secondary superblock
Exiting now.
1 root@grml-2017-05 ~ # mount ./sdd1.dd /mnt
root@grml-2017-05 ~ # mount -t xfs
/root/sdd1.dd on /mnt type xfs (rw,relatime,attr2,inode64,sunit=1024,swidth=512,noquota)
root@grml-2017-05 ~ # ls /mnt
activate.monmap  active  block  block_uuid  bluefs  ceph_fsid  fsid  keyring  kv_backend  magic  mkfs_done  ready  require_osd_release  systemd  type  whoami
root@grml-2017-05 ~ # xfs_info /mnt
meta-data=/dev/loop1             isize=2048   agcount=4, agsize=6272 blks
         =                       sectsz=4096  attr=2, projid32bit=1
         =                       crc=1        finobt=1 spinodes=0 rmapbt=0
         =                       reflink=0
data     =                       bsize=4096   blocks=25088, imaxpct=25
         =                       sunit=128    swidth=64 blks
naming   =version 2              bsize=4096   ascii-ci=0 ftype=1
log      =internal               bsize=4096   blocks=1608, version=2
         =                       sectsz=4096  sunit=1 blks, lazy-count=1
realtime =none                   extsz=4096   blocks=0, rtextents=0

Mounting there indeed works! Now, if we mount the filesystem with new and proper sunit/swidth settings using the older kernel, it should rewrite them on disk:

root@grml-2017-05 ~ # mount -t xfs -o sunit=512,swidth=512 ./sdd1.dd /mnt/
root@grml-2017-05 ~ # umount /mnt/

And indeed, mounting this rewritten filesystem then also works with newer kernels:

root@grml-2020-06 ~ # mount ./sdd1.rewritten /mnt/
root@grml-2020-06 ~ # xfs_info /root/sdd1.rewritten
meta-data=/dev/loop1             isize=2048   agcount=4, agsize=6272 blks
         =                       sectsz=4096  attr=2, projid32bit=1
         =                       crc=1        finobt=1, sparse=0, rmapbt=0
         =                       reflink=0
data     =                       bsize=4096   blocks=25088, imaxpct=25
         =                       sunit=64    swidth=64 blks
naming   =version 2              bsize=4096   ascii-ci=0, ftype=1
log      =internal log           bsize=4096   blocks=1608, version=2
         =                       sectsz=4096  sunit=1 blks, lazy-count=1
realtime =none                   extsz=4096   blocks=0, rtextents=0
root@grml-2020-06 ~ # mount -t xfs                
/root/sdd1.rewritten on /mnt type xfs (rw,relatime,attr2,inode64,logbufs=8,logbsize=32k,sunit=512,swidth=512,noquota)

FTR: The ‘sunit=512,swidth=512‘ from the xfs mount option is identical to xfs_info’s output ‘sunit=64,swidth=64‘ (because mount.xfs’s sunit value is given in 512-byte block units, see man 5 xfs, and the xfs_info output reported here is in blocks with a block size (bsize) of 4096, so ‘sunit = 512*512 := 64*4096‘).

mkfs uses minimum and optimal sizes for stripe unit and stripe width; you can check this e.g. via (note that server2 with fixed firmware version reports proper values, whereas server3 with broken controller firmware reports non-sense):

synpromika@server2 ~ % for i in /sys/block/sd*/queue/ ; do printf "%s: %s %s\n" "$i" "$(cat "$i"/minimum_io_size)" "$(cat "$i"/optimal_io_size)" ; done
[...]
/sys/block/sdc/queue/: 262144 262144
/sys/block/sdd/queue/: 262144 262144
/sys/block/sde/queue/: 262144 262144
/sys/block/sdf/queue/: 262144 262144
/sys/block/sdg/queue/: 262144 262144
/sys/block/sdh/queue/: 262144 262144
/sys/block/sdi/queue/: 262144 262144
/sys/block/sdj/queue/: 262144 262144
/sys/block/sdk/queue/: 262144 262144
/sys/block/sdl/queue/: 262144 262144
/sys/block/sdm/queue/: 262144 262144
/sys/block/sdn/queue/: 262144 262144
[...]

synpromika@server3 ~ % for i in /sys/block/sd*/queue/ ; do printf "%s: %s %s\n" "$i" "$(cat "$i"/minimum_io_size)" "$(cat "$i"/optimal_io_size)" ; done
[...]
/sys/block/sdc/queue/: 524288 262144
/sys/block/sdd/queue/: 524288 262144
/sys/block/sde/queue/: 524288 262144
/sys/block/sdf/queue/: 524288 262144
/sys/block/sdg/queue/: 524288 262144
/sys/block/sdh/queue/: 524288 262144
/sys/block/sdi/queue/: 524288 262144
/sys/block/sdj/queue/: 524288 262144
/sys/block/sdk/queue/: 524288 262144
/sys/block/sdl/queue/: 524288 262144
/sys/block/sdm/queue/: 524288 262144
/sys/block/sdn/queue/: 524288 262144
[...]

This is the underlying reason why the initially created XFS partitions were created with incorrect sunit/swidth settings. The broken firmware of server1 and server3 was the cause of the incorrect settings – they were ignored by old(er) xfs/kernel versions, but treated as an error by new ones.

Make sure to also read the XFS FAQ regarding “How to calculate the correct sunit,swidth values for optimal performance”. We also stumbled upon two interesting reads in RedHat’s knowledge base: 5075561 + 2150101 (requires an active subscription, though) and #1835947.

Am I affected? How to work around it?

To check whether your XFS mount points are affected by this issue, the following command line should be useful:

awk '$3 == "xfs"{print $2}' /proc/self/mounts | while read mount ; do echo -n "$mount " ; xfs_info $mount | awk '$0 ~ "swidth"{gsub(/.*=/,"",$2); gsub(/.*=/,"",$3); print $2,$3}' | awk '{ if ($1 > $2) print "impacted"; else print "OK"}' ; done

If you run into the above situation, the only known solution to get your original XFS partition working again, is to boot into an older kernel version again (4.17 or older), mount the XFS partition with correct sunit/swidth settings and then boot back into your new system (kernel version wise).

Lessons learned

  • document everything and ensure to have all relevant information available (including actual times of changes, used kernel/package/firmware/… versions. The thorough documentation was our most significant asset in this case, because we had all the data and information we needed during the emergency handling as well as for the post mortem/RCA)
  • if something changes unexpectedly, dig deeper
  • know who to ask, a network of experts pays off
  • including timestamps in your shell makes reconstruction easier (the more people and documentation involved, the harder it gets to wade through it)
  • keep an eye on changelogs/release notes
  • apply regular updates and don’t forget invisible layers (e.g. BIOS, controller/disk firmware, IPMI/OOB (ILO/RAC/IMM/…) firmware)
  • apply regular reboots, to avoid a possible delta becoming bigger (which makes debugging harder)

Thanks: Darshaka Pathirana, Chris Hofstaedtler and Michael Hanscho.

Looking for help with your IT infrastructure? Let us know!