Making Cobbler work with SElinux on CentOS / RHEL 6

By default, Cobbler will not work properly on a CentOS / RHEL 6 machine with SElinux enabled. The easy way out is to disable SElinux entirely, but I prefer to write a custom policy instead – it is not that difficult.

The basic approach is this:

  1. Use Cobbler as you normally would (you will trigger several SElinux denials, so expect errors)
  2. Extract the relevant SElinux audit messages; convert them into a local policy
  3. Load your local policy
  4. Repeat steps 1..3 until everything works as expected

First attempt: the “cobbler import” command fails; rsync cannot access files on the mounted DVD ISO. Time to start writing a local policy!

The following command generates a basic SElinux policy from the SElinux audit messages:

  cat /var/log/audit/audit.log | audit2allow -l -v -m local > local.te

The resulting local.te file (ASCII, open it in your favorite editor) will list various items, some if which are not related to the Cobbler / Rsync operations. Edit the file to taste. Now, compile and load that policy:

  checkmodule -M -m -o local.mod local.te
  semodule_package -o local.pp -m local.mod
  semodule -v -i local.pp

Note: every invocation of “audit2allow -l” will overwrite your local.te policy file with new events since the last time a policy module was loaded. This is why you should keep backup copies of the previous versions so you can merge new events in with the existing ones.

In the end, you will end up with a policy in local.te like this:

module local 1.0;

require {
    type cobblerd_t;
    type cobbler_var_lib_t;
    type iso9660_t;
    type public_content_t;
    type rpm_var_lib_t;
    type rsync_etc_t;
    type security_t;
    type tmp_t;
    class capability { sys_module fsetid };
    class dir { add_name create getattr open read remove_name rmdir search write };
    class file { create getattr open read unlink write };
    class lnk_file create;
    class unix_dgram_socket create;

#============= cobblerd_t ==============
allow cobblerd_t cobbler_var_lib_t:lnk_file create;
allow cobblerd_t iso9660_t:dir { open read search getattr };
allow cobblerd_t iso9660_t:file { open read getattr };
allow cobblerd_t public_content_t:dir { write rmdir remove_name };
allow cobblerd_t rpm_var_lib_t:dir { open read search getattr write };
allow cobblerd_t rsync_etc_t:file create;
allow cobblerd_t security_t:dir read;
allow cobblerd_t self:capability fsetid;
allow cobblerd_t self:unix_dgram_socket create;
allow cobblerd_t tmp_t:dir { add_name create remove_name rmdir write };
allow cobblerd_t tmp_t:file { create getattr open read unlink write };

Experimenting with the JeeLabs Room Node

JeeNode with Room Node attachedAfter many years I’ve re-discovered electronics as a hobby, thanks to the JeeLabs and Arduino communities.

I’m setting up a small electronics lab with some basic equipment like the Rigol DS1052E oscilloscope (approx. 300 Euros; I “upgraded” mine to the DS1102E firmware to increase the scope’s bandwidth to 100MHz).

One of my first projects is building a Wireless Sensor Network (WSN) to measure humidity, temperature, brightness and motion in several locations at home. The necessary hardware is depicted on the right.

I’ve added a simple resistor ladder network to one of the analog inputs, allowing me to measure battery voltage; these units are supposed to be powered from rechargable batteries for at least a year. Standby power consumption of these devices is in the micro-Amp range; much better than a standard Arduino. The JeeNode comes with an onboard RF12B wireless module (not visible in the picture; it’s below the PIR board) for communications.

While experimenting with the software, I wanted to take a closer look at the actual PIR sensor output signal. The Rigol oscilloscope has all kinds of handy features that assist in analysing and measuring these signals. It can store screenshots on a USB stick, or be remote controlled from a PC – excellent value for money!

Rigol DS1052E Screenshot of PIR sensor output, 570ms pulse widthRigol DS1052E Screenshot of PIR sensor output, with additional information
As you can see, the display is only 320 pixels wide (QVGA) but that is enough for my modest needs ;-)

I tried triggering the PIR as short as possible. The PIR open collector output is pulled low (negative edge) if motion is detected. The minimum output pulse width was approx. 570 milliseconds wide. If the sensor sees continuing motion, the output will remain low for that period (at least, in Continuous trigger mode).

The accompanying “sketch” (Arduino-talk for a program that you write) sends out packets at regular intervals (once per minute, or less), containing all the telemetry info. If motion is detected, an interrupt is generated that causes a packet to be sent out immediately.

I modified a receiver “sketch” to decode the telemetry info and generate a human-readable report:

ROOM-18 1695b 221* 1 38% 22.6C 4.638V 0
 -> ack-18
ROOM-25 1695b 21* 0 46% 19.6C 5.180V 0
ROOM-18 1695b 221* 1 38% 22.7C 4.638V 0
 -> ack-18
 ? 17 166 224 91 134 200 17 70 143 23 173 91 150 205 3 49 236 76 147 243 149
 ? 45 230 233 2 36 124 197 34 202 40 8 137 155 8 37 81 182 185 91 22 183
ROOM-18 1695b 221* 0 38% 22.7C 4.638V 0

Here, I have two JeeNodes (ID 18 and 25), each outfitted with a Room Board. The 433MHz band is crowded, so you’ll see spurious traffic (indicated by ‘?’). If a proper Room Node packet is recognized, it is decoded and displayed.

The report indicates the source of the transmission (ROOM-18 or ROOM-25); free RAM (1695 bytes); brightness (0-255); motion (0-1); humidity; temperature and battery voltage. The last “0” is the Low Battery indicator.

Regular transmissions are not acknowledged; it’s no problem if you lose a couple of data points. If the PIR is triggered however, acknowledgements are requested to ensure that the central node registers this event.

I’m still working on the central node software; I’ll probably just parse the data and stick it in a RRD file or database…

Electronics + Software = hours of fun! ;-)

Panic after installing new kernel on CentOS 6

I just finished updating all of my CentOS 6 machines, resulting in a couple of machines (VMs) no longer booting:

Kernel panic - not syncing: No init found. Try passing init= option to kernel.

It appears that “yum update” installs the new kernel:

[root@c3p0 boot]# rpm -qa |grep ^kernel-

… but no initramfs is created under /boot:

[root@c3p0 boot]# ls -l /boot
total 25561
-rw-r--r--. 1 root root 100203 Oct 6 20:44 config-2.6.32-131.17.1.el6.x86_64
-rw-r--r--. 1 root root 97911 Jun 27 21:08 config-2.6.32-71.29.1.el6.x86_64
drwxr-xr-x. 3 root root 1024 Aug 16 12:58 efi
drwxr-xr-x. 2 root root 1024 Dec 1 17:15 grub
-rw-r--r--. 1 root root 13435614 Aug 16 12:59 initramfs-2.6.32-71.29.1.el6.x86_64.img
drwx------. 2 root root 12288 Aug 16 12:54 lost+found
-rw-r--r--. 1 root root 165827 Oct 6 20:47 symvers-2.6.32-131.17.1.el6.x86_64.gz
-rw-r--r--. 1 root root 160602 Jun 27 21:11 symvers-2.6.32-71.29.1.el6.x86_64.gz
-rw-r--r--. 1 root root 2279162 Oct 6 20:44
-rw-r--r--. 1 root root 2228188 Jun 27 21:08
-rwxr-xr-x. 1 root root 3882992 Oct 6 20:44 vmlinuz-2.6.32-131.17.1.el6.x86_64
-rwxr-xr-x. 1 root root 3795744 Jun 27 21:08 vmlinuz-2.6.32-71.29.1.el6.x86_64

Also, in /etc/boot/grub.conf, the initrd entry is missing for the new kernel:

[root@c3p0 boot]# cat /etc/grub.conf
# grub.conf generated by anaconda
# Note that you do not have to rerun grub after making changes to this file
# NOTICE:  You have a /boot partition.  This means that
#          all kernel and initrd paths are relative to /boot/, eg.
#          root (hd0,0)
#          kernel /vmlinuz-version ro root=/dev/mapper/VolGroup-lv_root
#          initrd /initrd-[generic-]version.img
title CentOS Linux (2.6.32-131.17.1.el6.x86_64)
	root (hd0,0)
	kernel /vmlinuz-2.6.32-131.17.1.el6.x86_64 ro root=/dev/mapper/VolGroup-lv_root rd_LVM_LV=VolGroup/lv_root rd_LVM_LV=VolGroup/lv_swap rd_NO_LUKS rd_NO_MD rd_NO_DM LANG=en_US.UTF-8 SYSFONT=latarcyrheb-sun16 KEYBOARDTYPE=pc KEYTABLE=us crashkernel=auto rhgb quiet
title CentOS (2.6.32-71.29.1.el6.x86_64)
	root (hd0,0)
	kernel /vmlinuz-2.6.32-71.29.1.el6.x86_64 ro root=/dev/mapper/VolGroup-lv_root rd_LVM_LV=VolGroup/lv_root rd_LVM_LV=VolGroup/lv_swap rd_NO_LUKS rd_NO_MD rd_NO_DM LANG=en_US.UTF-8 SYSFONT=latarcyrheb-sun16 KEYBOARDTYPE=pc KEYTABLE=us crashkernel=auto rhgb quiet
	initrd /initramfs-2.6.32-71.29.1.el6.x86_64.img

I remember seeing this problem before on a fairly recent Fedora system, probably Fedora 14 or 15, but never on older CentOS / RHEL releases.

My guess is that this is a problem with Dracut. You can re-generate the initramfs by running dracut (as root, of course), but I’d rather not have to perform emergency surgery on lots of (virtual) machines…

Anyway, the command line would look like this:

dracut initramfs-${version}.img ${version}
dracut initramfs-2.6.32-131.17.1.el6.x86_64.img 2.6.32-131.17.1.el6.x86_64

Uninstalling the Silicon Labs CP210x USB to Serial driver

I use several types of USB to Serial converters on Mac OS X, mostly for playing with Jeenode / Arduino hardware or connecting my HAM radio devices.

One of these devices, a Kenwood TH-D72, has a built-in Silicon Labs CP210x chip. The Mac OS X driver supplied by Silicon Labs is not very stable; it has caused my Mac to crash several times already. Uninstalling this driver is not as easy as uninstalling other applications on Mac; normally, you just drag the app into the trash – done. However, these drivers are supplied in “pkg” (package) format. Uninstalling software packages is a bit more involved.

Open Terminal and type the following commands:

macbookpro-ed:/ ed$ pkgutil --pkgs |grep silabs

macbookpro-ed:/ ed$ pkgutil --lsbom com.silabs.siliconLabsVcpDriver.SiLabsUSBDriver.pkg

macbookpro-ed:/ ed$ pkgutil --lsbom com.silabs.siliconLabsVcpDriver.SiLabsUSBDriver64.pkg

The first command looks for all PKG receipts pertaining to the Silicon Labs drivers. The next commands list the contents (Bill of Materials) for each driver package. Uninstalling the drivers can now be accomplished in several ways:

Leave the PKG, but disable the drivers (safest, but least clean):

This method does not actually uninstall the drivers. Locate the driver kext (kernel extensions) and rename to disable them:

mdfind SiLabsUSBDriver.kext
cd /System/Library/Extensions/
sudo mv SiLabsUSBDriver.kext SiLabsUSBDriver.kext_DISABLED
sudo mv SiLabsUSBDriver64.kext SiLabsUSBDriver64.kext_DISABLED

Reboot to verify that the driver is actually disabled. For example, plug in the USB device and check for a corresponding error message indicating that no driver could be found:

2011-11-29 8:34:56.000 PM kernel: 0 0 AppleUSBCDC: start - initDevice failed

Remove all files listed in the PKG Bill of Materials (clean, but less safe):

mdfind SiLabsUSBDriver.kext
cd /System/Library/Extensions/
sudo rm -rf SiLabsUSBDriver.kext
sudo rm -rf SiLabsUSBDriver64.kext
sudo pkgutil --forget com.silabs.siliconLabsVcpDriver.SiLabsUSBDriver.pkg
sudo pkgutil --forget com.silabs.siliconLabsVcpDriver.SiLabsUSBDriver64.pkg

Reboot to verify that the drivers are now completely gone.