This page describes how to build your own Linux kernel under Debian . It is often useful to build your own kernel as sometimes the Debian default lacks something you need (for example, I need to enable RMI4 on my Thinkpad X1C6) or includes bloat you do not want (e.g., uncommon protocols such as RDS that might leave you exposed to an undisclosed or future vulnerability unecessarily.

The official documentation for this is here provided by Debian here. The below method is a very simple and reliable remix of the approaches list here that I find work very well.

Begin by installing packages for building:

$ sudo apt install build-essential fakeroot
$ sudo apt install libncurses5-dev  # for make nconfig
$ sudo apt install gcc-XXX-plugin-dev # for gcc plugins
$ sudo apt-get build-dep linux

(replace XXX with the current gcc version)

Get Linux source, extract:

$ mkdir -p build # make a build directory
$ cd build
$ apt-get source linux
$ cd linux-XXX

I prefer to use apt to get the source: it will verify checksums for you automatically and include any handy patches from Debian. Replace XXX with the current Linux version.

Now the fun part: Configure the kernel to your liking. I find it helpful to base the new config of the current kernel config. You at least know the current kernel config boots with your current efi/initramfs/lvm/systemd/X combination.

$ cp /boot/config-$(uname -r) .config
$ make nconfig

If this fails, start from scratch: delete .config and start again.

Tips:

  • See this list of suggestions for hardening your kernel configuration.
  • Be sure to set Additional X.509 keys for default system keyring to empty.
  • Thinkpad X1 6th Generation touchpad support requires Synaptics RMI4 support which can be found in Device Drivers -> Input device support -> Synaptics RMI4 bus support.
  • Don’t forget to enable cipher modes for encrypted filesystems, e.g., XTS.
  • Also don’t forget to enable DM crypt if you have an encrypted disk; it’s under RAID/LVM.

Build it!

$ time make -j8 bindeb-pkg

Should take around 40 minutes on a recent machine. Go do something else.

Once the compilation has finished, several debian packages are produced in the parent directory.

DKMS

DKMS allows the automatic building of additional kernel modules once a kernel is compiled. Naturally then, if you force your modules to be signed, then it’s nicer for new modules to automatically be signed by DKMS. To do this, edit /etc/dkms/framework.conf and add:

sign_tool="/etc/dkms/sign_helper.sh"

Then create /etc/dkms/sign_helper.sh with:

#!/bin/sh
/lib/modules/"$1"/build/scripts/sign-file sha256 /root/signing_key.pem /root/signing_key.x509 "$2"

and then copy signing_key.{pem,x509} from the build directory of the kernel under certs, to /root.

If you need to re-install something, look in /usr/src, and suppose you find a directory called zfs-2.0.0, then you can reinstall this and resign it with dkms install zfs/2.0.0.

Install!

Go install them:

$ cd ..
$ sudo dpkg -i linux-headers-4.19.28_4.19.28-1_amd64.deb linux-image-4.19.28_4.19.28-1_amd64.deb linux-libc-dev_4.19.28-1_amd64.deb

Now reboot!

Potential problems:

  • Cannot find missing AES-XTS-PLAIN64 at boot. Ensure dm_crypt is enabled in the kernel configuration.

  • kernel: request_module fs-efivarfs succeeded, but still no fs? at boot. Ensure that CONFIG_EFI_RUNTIME_MAP=y is in .config

  • $ modprobe foo
    foo: Key was rejected by service`
    

    The steps above enforced modules to be signed. It’s easy to sign if you’ve got the key from the build:

    $ sudo ./scripts/sign-file sha256 ./certs/signing_key.pem ./certs/signing_key.x509 /lib/modules/5.2.9/updates/dkms/foo.ko
    

    See above how to solve this long term.

  • No network access when using ufw. Try ufw disable. If this fixes things, then try ufw enable and see if you get errors like:

    ERROR: problem running ufw-init
    

iptables-restore v1.8.7 (nf_tables): line 42: RULE_APPEND failed (No such file or directory): rule in chain INPUT … line 35: RULE_APPEND failed (No such file or directory): rule in chain ufw6-user-limit-accept ip6tables-restore: line 5 failed

Problem running ‘/etc/ufw/before.rules’ Problem running ‘/etc/ufw/after.rules’ Problem running ‘/etc/ufw/user.rules’ Problem running ‘/etc/ufw/before6.rules’ Problem running ‘/etc/ufw/after6.rules’ Problem running ‘/etc/ufw/user6.rules’ The fix is very simple, and I do not understand why it's needed but, eh:shell $ sudo update-alternatives –set ip6tables /usr/sbin/ip6tables-legacy $ sudo update-alternatives –set iptables /usr/sbin/iptables-legacy $ sudo ufw enable ``` Linux firewalling is a real mess.