Friday, August 24, 2012

CentOS/RHEL Shrink Partitions

Increasing LVM partition sizes in CentOS/RHEL 5.X is infinitely easier than shrinking them, but in the rare instance where you might have to, here's a quick guide on a couple of gotchas. If you need to shrink the / partition (probably the rarest occurrence), you're stuck booting off a LiveCD and hoping for the best.

Now I bet you're saying something along the lines of "but all the other partitions should be easy, right?" Uh, no, particularly /usr. Why? Well, someone decided that the LVM utilities should reside under /usr. Not a big deal, they provide a static /sbin/lvm.static, which, while the syntax is slightly different, provides most (all?) of the functionality you are used to from the LVM utils.

Great, problem solved, right?! Nope, not quite. While /bin/bash (default root shell) doesn't depend on libraries under /usr, it does hold open files from the /usr tree. That prevents you from un-mounting /usr.

To shrink "system" partitions (except /, see above), you will likely need to be in single user mode, but before you do that, run chsh:

[root@centos5 ~]# chsh
Changing shell for root.
New shell [/bin/bash]: /bin/sh
Shell changed.
[root@centos5 ~]#

to change the login shell for the root user. After you are done, you can switch it back. Now reboot into single user mode.

Once in single user mode, you'll notice the prompt has now changed to:

sh-3.2#

or similar. Even though /bin/sh is just a symlink to /bin/bash, bash detects that it's being run as sh, runs with a reduced feature set, which doesn't require it to open files on /usr.

To shrink the /usr partition:

  • umount /usr 
  • e2fsck -f /dev/path/to/lvm/partition 
  • resize2fs /dev/path/to/lvm/partition  [new size slightly smaller than desired final result]
  • lvm.static lvmreduce -L [new size] /dev/path/to/lvm/partition
  • resize2fs /dev/path/to/lvm/partition
  • e2fsck -f /dev/path/to/lvm/partition
  • mount /usr  
Wash, rinse, repeat for other partitions.

Enjoy. -R

Don't miss SANS Network Security 2012, September 16-24 in Las Vegas, your annual mega-networking opportunity. Choose from over 35 courses, huge vendor expo, riveting bonus sessions, and a thrilling NetWars competition. Sign up today! http://www.sans.org/info/107529

Labels: ,

Tuesday, July 28, 2009

WIP: Steps to Grow Physical Volume on LVM on Virtual Machine

This is a work in progress, expect the post to change, perhaps drastically. This isn't the "simplest" way to do this, you could do this all online, but this allowed us to maintain consistency in setup across multiple physical and virtual machines.

Skeleton outline:

- Snapshot and shutdown the VM (bummer)
- Within VMware Infrastructure Client, extend the disk allocation for the VM
- Power on the VM
- Check that the disk size change is seen by the VM: run dmesg or fdisk -l
- fdisk the disk
- within fdisk, delete the physical partition that you wish to extend, then recreate the physical partition with the same options except extend the size to use the newly added free disk space
- write out the changes to disk and exit
- reboot the VM
- run pvdisplay
- run pvresize on the newly extended partition
- verify that the resize worked by comparing pvdisplay output
- verify that the new "Free PE" has increased with vgdisplay
- use lvcreate (-n LVNAME -L SIZE VolumeGroup) or lvextend to allocate new space

Voila!

Labels: , ,

Thursday, February 01, 2007

Dual Boot FreeBSD 6.2 and Linux (CentOS 4.4)

I've been building some machines for testing various network foo, and found that this would a good opportunity to try FreeBSD again. I've been heavily into Linux lately, mainly due to job requirements, but I don't want my *BSD skills to horribly stagnate (shocking coming from a gov't employee, I know), and this seemed like a good time. Since I can't get completely away from Linux, I wanted this machine to be dual boot.

The first obstacle was installation. FreeBSD still uses, by default, an ncurses-based menu driven install, although I understand there is a GUI install system being developed. No problem, as I'm just as comfortable on the command line as I am with a graphical interface. Installing CentOS 4.4 has the option of a text menu install, but it defaults to a graphical install (my biggest annoyance with RH/Fedora/CentOS install (anaconda?) is that it picks the strangest hard disk layouts if you don't specify exactly what you want, and sometimes it even screws that up). The difference in install methods speaks to how Linux is trying to be everything to everybody, whereas FreeBSD is comfortable sticking to it's roots. Personally, I'm on the fence as to whether either camp has it "right." Both installs went smooth.

I installed FreeBSD first, giving it the first half of the hard drive (1 partition, with 5 slices within that partition), and CentOS the last half of the disk with 3 partitions. Given the maturity and open source nature of both of these operating systems, I was surprised that CentOS didn't recognize that FreeBSD was installed, and offer to add it to the GRUB boot menu like it would have done if it detected MS Windows something or other. Silly. Reminds me of Mom yelling at us as a kid, "Now children, stop fighting and play nice."

Anyway, the fix to that was (thankfully) fairly simple because GRUB is such a well designed boot loader. After installing CentOS, it left itself as the only option, so I boot into that, and edit /etc/grub.conf (symlink to /boot/grub/grub.conf), and add the following (YMMV, primarily with regard to partition numbers, etc.):

title FreeBSD 6.2
root (hd0,0,a)
kernel /boot/loader

and upon the next boot, FreeBSD 6.2 will be a boot option. Selecting it from the list allowed it to boot normally.

Enjoy.

Labels: , ,

Tuesday, November 14, 2006

PF_RING and Snort

In the hopes of minimizing packet loss on my Snort IDS sensors, I've been experimenting with the PF_RING Linux kernel patches. My initial results have been impressive as both sensors report 0% packet loss (I'm of course presuming it isn't a blatant lie :-) ). I'll try to document my experiences here.

UPDATE: An anonymous commenter (thanks!) noted that PF_RING doesn't report lost packets through libpcap (as Snort expects), but rather through files in /proc/net/pf_ring. I'm still working out the details on how to use that information effectively.

My work is on RedHat Enterprise 4, so if you are using a different distro, your mileage may vary, however, it shouldn't be drastically different.

UPDATE: Here's a Debian Sarge oriented howto:
http://bjou.homeunix.net/blog/2006/12/advanced-packet-capturing-howto-pf_ring-napi-and-extended-libpcap-on-debian-sarge/

There are 2 Fedora Core (4 and 5) instruction pages at:

http://wiki.ntop.org/mediawiki/index.php/Installing_PF_RING_and_nProbe_on_Fedora_Core_4_%28FC4%29

and

http://wiki.ntop.org/mediawiki/index.php/Installing_on_Fedora_Core_5_%28FC5%29

that these are based upon, and (hopefully) expand upon. Thanks to the authors of those.

Before beginning, make sure that your system is fully up to date with patches. These instructions presume that you have at least 2+ GBs of free disk space, primarily in /usr/src.

1. Software packages needed (in addition to a minimal install on RHEL):

glibc-kernheaders
autoconf
automake
bison
flex
cvs
gcc
gcc-c++
libtool
tcl (note this version is compiled without threading, so good for Sguil)
tcl-devel
tclx
rpm-build
redhat-rpm-config
openssl-devel
pcre-devel
ncurses-devel

On a registered RHEL, you'd run the command:

up2date -f install [package_name]

to download package_name and required dependancies, and install them.

* Note: not all of these are neccessary for just PF_RING, however, are needed for other things like Snort, Sguil, barnyard, sancp, etc.

2. Remove software:

At a bare minimum, the following software packages need to be removed:
libpcap
ppp *
rp-pppoe *
wvdial *

The command to do this is:

rpm -e

* relies on libpcap. If needed, will need to be recompiled with the new libpcap that we'll compile and install later.

3. Install the kernel src.rpm of the latest kernel (on RHEL, kernel-2.6.9-42.0.3.EL.src.rpm at the time of this writing).

For RHEL 4, the file will be located ftp.redhat.com. For example, to get the latest kernel for RHEL as of today, you'd run the command:

wget ftp://ftp.redhat.com:/pub/redhat/linux/updates/enterprise/4XX/en/os/SRPMS/kernel-2.6.9-42.0.3.EL.src.rpm

where XX is the type of RHEL 4 you're running: Desktop (uhh, desktop), WS (workstation), ES (enterprise server), or AS (advanced server). If you don't know, run the command:

[root@hostname ~]# cat /etc/redhat-release
Red Hat Enterprise Linux WS release 4 (Nahant Update 4)

In this case, this machine was a workstation, so use WS.

Now install the kernel with the command:

rpm -ivh kernel-2.6.9-42.0.3.EL.src.rpm

This will place the vanilla 2.6.9 kernel src, RedHat's patches, spec file, etc. into /usr/src/redhat/{SOURCES,SPECS}.

4. Prep the kernel for the PF_RING patches.

Now we need to prep the kernel. First, change to the appropiate directory:

cd /usr/src/redhat/SPECS

Then run the command:

rpmbuild -bp --target $(arch) kernel-2.6.spec

If this works, you should see something similar to the following:

Building target platforms: i686
Building for target i686
Executing(%prep): /bin/sh -e /var/tmp/rpm-tmp.7797
+ umask 022
+ cd /usr/src/redhat/BUILD
+ LANG=C
+ export LANG
+ unset DISPLAY
+ cd /usr/src/redhat/BUILD
+ rm -rf kernel-2.6.9
+ /bin/mkdir -p kernel-2.6.9
+ cd kernel-2.6.9
+ /usr/bin/bzip2 -dc /usr/src/redhat/SOURCES/linux-2.6.9.tar.bz2
+ tar -xf -
+ STATUS=0
+ '[' 0 -ne 0 ']'
++ /usr/bin/id -u
+ '[' 0 = 0 ']'
+ /bin/chown -Rhf root .
++ /usr/bin/id -u
+ '[' 0 = 0 ']'
+ /bin/chgrp -Rhf root .
+ /bin/chmod -Rf a+rX,u+w,g-w,o-w .
+ cd linux-2.6.9
+ echo 'Patch #3 (patch-2.6.9-ac11.bz2):'
Patch #3 (patch-2.6.9-ac11.bz2):
+ /usr/bin/bzip2 -d
+ patch -p1 -s
[snip]
removed `./net/xfrm/xfrm_state.c.orig'
removed `./net/socket.c.orig'
removed `./net/netlink/af_netlink.c.orig'
removed `./net/ipv6/ip6_output.c.orig'
removed `./net/ipv6/addrconf.c.orig'
removed `./net/ipv6/netfilter/ip6_tables.c.orig'
removed `./net/bluetooth/af_bluetooth.c.orig'
removed `./net/8021q/vlan.c.orig'
removed `./net/sched/sch_api.c.orig'
+ find . -name '*~' -exec rm -fv '{}' ';'
+ exit 0

This applies all of the various patches (nearly 1000) that RedHat applies to it's kernels.

Now we need to copy that patched kernel source to /usr/src with the command:

cp -a /usr/src/redhat/BUILD/kernel-2.6.X/linux-2.6.X /usr/src

where X is the subversion. In this case, for RHEL 4, X = 9.

Now, create a symlink from the actual kernel to the generic linux:

cd /usr/src
ln -s ./linux-2.6.X linux

where X is the subversion. Again, in this case, for RHEL 4, X = 9.

5. Download and build the PF_RING patch for your kernel.

Now we need to get the PF_RING patches downloaded and built for our kernel. PF_RING is currently only available via CVS. To do this, run the following:

cd /usr/src
CVSROOT=:pserver:anonymous@cvs.ntop.org:/export/home/ntop;export CVSROOT
mkdir pf_ring && cd pf_ring
cvs login

which should produce the following output:

Logging in to :pserver:anonymous@cvs.ntop.org:2401/export/home/ntop
CVS password:

At the prompt, type "ntop" (no quotes), and hit Enter. (Note: ntop will not appear on the screen.) Next type the following:

cvs checkout PF_RING

which, if it works, should produce something simliar to the following:

cvs checkout: Updating PF_RING
U PF_RING/README
U PF_RING/mkpatch.sh
cvs checkout: Updating PF_RING/kernel
U PF_RING/kernel/README
cvs checkout: Updating PF_RING/kernel/include
cvs checkout: Updating PF_RING/kernel/include/linux
U PF_RING/kernel/include/linux/ring.h
cvs checkout: Updating PF_RING/kernel/include/net
U PF_RING/kernel/include/net/PATCH-to-sock.h
cvs checkout: Updating PF_RING/kernel/net
U PF_RING/kernel/net/PATCH-to-Config.in
U PF_RING/kernel/net/PATCH-to-netsyms.c
cvs checkout: Updating PF_RING/kernel/net/core
U PF_RING/kernel/net/core/PATCH-1-to-dev.c
U PF_RING/kernel/net/core/PATCH-2-to-dev.c
U PF_RING/kernel/net/core/PATCH-3-to-dev.c
cvs checkout: Updating PF_RING/kernel/net/ring
U PF_RING/kernel/net/ring/Config.in
U PF_RING/kernel/net/ring/Kconfig
U PF_RING/kernel/net/ring/Makefile
U PF_RING/kernel/net/ring/Makefile-2.4.X
U PF_RING/kernel/net/ring/Makefile-2.6.X
U PF_RING/kernel/net/ring/ring_packet.c
cvs checkout: Updating PF_RING/userland
cvs checkout: Updating PF_RING/userland/libpcap-0.9.4-ring
U PF_RING/userland/libpcap-0.9.4-ring/README
U PF_RING/userland/libpcap-0.9.4-ring/pcap-int.h
U PF_RING/userland/libpcap-0.9.4-ring/pcap-linux.c
cvs checkout: Updating PF_RING/userland/libpfring
U PF_RING/userland/libpfring/Makefile
U PF_RING/userland/libpfring/pfcount.c
U PF_RING/userland/libpfring/pfring.c
U PF_RING/userland/libpfring/pfring.h
cvs checkout: Updating PF_RING/userland/pcount
U PF_RING/userland/pcount/Makefile
U PF_RING/userland/pcount/pcount.c

The current version of PF_RING comes with a script that creates a patch specific to your kernel. Now we'll get things in order to run that script with the following commands:

cd /usr/src/pf_ring/PF_RING
mkdir workspace
cd workspace
cp /usr/src/redhat/SOURCES/linux-2.6.9.tar.bz2 .
bunzip2 linux-2.6.9.tar.bz2
gzip linux-2.6.9.tar
cd ..

Now edit the file mkpatch.sh, and adjust the following variables to match your environment:

SUBLEVEL=${SUBLEVEL:-18.1}

EXTRAVERSION=${EXTRAVERSION:--i686-smp-$PATCH}


For example, on RHEL 4, you'd change to the variables to:

SUBLEVEL=${SUBLEVEL:-9}

EXTRAVERSION=${EXTRAVERSION:--42.0.3.ELsmp-$PATCH}


Save your changes, and run the script:

sh ./mkpatch.sh

If all goes well, the output should look similar to the following:

Creating patch for Linux kernel linux-2.6.9 ...
Edit this file (mkpatch.sh) for a different kernel version
Kernel build area is /usr/src/pf_ring/PF_RING/workspace
rm: cannot remove `/usr/src/pf_ring/PF_RING/workspace/ring3': No such file or directory
Creating link to /usr/src/pf_ring/PF_RING in /usr/src/pf_ring/PF_RING/workspace called ring3
Found linux-2.6.9.tar.gz in source directory /usr/src/pf_ring/PF_RING/workspace
Untarring Linux sources (read-only tree) in /usr/src/pf_ring/PF_RING/workspace/linux-2.6.9
Cloning Linux sources (read-write tree) in /usr/src/pf_ring/PF_RING/workspace
Patching Linux sources ...
1. Install additional file include/linux/ring.h with definitions
for packet ring.
done
2. Install the ring sources under the kernel tree.
Installing kernel ring sources in
linux-2.6.9-42.0.3.ELsmp-ring3/net/ring ... done
3. Patch net/core/dev.c ...
Patch #1 (define ring_handler)
Patch #2 (modify function netif_rx and netif_receive_skb)
Patch #3 (modify dev_queue_xmit, found in PATCH-3-to-dev.c)
... done
4. Patching file net/Makefile ... done
5. Copy net/ring/Kconfig to linux-2.6.9-42.0.3.ELsmp-ring3/net/ring/Kconfig done
6. Patching file net/Kconfig ... done
diff --unified --recursive --new-file linux-2.6.9 linux-2.6.9-42.0.3.ELsmp-ring3 > linux-2.6.9-42.0.3.ELsmp-ring3.patch
Making Linux patch file. This could take some time, please wait ... done
Your patch file is now in /usr/src/pf_ring/PF_RING/workspace/linux-2.6.9-42.0.3.ELsmp-ring3.patch.gz

6. Apply the patch and build the kernel.

To apply the patch, run the following:

cd /usr/src
zcat /usr/src/pf_ring/PF_RING/workspace/linux-2.6.*patch.gz | patch --dry-run -p0

If the last command doesn't report any errors, then run the following:

zcat /usr/src/pf_ring/PF_RING/workspace/linux-2.6.*patch.gz | patch -p0

The output should look similar to:

patching file linux-2.6.9/include/linux/ring.h
patching file linux-2.6.9/net/core/dev.c
Hunk #2 succeeded at 1302 (offset -56 lines).
Hunk #3 succeeded at 1519 with fuzz 2 (offset -60 lines).
Hunk #4 succeeded at 1738 with fuzz 2 (offset -43 lines).
patching file linux-2.6.9/net/core/dev.c.ORG
patching file linux-2.6.9/net/Kconfig
patching file linux-2.6.9/net/Makefile
Hunk #1 succeeded at 41 (offset 1 line).
patching file linux-2.6.9/net/Makefile.ORG
patching file linux-2.6.9/net/ring/Kconfig
patching file linux-2.6.9/net/ring/Makefile
patching file linux-2.6.9/net/ring/ring_packet.c

Next, run the following:

cd /usr/src/linux
make menuconfig

When the configuration menu appears, change the following:

Processor type and features -> High Memory Support -> 64GB
Device Drivers -> Networking Support -> Networking Options -> PF_RING (module)

Exit and save the configuration. Now, run the following to compile the kernel:

make
make modules
make modules_install
make install

UPDATE: If the first command 'make' fails with:


net/ring/ring_packet.c:15:26: linux/config.h: No such file or directory


then, as documented here, edit the file net/ring/ring_packet.c, and replace:

#include

with

#include


This sequence of commands will take a long time to complete, which is normal.

The command "make install" will place the new kernel in /boot, typically with a -prep tag:

[root@idsext ~]# ls -l /boot/*prep*
-rw-r--r-- 1 root root 492685 Nov 18 17:52 /boot/initrd-2.6.9-prep.img
-rw-r--r-- 1 root root 750587 Nov 18 17:52 /boot/System.map-2.6.9-prep
-rw-r--r-- 1 root root 1509678 Nov 18 17:52 /boot/vmlinuz-2.6.9-prep

as well as add an entry to /etc/grub.conf:

title Linux (2.6.9-prep)
root (hd0,0)
kernel /vmlinuz-2.6.9-prep ro root=/dev/md1
initrd /initrd-2.6.9-prep.img

Now, reboot the machine into the new kernel. NOTE: Do NOT remove older kernels until you are positive this one works. In fact, probably best to leave the old kernel there, so up2date doesn't get confused.

7. Compile libpfring, and test that the module works.

First off, start with doing the following:

cp /usr/src/linux/include/linux/ring.h /usr/include/linux

which will add the neccessary header file, ring.h, to the standard include directory.

Next, run the following:

cd /usr/src/pf_ring/PF_RING/userland/libpfring
make

If all goes well, you should see something similar to:

gcc -g -c -I/lib/modules/2.6.9-prep/source/include pfcount.c
gcc -g -c -I/lib/modules/2.6.9-prep/source/include pfring.c
ar rc libpfring.a pfring.o
ranlib libpfring.a
gcc -g pfcount.o pfring.o -o pfcount

Now, we are going to generate a .so from these files, by running the following:

gcc -shared -Wl,-soname -Wl,libpfring.so.0.9.4 -o libpfring.so.0.9.4 *.o -lc

Now, we copy the files we just created to a common system directory:

cp libpfring.a libpfring.so.0.9.4 /usr/local/lib
cp pfring.h /usr/local/include

Next, we need to add /usr/local/lib to the list of directories the dynamic loader will search:

echo "/usr/local/lib" >> /etc/ld.so.conf
ldconfig

To check that the dynamic loader sees the libraries, run the following:

ldconfig -v |grep pfring

which should produce the following output:

libpfring.so.0.9.4 -> libpfring.so.0.9.4

Now, to test the ring module we added to the kernel earlier, run the following:

./pfcount -v -i [interface]

where [interface] is the interface that you will be monitoring traffic on (and hopefully has traffic on it already, otherwise, this test won't be very interesting). For example, that interface for me is eth1, so I would type:

./pfcount -v -i eth1

and the output should look something similar to:

14:23:04.794105 [00:30:48:2B:EF:76 -> 00:07:E9:47:DD:5F] [192.168.36.39 -> 192.168.156.118] [caplen=66][len=66]
14:23:04.794162 [00:07:E9:47:DD:5F -> 00:30:48:2B:EF:76] [192.168.156.118 -> 192.168.36.39] [caplen=226][len=226]
14:23:04.794252 [00:07:E9:47:DD:5F -> 00:30:48:2B:EF:76] [192.168.156.118 -> 192.168.36.39] [caplen=338][len=338]
14:23:04.794341 [00:07:E9:47:DD:5F -> 00:30:48:2B:EF:76] [192.168.156.118 -> 192.168.36.39] [caplen=226][len=226]
14:23:04.794426 [00:07:E9:47:DD:5F -> 00:30:48:2B:EF:76] [192.168.156.118 -> 192.168.36.39] [caplen=226][len=226]
14:23:04.794514 [00:07:E9:47:DD:5F -> 00:30:48:2B:EF:76] [192.168.156.118 -> 192.168.36.39] [caplen=226][len=226]
14:23:04.794597 [00:07:E9:47:DD:5F -> 00:30:48:2B:EF:76] [192.168.156.118 -> 192.168.36.39] [caplen=226][len=226]
14:23:04.794680 [00:07:E9:47:DD:5F -> 00:30:48:2B:EF:76] [192.168.156.118 -> 192.168.36.39] [caplen=226][len=226]
14:23:04.794767 [00:07:E9:47:DD:5F -> 00:30:48:2B:EF:76] [192.168.156.118 -> 192.168.36.39] [caplen=226][len=226]
14:23:04.794849 [00:07:E9:47:DD:5F -> 00:30:48:2B:EF:76] [192.168.156.118 -> 192.168.36.39] [caplen=226][len=226]
14:23:04.794932 [00:07:E9:47:DD:5F -> 00:30:48:2B:EF:76] [192.168.156.118 -> 192.168.36.39] [caplen=226][len=226]
14:23:04.794995 [00:30:48:2B:EF:76 -> 00:07:E9:47:DD:5F] [192.168.36.39 -> 192.168.156.118] [caplen=66][len=66]
14:23:04.795030 [00:07:E9:47:DD:5F -> 00:30:48:2B:EF:76] [192.168.156.118 -> 192.168.36.39] [caplen=226][len=226]
14:23:04.795101 [00:07:E9:47:DD:5F -> 00:30:48:2B:EF:76] [192.168.156.118 -> 192.168.36.39] [caplen=226][len=226]
14:23:04.795355 [00:07:E9:47:DD:5F -> 00:30:48:2B:EF:76] [192.168.156.118 -> 192.168.36.39] [caplen=146][len=146]

Hit ctrl-C, and the last few lines of the output should give you summary similar to:

=========================
Absolute Stats: [3672 pkts rcvd][47 pkts dropped]
Total Pkts=3625/Dropped=1.3 %
3672 pkts [4116.2 pkt/sec] - 871764 bytes [7.82 Mbit/sec]
=========================
Actual Stats: 3672 pkts [1599568.0 ms][2.3 pkt/sec]
=========================

Now, run the following:

dmesg

and the last few lines of output should look similar to the following:

RING: succesfully allocated 128 KB [tot_mem=26509372][order=5]
RING: allocated 80 slots [slot_len=1618][tot_mem=131072]
device eth1 entered promiscuous mode

which is a good indication that the kernel module is working.

8. Next step is to build libpcap to use the PF_RING interface to the kernel.

First, run the following:

cd /usr/src/pf_ring/PF_RING/userland/
ls |grep pcap

The output should be something similar to:

libpcap-0.9.4-ring

which indicates that this version of PF_RING was built to work with a patched version of libpcap-0.9.4, so we need to download that version.

The simplest way to download that version is to run the following:

wget http://www.tcpdump.org/release/libpcap-0.9.4.tar.gz

which should produce output similar to:

--14:37:06-- http://www.tcpdump.org/release/libpcap-0.9.4.tar.gz
=> `libpcap-0.9.4.tar.gz'
Resolving www.tcpdump.org... 205.150.200.214
Connecting to www.tcpdump.org|205.150.200.214|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 425,887 (416K) [application/x-tar]

100%[===================================================>] 425,887 78.37K/s ETA 00:00

14:37:15 (79.23 KB/s) - `libpcap-0.9.4.tar.gz' saved [425887/425887]

If the above command doesn't work, you'll need to download it by hand. I'll leave that as an exercise for the reader to figure out.

Now, unpack the gzip'd tarball:

tar -zxvf libpcap-0.9.4.tar.gz

which should produce output similar to:

libpcap-0.9.4/./
libpcap-0.9.4/./ChmodBPF/
libpcap-0.9.4/./ChmodBPF/ChmodBPF
libpcap-0.9.4/./ChmodBPF/StartupParameters.plist
libpcap-0.9.4/./.cvsignore
libpcap-0.9.4/./CHANGES
libpcap-0.9.4/./CREDITS
libpcap-0.9.4/./FILES
libpcap-0.9.4/./INSTALL.txt
libpcap-0.9.4/./LICENSE
libpcap-0.9.4/./Makefile.in
libpcap-0.9.4/./README
[snip]
libpcap-0.9.4/./msdos/readme.dos
libpcap-0.9.4/./packaging/
libpcap-0.9.4/./packaging/pcap.spec
libpcap-0.9.4/./packaging/pcap.spec.in

Now, do the following:

cd libpcap-0.9.4
mv pcap-int.h pcap-int.h.orig
mv pcap-linux.c pcap-linux.c.orig
cp ../libpcap-0.9.4-ring/pcap* .
./configure CPPFLAGS="-I/usr/local/include" LDFLAGS="-L/usr/local/lib" CFLAGS="-D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64"

If the ./configure command completes without any errors, run the following:

make && gcc -shared -Wl,-soname -Wl,libpcap.so.`cat VERSION` -o libpcap.so.`cat VERSION` *.o -lc

If the above commands complete successfully, you should see something similar to:

gcc -O2 -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -I. -DHAVE_CONFIG_H -D_U_="__attribute__((unused))" -c ./pcap-linux.c
gcc -O2 -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -I. -DHAVE_CONFIG_H -D_U_="__attribute__((unused))" -c ./fad-getad.c
sed -e 's/.*/static const char pcap_version_string[] = "libpcap version &";/' ./VERSION > version.h
gcc -O2 -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -I. -DHAVE_CONFIG_H -D_U_="__attribute__((unused))" -c ./pcap.c
gcc -O2 -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -I. -DHAVE_CONFIG_H -D_U_="__attribute__((unused))" -c ./inet.c
gcc -O2 -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -I. -DHAVE_CONFIG_H -D_U_="__attribute__((unused))" -c ./gencode.c
gcc -O2 -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -I. -DHAVE_CONFIG_H -D_U_="__attribute__((unused))" -c ./optimize.c
gcc -O2 -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -I. -DHAVE_CONFIG_H -D_U_="__attribute__((unused))" -c ./nametoaddr.c
gcc -O2 -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -I. -DHAVE_CONFIG_H -D_U_="__attribute__((unused))" -c ./etherent.c
gcc -O2 -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -I. -DHAVE_CONFIG_H -D_U_="__attribute__((unused))" -c ./savefile.c
rm -f bpf_filter.c
ln -s ./bpf/net/bpf_filter.c bpf_filter.c
gcc -O2 -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -I. -DHAVE_CONFIG_H -D_U_="__attribute__((unused))" -c bpf_filter.c
gcc -O2 -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -I. -DHAVE_CONFIG_H -D_U_="__attribute__((unused))" -c ./bpf_image.c
gcc -O2 -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -I. -DHAVE_CONFIG_H -D_U_="__attribute__((unused))" -c ./bpf_dump.c
flex -Ppcap_ -t scanner.l > $$.scanner.c; mv $$.scanner.c scanner.c
bison -y -p pcap_ -d grammar.y
mv y.tab.c grammar.c
mv y.tab.h tokdefs.h
gcc -O2 -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -I. -DHAVE_CONFIG_H -D_U_="__attribute__((unused))" -c scanner.c
gcc -O2 -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -I. -DHAVE_CONFIG_H -D_U_="__attribute__((unused))" -Dyylval=pcap_lval -c grammar.c
sed -e 's/.*/char pcap_version[] = "&";/' ./VERSION > version.c
gcc -O2 -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -I. -DHAVE_CONFIG_H -D_U_="__attribute__((unused))" -c version.c
ar rc libpcap.a pcap-linux.o fad-getad.o pcap.o inet.o gencode.o optimize.o nametoaddr.o etherent.o savefile.o bpf_filter.o bpf_image.o bpf_dump.o scanner.o grammar.o version.o
ranlib libpcap.a

Now, run the following:

make install && cp libpcap.so.0.9.4 /usr/local/lib

Next, make sure the dynamic loader sees this new library:

ldconfig -v |grep pcap

the output should look similar to:

libpcap.so.0.9.4 -> libpcap.so.0.9.4

9. Now, we build Snort 2.4.5 using the new libpcap and libpfring.

First, download snort-2.4.5:

cd /usr/src
wget http://www.snort.org/dl/old/snort-2.4.5.tar.gz

Now, unpack the gzip'd tarball:

tar -zxvf snort-2.4.5.tar.gz && cd snort-2.4.5

Next, use ./configure to setup the compile:

./configure --enable-timestats --enable-perfmonitor --enable-linux-smp-stats CPPFLAGS="-I/usr/local/include" LDFLAGS="-L/usr/local/lib -lpfring -lpcap"

The output should look similar to:

checking for a BSD-compatible install... /usr/bin/install -c
checking whether build environment is sane... yes
checking for gawk... gawk
checking whether make sets $(MAKE)... yes
checking whether to enable maintainer-specific portions of Makefiles... no
[snip]
config.status: creating m4/Makefile
config.status: creating etc/Makefile
config.status: creating templates/Makefile
config.status: creating src/win32/Makefile
config.status: creating config.h
config.status: executing depfiles commands

Now, run the following:

make && make install

If the above command completes successfully, then the command:

ldd /usr/local/bin/snort

should produce output similar to:

libpfring.so.0.9.4 => /usr/local/lib/libpfring.so.0.9.4 (0x00143000)
libpcap.so.0.9.4 => /usr/local/lib/libpcap.so.0.9.4 (0x00725000)
libpcre.so.0 => /lib/libpcre.so.0 (0x00760000)
libm.so.6 => /lib/tls/libm.so.6 (0x00111000)
libnsl.so.1 => /lib/libnsl.so.1 (0x007f2000)
libc.so.6 => /lib/tls/libc.so.6 (0x00147000)
/lib/ld-linux.so.2 (0x00615000)

where the line containing libpfring and libpcap are of particular importance.

At this point, you have a version of snort that will use the PF_RING ring module in the kernel. Congrats.

Some things of note:
- the ring module has some load options that affect it's behavior. You'll need to tweak these to your environment, however, most folks will want to add the following to the end of /etc/modprobe.conf:

options ring transparent_mode=0 bucket_len=1600

- if you disable transparent_mode (as I have with transparent_mode=0), do not run a program that uses the PF_RING interface (Snort, tcpdump, pfcount, etc.) on the management interface by accident, as you will lose connectivity to the machine.

Enjoy.

Labels: , , ,