Hacking, Code & Open Source Reads

Debian 10 - What Two Years Brought

Christian Lehnert2019-08-04~9 min read

Debian 10, codenamed Buster after the cowboy doll's pull-string-controlled toy from Toy Story, released on July 6 and ended Stretch's two-year run as stable. A month in, the early adopters have shaken out the rough edges, the .1 point release is expected in early September, and most operators can now plan a migration without the bleeding-edge anxiety of the first weeks.

Buster is a more disruptive release than Stretch was. The package versions are newer in the way every Debian release brings newer versions, but Buster also makes two structural changes that Stretch did not: nftables replaces iptables as the default firewall framework, and secure boot is supported on amd64 and arm64. Both are migrations the broader Linux ecosystem has been working through for years; Buster is the first Debian release where they land as the defaults.

This post covers what's actually new, the structural changes worth knowing about, the migration path from Stretch, and the gotchas that will bite you.

What's actually new

The headline package versions:

  • Linux kernel 4.19 LTS (up from 4.9 in Stretch). Two years of hardware support improvements, particularly for newer Intel and AMD chipsets, NVMe drives, and USB-C hardware. The 4.19 series is the long-term-supported kernel for this Debian generation.

  • systemd 241 (up from 232). A long list of new directives, better cgroup v2 support, improved sandboxing primitives (PrivateUsers, ProtectKernelLogs, SystemCallFilter improvements). Existing unit files written for Stretch's systemd 232 work unchanged.

  • GCC 8.3 as the default compiler (up from 6.3). Full C++17 support, partial C++20.

  • Python 3.7 as default Python 3. Python 2.7 is still available but is the last release that will ship it — upstream Python 2 support ends in January 2020, and Debian's policy is to drop Python 2 in the release after Buster (i.e., Bullseye).

  • OpenJDK 11 as default Java, replacing OpenJDK 8 from Stretch.

  • PHP 7.3 as default. PHP 5.6 is gone entirely.

  • OpenSSL 1.1.1 as default — the LTS branch with TLS 1.3 support.

  • GnuPG 2.2 as default gpg.
    The graphical environment defaults:

  • GNOME 3.30 as the default desktop, running on Wayland by default on hardware that supports it (most modern Intel and AMD GPUs; NVIDIA still defaults to Xorg).

  • KDE Plasma 5.14 for the KDE flavor.

  • LibreOffice 6.1.
    The server-relevant defaults:

  • MariaDB 10.3 (up from 10.1 in Stretch).

  • PostgreSQL 11.

  • Apache 2.4.38 and nginx 1.14.

  • OpenJDK 11 for everyone, including server-side JVM workloads.

The structural changes

Two changes are not version bumps but architectural shifts. Both deserve more attention than they typically get.

nftables replaces iptables

This is the biggest structural change in Buster. For two decades, the standard Linux firewall framework has been iptables, with its various extensions — ip6tables, arptables, ebtables — for different protocols. Buster replaces all of them with nftables, a unified framework with a single command-line tool and a more consistent rule syntax.

The migration is not all-or-nothing. Buster ships an iptables-nft compatibility layer: if you run iptables -A INPUT ... on Buster, it works, but the rule is stored in nftables internally and managed by the nftables backend. This means existing firewall scripts continue to function. It also means the output of iptables-save may look slightly different — the rules are equivalent but expressed through the compatibility layer.

For new firewall configurations, the recommended path is to write nftables rules directly. The syntax is more readable than iptables, the command-line is faster (no per-rule fork-and-exec), and the model handles IPv4 and IPv6 in a single ruleset rather than requiring parallel iptables and ip6tables rules.

A minimal nftables ruleset for a server:

#!/usr/sbin/nft -f
 
flush ruleset
 
table inet filter {
    chain input {
        type filter hook input priority 0; policy drop;
        ct state established,related accept
        iifname lo accept
        ip protocol icmp accept
        ip6 nexthdr icmpv6 accept
        tcp dport { 22, 80, 443 } accept
    }
    chain forward {
        type filter hook forward priority 0; policy drop;
    }
    chain output {
        type filter hook output priority 0; policy accept;
    }
}

Save as /etc/nftables.conf, enable the service:

1sudo systemctl enable --now nftables

The inet family handles IPv4 and IPv6 simultaneously, eliminating the duplication between iptables and ip6tables. The set syntax ({ 22, 80, 443 }) is concise and efficient. Rules can be added and removed at runtime via nft without flushing and reloading.

For sysadmins coming from iptables, the conceptual model is similar but the commands are not. Plan an afternoon to read the nftables wiki and rewrite your existing rules; the result will be shorter and more maintainable than the iptables original.

Secure boot on amd64 and arm64

Buster is the first Debian release with first-class UEFI Secure Boot support on amd64 and arm64. The Debian project has signed shim, GRUB, the kernel, and the kernel modules, and the standard installer can deploy onto Secure Boot-enabled hardware without disabling Secure Boot.

This matters more for the desktop and laptop case than the server case. Most server hardware ships with Secure Boot disabled, and Linux server admins have generally turned it off as a matter of course. For laptops — particularly newer hardware where disabling Secure Boot is awkward or lockable by IT policy — Buster's signed boot chain means Linux can be deployed as a co-equal to the signed Windows installation rather than requiring firmware reconfiguration.

The implementation uses the standard shim-then-GRUB chain: shim is signed by Microsoft (the only practical CA whose keys are in shipped firmware), GRUB and the kernel are signed by Debian, and the kernel-modules are checked at load time. DKMS-built modules — including, currently, WireGuard — fail to load under Secure Boot unless you enroll your own signing key, which is a real friction for users running out-of-tree modules. This will improve as more modules land in the mainline kernel.

AppArmor by default

AppArmor was packaged in Stretch but not enabled by default. In Buster, it is enabled by default and ships with profiles for several daemons — Apache, MariaDB, MySQL, dovecot, smbd, nmbd, and others. The profiles are mostly in complain mode initially; they log violations rather than blocking them, giving administrators visibility into what the profiles would block before they enforce.

This is the right migration path for AppArmor. Enabling it in enforce mode by default would have broken too many edge cases; enabling it in complain mode gives the project years of telemetry to refine the profiles before transitioning to enforcement. By Bullseye (Debian 11, expected 2021), most profiles are likely to be in enforce by default.

For sysadmins, the practical effect today is that AppArmor logs will appear in journalctl and /var/log/syslog for processes that the profile would have blocked. Read them. They reveal what each daemon is actually doing on your system, which is more interesting than you might expect.

Migration from Stretch

The standard Debian apt-based migration path applies. From a clean, fully-updated Stretch system:

1apt-get update
2apt-get upgrade
3apt-get full-upgrade

Then update sources:

1sed -i 's/stretch/buster/g' /etc/apt/sources.list
2sed -i 's/stretch/buster/g' /etc/apt/sources.list.d/*.list

If you had stretch-backports, replace with buster-backports only after the migration is complete and you have confirmed the system is stable on Buster main.

The actual upgrade:

1apt-get update
2apt-get upgrade --without-new-pkgs
3apt-get full-upgrade

Then reboot. Verify:

1cat /etc/debian_version    # should now read 10.0
2uname -r                   # should be 4.19.x
3systemctl --version        # should be 241

The gotchas

In rough order of likelihood to bite you:

iptables-save format change. As mentioned above, iptables-save on Buster shows rules expressed through the nftables compatibility layer. If you have automation that compares iptables-save output across releases, expect spurious differences. Either update the automation to use nft list ruleset directly, or accept the format change as cosmetic.

Python 2 packages on the deprecation path. Many packages that depended on Python 2 in Stretch have been ported to Python 3 or dropped. If you have local scripts depending on Python 2 system packages (python-requests, python-yaml, etc.), test before upgrading. The packages are still available in Buster but are explicitly marked for removal in Bullseye.

OpenJDK 8 to 11. Java applications that worked on OpenJDK 8 mostly work on OpenJDK 11, but the --module-path and Jigsaw module system changes have caused real breakage in some applications. Test on a non-production host first. If you need OpenJDK 8 long-term, it remains available as openjdk-8-jre, just not as default.

MariaDB 10.1 to 10.3 schema changes. The data files migrate cleanly in almost all cases, but some INFORMATION_SCHEMA queries return slightly different results, and a few obscure storage engines were deprecated. Take a database backup before upgrading, as you should anyway.

PostgreSQL 9.6 to 11 is not automatic. Debian provides PostgreSQL 11 in Buster, but it does not migrate the data from 9.6 to 11 during the OS upgrade. You need to run pg_upgradecluster manually after the OS upgrade. The 9.6 cluster remains available alongside 11; plan a maintenance window for the database migration separately from the OS migration.

Wayland on NVIDIA. GNOME on Wayland is the default for AMD and Intel graphics. NVIDIA proprietary drivers do not yet work well with Wayland, so the GNOME session falls back to Xorg automatically on NVIDIA systems. This is invisible to most users but causes confusion when troubleshooting "why isn't Wayland working" — the answer, on NVIDIA, is "it isn't, by design."

SSH key types. OpenSSH 7.9 in Buster disables RSA-SHA1 by default. SSH keys generated with ssh-keygen default to ED25519 now. If you have older RSA keys in your authorized_keys files, they continue to work, but if you have automation that uses ssh-keyscan to gather host keys, you may see different output for hosts that previously offered RSA-SHA1.

Should you upgrade now or wait

Buster has been stable for a month and the .1 point release is expected in around five weeks. For production servers, the conservative pattern remains: wait for .1, run a small fleet on Buster for two to four weeks after that, and then plan the larger migration.

For development machines, laptops, and home servers, upgrading now is fine. The kernel and userspace are meaningfully better, the security defaults (AppArmor, secure boot, the nftables conversion) are improvements worth having, and the rough edges that exist will mostly be discovered by the people upgrading early. By the end of 2019, most personal machines will be on Buster regardless.

Stretch's standard support continues until July 2020, with LTS support to mid-2022. There is no calendar pressure. There is also no reason to put Buster off — the migration is well-tested, the gotchas are documented, and the structural changes (nftables, secure boot, AppArmor) are the direction the entire Linux ecosystem is heading.

The summary

Buster is a substantial Debian release. The package versions are newer in the way every release brings newer versions, but the structural changes — nftables as the firewall default, signed UEFI Secure Boot, AppArmor enabled by default — are what will matter over the next two years. The migration path from Stretch is clean, the early-adoption period has surfaced the meaningful gotchas, and the .1 point release in September will smooth out the remaining rough edges.

Plan it. Upgrade a non-critical machine first. Read the release notes. The hour you invest in preparation buys you a smooth upgrade and another two years of running on a Debian release that takes security defaults more seriously than its predecessors did.

Tagged:
#linux #debian #selfhosted
← Back to posts