selinux

Towards a moderately paranoid Debian laptop setup [Update]

I was planning to set up my laptop from scratch for a while now... so I did.

Preparation

  • First, go home. No, really! Do all of this at home in a non-hostile, firewalled network. You don't want to be in a crowded place such as a conference where people can shoulder-surf your passwords, nor do you want your network traffic sniffed or MITM'd in a hostile network.
  • Backup all your data! You'll be wiping your whole drive soon, so make sure you have recent, tested backups.
  • Get the most recent Debian-installer ISO image (currently etch-beta3), as well as the MD5SUMS and MD5SUMS.sign files:
    wget http://cdimage.debian.org/cdimage/etch_di_beta3/i386/iso-cd/debian-testing-i386-binary-1.iso
    wget http://cdimage.debian.org/cdimage/etch_di_beta3/i386/iso-cd/MD5SUMS
    wget http://cdimage.debian.org/cdimage/etch_di_beta3/i386/iso-cd/MD5SUMS.sign
  • Run gpg --verify MD5SUMS.sign, which will fail but tell you the signing key ID (88C7C1F7 in this case). Get the key and re-run the verification: gpg --recv-key --keyserver subkeys.pgp.net 88C7C1F7 && gpg --verify MD5SUMS.sign. The output should now say "Good signature from [...]".
  • Now check the MD5 checksums via md5sum -c MD5SUMS. The output should contain debian-testing-i386-binary-1.iso: OK.
  • As you now have (somewhat) verified the integrity of the ISO image, burn it on a CD-R: wodim debian-testing-i386-binary-1.iso.
  • Put trusted versions of some files on a USB thumb drive (or CD-ROM); at least a firewall script, but maybe also your bashrc, bash_logout, inputrc, vimrc, muttrc.
  • Disconnect your laptop from any kinds of networks. Pull all ethernet cables. Disable WLAN (via hardware killswitch). Disable Bluetooth. Disable/remove Firewire, USB, serial, whatever.
  • Put on your tin-foil hat (optional).

BIOS

  • Set a good BIOS boot password (which you need to boot any OS). Set a (different) good BIOS boot setup password (which you need to enter the BIOS).
  • Disable all boot possibilities in the BIOS, except for CD-ROM. This means it should not be possible to boot via USB, hard drive, network, PXE, Firewire, floppy, whatever. The BIOS setup password helps to prevent tampering with this setting.
  • Finally, never rely on BIOS passwords alone for security! They can often be circumvented very easily.

Installation / Setting up full-disk encryption using dm-crypt

  • Insert the installer CD and boot in expert-mode (don't hit ENTER when you boot, but rather type "expert").
  • As for networking: select "Do not configure the network at this time". We'll fix and enable networking later.
  • Partitioning:

    • Select manual partitioning. Remove all partitions (if any). Create a 100 MB /boot (ext3) as primary partition, and make the rest of the hard drive one huge partition which has "Use as:" set to "physical volume for encryption".
    • The standard options for cipher, key size, IV mode etc. should be fine (AES, 256 bit, CBC-ESSIV-SHA256, dm-crypt).
    • After the erasing is done (this is important!), use the whole encrypted space as "physical volume for LVM". Then select "Configure the Logical Volume Manager". Create one big volume group and a bunch of logical volumes for the various partitions we'll use (lv-root, lv-usr, lv-var, lv-tmp, lv-swap, lv-home).
    • It is extremely important that your swap space is encrypted (in this case it is, as all partitions except for /boot reside on a dm-crypt device)! Never set up unencrypted swap!
  • Enable shadow passwords. Allow login as root (I feel confident that I won't do stupid things as root).
  • Choose a good root password, and a (different) good user password. Don't enter a full name for the user.
  • Choose the latest kernel (old kernels might have security issues). Do not participate in popcon.
  • Do not install any tasks (no "desktop", no "base system"). We want the smallest installation possible, and add only the packages we really need. Fewer packages means fewer security issues (statistically).
  • That's it. Eject the CD-ROM, reboot, change the BIOS to only allow booting from hard drive.

Post-installation tasks

  • Enter the USB thumb drive, copy all config-files to /root and /home/uwe. Log out and log in again to make ~/.bashrc and ~/.inputrc take effect.
  • Enable the firewall: mkdir /etc/rc.boot && cp fw_laptop /etc/rc.boot && chmod 700 /etc/rc.boot/fw_laptop && sh /etc/rc.boot/fw_laptop
  • Shut down all networked daemons (if any): /etc/init.d/foo stop.
  • Tighten home-directory permissions: chmod 700 /root /home/uwe.
  • Edit /etc/passwd: give all users except for root, sync, uucp and your user account /usr/sbin/nologin as login shell. None of these accounts really needs a valid login shell (nologin will log any login attempts for those accounts).
  • Edit /etc/group: remove your user account from the dialout, cdrom, and floppy group. The groups audio, video, and plugdev can stay.
  • Edit /etc/fstab: add some mount options such as ro, nosuid, noexec, or nodev as you see fit. Example:
    /dev/mapper/vg--whole-lv--root /     ext3 defaults,errors=remount-ro      0 0
    /dev/sda2                      /boot ext3 defaults,nodev,nosuid,noexec,ro 0 0
    /dev/mapper/vg--whole-lv--home /home ext3 defaults,nodev,nosuid           0 0
    /dev/mapper/vg--whole-lv--tmp  /tmp  ext3 defaults,nodev,nosuid           0 0
    /dev/mapper/vg--whole-lv--usr  /usr  ext3 defaults,nodev,ro               0 0
    /dev/mapper/vg--whole-lv--var  /var  ext3 defaults,nodev                  0 0
    /dev/mapper/vg--whole-lv--swap none  swap sw                              0 0
    /dev/scd0 /media/cdrom iso9660 noauto,nodev,nosuid,noexec,uid=uwe,gid=uwe 0 0
    
  • If you have read-only (ro) file systems, configure Apt so that it can remount them read-write when installing/removing packages. Add this to /etc/apt/apt.conf:
    DPkg
    {
      Pre-Invoke { "mount -o remount,rw /usr; mount -o remount,rw /boot"; }
      Post-Invoke { "mount -o remount,ro /usr; mount -o remount,ro /boot"; }
    }
    
  • Fix the GRUB configuration. Replace the "password foo" line (which contains the GRUB password in plain-text) from your /boot/grub/menu.lst with a "password --md5 $1$1234567890..." line, where the MD5 hash ($1$1234567890...) can be generated with grub-md5-crypt. Additionally, add such a password line after each "title" line in the GRUB config-file, so that nobody can boot any OS installed on the laptop without a password!

Networking, Upgrading and Apt-secure

  • Now that we have a small, hardened system, it should be reasonably safe to enable networking. Add this to /etc/network/interfaces:
    auto eth0
    iface eth0 inet dhcp
      pre-up /etc/rc.boot/fw_laptop
    

    Run /etc/init.d/networking restart. The firewall script will run every time the network is started.

  • Now add this (tweak as you see fit) to /etc/apt/sources.list:
    deb http://ftp.de.debian.org/debian unstable main
    deb-src http://ftp.de.debian.org/debian unstable main
  • Time for upgrading: apt-get update && apt-get dist-upgrade. All packages are GnuPG-signed and will be verified by Apt. The installer already ships the required key (for 2006), so everything should just work. Still, you should read about SecureApt.
  • Install the rest of your system now, and restore your data from backups.
  • Use sysv-rc-conf to disable all daemons you don't want to start per default: sysv-rc-conf foo off.
  • Install and set up Samhain (or any other file integrity checker): apt-get install samhain. You want to be notified if your system files are being tampered with (e.g. replaced by a rootkit).
  • Install and configure Tor for anonymous browsing. More details here.
  • Install and configure more security-related programs, e.g. logcheck, snort, rkhunter, chkrootkit, tiger, sxid, etc.

SELinux

Now install and set up SELinux. This section is based on notes from Erich Schubert (thanks!), and will soon appear in the SELinuxSetup wiki page, too.

  • Install the base packages and an SELinux policy: apt-get install selinux-basics selinux-policy-refpolicy-targeted.
  • Edit /boot/grub/menu.lst and add selinux=1 to your kernel command line to enable SELinux upon booting.
  • In /etc/pam.d/login uncomment the "session required pam_selinux.so multiple" line. Do the same in /etc/pam.d/ssh if you have ssh installed.
  • In /etc/default/rcS set FSCKFIX=yes.
  • In /etc/init.d/bootmisc.sh search for "Update motd" and comment the two lines below that line. Then rm /var/run/motd.
  • If you have exim installed, you must either install postfix or write an exim policy, as none currently exists. But even postfix needs some fixing (no pun intended ;-). Disable chroot-support (change all "chroot" fields to "n" in /etc/postfix/master.cf and execute echo 'SYNC_CHROOT="n" >> /etc/default/postfix').
  • Use check-selinux-installation to check for common SELinux problems on Debian (such as the above mentioned).
  • touch /.autorelabel. Reboot. touch /.autorelabel (again). Reboot (again).
  • Done. You should now have a working SELinux system. If no critical audit errors appear and you feel comfortable with SELinux, enable enforcing mode via setenforce 1 or by adding enforcing=1 to the kernel command line in /boot/grub/menu.lst.

Behaviour

  • Never leave your laptop unattended!
  • Always lock your terminal (using vlock) when you move more than 30 cm away from the laptop!
  • Don't run insecure and/or closed-source software (which you can never trust!). No NVIDIA/ATI drivers, no VMware, no Google Earth, no Flash Plugin (except for Gnash maybe), no Adobe Acrobat. You get the idea.
  • Keep the number of installed packages small and try to configure each of them as secure as possible.
  • Never enable networking or WLAN or Bluetooth if you don't absolutely have to.
  • Trust no one. Don't let other people use you laptop, don't give out shell accounts.

Further ideas

  • The /boot partition is still unencrypted, so an attacker can tamper with it. Boot from a CD-R, forbid booting from hard drive (BIOS). Sign/mark the CD-R physically, so you'll know when someone replaced your CD-R with his own, back-doored one.
  • Another idea is to use an additionaly USB thumb drive or CD-ROM or smartcard for two-factor authentication.
  • Install another Debian into a QEMU image. Use it as a sandbox for stuff you don't trust: qemu -snapshot -net none foo.img.
  • At all costs, disable Firewire! If possible via hardware or BIOS, or at least don't load the drivers and/or fix them (page 19).
  • Replace the proprietary, closed-source BIOS with LinuxBIOS, if possible.

That's it. You can take off that stupid tin-foil hat now.

Update 2006-09-29: Fixed typos. Mentioned sxid. Added two-factor authentication.

SELinux by Example - Using Security Enhanced Linux

SELinux by Example

Recently in my (physical) mailbox: SELinux by Example by Frank Mayer, Karl MacMillan, David Caplan. The most recent and up-to-date book about SELinux I know about, written by some of the most involved and knowledgeable people in the field.

From what I've read until now it seems to be a really in-depth and easy to understand introduction, and what's more important, it covers the practical aspects of how you use, configure, and administer SELinux in real deployed systems.

This should make an interesting read...

Benchmarking an encrypted dm-crypt/LVM/ext3/SELinux hard drive with bonnie++ and hdparm

I'm going to set up a new laptop system soonish (more on that later) which shall have a completely encrypted hard drive. Hence, I'm testing a few setups wrt security, performance, manageability and fault-tolerance.

Here's a few performance tests I did on an 80 GB laptop hard drive (in an Intel Celeron based laptop, 1.7 GHz, 256 MB RAM, Linux 2.6.17, Debian unstable).
I ran bonnie++ (with no options) and hdparm as hdparm -tT /dev/hda each time. I haven't put too much thought into the test setup, so if I made some stupid mistakes, please let me know.

Unencrypted plain ext3 partitions:

  • Extra partitions for /, /boot, /usr, /var, /tmp, /home, and swap (no LVM).
  • Optionally, SELinux enabled on that system (targeted policy in permissive mode).

bonnie++:

Version  1.03       ------Sequential Output------ --Sequential Input- --Random-
                    -Per Chr- --Block-- -Rewrite- -Per Chr- --Block-- --Seeks--
Machine        Size K/sec %CP K/sec %CP K/sec %CP K/sec %CP K/sec %CP  /sec %CP
forest         432M 19857  84 21831  10  9536   4 16355  58 22165   3 148.8   0
                    ------Sequential Create------ --------Random Create--------
                    -Create-- --Read--- -Delete-- -Create-- --Read--- -Delete--
              files  /sec %CP  /sec %CP  /sec %CP  /sec %CP  /sec %CP  /sec %CP
                 16  1650  98 +++++ +++ +++++ +++  1734  98 +++++ +++  3820  96
forest,432M,19857,84,21831,10,9536,4,16355,58,22165,3,148.8,0,16,1650,98,+++++,
+++,+++++,+++,1734,98,+++++,+++,3820,96

bonnie++ with SELinux:

Version  1.03       ------Sequential Output------ --Sequential Input- --Random-
                    -Per Chr- --Block-- -Rewrite- -Per Chr- --Block-- --Seeks--
Machine        Size K/sec %CP K/sec %CP K/sec %CP K/sec %CP K/sec %CP  /sec %CP
forest         432M 20321  90 21036  13  9473   5 16742  61 21978   4 148.1   0
                    ------Sequential Create------ --------Random Create--------
                    -Create-- --Read--- -Delete-- -Create-- --Read--- -Delete--
              files  /sec %CP  /sec %CP  /sec %CP  /sec %CP  /sec %CP  /sec %CP
                 16  1398  98 +++++ +++ +++++ +++  1473  98 +++++ +++  3305  98
forest,432M,20321,90,21036,13,9473,5,16742,61,21978,4,148.1,0,16,1398,98,+++++,
+++,+++++,+++,1473,98,+++++,+++,3305,98

hdparm:

 Timing cached reads:   1416 MB in  2.00 seconds = 707.48 MB/sec
 Timing buffered disk reads:   82 MB in  3.06 seconds =  26.80 MB/sec

hdparm with SELinux:

 Timing cached reads:   1404 MB in  2.00 seconds = 700.59 MB/sec
 Timing buffered disk reads:   80 MB in  3.02 seconds =  26.53 MB/sec

Ext3 partitions on top of LVM on top of dm-crypt:

  • One partition which is encrypted using dm-crypt (aes-cbc-essiv:sha256 mode, AES, 256 bit key size)
  • On top of that an LVM2 system, with extra partitions for /, /boot, /usr, /var, /tmp, /home, and swap.
  • Optionally, SELinux enabled on that system (targeted policy in permissive mode).

bonnie++:

Version  1.03       ------Sequential Output------ --Sequential Input- --Random-
                    -Per Chr- --Block-- -Rewrite- -Per Chr- --Block-- --Seeks--
Machine        Size K/sec %CP K/sec %CP K/sec %CP K/sec %CP K/sec %CP  /sec %CP
forest         464M 11149  54 16660  20  6461   5  7472  58 11129   5 136.4   0
                    ------Sequential Create------ --------Random Create--------
                    -Create-- --Read--- -Delete-- -Create-- --Read--- -Delete--
              files  /sec %CP  /sec %CP  /sec %CP  /sec %CP  /sec %CP  /sec %CP
                 16  1564  98 +++++ +++ +++++ +++  1650  98 +++++ +++  2640  97
forest,464M,11149,54,16660,20,6461,5,7472,58,11129,5,136.4,0,16,1564,98,+++++,
+++,+++++,+++,1650,98,+++++,+++,2640,97

bonnie++ with SELinux:

Version  1.03       ------Sequential Output------ --Sequential Input- --Random-
                    -Per Chr- --Block-- -Rewrite- -Per Chr- --Block-- --Seeks--
Machine        Size K/sec %CP K/sec %CP K/sec %CP K/sec %CP K/sec %CP  /sec %CP
forest         464M  9878  52 12138  11  5457   6  6834  56 11037   5 137.2   0
                    ------Sequential Create------ --------Random Create--------
                    -Create-- --Read--- -Delete-- -Create-- --Read--- -Delete--
              files  /sec %CP  /sec %CP  /sec %CP  /sec %CP  /sec %CP  /sec %CP
                 16  1426  97 +++++ +++ +++++ +++  1451  98 +++++ +++  2433  97
forest,464M,9878,52,12138,11,5457,6,6834,56,11037,5,137.2,0,16,1426,97,+++++,
+++,+++++,+++,1451,98,+++++,+++,2433,97

hdparm:

 Timing cached reads:   1408 MB in  2.00 seconds = 704.01 MB/sec
 Timing buffered disk reads:   80 MB in  3.02 seconds =  26.53 MB/sec

hdparm with SELinux:

 Timing cached reads:   1396 MB in  2.00 seconds = 698.06 MB/sec
 Timing buffered disk reads:   82 MB in  3.07 seconds =  26.69 MB/sec

So yes, there is some overhead, but it's nothing too serious, IMHO. And quite honestly, I don't care too much about performance here — security is more important than performance. I think you'll agree; if you don't agree now, you will agree with me on the very day someone steals your laptop ;-)

User-friendly SELinux policy editing in vim or Eclipse (using SLIDE)

SLIDE screenshot
SELinux file in vim

After you have installed a minimum SELinux setup in QEMU, you might want to tweak and edit the policy to fit your needs.

A nice, graphical method to do so is to use SLIDE, written by Tresys (and released under the terms of the GPL). SLIDE is an Eclipse (>= 3.1) plugin, which you can install easily:

  • Click Help->Software Updates->Find and install...
  • Click Search for new features to install, then New remote site
  • Enter "http://www.tresys.com/files/eclipse-update/" as URL, click Finish.
  • After that, select the new entry, and install SLIDE (will restart Eclipse).

Of course, you can also easily use your favourite text-editor to edit the plain policy files (if you use the te.vim file from Thomas Bleher you get syntax highlighting, at least for *.te files). After placing the file in the ~/.vim/syntax directory, add this to your ~/.vimrc:

if has("autocmd")
  filetype plugin on
  augroup te
    autocmd BufRead,BufNewFile          *.te set filetype=te
  augroup END
endif

Testing stuff with QEMU - Part 1: SELinux support in Debian unstable [Update]

Update: "Testing stuff with QEMU"-articles published so far:

Here's a quick HOWTO to get you started with the QEMU emulator, the Debian installer (etch beta 3), and SELinux. If you execute the following steps you'll be left with an SELinux-enabled Debian unstable QEMU image, but not with a complete working and perfectly configured SELinux system. A more detailed article about SELinux will probably follow...

Basic Debian unstable install in QEMU:

  1. Install QEMU:
    apt-get install qemu
  2. Download the latest Debian etch installer ISO image (etch beta 3, currently):
    wget http://cdimage.debian.org/cdimage/etch_di_beta3/i386/iso-cd/debian-testing-i386-binary-1.iso
  3. Create a QEMU image which will hold the Debian installation:
    qemu-img create -f qcow /path/to/debian.img 5000M
  4. Boot directly from the ISO image and install Debian into the QEMU image (I won't go into the details of the installation itself; Wolfang Lonien has nice HOWTOs for that: part 1, part 2, video):
    qemu -hda /path/to/debian.img -boot d -cdrom debian-testing-i386-binary-1.iso
  5. After the installation is done, configure the system, tweak /etc/apt/sources.list if needed, and then dist-upgrade to the latest stuff:
    apt-get update && apt-get dist-upgrade
  6. That's about it for the basic Debian install, you can now shutdown the OS and QEMU (type "halt" in the emulated Debian, wait for the shutdown to complete, press CTRL+ALT+2 to switch to the QEMU console, and type "quit").

Creating a QEMU overlay image:

QEMU has a nice feature called overlay images which allows you to "clone" an image, where the new (overlay) image will only store the "diffs" to the original one, thus saving lots of space. This also allows you to remove the overlay image at any time and restart from the original image (which is nice for testing stuff which may break).

  1. Create an overlay image based on the previously installed Debian image:
    qemu-img create -b /path/to/debian.img -f qcow /path/to/debian_selinux_overlay.img
  2. Now boot into the new overlay image:
    qemu -hda /path/to/debian_selinux_overlay.img

Basic SELinux setup:

SELinux / sestatus screenshot

  1. SELinux wants to label all the files on your system (all inodes actually), so your filesystem(s) need the so-called extended attributes (xattr) and "security labels" (both are kernel options) which most modern file systems now support. For ext3 (for example) you need these config options:
    CONFIG_EXT3_FS=y
    CONFIG_EXT3_FS_XATTR=y
    CONFIG_EXT3_FS_SECURITY=y
    Luckily the Debian kernels are xattr-enabled by default so we don't have to do anything at all here.

  2. Install the basic SELinux packages and the source package of the SELinux reference policy:
    apt-get install checkpolicy policycoreutils selinux-policy-refpolicy-src
  3. I noticed a bug in the current Debian packages (the setfiles utility is in the wrong place, see #384850), but there's a simple workaround:
    ln -s /sbin/setfiles /usr/sbin/setfiles
  4. Now we can (re-)label the file system:
    cd /etc/selinux/refpolicy/src/policy
    make relabel
    This will build the reference policy from source and relabel your file system (this will take a while).
    There might be some warnings (and maybe you'll notice further bugs), but they seem not to be critical.
  5. We can now (almost) enable SELinux, but before we can reboot we need to work around another bug (#384852), otherwise SELinux will not be enabled when we reboot:
    ln -s /etc/selinux/refpolicy/src /etc/selinux/targeted
  6. Now reboot the emulated Debian system, and at the GRUB console add the kernel option selinux=1 to enable SELinux in the kernel (press "e" to edit the boot options).
  7. You'll get tons of SELinux log messages while the system boots, that's normal at this point, don't worry.
    Then you can type "sestatus", which should print some information on the running SELinux system. If it says "SELinux status: disabled" something went wrong.

Congratulations! You now have a QEMU image with minimal SELinux support and you can start playing with it, tweaking the policy, finding and reporting bugs, reading tons of documentation on how SELinux actually works etc. etc.

As SELinux is (half?) a release-goal for Debian etch, it would be nice if many people could test it before the release, and this is one method to do so without breaking your production systems.

Update 2006-08-28: You don't really need user_xattr support for SELinux, only xattr support (for security.selinux xattrs) for the filesystem you use, which is available per default in Debian kernels (thanks Russell Coker).

Syndicate content