CentOS Linux produces a "community rebuild" of one of the major "Enterprise Linux" operating systems, and is often used for test systems needing a RPM-based Linux system. The latest release is CentOS 6.2 released late December 2011.

In order to patch arpwatch to avoid unnecessary alerts for RFC5227 style duplicate address detection -- with a fix like Debian's fix in 2004 -- I wanted to install a small CentOS 6.2 system in a VM on my remote KVM server.

The general approach to the remote install in KVM is the same as I used to install OpenBSD and install Ubuntu, viz use a VNC console to do the install, with a ssh port forward to connect to the VNC port. But there are some specific things worth noting:

  • There is a CentOS-6.2-i386-minimal.iso (and CentOS-6.2-x86_64-minimal.iso) install image which can be used to do a minimal install without additional network access (about 320MB ISO files). It will produce a very minimal install, though so be prepared to install some "essential" things manually and tidy up some loose ends.

  • The automatic drive partitioning will try to reserve 512MB for /boot, and twice the RAM size for swap (often 1GB or more of swap), which is undesirable if you are trying to do a minimal install onto small disk image. So you really want to do a custom parition of the hard drive.

  • In order to be able to custom partition the hard drive image, you need to use the graphical installer. And in order to run the graphical installer you need to be installing with more than 512MB of RAM (I used 1GB during the install, and then reduced it to 384M after the installer had finished). I used 256MB for /boot, 512MB for swap, and the rest for the whole drive (with such a small drive and a modern BIOS image you could probably just not have a /boot partition, and put the boot files on the main partition -- but I generally like to mirror the default layout where possible).

  • CentOS 6.2 (and the other Linux operating systems derived from the same source) now always use Network Manager to manage the network interfaces, but it is not installed in a minimal install! As a result networking does not get set up on first boot by default. Historically one would use system-config-network-tui on a system like this to do the configuration, but that too is not in the minimal CentOS 6.2 install. The solution is to manually configure the network startup scripts:

    vi /etc/sysconfig/network-scripts/ifcfg-eth0
    # Change: NM_CONTROLLED="no" (ie, *NOT* controlled by Network Manager)
    # Change: ONBOOT="yes"       (ie, autostarted by base OS)
    # Add:    BOOTPROTO="dhcp"
    # Save, and exit editor
    /etc/init.d/network restart
    

    after which it will work automatically at boot.

  • You'll need to manually create a user account, as only the "root" account is created at install time, eg:

    adduser NAME
    vipw
    vigr
    
  • Even "essential" tools like sudo and man are not included in the minimal image (unlike some other Linux systems which push everyone into using sudo). So a little bit of additional work is required once networking is active (see above) to get a more useful environment:

    su -
    yum update
    yum install sudo man
    visudo
    # Uncomment entry for wheel group, then save
    vigr
    # Add your username to the "wheel" group, and save
    exit
    # Log out and then in again, to pick up wheel group credentials
    # and be able to use sudo
    
  • While the installation needs to be done via VNC, it is possible to configure serial console after the install is complete:

    sudo vi /boot/grub/grub.conf
    # Comment out "splashimage"
    # Comment out "hiddenmenu"
    # Add near top: "serial --unit=0 --speed=115200 --word=8 --parity=no --stop=1"
    # Add near top: "terminal --timeout=10 serial"
    # At each entry add "console=ttyS0,115200" somewhere
    

    Once this is done you could then deconfigure the VNC console support in the KVM configuration if desired.

On a related note, the error message that vncviewer (from TightVNC) produces from time to time, viz "Rect too large" is apparently caused by the bit depth settings getting out of sync between the client and server, due to there being no acknowledgement of the change request and a potential for a race between the client and server. SSH port forwarding of the VNC connection and/or KVM/Qemu seems to provoke it to be triggered more often. The suggested work around is to disable automatic selection of the pixel encoding with:

vncviewer --AutoSelect=0

(I haven't tested that, but it seems like a useful thing to note for the future, as it puzzles me each time it happens in these remote KVM installs.)

Patching and rebuilding arpwatch

Having completed the install, I could move on to building a custom arpwatch with a patch to avoid log messages in the fact of RFC5227 "address in use" probes (done by Apple OS X for years, and some more recent Linux/Windows installs). In the default packaged arpwatch they produce messages like:

Feb  3 09:00:04 SYSTEM arpwatch: reused old ethernet address 0.0.0.0 14:fe:b5:a6:d4:15 (bc:30:5b:cf:ad:44) 
Feb  3 09:00:05 SYSTEM arpwatch: flip flop 0.0.0.0 14:fe:b5:a6:d4:15 (0:1e:c9:f2:c3:8b) 

(depending on how many systems on the network are going through DHCP negotiation and how many of them are checking the address they are given using the method described in RFC5227 before they start using it).

The basic approach is to install the packages needed to rebuild the RPM, download the source RPM for arpwatch, and then patch and rebuild the RPM. I followed the instructions from Owl River to build packages in your user directory, as well as their suggestions for a method of SRPMs with custom patches.

For the basic build tools:

sudo yum install rpm-build make m4 gcc-c++ autoconf automake redhat-rpm-config wget

Then the "build in a user directory" setup:

wget http://www.oldrpm.org/hintskinks/buildtree/RPM-build-tree.txt
cat RPM-build-tree.txt     # Check what is going to do
sh -x RPM-build-tree.txt

Next, download the existing Source RPM file. In CentOS 6.2, per the release notes, these have been moved to vault.centos.org, and are not included in the mirrors, so you need to look in the CentOS 6.2 OS source directory:

mkdir -p ~/build/arpwatch
cd ~/build/arpwatch
wget http://vault.centos.org/6.2/os/Source/SPackages/arpwatch-2.1a15-14.el6.src.rpm

Install the build dependencies of the package (arpwatch), determined by trying to build it and looking at what is reported as missing. In this case:

sudo yum install libpcap-devel postfix

And do a test rebuild of the package as-is to make sure that the build environment is ready:

rpmbuild --rebuild arpwatch-2.1a15-14.el6.src.rpm
ls ~/rpmbuild/RPMS/i686/

Finally prepare a patch to be automatically applied and built:

cd ~/build/arpwatch
rpm -U arpwatch-2.1a15-14.el6.src.rpm
cp -p ~/rpmbuild/SPECS/arpwatch.spec arpwatch.spec
cp -p ~/rpmbuild/SOURCES/arpwatch-2.1a15.tar.gz .
tar -xzf arpwatch-2.1a15.tar.gz
mv arpwatch-2.1a15 arpwatch-2.1a15-pristine
tar -xzf arpwatch-2.1a15.tar.gz
cd arpwatch-2.1a15
# Edit relevant files to fix the problem.  In this case
# vi db.c
# At the top of ent_add(), put a check like the one added in Debian,
# viz:
#     /* Ignore 0.0.0.0 */
#     if (a == 0) {
#         return(1);
#     }
# Save file and carry on.
cd ..
diff -ur arpwatch-2.1a15-pristine/ arpwatch-2.1a15 | tee arpwatch-2.1a15-rfc5227.patch
cp -p arpwatch-2.1a15-rfc5227.patch ~/rpmbuild/SOURCES/
vi arpwatch.spec
# Change Release number to include a local modifier
# Add patch reference: Patch11: arpwatch-2.1a15-rfc5227.patch
# Add patching command: %patch11 -p1 -b .rfc5227
# Update the change log with suitable message

Then build the new package with that spec file:

rpmbuild -ba arpwatch.spec

All going well in ~/rpmbuild/SRPMS you have a new source RPM, and in ~/rpmbuild/RPMS/i686 (or similar; depending on CentOS version installed) you have binary RPMs that can be installed. Install, test, and hopefully be happy.

Of possible note, in theory it was possible to download source RPMs with:

sudo yum install yum-utils
yumdownloader --source arpwatch

but this relies on yum having been configured with repositories for the source. This doesn't appear to be the case, out of the box, at least with a minimal CentOS 6.2 install. So since I needed only one source RPM, having found it I just downloaded it manually.