Strip the Kernel





Strip the Kernel

figs/moderate.gif figs/hack54.gif

Don't be shy. A kernel stripped down to the bare essentials is a happy kernel.

Picture the typical day in the life of a system administrator. Your mission, if you choose to accept it, is to achieve the impossible. Today, you're expected to:

  • Increase the security of a particular server

  • Attain a noticeable improvement in speed and performance

Although there are many ways to go about this, the most efficient way is to strip down the kernel to its bare-bones essentials. Having this ability gives an administrator of an open source system a distinct advantage over his closed source counterparts.

The first advantage to stripping the kernel is an obvious security boost. A vulnerability can't affect an option the kernel doesn't support. The second is a noticeable improvement in speed and performance. Kernels are loaded into memory and must stay in memory. You may be wasting precious memory resources if you're loading options you have no intention of ever using.

If you've never compiled a kernel or changed more than one or two kernel options, I can hear you groaning now. You're probably thinking, "Anything but that. Kernels are too complicated to understand." Well, there is a lot of truth in the idea that you haven't really used an operating system until you've gone through that baptism of fire known as kernel compiling. However, you may not have heard that compiling a kernel isn't all that difficult. So, grab a spare afternoon and a test system; it's high time to learn how to hack a BSD kernel.

I'll demonstrate on a FreeBSD system, but you'll find resources for other systems at the end of this hack.

Before you start, double-check that you have the kernel source installed. On an Intel FreeBSD system, it lives in /usr/src/sys/i386/conf. If that directory doesn't exist, become the superuser and install it:

# /stand/sysinstall

Configure

Distributions

spacebar [  ] src to select it

spacebar [  ] sys to select it

tab to OK

Next, navigate into that directory structure and check out its contents:

# cd /usr/src/sys/i386/conf

# ls

 ./        GENERIC.hints    OLDCARD        gethints.awk

../        Makefile         PAE            GENERIC

NOTES      SMP

Two files are important: the original kernel configuration file, GENERIC, and NOTES. Note that NOTES is instead called LINT on 4.x FreeBSD systems.

1 Customizing Your Kernel

Customizing a kernel is a very systematic process. Basically, you examine each line in the current configuration file, asking yourself, "Is this applicable to my situation?" If so, keep it. Otherwise, remove it. If you don't know, read NOTES for that option.

I always customize my kernel in several steps. First, I strip out what I don't need. Then, I use buildkernel to test my new configuration file. If it doesn't build successfully, I know I've inadvertently removed something essential. Using the error message, I go back and research that missing line.

If the build succeeds, I read through NOTES to see if there are any options I wish to add to the kernel. If I add anything, I'll do another buildkernel, followed by an installkernel if the build is successful. I find it much easier to troubleshoot if I separate my deletions from my additions.

Let's copy over GENERIC and see about stripping it down:

# cp GENERIC STRIPPED

# vi STRIPPED

#

# GENERIC -- Generic kernel configuration file for FreeBSD/i386

#

# For more information on this file, please read the handbook section on

# Kernel Configuration Files:

#

#    http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html

#

# The handbook is also available locally in /usr/share/doc/handbook

# if you've installed the doc distribution, otherwise always see the

# FreeBSD World Wide Web server (http://www.FreeBSD.org/) for the

# latest information.

#

# An exhaustive list of options and more detailed explanations of the

# device lines is also present in the ../../conf/NOTES and NOTES files. 

# If you are in doubt as to the purpose or necessity of a line, check first 

# in NOTES.

1.1 CPU options

The first thing you'll notice is that this file is very well commented. It's also divided into sections, making it easier to remove things such as ISA NIC, SCSI, and USB support. The first section deals with CPU type:

machine    i386

cpu        I486_CPU

cpu        I586_CPU

cpu        I686_CPU

ident      GENERIC

Whenever you come across a section you're not sure about, look for that section in NOTES. Here, I'll search for CPU:

# grep CPU NOTES

Your output will include a few pages worth of CPU information. The first few lines describe which CPUs belong with the I486, I586, and I686 entries. Once you find your CPU, remove the two entries that don't apply. If you're not sure what type of CPU is installed on the system you're configuring, try:

# grep CPU /var/run/dmesg.boot

CPU: Intel(R) Pentium(R) III CPU         1133MHz (1138.45-MHz 686-class CPU)

acpi_cpu0: <CPU> port 0x530-0x537 on acpi0

Since a Pentium III is considered to be an I686_CPU, I'll remove the I486_CPU and I586_CPU lines from this system's configuration file.

The rest of the output from grep CPU NOTES contains extra lines that can be added to the kernel. Read through these to see if any apply to your specific CPU and the needs of the machine you are configuring. If so, make a note to try adding these later.

1.2 System-specific options

The next section contains a heck of a lot of options. If this is your first kernel, most of your research will be deciding which options you need for your particular system. I find the handbook most helpful here, as it lists the pros and cons of nearly every option. I always keep these options on all of my systems:

options     SCHED_4BSD       # 4BSD scheduler

options     INET             # InterNETworking

options     FFS              # Berkeley Fast Filesystem

options     COMPAT_FREEBSD4  # Compatible with FreeBSD4

options     COMPAT_43        # Compatible with BSD 4.3 [KEEP THIS!]

Note that that last listed option tells you to keep it. Do keep anything that contains such a comment.

The rest of the options are specific to that system's needs. For example, does it need to support IPv6? Do you wish to use softupdates or the new MAC framework? Does this system need to be an NFS server or NFS client? Does this system have a CD-ROM attached or any SCSI devices?

Does the system have multiple processors? If so, uncomment the next two lines; otherwise, you can safely remove them:

# To make an SMP kernel, the next two are needed

#options     SMP            # Symmetric MultiProcessor Kernel

#options     APIC_IO        # Symmetric (APIC) I/O

1.3 Supported buses and media devices

The next section deals with devices. First, we start with the buses:

device        isa

device        eisa

device        pci

If you grep device NOTES, you'll see that you can also add the agp and mca buses if your system requires them. If your system doesn't use the isa or eisa buses, you can remove those lines.

If you wish to disable floppy support on your server, removing these lines will do it:

# Floppy drives

device        fdc

Next, does your server use IDE or SCSI devices? If it uses IDE, the next section applies:

# ATA and ATAPI devices

device      ata

device      atadisk            # ATA disk drives

device      atapicd            # ATAPI CDROM drives

device      atapifd            # ATAPI floppy drives

device      atapist            # ATAPI tape drives

options     ATA_STATIC_ID      # Static device numbering

Remember, you can remove the CD-ROM, floppy, and tape lines to suit your requirements. However, keep the other lines if you use an IDE hard drive. Conversely, if your system is all SCSI, delete the ATA lines and concentrate on this section:

# SCSI Controllers

device        ahb        # EISA AHA1742 family

device        ahc        # AHA2940 and onboard AIC7xxx devices

<snip>

Keep the entries for the SCSI hardware your system is using, and remove the entries for the other devices. If your system doesn't have SCSI hardware, you can safely delete the entire SCSI section.

The same logic applies to the following RAID section:

# RAID controllers interfaced to the SCSI subsystem

device        asr        # DPT SmartRAID V, VI and Adaptec SCSI RAID

device        ciss       # Compaq Smart RAID 5*

device        dpt        # DPT Smartcache III, IV - See NOTES for options!

device        iir        # Intel Integrated RAID

device        mly        # Mylex AcceleRAID/eXtremeRAID

and for the SCSI peripherals and RAID controllers sections:

# SCSI peripherals

device        scbus     # SCSI bus (required)

device        ch        # SCSI media changers

<snip>



# RAID controllers

device        aac        # Adaptec FSA RAID

device        aacp       # SCSI passthrough for aac (requires CAM)

<snip>

1.4 Peripheral support and power management

The next few entries are usually keepers as it's always nice to have a working keyboard, unless you're using a headless system [Hack #26] .

# atkbdc0 controls both the keyboard and the PS/2 mouse

device        atkbdc       # AT keyboard controller

device        atkbd        # AT keyboard

The next line depends on whether you're using a serial or a PS/2 mouse:

device        psm        # PS/2 mouse

You'll probably want to keep your video driver:

device        vga        # VGA video card driver

However, you'll probably remove the splash device, unless you plan on configuring a splash screen [Hack #24] .

device        splash        # Splash screen and screen saver support

You'll have to choose a console driver. It can be either the default SCO driver or the pcvt driver (see the handbook for details):

# syscons is the default console driver, resembling an SCO console

device       sc

# Enable this for the pcvt (VT220 compatible) console driver

#device      vt

#options     XSERVER           # support for X server on a vt console

#options     FAT_CURSOR        # start with block cursor

The next options refer to power management on laptops, as well as laptop PCMCIA cards. Unless your server is a laptop, you can remove these:

# Power management support (see NOTES for more options)

#device       apm

# Add suspend/resume support for the i8254.

device        pmtimer



# PCCARD (PCMCIA) support

# Pcmcia and cardbus bridge support

device        cbb            # cardbus (yenta) bridge

#device       pcic           # ExCA ISA and PCI bridges

device        pccard         # PC Card (16-bit) bus

device        cardbus        # CardBus (32-bit) bus

Do you plan on using your serial and parallel ports? If not, the next section allows you to disable them:

# Serial (COM) ports

device        sio        # 8250, 16[45]50 based serial ports



# Parallel port

device        ppc

device        ppbus      # Parallel port bus (required)

device        lpt        # Printer

device        plip       # TCP/IP over parallel

device        ppi        # Parallel port interface device

#device       vpo        # Requires scbus and da

1.5 Interface support

Now it's time to support your system's NICs. Here's one way to find out the device names of your interfaces:

# grep Ethernet /var/run/dmesg.boot

rl0: Ethernet address: 00:05:5d:d2:19:b7

rl1: Ethernet address: 00:05:5d:d1:ff:9d

ed0: <NE2000 PCI Ethernet (RealTek 8029)> port 0x9800-0x981f irq 10 at device 11.0 on pci0

Once you know which interfaces are in your system, remove the NICs that aren't. If your system doesn't contain any ISA or wireless NICs, you can safely remove those entire sections.

Do make note of this comment, though:

# PCI Ethernet NICs that use the common MII bus controller code.

# NOTE: Be sure to keep the 'device miibus' line in order to use these NICs!

device        miibus    # MII bus support

device        dc        # DEC/Intel 21143 and various workalikes

<snip>

Any NICs underneath that comment require that miibus entry. If you forget it, your kernel won't build. Fortunately, the error message will have the word miibus in it.

Next come the pseudodevices. If you plan on using encryption, keep the random device. You'll probably also need to keep the loop and ether devices.

If you use an analog modem to connect to your service provider, keep the ppp and tun devices. Otherwise, remove them, along with the slip device.

Several applications—including emacs, xterm, script, and the notorious telnet—require the pty device. Depending upon the use of your server, you may be able to remove that device. If it breaks needed functionality, you can always recompile it back into your kernel.

Are you planning on using memory disks? If not, you can remove md. If you're not sure, try reading man mdmfs.

If you previously removed IPv6 support with options INET6, you might as well remove these two devices as well:

device        gif        # IPv6 and IPv4 tunneling

device        faith      # IPv6-to-IPv4 relaying (translation)

The next device has some security implications, as it is required in order to run a packet sniffer such as tcpdump. However, it's also required if your system is a DHCP client. If neither applies, remove the bpf device:

# The `bpf' device enables the Berkeley Packet Filter.

# Be aware of the administrative consequences of enabling this!

device        bpf        # Berkeley packet filter

1.6 USB support

Does your system have any USB devices? If so, you need a host controller as well as USB bus support. First, determine which type of USB host controller you have. man uhci and man ohci describe which hardware goes with which controller. Once you've found your hardware, keep the appropriate interface entry:

# USB support

device        uhci        # UHCI PCI->USB interface

device        ohci        # OHCI PCI->USB interface

Also, don't forget to keep that USB bus line:

device        usb        # USB Bus (required)

Are you confused about the next three USB options? Fortunately, each has a manpage. Try man udbp, man ugen, and man uhid to see if any apply to your particular situation.

#device       udbp        # USB Double Bulk Pipe devices

device        ugen        # Generic

device        uhid        # "Human Interface Devices"

Next, keep the devices you have installed and remove the rest. Again, note that USB NICs need that miibus entry we saw earlier. Also, some entries require device scbus and device da. Double-check your SCSI sections. If you removed these devices earlier and need them, add them to this section.

device        ukbd        # Keyboard

device        ulpt        # Printer

device        umass       # Disks/Mass storage - Requires scbus and da

device        ums         # Mouse

device        urio        # Diamond Rio 500 MP3 player

device        uscanner    # Scanners

# USB Ethernet, requires mii

device        aue        # ADMtek USB ethernet

device        axe        # ASIX Electronics USB ethernet

device        cue        # CATC USB ethernet

device        kue        # Kawasaki LSI USB ethernet

Finally, the only option group left is Firewire support. If you need it, keep the entire section, and double-check that you have a device scbus and device da entry somewhere in your configuration file. If you don't need Firewire support, remove the entire section:

# FireWire support

device        firewire   # FireWire bus code

device        sbp        # SCSI over FireWire (Requires scbus and da)

device        fwe        # Ethernet over FireWire (non-standard!)

Whew. We finally made it through the configuration file. Congratulations! You now have a much better idea of the hardware on your system and can rest easily in the knowledge that soon no extra drivers will be wasting memory resources. Not only that, your next kernel configuration will go much more quickly as you've already researched the possibilities.

2 Building the New Kernel

Now comes the moment of truth. Will the configuration file actually build? To find out:

# cd /usr/src

# make buildkernel KERNCONF=

STRIPPED

Replace STRIPPED with whatever name you called your kernel configuration file. If all goes well, you should just get your prompt back after a period of time, which varies depending upon the speed of your CPU. If you instead get an error message, you probably forgot miibus, scbus, or da, and the message will reflect that. Add the missing line and try again.

Occasionally you'll get a kernel that just refuses to build, even when you're sure the configuration file is fine. If that's the case, try building GENERIC. If that fails, you have a hardware issue.

I once inherited a system with a flaky motherboard. I tried a few kernel compiles, which took forever before finally resulting in an error code 1. Fortunately, I use removable drives, so I simply inserted the drive into another system, successfully compiled the kernel, and then returned the drive to the flaky system for the actual kernel install.

3 Keeping Track of Your Options

Once I have a successful build, I like to document what I removed from the original kernel. This is easily done:

# echo "These are the lines I deleted" > changes.txt \

    & diff GENERIC STRIPPED >> changes.txt

The diff utility will list the differences between the original and my version of the kernel configuration file. Note that I used >> to append those differences without removing my previously echoed comment. See [Hack #92] for more examples that use diff.

Before installing the kernel, read through NOTES to see if there are any lines you wish to add. Additionally, if you wish to take advantage of memory addresses over 4 GB, carefully read through PAE and its section in the handbook to see if it is appropriate for your situation.

If you add any lines, repeat the make buildkernel command when you are finished. I also like to append my additions to my changes.txt file:

# echo "And these are the lines I added" >> changes.txt \

    & diff GENERIC STRIPPED >> changes.txt

Note that this time it is very important I remember to append both my comment and the output of diff by using two > characters.

4 Installing the New Kernel

Now, let's install the kernel:

# cd /usr/src

# make installkernel KERNCONF=STRIPPED

This process is much quicker than building the kernel. However, the kernel won't actually be loaded into memory until you reboot. Before you do that, it's always a good idea to print out the "If Something Goes Wrong" page of the FreeBSD Handbook, just in case something goes wrong. See http://www.freebsd.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-trouble.html#KERNELCONFIG-NOBOOT.

It's rare that a kernel will install but not boot, but it never hurts to be prepared ahead of time.

5 See Also


     Python   SQL   Java   php   Perl 
     game development   web development   internet   *nix   graphics   hardware 
     telecommunications   C++ 
     Flash   Active Directory   Windows