The upgrade was performed three times, on amber, opal and ash (current web server). This article conflates the issues encounted.
Python
Needed to setup /usr/bin/python
as a link for the newly installed
Python 3.13.
sudo update-alternatives --install /usr/bin/python python /usr/bin/python3.13 5
Dovecot
The Dovecot configuration files have changed quite a bit for 2.4 This is a summary of the changes I had to make, starting from the default Debian dovecot package configuration files.
10-auth.conf
disable_plaintext_auth
has been replaced by auth_allow_cleartext
which defaults to "no". To be explicit, I have uncommented this
directive.
Don’t forget to uncomment the line which reads in auth-passwdfile.conf.ext
.
10-mail.conf
Debian default for the mail_driver is mbox; changed to maildir:
mail_driver = maildir
The specification of the Maildir location in 2.3 was this:
mail_location = maildir:~/Maildir:INDEX=~/Maildir/index:CONTROL=~/Maildir/control
In 2.4, it is replaced by:
mail_path = ~/Maildir
mail_control_path = ~/Maildir/control
mail_index_path = ~/Maildir/index
10-ssl.conf
To specify the location of the certificate files, the 2.3 syntax is:
ssl_cert = </etc/letsencrypt/live/hydrus.org.uk/fullchain.pem
ssl_key = </etc/letsencrypt/live/hydrus.org.uk/privkey.pem
In 2.4, these lines are replaced by:
ssl_server_cert_file = /etc/letsencrypt/live/hydrus.org.uk/fullchain.pem
ssl_server_key_file = /etc/letsencrypt/live/hydrus.org.uk/privkey.pem
auth-passwdfile.conf.ext
This now looks like:
passdb passwd-file {
default_password_scheme = crypt
auth_username_format = %{user}
passwd_file_path = /etc/mail-auth
}
userdb passwd-file {
auth_username_format=%{user}
passwd_file_path = /etc/mail-auth
Grub
During the install on opal, Grub refused to install itself on /dev/sda, due to detection of a ufs2 filesystem:
usr/sbin/grub-setup: error: /dev/sda appears to contain a ufs2
filesystem which isn't known to reserve space for DOS-style
boot. Installing GRUB there could result in FILESYSTEM DESTRUCTION
if valuable data is overwritten by grub-setup (--skip-fs-probe
disables this check, use at your own risk).
So, specifying --skip-fs-probe
did not work, just generated an even
more bizarre error message:
grub-install: warning: Embedding is not possible. GRUB can only be
installed in this setup by using blocklists. However, blocklists are
UNRELIABLE and their use is discouraged..
grub-install: error: will not proceed with blocklists.
However, since the first partition started at sector 2048, I could fix the problem by clobbering the preceeding sectors:
[mark@opal]$ sudo dd if=/dev/zero of=/dev/sda bs=512 seek=1 count=2047
2047+0 records in
2047+0 records out
1048064 bytes (1.0 MB, 1.0 MiB) copied, 0.0666945 s, 15.7 MB/s
[mark@opal:~]$ sudo grub-install /dev/sda
Installing for i386-pc platform.
Installation finished. No error reported.
The solution was found in this post, from someone with a similar issue:
Logwatch
The logwatch report in trixie considered legal IMAP logins as unmatched entries. It also was way more chatty regarding aborted logins.
To fix, needed to patch /usr/share/logwatch/scripts/services/dovecot
:
--- dovecot.orig 2025-08-13 11:12:31.942391344 +0100
+++ dovecot 2025-08-16 07:34:52.203302308 +0100
@@ -164,8 +164,8 @@
$ConnectionPOP3{$Host}++;
$Connection{$Host}++;
}
- } elsif ( (($User, $Host) = ( $ThisLine =~ /^(?:$dovecottag )?imap-login: Login: (.*?) \[(.*)\]/ ) ) or
- (($User, $Host) = ( $ThisLine =~ /^(?:$dovecottag )?imap-login: Login: user=\<(.*?)\>.*rip=(.*), lip=.*/ ) ) or
+ } elsif ( (($User, $Host) = ( $ThisLine =~ /^(?:$dovecottag )?imap-login: Logged in: (.*?) \[(.*)\]/ ) ) or
+ (($User, $Host) = ( $ThisLine =~ /^(?:$dovecottag )?imap-login: Logged in: user=\<(.*?)\>.*rip=(.*), lip=.*/ ) ) or
(($User, $Host, $Session) = ( $ThisLine =~ /^(?:$dovecottag )?imap-login: (?:Info: )?Login: user=\<(.*?)\>.*rip=(.*), lip=.*, session=<([^>]+)>/ ) ) ) {
if ($Host !~ /$IgnoreHost/) {
$Host = hostName($Host);
@@ -290,13 +290,13 @@
$ConnectionClosed{"Server shutting down"}++;
} elsif ( ($Reason, $Host) = ($ThisLine =~ /TLS initialization failed/) ) {
$TLSInitFail++;
- } elsif ( ($Host) = ($ThisLine =~ /Aborted login:.* rip=(.*),/) ) {
+ } elsif ( ($Host) = ($ThisLine =~ /Login aborted:.* rip=(.*),/) ) {
$Host = hostName($Host);
$Aborted{$Host}++;
- } elsif ( ($Host) = ($ThisLine =~ /Aborted login \[(.*)\]/) ) {
+ } elsif ( ($Host) = ($ThisLine =~ /Login aborted \[(.*)\]/) ) {
$Host = hostName($Host);
$Aborted{$Host}++;
- } elsif ( ($Reason) = ($ThisLine =~ /Aborted login \((.*)\):/)) {
+ } elsif ( ($Reason) = ($ThisLine =~ /Login aborted \((.*)\):/)) {
$Aborted{$Reason}++;
} elsif ( ($User,$IP) = ($ThisLine =~ /auth: (?:LOGIN|login)\((.*),(\d+\.\d+\.\d+\.\d+)\): Request timed out waiting for client to continue authentication/) ) {
$AuthTimedOut{$User}{$IP}++;
@@ -331,7 +331,7 @@
$ConnectionClosed{$Reason}++;
} elsif ($ThisLine =~ /(IMAP|POP3).+: (Connection closed.*)/) {
$Disconnected{$2}++;
- } elsif ( ($Host) = ($ThisLine =~ /(?:imap\-login|pop3\-login): Aborted login: .*rip=(?:::ffff:)?(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})/) ) {
+ } elsif ( ($Host) = ($ThisLine =~ /(?:imap\-login|pop3\-login): Login aborted: .*rip=(?:::ffff:)?(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})/) ) {
$Aborted{$Host}++;
} elsif ( ($Error) = ($ThisLine =~ /child \d* (?:\(login\) )?returned error (.*)/)) {
# dovecot: child 23747 (login) returned error 89
Looks like Dovecot 2.4 has some modified logging messages.