There are good instructions on the Linode Library here on how to compile and use your own Kernel, but I do things slightly differently using the grsecurity hardening patch and build a .deb (Debian) package of my kernel.

apt-get install build-essential make fakeroot pgpgpg wget git ncurses-dev curl wget xz-utils grub-legacy need gcc-4.7-plugin-dev paxctl
$ wget https://grsecurity.net/test/grsecurity-2.9.1-3.5.2-201208151951.patch
$ wget https://grsecurity.net/test/grsecurity-2.9.1-3.5.2-201208151951.patch.sig
$ wget http://www.kernel.org/pub/linux/kernel/v3.0/linux-3.5.2.tar.gz
$ wget http://www.kernel.org/pub/linux/kernel/v3.0/linux-3.5.2.tar.gz.sign
$ gpg --verify grsecurity-2.9.1-3.5.2-201208151951.patch.sig grsecurity-2.9.1-3.5.2-201208151951.patch
$ gpg --verify linux-3.5.2.tar.gz.sign linux-3.5.2.tar.gz
$ tar -xf linux-3.5.2.tar.gz
$ cd linux-3.5.2
$ patch -p1 ../grsecurity-2.9.1-3.5.2-201208151951.patch
$ sudo cp /boot/config-`uname -r`.config
$ make menuconfig

Make any changes to your kernel configuration and then save them. I have disabled loadable module support (not something I require on a server + the security considerations) and a couple of other features (NFS), even so the kernels Linode offer are pretty lean.

Under grsecurity I have enabled mostly all of the settings without any issues, read about those config options here. Depends on what your requirements are as to how suitable some of these options are.

$ make-kpkg --rootcmd fakeroot kernel_image kernel_headers --initrd --revision=grsec.352
$ cd ..
$ sudo dpkg -i linux-headers-3.5.2-grsec_352_i386.deb linux-image-3.5.2-grsec_352_i386.deb
$ update-initramfs -c -k 3.5.2

If you are running a Grsec kernel when you do this you will need to adjust the flags of /usr/sbin/grub-probe with paxctl

$ paxctl -v /usr/sbin/grub-probe
PaX control v0.7
Copyright 2004,2005,2006,2007,2009,2010,2011,2012 PaX Team <pageexec@freemail.hu>

- PaX flags: -p-s-m-x-e-r [/usr/sbin/grub-probe]
        PAGEEXEC is disabled
        SEGMEXEC is disabled
        MPROTECT is disabled
        RANDEXEC is disabled
        EMUTRAMP is disabled
        RANDMMAP is disabled

Check /boot/grub/menu.lst and add the new kernel if it’s not there (it should be).

timeout 2
title kernel 3.5.2
root (hd0)
kernel /boot/vmlinuz-3.5.2-grsec root=/dev/xvda ro
initrd /boot/initrd.img-3.5.2-grsec

Restart the server and all going well it should boot up using the new kernel.

$ uname -a Linux hostname 3.5.2-grsec #1 SMP Sun Aug 19 01:36:55 PDT 2012 i686 GNU/Linux

Updated: other brief relevant notes:

  • Add barrier=0 to your fstab file. To stop all the page allocation errors I was getting In sysctl.conf I had to add vm.min_free_kbytes = 5120

  • If you get this error when booting: close blk: backend at /local/domain/0/backend/vbd/6401/51712 Then disable “Sanitize kernel stack” in Grsecurity.

  • Problems with removing the kernel: If you have /var mounted with noexec when you apt-get remove your-compiled-kern you will get an error message because the post-remove scripts will be unable to execute. If things get really broken you can remove your kernel this ugly way:

    manually delete the scripts which are stored in /var/lib/dpkg/info/
    remove the files for that particular kernel in /boot/ (Remember to edit /boot/grub/menu.lst to reflect your changes!!)
    run: dpkg --purge linux-image-x