Over the last few months, I upgraded my Debian machines from bullseye to bookworm. The process was uneventful (besides the asterisk issue described below), but I ended up reconfiguring several things afterwards in order to modernize my upgraded machines.
Logcheck
I noticed in this release that the transition to
journald is essentially
complete. This means that rsyslog
is no longer needed on most of my systems:
apt purge rsyslog
Once that was done, I was able to comment out the following lines in
/etc/logcheck/logcheck.logfiles.d/syslog.logfiles
:
#/var/log/syslog
#/var/log/auth.log
I did have to adjust some of my custom logcheck rules, particularly the ones that deal with kernel messages:
--- a/logcheck/ignore.d.server/local-kernel
+++ b/logcheck/ignore.d.server/local-kernel
@@ -1,1 +1,1 @@
-^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ kernel: \[[0-9. ]+]\ IN=eno1 OUT= MAC=[0-9a-f:]+ SRC=[0-9a-f.:]+
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ kernel: (\[[0-9. ]+]\ )?IN=eno1 OUT= MAC=[0-9a-f:]+ SRC=[0-9a-f.:]+
Then I moved local entries from /etc/logcheck/logcheck.logfiles
to /etc/logcheck/logcheck.logfiles.d/local.logfiles
(/var/log/syslog
and /var/log/auth.log
are enabled by default when
needed) and removed some files that are no longer used:
rm /var/log/mail.err*
rm /var/log/mail.warn*
rm /var/log/mail.info*
Finally, I had to fix any unescaped |
characters in my local rules. For example
error == NULL || \*error == NULL
must now be written as error == NULL \|\| \*error == NULL
.
Networking
After the upgrade, I got a notice that the isc-dhcp-client
is now
deprecated and so I removed if from my system:
apt purge isc-dhcp-client
This however meant that I need to ensure that my network configuration software does not depend on the now-deprecated DHCP client.
On my laptop, I was already using NetworkManager for my main network interfaces and that has built-in DHCP support.
Migration to systemd-networkd
On my backup server, I took this opportunity to switch from ifupdown
to
systemd-networkd
by
removing ifupdown
:
apt purge ifupdown
rm /etc/network/interfaces
putting the following in /etc/systemd/network/20-wired.network
:
[Match]
Name=eno1
[Network]
DHCP=yes
MulticastDNS=yes
and then enabling/starting systemd-networkd
:
systemctl enable systemd-networkd
systemctl start systemd-networkd
I also needed to install polkit:
apt install --no-install-recommends policykit-1
in order to allow systemd-networkd
to set the hostname.
In order to start my firewall automatically as interfaces are brought up, I
wrote a dispatcher script to apply my existing iptables
rules.
Migration to predictacle network interface names
On my Linode server, I did the same as on the backup server, but I put the
following in /etc/systemd/network/20-wired.network
since it has a static
IPv6 allocation:
[Match]
Name=enp0s4
[Network]
DHCP=yes
Address=2600:3c01::xxxx:xxxx:xxxx:939f/64
Gateway=fe80::1
and switched to predictable network interface names by deleting these two files:
/etc/systemd/network/50-virtio-kernel-names.link
/etc/systemd/network/99-default.link
and then changing eth0
to enp0s4
in:
/etc/network/iptables.up.rules
/etc/network/ip6tables.up.rules
/etc/rc.local
(for OpenVPN)/etc/logcheck/ignored.d.*/*
Then I regenerated all initramfs:
update-initramfs -u -k all
and rebooted the virtual machine.
Giving systemd-resolved control of /etc/resolv.conf
After reading this history of DNS resolution on
Linux, I decided to
modernize my resolv.conf
setup and let systemd-resolved
handle
/etc/resolv.conf
.
I installed the package:
apt install systemd-resolved
and then removed no-longer-needed packages:
apt purge openresolv resolvconf avahi-daemon
I also disabled support for Link-Local Multicast Name Resolution (LLMNR) after reading this person's reasoning by putting the following in /etc/systemd/resolved.conf.d/llmnr.conf
:
[Resolve]
LLMNR=no
I verified that mDNS is enabled and LLMNR is disabled:
$ resolvectl mdns
Global: yes
Link 2 (enp0s25): yes
Link 3 (wlp3s0): yes
$ resolvectl llmnr
Global: no
Link 2 (enp0s25): no
Link 3 (wlp3s0): no
Note that if you want auto-discovery of local printers using CUPS, you
need to keep avahi-daemon
and ensure that systemd-resolved
does
not conflict with it.
DNS resolution problems with ifupdown
Also, if you haven't migrated to systemd-networkd
yet and are still using
ifupdown
with a static IP address, you will likely run into DNS
problems which
can be fixed using the following patch to /etc/network/if-up.d/resolved
:
@@ -43,11 +43,11 @@ if systemctl is-enabled systemd-resolved > /dev/null 2>&1; then
fi
if [ -n "$NEW_DNS" ]; then
cat <<EOF >"$mystatedir/ifupdown-${ADDRFAM}-$interface"
-"$DNS"="$NEW_DNS"
+$DNS="$NEW_DNS"
EOF
if [ -n "$NEW_DOMAINS" ]; then
cat <<EOF >>"$mystatedir/ifupdown-${ADDRFAM}-$interface"
-"$DOMAINS"="$NEW_DOMAINS"
+$DOMAINS="$NEW_DOMAINS"
EOF
fi
fi
@@ -66,7 +66,7 @@ EOF
# ignore errors due to nonexistent file
md5sum "$mystatedir/isc-dhcp-v4-$interface" "$mystatedir/isc-dhcp-v6-$interface" "$mystatedir/ifupdown-inet-$interface" "$mystatedir/ifupdown-inet6-$interface" > "$newstate" 2> /dev/null || true
if ! cmp --silent "$oldstate" "$newstate" 2>/dev/null; then
- DNS DNS6 DOMAINS DOMAINS6 DEFAULT_ROUTE
+ unset DNS DNS6 DOMAINS DOMAINS6 DEFAULT_ROUTE
# v4 first
if [ -e "$mystatedir/isc-dhcp-v4-$interface" ]; then
. "$mystatedir/isc-dhcp-v4-$interface"
and make sure you have nameservers setup in your static config, for example
one of my servers' /etc/network/interfaces
looks like this:
iface enp4s0 inet static
address 192.168.1.2
netmask 255.255.255.0
gateway 192.168.1.1
dns-nameservers 149.112.121.20
dns-nameservers 149.112.122.20
pre-up iptables-restore /etc/network/iptables.up.rules
Dynamic DNS
I replaced ddclient with inadyn since it doesn't work with no-ip.com anymore, using the configuration I described in an old blog post.
chkrootkit
I moved my customizations in /etc/chkrootkit.conf
to
/etc/chkrootkit/chkrootkit.conf
after seeing this message in my logs:
WARNING: /etc/chkrootkit.conf is deprecated. Please put your settings in /etc/chkrootkit/chkrootkit.conf instead: /etc/chkrootkit.conf will be ignored in a future release and should be deleted.
ssh
As mentioned in Debian bug#1018106, to silence the following warnings:
sshd[6283]: pam_env(sshd:session): deprecated reading of user environment enabled
I changed the following in /etc/pam.d/sshd
:
--- a/pam.d/sshd
+++ b/pam.d/sshd
@@ -44,7 +44,7 @@ session required pam_limits.so
session required pam_env.so # [1]
# In Debian 4.0 (etch), locale-related environment variables were moved to
# /etc/default/locale, so read that as well.
-session required pam_env.so user_readenv=1 envfile=/etc/default/locale
+session required pam_env.so envfile=/etc/default/locale
# SELinux needs to intervene at login time to ensure that the process starts
# in the proper default security context. Only sessions which are intended
I also made the following changes to /etc/ssh/sshd_config.d/local.conf
based on the advice of ssh-audit 2.9.0:
-KexAlgorithms curve25519-sha256@libssh.org,curve25519-sha256,diffie-hellman-group14-sha256,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512,diffie-hellman-group-exchange-sha256
+KexAlgorithms curve25519-sha256@libssh.org,curve25519-sha256,sntrup761x25519-sha512@openssh.com,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512
Unwanted power management
I ran into a problem with one of my servers where it would suspend
itself after a certain amount of time. This was due to default GDM behaviour
it turns out and while I could tell gdm not to sleep on inactivity,
I instead put the following in /etc/systemd/sleep.conf.d/nosuspend.conf
to fully
disable systemd-based suspend or hibernate:
[Sleep]
AllowSuspend=no
AllowHibernation=no
AllowSuspendThenHibernate=no
AllowHybridSleep=no
Asterisk has been removed from Debian
The only major problem I ran into while upgrading to bookworm is that I discovered
that Asterisk has been removed from stable
and testing
.
For some reason, this was not mentioned in the release notes
and I have not yet found a good solution.
If you upgrade to bookworm, be warned that the bullseye
packages will remain
installed (and will work fine in my experience) unless you "clean them up" with
apt purge '~o'
accidentally and then you'll have to fetch these old debs manually.
I use
reboot-notifier
on most of my
servers to let me
know when I need to reboot them for kernel updates since I want to decide
exactly when those machines go down. On the other hand, my home backup
server has very predictable usage patterns and so I decided to go one step
further there and automate these necessary reboots.
To do that, I first installed
reboot-notifier
which puts the following script in /etc/kernel/postinst.d/reboot-notifier
to detect when a new kernel was installed:
#!/bin/sh
if [ "$0" = "/etc/kernel/postinst.d/reboot-notifier" ]; then
DPKG_MAINTSCRIPT_PACKAGE=linux-base
fi
echo "*** System restart required ***" > /var/run/reboot-required
echo "$DPKG_MAINTSCRIPT_PACKAGE" >> /var/run/reboot-required.pkgs
Note that
unattended-upgrades
puts a similar script in /etc/kernel/postinst.d/unattended-upgrades
:
#!/bin/sh
case "$DPKG_MAINTSCRIPT_PACKAGE::$DPKG_MAINTSCRIPT_NAME" in
linux-image-extra*::postrm)
exit 0;;
esac
if [ -d /var/run ]; then
touch /var/run/reboot-required
if ! grep -q "^$DPKG_MAINTSCRIPT_PACKAGE$" /var/run/reboot-required.pkgs 2> /dev/null ; then
echo "$DPKG_MAINTSCRIPT_PACKAGE" >> /var/run/reboot-required.pkgs
fi
fi
and so you only need one of them to be installed since they both write to
/var/run/reboot-required
. It doesn't hurt to have both of them though.
Then I created the following cron job (/etc/cron.daily/reboot-local
) to
actually reboot the server:
#!/bin/bash
REBOOT_REQUIRED=/var/run/reboot-required
if [ -s $REBOOT_REQUIRED ] ; then
cat "$REBOOT_REQUIRED" | /usr/bin/mail -s "Rebooting $HOSTNAME" root
/bin/systemctl reboot
fi
With that in place, my server will send me an email and then automatically reboot itself.
This is a work in progress because I'd like to add some checks later on to make sure that no backup is in progress during that time (maybe by looking for active ssh connections?), but it works well enough for now. Feel free to leave a comment if you've got a smarter script you'd like to share.