Using LIDS with your Mandrake Linux kernel
Revision/Modified: Jan 11, 2002
Author: Vincent Danen		
The Mandrake Linux 2.4 kernel contains the FreeS/WAN security enhancements, but not much else. The 2.2 kernel contains the OpenWall security patches from Solar Designer, but there is no OpenWall security patch for the 2.4 kernels (yet). There are a few choices, however, if you're up to compiling your own kernel. We will take a look at one of these choices today: LIDS.
LIDS stands for the Linux Intrusion Detection System and it is a kernel patch and administrative tool to provide a security-enhanced Linux kernel. As of this writing, the current version of LIDS is 1.1.1pre2 for the 2.4.16 Linux kernel; it was released on January 9th, 2002.
Unfortunately, there are some incompatibilities between the numerous Mandrake patches that are applied to the Linux kernel, and the patch provided on the LIDS website. I have re-generated the parts of the patch that were being rejected and a new LIDS 1.1.1pre2-2.4.16 patch is available in the lids rpm package, which also contains the LIDS administrative tools:
•	unsupported/8.1/i586/lids/lids-1.1.1pre2-1mdk.i586.rpm 
•	unsupported/8.1/ppc/lids/lids-1.1.1pre2-1mdk.ppc.rpm 
•	unsupported/8.1/i586/lids/lids-1.1.1pre2-1mdk.src.rpm 
Note that these files are available on our FTP mirror sites in the unsupported/ directory.
Building a LIDS kernel will require you to recompile your kernel. It has not yet been decided if the LIDS system will become a base part of the Mandrake Linux distribution or not. In the meantime, with a little effort on your part, you can have a LIDS-enhanced Mandrake Linux system in no time.
The first step is to ensure that you are able to compile your kernel. You will need the appropriate tools (like gcc, make, etc.) installed on your system. You will also need the kernel-source RPM package installed. Currently, 2.4.16 is in cooker, but it is also available here since cooker currently contains 2.4.17.
•	unsupported/8.1/i586/lids/kernel-source-2.4.16.11mdk-1-1mdk.i586.rpm 
•	unsupported/8.1/ppc/lids//kernel-source-2.4.16.6mdk-1-1mdk.ppc.rpm 
Once you have installed the kernel-source package, install the lids userspace package. This will provide you with the LIDS administrative tools. It also provides the required patch.
Compiling the LIDS kernel
The first step is to apply the LIDS kernel patch, which is located in /usr/src/lids-1.1.1pre2/ as the file lids-1.1.1pre2-2.4.16-11mdk.patch for x86 and lids-1.1.1pre2-2.4.16-6mdk.patch for PPC. Before applying the patch, it is recommended to copy the source directory to another directory first, like this:
[root@linux]# cd /usr/src
[root@linux]# cp -a linux-2.4.16-11mdk linux-2.4.16-11mdklids
To apply the patch, execute the following:
[root@linux]# cd /usr/src/linux-2.4.16-11mdklids
[root@linux]# patch -p1 <../lids-1.1.1pre2/lids-1.1.1pre2-2.4.16-11mdk.patch
These steps are identical for the PPC version, just replace -11mdk with -6mdk.
You will likely need to skip a number of patches for missing configuration files in the arch/[platform]/ directories, such as support for Motorola kernels, alpha, SPARC, PPC, etc. hardware. These were kept in the patch for those who wish to use LIDS on IA64, PPC, SPARC, alpha, or other platforms. Simply press enter when asked about a non-existing file to patch. Once the patch is applied, double-check the output from patch to make sure there were no failures. An easy way to see if there were any rejected patches is to use:
[root@linux]# find . -name *.rej
If find returns nothing, you're ready to go. If it does return any files (like, for example, include/linux/version.h.rej) you are either not using the 2.4.16-11mdk or 2.4.16-6mdk (PPC) kernels or you have applied/removed some other patches.
Once you have verified the patch applied clean , you will need to configure LIDS support in the kernel and compile it. The first step is to execute:
[root@linux]# make clean
[root@linux]# make distclean
[root@linux]# make mrproper
[root@linux]# cp ../lids-1.1.1pre2/config-2.4.16-11mdklids .config     
[root@linux]# make xconfig
You can also use make menuconfig or make config here if you prefer, but make xconfig will give you a GUI interface like that shown below:

As you can see, on the far right column there is an entry for Intrusion Detection System. Click here to configure LIDS and you will see something like this:

There are a number of default options. If you used the config-2.4.16-11mdklids file from the lids rpm package (located in /usr/src/lids-1.1.1pre2/, you will have the recommended default settings, but feel free to change them to suit your needs. Clicking on the Help button will describe each configurable setting. Feel free to browse the settings and enable or disable those options you wish. For a basic LIDS system, the selected defaults are adequate.
Once you have set the options you want for LIDS, save and exit the configuration program. Even if you do not change any options, be sure that you select "Save and Exit" instead of "Quit Without Saving" as without saving your configuration (even unchanged) will prevent make dep from working properly. Now you must build the kernel itself, by executing:
[root@linux]# make dep
[root@linux]# make clean
[root@linux]# make bzImage
[root@linux]# make modules
[root@linux]# make modules_install
[root@linux]# make install
Note that PPC users should use make vmlinux and not make bzImage. PPC users also cannot use make install for some reason, so the following steps need to be taken instead:
[root@linux]# cd /usr/src/linux-2.4.16-6mdk
[root@linux]# installkernel 2.4.16-6mdklids vmlinux System.map
[root@linux]# chmod a+x /boot/vmlinuz-2.4.16-6mdklids
[root@linux]# mkinitrd /boot/initrd-2.4.16-6mdklids.img 2.4.16-6mdklids
This process can take anywhere from 30 minutes to a few hours, depending on the speed of your system. The resulting kernel will be called kernel-2.4.16-11mdklids, with the modules in /lib/modules/2.4.16-11mdklids/.
With Mandrake Linux 8.1/ix86, and possibly previous versions, the make install command will automatically generate your initrd and move your kernel into /boot, as well as try to run lilo automatically. This may fail in certain places, depending on your setup. It will try to add an entry for your new kernel into your /etc/lilo.conf as well.
You should have in your /boot directory a few new files: config-2.4.16-11mdklids, initrd-2.4.16-11mdklids.img, System.map-2.4.16-11mdklids, and vmlinuz-2.4.16-11mdklids. Verify that each of these files are present. For PPC users, these will be -6mdk version files. Depending on your system, you may not need an initrd file (ie. if you do not use reiserfs, XFS, ext3, etc. on your / partition, do not boot off of SCSI devices, etc.).
An entry like the following should be in your /etc/lilo.conf file for your LIDS-enhanced kernel:
image=/boot/vmlinuz-2.4.16-11mdklids
	label=246-11lids
	root=/dev/hde1
	read-only
	optional
	vga=788
	append=" hda=ide-scsi devfs=mount"
	initrd=/boot/initrd-2.4.16-11mdklids.img
If you are using grub, you will need to edit /boot/grub/menu.lst instead, with something like this:
title lids
kernel (hd0,0)/boot/vmlinuz-2.4.16-11mdklids root=/dev/hde1  hda=ide-scsi devfs=mount
initrd (hd0,0)/boot/initrd-2.4.16-11mdklids.img
PPC users will be using yaboot instead. Your /etc/yaboot.conf file should look something like this (note that due to a lack of a make install you must add this code yourself):
image=hd:12,/boot/vmlinuz-2.4.16-6mdklids
	label=2416-6lids
	root=/dev/hda12
	initrd=hd:12,/boot/initrd-2.4.16-6mdklids
	append=" hdb=ide-scsi"
	read-only
If make install did not create an initrd file for you and you require one, you will need to execute the following. PPC users will have to substitute -11mdk with -6mdk:
[root@linux]# mkinitrd /boot/initrd-2.4.16-11mdklids.img 2.4.16-11mdklids
Finally you will be able to re-generate your boot record using:
[root@linux]# /sbin/lilo -v
or:
[root@linux]# sh /boot/grub/install.sh
PPC users will have to use:
[root@linux]# /sbin/ybin -v
Of course, change the above entries to suit your particular system environment (paths and root devices, etc.).
Once you have done this, you are almost ready to reboot your system into your new LIDS-enhanced kernel. The next step is to run the lidsconf program to generate a LIDS password:
[root@linux]# lidsconf -P
This is the master password for LIDS configuration. Keep this password safe and don't forget it! Next you can edit /etc/lids/lids.cap to enable or disable any capabilities you want on your LIDS system. The file is heavily commented and you should go through the entire file. The lids RPM package installs /etc/lids/lids.cap with a reasonable set of defaults that are not too restrictive, so if you want more system security, you will want to edit the file and make changes. If you're new to LIDS and don't have a comprehensive set of ACLs for your system, these defaults should be fine.
Next, if you have enabled CONFIG_LIDS_SA_THROUGH_NET in the kernel, you will want to edit the /etc/lids/lids.net file. This file is likewise heavily commented and is very easy to configure. You simply configure whether or not to enable the mail alert function by setting MAIL_SWITCH (set it to 1 to enable, 0 to disable). Then configure your MAIL_RELAY (IP address and port for the SMTP server to send the message through), and the source name of the system in MAIL_SOURCE. The rest is very self-explanatory.
The next step is to configure the LIDS ruleset with the lidsconf utility. Use lidsconf -h to obtain help on how to use the tool. In /usr/share/doc/lids-1.1.1pre2/FAQ is the LIDS FAQ which will also help you understand how to use lidsconf more. Unfortunately, the LIDS FAQ is a little dated and indicates that lidsadm is used to set ACLs whereas lidsconf is actually used for this (and the FAQ doesn't mention lidsconf at all).
The lidsconf program uses a syntax similar to ipchains. This is a list of the available options:
•	-A, --add: Add an entry 
•	-D, --delete: Deletes an entry 
•	-Z, --zero: Deletes all entries 
•	-U, --update: Update the device/inode numbers of all files 
•	-L, --list: List all existing rules 
•	-P, --passwd: Create/update the LIDS password 
•	-s, --subject: Any program (must be a file) 
•	-o, --object: Any file, directory, or special device 
•	-j, --jump: Specifies a rule to jump to (target), can be: 
o	DENY: deny access 
o	READONLY: read-only access 
o	APPEND: append-only access 
o	WRITE: write access 
o	GRANT: grant capability to subject 
o	IGNORE: ignore any permissions set on this object 
Let's look at a very basic example: 
# Protect system binaries
/sbin/lidsconf -A -o /sbin -j READONLY
/sbin/lidsconf -A -o /bin -j READONLY

# Protect all of /usr and /usr/local
/sbin/lidsconf -A -o /usr -j READONLY
/sbin/lidsconf -A -o /usr/local -j READONLY

# Protect system libraries (/usr/lib is caught above)
/sbin/lidsconf -A -o /lib -j READONLY

# Protect configuration files
/sbin/lidsconf -A -o /etc -j READONLY
/sbin/lidsconf -A -o /etc/shadow -j DENY
/sbin/lidsconf -A -o /etc/lilo.conf -j DENY

# Enable system authentication
/sbin/lidsconf -A -s /bin/login -o /etc/shadow -j READONLY
/sbin/lidsconf -A -s /usr/bin/vlock -o /etc/shadow -j READONLY
/sbin/lidsconf -A -s /bin/su -o /etc/shadow -j READONLY
/sbin/lidsconf -A -s /bin/su -o CAP_SETUID -j GRANT
/sbin/lidsconf -A -s /bin/su -o CAP_SETGID -j GRANT

# Protect /boot
/sbin/lidsconf -A -o /boot -j READONLY

# Protect root's homedir, but allow bash history
/sbin/lidsconf -A -o /root -j READONLY
/sbin/lidsconf -A -s /bin/bash -o /root/.bash_history -j WRITE

# Protect system logs
/sbin/lidsconf -A -o /var/log -j APPEND
/sbin/lidsconf -A -s /bin/login -o /var/log/wtmp -j WRITE
/sbin/lidsconf -A -s /bin/login -o /var/log/lastlog -j WRITE
/sbin/lidsconf -A -s /sbin/init -o /var/log/wtmp -j WRITE
/sbin/lidsconf -A -s /sbin/init -o /var/log/lastlog -j WRITE
/sbin/lidsconf -A -s /sbin/halt -o /var/log/wtmp -j WRITE
/sbin/lidsconf -A -s /sbin/halt -o /var/log/lastlog -j WRITE
/sbin/lidsconf -A -s /etc/rc.d/rc.sysinit -o /var/log/wtmp -i 1 -j WRITE
/sbin/lidsconf -A -s /etc/rc.d/rc.sysinit -o /var/log/lastlog -i 1 -j WRITE

# Startup
/sbin/lidsconf -A -s /sbin/hwclock -o /etc/adjtime -j WRITE

# Shutdown
/sbin/lidsconf -A -s /sbin/init -o CAP_INIT_KILL -j GRANT
/sbin/lidsconf -A -s /sbin/init -o CAP_KILL -j GRANT

# Grant halt the privilege to kill processes and unmount file systems
/sbin/lidsconf -A -s /etc/rc.d/init.d/halt -o CAP_INIT_KILL -i 1 -j GRANT
/sbin/lidsconf -A -s /etc/rc.d/init.d/halt -o CAP_KILL -i 1 -j GRANT
/sbin/lidsconf -A -s /etc/rc.d/init.d/halt -o CAP_NET_ADMIN -i 1 -j GRANT
/sbin/lidsconf -A -s /etc/rc.d/init.d/halt -o CAP_SYS_ADMIN -i 1 -j GRANT
This is, of course, just for starters. =) You will notice that we did not choose to be quite this restrictive with the Mandrake-recommended ACLs (which are enabled by executing the /etc/lids/initlidsmdk.sh script). You can go hog wild setting all kind of ACLs on your system now, to protect things like Apache, qmail, bind, openssh, etc. In fact, you can use LIDS to further secure every running server on your system. The LIDS FAQ contains examples of many servers in section 7 with illustrations on how to use LIDS to protect them. Just be sure that where the FAQ mentions lidsadm, you use lidsconf instead.
To use the recommended defaults (for beginners to LIDS who want protection but not with too many restrictions), you should run the /etc/lids/initlidsmdk.sh script. This will set some basic ACLs for you:
•	Makes /sbin, /bin, /usr/bin, /usr/sbin, /usr/lib, /lib, and /boot readonly 
•	Makes /root readonly except for /root/.bash_history 
•	Allows devfsd to write to /lib/dev-state 
•	Allows hwclock to sync the clock on shutdown 
•	Denies all access to /etc/lids 
Because of this, if you plan to update RPM packages on your system, you will need to either disable LIDS globally while you do the update, or do it manually in an LFS (see below). Likewise if you build a new kernel, new modules, etc.
The file /etc/lids/lids.conf contains all of the rules that LIDS will read. Each time you run lidsconf and add or delete a rule, it will be added or remove from this file. This file must not be edited by hand! You can cause serious problems doing this.
The final step is to edit /etc/rc.d/rc.local and at the very end of the file place:
# enable LIDS kernel sealing
/sbin/lidsadm -I
This will "seal" the kernel after everything has booted and before logins are permitted. Sealing the kernel is what activates LIDS and all of it's settings.
Now you are able to reboot your system into your LIDS kernel. If something goes wrong and you need to boot without LIDS enabled, you can do so by passing "lids=0" at the boot prompt, or booting into your old non-LIDS kernel.
Using LIDS
Using LIDS can be both helpful and detrimental to your system. By this I mean that LIDS is so powerful that it can prevent things from working if you do not configure it correctly. To this end, you should start with a minimalistic LIDS approach before fine-tuning the ACLs on the system.
There are a few LIDS commands you should be aware of. The first is to create a LIDS-Free Session (LFS). The LFS is required for re-configuring LIDS, updating the configuration, etc. It will help you customize and fine-tune your system. To start an LFS, you must have one of the following enabled in your kernel: CONFIG_LIDS_MODE_SWITCH_CONSOLE, CONFIG_LIDS_MODE_SWITCH_SERIAL, or CONFIG_LIDS_MODE_SWITCH_PTY. For complete and comprehensive security, you will want none of these enabled, but this prevents you from creating an LFS, which is a bad idea if you're just starting out with LIDS and experimenting a little bit. If you have _CONSOLE enabled, you will only be able to start an LFS from a virtual console (no xterms). If you enable _PTY, you can create an LFS in pretty much any terminal (xterm, remote (ie. ssh), etc.).
So go to a console or other terminal that will allow you to create an LFS and execute:
[root@linux]# lidsadm -S -- -LIDS
Now, in the current console (and only the current console) you can work without any LIDS restrictions. To exit the LFS, you can either logout of the terminal or use:
[root@linux]# lidsadm -S -- +LIDS
When you're in the LFS, you can do a number of things such as resetting your password, updating the config, reloading the configuration, etc. To reload your configuration, use:
[root@linux]# lidsadm -S -- +RELOAD_CONF
To reset your password, use:
[root@linux]# lidsconf -P
[root@linux]# lidsadm -S -- +RELOAD_CONF
Notice that when you reset the password it does not ask for your old password. Since you can only do this in an LFS (or with LIDS disabled), the assumption is you must know the password before you can change it because you have either a) booted into a non-LIDS kernel or b) started an LFS. Now, to disable LIDS entirely (if it's causing too many errors or problems with your applications, or your config is seriously wrong), you can use:
[root@linux]# lidsadm -S -- -LIDS_GLOBAL
To re-start LIDS, use +LIDS_GLOBAL. Finally, to update the configuration (for inode and device information), you must use:
[root@linux]# lidsconf -U
You should do this after you update system files or binaries so that LIDS has all of the correct information on files and devices. You should also do this prior to your first reboot.
Now that you know some of the administrative commands to use LIDS, let's take a look at how to configure it. As stated before, LIDS can be quite intrusive, but this is a good thing. This means that it can be used to really lock down servers and really make things difficult for attackers, if not impossible. However, to start you will likely want something a little easier to use. The first step is to set system-wide capabilities, and this is done in /etc/lids/lids.cap. This file is heavily commented for each entry. The entries starting with a "+" means the capability is globally allowed, while those prefixed with a "-" means the capability is globally denied; you will need to use rules to enable those capabilities for applications that require them.
To keep things as un-intrusive as possible, by default we only enable four capabilities: CAP_LINUX_IMMUTABLE, CAP_SYS_CHROOT, CAP_SYS_PTRACE, and CAP_SYS_TIME. The first disallows modification of S_IMMUTABLE and S_APPEND file attributes; the second disallows the use of chroot(); the third disallows the use of ptrace() of any process; the last disallows manipulation of the system clock and the setting of the real-time clock.
Ideally, you would also want CAP_SYS_ADMIN, CAP_SYS_RAWIO, CAP_SYS_MODULE, CAP_NET_RAW, CAP_NET_ADMIN, and CAP_NET_BIND_INTERFACE disallowed as well. However, to do this, you need to write a comprehensive set of ACLs. For instance, many programs, like /sbin/init or /sbin/mount require CAP_SYS_ADMIN, the X server requires CAP_SYS_RAWIO, autofs requires CAP_SYS_MODULE, ping and iplog require CAP_NET_RAW, and all services binding to a port below 1024 required CAP_NET_BIND_INTERFACE if you need to restart the service while LIDS is running. Because of this, when you first start out, keeping them enabled will keep your system running while you determine and write the ACLs you need to handle your processes and services.
I will be working on a comprehensive script to setup a more restrictive set of ACLs for a server system (to do this on a workstation or desktop system would be an act of lunacy, I think). I also think that LIDS has it's place on the desktop/workstation systems with a simple set of enabled ACLs like those we set by default, but where LIDS will really shine is on the server. By restricting a lot of capabilities globally, you can ensure that the server runs in a very strict and controlled environment. You can control the behavior of your servers using LIDS, and the whole system environment.
For more information on using LIDS itself, you can subscribe to the lids-user mailing list or view some of the below resources:
•	LIDS homepage 
•	LIDS HOWTO 
•	SecurityFocus: An Overview of LIDS, Part One 
•	SecurityFocus: An Overview of LIDS, Part Two 
•	SecurityFocus: An Overview of LIDS, Part Three 
•	SecurityFocus: An Overview of LIDS, Part Four 
As a final note, I've used this procedure on an 8.1/x86 box and it works great. There were a few issues with it on 8.0/ppc but I'm not entirely sure what the problem is. On the imac Indigo system I used, the framebuffer seemed not to work properly and the Xpmac server came up black and white with horrible rendering. However, I think this may be a problem with the 2.4.16 kernel and not with LIDS specifically as the kernel boots and shuts down just fine with LIDS enabled. I have not yet tried it on an 8.0 box.
The other thing to keep in mind is you can always grab a vanilla 2.4.16 kernel, apply the LIDS patch and build it, and use that instead of the Mandrake-supplied 2.4.16 kernel. You will have to do a little work to include some patches for support for things like ReiserFS or XFS (if you use them), but that might be the route to take if you intend to use LIDS on an older pre-8.x Mandrake distribution.
Finally, please note that LIDS is probably not the best security solution for workstations. It takes quite a bit of work to provide a set of comprehensive ACLs on a workstation system where many different programs can be running at any given time. LIDS works best in a server situation where the programs running are all pre-determined (ie. you have your web server, mail server, etc.). This will allow you to write a fine-grained set of ACLs to use without worrying about unknown applications running (in fact, this is the idea; LIDS will prevent unknown programs from affecting the system unless you specifically permit it). To that end, I do not recommend using LIDS on a desktop or workstation system, but would generally reserve it for a server system.
For an example set of comprehensive LIDS ACLs, take a look at the below link. It is a work-in-progress and additions or corrections are more than welcome. It is, however, tuned for a server system and not a desktop system.
•	mdklids.sh (CVS info: 1.2 2002/01/12 19:56:35 )