Using qemu to run Cisco IPS
From Internetworkpro
Contents |
[edit] Preface
This guide is based on my previous HOWTO, running Cisco IPS inside a VMWare instance. The major problem with this approach was that it worked only with IP release 5.x. All newer IPS software versions didnt work, because the e1000 emulation in VMWare could not deal with the special NIC drivers Cisco ships since IPS release 6.
People still want the newer IPS software versions to be emulated, mainly for practice and study reasons. I used qemu in the past for other things (like for Olive), and now I had time to take a closer look. Thanks to the qemu folks and lots of people that provide contributions, qemu became very powerful. Since release 0.11 its even possible to provide DMI/SMBIOS data directly at the command line, so no need to play with the BOCHS BIOS anymore!
Long story short: Its possible to run IPS release 6.0 within qemu. With the correct patches, you even have direct connectivity to your dynamips/dynagen labs through UDP connectors. And everything on the emulation side is done with free software - no need to buy VMWare, no need for a modified BIOS binary anymore. However, IPS release 6.0 doesnt differ much from release 5.x. The main benefit is the better integration into dynamips. If you still use VMWare approach (especially with Linux), i stongly suggest to consider using qemu from now on.
On the flip side, most of you would like to run 6.1 and newer because thats the version the CCIE Security lab uses today. Cisco finally introduced virtual sensors in this release. The catch is that since 6.1, support for most of the older platforms (like the IDS-4215) was wiped out. However, you can have up to 4 virtual sensors starting from the IPS-4235 in 6.0. And these devices are completely different in terms of qemu hardware "camouflage". I was able to upgrade a 4215 sensor to 6.2 and to make it behave like a 4240, but there is still work to do here.
So for now, 6.0 is ok, 6.1 and newer (including 7) doesnt work well and needs additional work. In this guide, I describe a sensor with 3 1000 Mbps NICs (1x C&C, 2x sensing), you can add more sensing interfaces if you like.
[edit] Dependencies
A Cisco IPS recovery CD is required. Log on to CCO and navigate at the download section through
Security > Intrusion Prevention System, IPS Appliances, IPS 4200 Sensors, IDS 4250 Sensor > Intrusion Prevention System (IPS) System Software > 6.0(5)E3.
Download the file IPS-K9-cd-1.1-a-6.0-5-E3.iso and place it at ~/ips/cisco-files. The guide assumes that the working directory for the IPS qemu will be ~/ips.
[edit] qemu Installation on Linux
You need a PC running Linux (x32 or x64) - I didnt had time to check how this procedure would work with windows (contributions are welcome). I did my testing with Ubuntu 9.10, x64 and 10.04 x64. The qemu version that ships with Ubuntu is fine to get the IPS up and running, but you need to apply a patch for dynamips connectivity through the UDP NIO.
It is the same patch used for Olive emulation - only the UDP NIC code is required, but we apply it completely (including modifications to eepro100 for multicast etc.). We need to use qemu 0.11, because it has the SMBIOS handling incorporated, and its possible in this release to hand various DMI/SMBIOS string through command line arguments (no need to modify a BOCHS BIOS anymore). The Olive patches were written for older qemu releases; luckily Jeremy Grossmann ported the patches to 0.11 (thanks!) - take a look on the article his GNS3 blog, [1].
mkdir -p ~/ips/cisco-files mv <whereever-the-file-is>/IPS-K9-cd-1.1-a-6.0-5-E3.iso ~/ips/cisco-files
For qemu, we need to get additional packages first.
sudo apt-get install build-essential libncurses5-dev libsdl-dev libpcap-dev zlib1g-dev
Now its time to install kvm Both kvm and kqemu seem to break everything after enabling the sensing interfaces and start sending traffic through the IPS.
Get the qemu 0.11 source, apply the patch, compile and install.
mkdir ~/src cd ~/src wget http://download.savannah.gnu.org/releases/qemu/qemu-0.11.0.tar.gz tar xvzf qemu-0.11.0.tar.gz cd qemu-0.11.0 wget http://www2.gns3.net/files/qemu-0.11.0-olive.patch patch -p1 -i qemu-0.11.0-olive.patch ./configure --target-list=i386-softmmu make sudo make install
Last, prepare the qemu environment by creating two disk images:
cd ~/ips qemu-img create ips-disk1.img 512M qemu-img create ips-disk2.img 4000M
[edit] Preparation and Installation of the sensor
[edit] IDS-4235 (IPS release 6.0)
Start qemu and load the CD Image downloaded earlier. As you can see, we provide the product ID that the appliance will query later on through on the command line. There are other values that you can set, but this is the bare minimum required to fool the IPS code; providing other IDs will not have any effect.
qemu -hda ips-disk1.img -hdb ips-disk2.img -m 1024 -smbios type=1,product="IDS-4235" \
-cdrom cisco-files/IPS-K9-cd-1.1-a-6.0-5-E3.iso -boot d
Now qemu boots, press "k" to start the reimaging process. Dont worry about error messages regarding failed platform detection, thats normal at this stage. When the process is done, the software reloads, and qemu pauses in the BIOS screen complaining about boot issues. Exit the qemu process.
Next step is to boot from the disk. When the system starts, you need to modify the grub boot entry to make sure the system starts at runlevel 1. Note: there is a 10 second timer, sou at the grub menu, you must press the "e" key to interrupt the normal boot sequence. Ok, start qemu again, now with the final command line arguments. WARNING! The strings must be all presented in the startup file, since the IPS validator checks those strings to be in place.
qemu -name IPS4235 ips-disk1.img -hdb ips-disk2.img -m 1024 \ -smbios type=0,vendor="Phoenix Technologies Ltd.",version="1.10",date="09/30/2002",release="A04" \ -smbios type=1,product="IDS-4235",manufacturer="Cisco Systems",version="1.0",serial="12345789012",uuid="E0A32395-8DFE-D511-8C31-001FC641BA6B",sku="011",family="IDS-4235/4250" \ -serial telnet::2023,server,nowait \ -net nic,vlan=1,macaddr=00:00:00:40:40:00,model=e1000 -net udp,vlan=1,sport=51300,dport=41300,daddr=127.0.0.1 \ -net nic,vlan=2,macaddr=00:00:00:40:40:01,model=e1000 -net udp,vlan=2,sport=51301,dport=41301,daddr=127.0.0.1 \ -net nic,vlan=3,macaddr=00:00:00:40:40:02,model=e1000 -net udp,vlan=3,sport=51302,dport=41302,daddr=127.0.0.1 \ -net nic,vlan=4,macaddr=00:00:00:40:40:03,model=e1000 -net udp,vlan=4,sport=51303,dport=41303,daddr=127.0.0.1 \ -net nic,vlan=5,macaddr=00:00:00:40:40:04,model=e1000 -net udp,vlan=5,sport=51304,dport=41304,daddr=127.0.0.1 \
At the grub menu, press "e" to edit the first boot entry. In the following menu, select the 2nd line (that starts with "kernel=") and press "e" again. Change the option init=/loadrc to init=1, then Enter followed by "b" to boot.
The IPS software now boots into runlevel 1. When prompted, press Enter and do the follwing
/loadrc cd /etc/init.d ./rc.init cp ids_functions ids_functions.orig vi ids_functions
The file controls the selection of the platform based on various criteria (asset data read through i2c, CPU speed etc.). Also, the default command and control interface gets selected. We trick the selection process by making sure that a IDS-4235 gets detected (the other detection steps fail here, obviously). In that file, search for the string "845" (with vi: /845), it will jump to the following section:
elif [[ `isCPU 845` -eq $TRUE && $NUM_OF_PROCS -eq 1 ]]; then
MODEL=$IDS4215
HTLBLOW=8
MEM_PAGES=${HTLBLOW}
DEFAULT_MGT_OS="fe0_0"
DEFAULT_MGT_CIDS="FastEthernet0/0"
Replace the first line (the elif statement) and the variables DEFAULT_MGT_OS and DEFAULT_MGT_CIDS to the following:
elif [[ 1 -eq 1 ]]; then
MODEL=$IDS4235
HTLBLOW=32
MEM_PAGES=${HTLBLOW}
DEFAULT_MGT_OS="ma0_0"
DEFAULT_MGT_CIDS="Management0/0"
Save and exit vi.
Now its time to adjust the process of mapping the emulated NIC cards to the IPS interfaces.
cd /usr/cids/idsRoot/etc cp interfaces.conf interfaces.conf.orig vi interfaces
Move forward to the section that deals with the 4235 sensor. The E1000 Intel cards provided by qemu use PCI vendor ID 0x8086 and device ID 0x100e. They are at PCI bus #0, the first card uses ID #3, the second ID #4, the third ID #5 and so on. You only need to make modifications at the [models/IDS-4250/interfaces/X] sections. There is an alias for the 4235 linked to 4250 models. Do not touch it.
The follwoing attributes must be changed:
name-template will be GigabitEthernet0/x, where x starts with 0 and increases by 1, at each sectionn port-number will be an increasing number, starting with 0 and increasing by 1, at each section pci-path= will be x.0, starting with 3 and increasing by 1, at each section vendor-id will always be 0x8086 device-id will always be 0x100e type will always be ge fixed-speed will always be yes fixed-duplex will always be yes For the Command and Control interface (GigabitEthernet0/0), set these two arguments: mgmt-capable net-dev-only=yes For any sensing interface (GigabitEthernet0/1 and /2), set these two arguments: sensing-capable=yes tcp-reset-capable=yes
Edit through the sections, the result must look like this:
[models/IDS-4250/interfaces/1]
name-template=Management0/0
port-number=0
pci-path=3.0
vendor-id=0x8086
device-id=0x100e
type=ge
mgmt-capable=yes
net-dev-only=yes
tcp-reset-capable=yes
[models/IDS-4250/interfaces/2]
name-template=GigabitEthertnet0/0
port-number=1
pci-path=4.0
vendor-id=0x8086
device-id=0x100e
type=ge
sensing-capable=yes
tcp-reset-capable=yes
[models/IDS-4250/interfaces/3]
name-template=GigabitEthernet0/1
port-number=2
pci-path=5.0
vendor-id=0x8086
device-id=0x100e
type=ge
sensing-capable=yes
tcp-reset-capable=yes
[models/IDS-4250/interfaces/4]
name-template=GigabitEthernet0/2
port-number=0
pci-path=6.0
vendor-id=0x8086
device-id=0x100e
type=ge
sensing-capable=yes
tcp-reset-capable=yes
[models/IDS-4250/interfaces/5]
name-template=GigabitEthernet0/3
port-number=0
pci-path=7.0
vendor-id=0x8086
device-id=0x100e
type=ge
sensing-capable=yes
tcp-reset-capable=yes
Save the changes and exit vi. The system changes are done, now reload the device
reboot
After the reboot, the system will detect changed hardware and reload by itself. When it comes up again, its fully functional. At the command promt, log in with the user cisco and the password cisco. The appliance prompts you to change the password for the user cisco. After this is done, you are at the CLI prompt.
Please verify that after the final reload, the model identification process must detect no change and give out the correct platform:
Checking model identification [ OK ] Model: IDS-4235 Model=IDS-4235
Also, when logging in, there must be no warning regarding "unsupported platform", only the copyright and maybe a notice regarding a missing license key should appear.
In addition, you should configure a service user account soon. This account enables you to directly log into the UNIX environment, bypassing the CLI:
conf t username service privilege service password <somepassword>
Now your qemu-powered IPS appliance is ready for normal usage. Of course, with the network settings provided above, it is isolated from the host operating system and any other device. Possible options to make it attach to other equipment are:
- attaching to the host using qemu user nic type (not very useful for the IPS)
- bridging to a real NIC with the qemu tun nic type
- attaching to dynamips instances with the qemu udp nic type
Of course, these methods can be combined - for example bridging the C&C interface to a real NIC to access the IPS IDM console from a windows PC and attaching the sensing interfaces to dynamips instances (router ports, or even ESW-16 switchports) for traffic inspection. Please see the last section for details.
[edit] What works
tested IDS-4235 with IPS 6.0.(5)E3 software release
- access the sensor from a different box (windows) via IDM (bridged interface)
- configuration and monitoring with IDM (although its slow)
- communication with dynamips with the help of NIO UDP
- communication between two dynamips routers through inline sensor config (running basic IP and forming a full OSPF adjacency)
- inline traffic inspection and traffic blocking
- qemu multicast support (OSPF broadcast type network works through inline sensor)
- shunning PIX/ASA works, but the ssh key must be 768-bit or lower, otherwise there is an error popping up when you try to add a device to Known Hosts list
[edit] Notes
After initial bootup and configuration, the system behaves very slow. This is because the signature engine initializes - this may take time (here it took around 10 minutes). For future starts, this procedure happens again, but it will run much faster because of cached data (guess). Using kvm greatly speeds up this process messes everything up once you enabled sensing interfaces and start to use them.
[edit] Known Issues
- The IPS complains that its interfaces are in the wrong duplex/speed settings, sending error messages into the logs. Just disregard this messages, they do not affect the functionality of the device.
- I could not get release 6.0.6 working. As soon as I try to ping anything from the IPS it freezes.
[edit] Some Tips
[edit] Bridging the C&C interface to a real network
You must have support for tun/tap devices (ships with most distribution), and the bridge-utils package. Your normal networking will change as you need to bridge the real NIC to a bridge interface, usually when the system starts. Any IP configuration that was done on the real NIC now must be done on the bridge interface. Later, when staring qemu, a tap interface is created that will be bridged to this bridge interface too.
The whole process of configuring bridging depends on the distribution. For Debian/Ubuntu, you can try the following:
$ cat /etc/network/interfaces auto lo iface lo inet loopback auto br0 iface br0 inet static address 192.168.10.2 netmask 255.255.255.0 gateway 192.168.10.254 nameserver 192.168.10.1 bridge_ports eth0 bridge_stp off bridge_maxwait 5
When invoking qemu, you need to add a vlan designation that ties the e1000 nic and the tap interface together:
qemu -hda ips-disk1.img -hdb ips-disk2.img -m 1024 -smbios type=1,product="IDS-4235" \
-net nic,vlan=1,model=e1000 -net tap,vlan=1,name=tap1 -net nic,model=e1000 \
-net nic,model=e1000
For debian/ubuntu, this command will start the script /etc/qemu-ifup that controls the addition of the tap1 interface to the bridge.
[edit] Integration into dynamips
The patch you applied earlier enables qemu to talk to dynamips through UDP; now qemu has a special nic type for that. You must configure both qemu and dynamips/dynagen to connect the various devices together. Please note that the UDP ports come in pairs for each network interface (send and receive), and you must swap them between the devices.
For the qemu side of things, there is this vlan designation again:
qemu -name IPS4235 ips-disk1.img -hdb ips-disk2.img -m 1024 \ -smbios type=0,vendor="Phoenix Technologies Ltd.",version="1.10",date="09/30/2002",release="A04" \ -smbios type=1,product="IDS-4235",manufacturer="Cisco Systems",version="1.0",serial="12345789012",uuid="E0A32395-8DFE-D511-8C31-001FC641BA6B",sku="011",family="IDS-4235/4250" \ -serial telnet::2023,server,nowait \ -net nic,vlan=1,macaddr=00:00:00:40:40:00,model=e1000 -net udp,vlan=1,sport=51300,dport=41300,daddr=127.0.0.1 \ -net nic,vlan=2,macaddr=00:00:00:40:40:01,model=e1000 -net udp,vlan=2,sport=51301,dport=41301,daddr=127.0.0.1 \ -net nic,vlan=3,macaddr=00:00:00:40:40:02,model=e1000 -net udp,vlan=3,sport=51302,dport=41302,daddr=127.0.0.1 \ -net nic,vlan=4,macaddr=00:00:00:40:40:03,model=e1000 -net udp,vlan=4,sport=51303,dport=41303,daddr=127.0.0.1 \ -net nic,vlan=5,macaddr=00:00:00:40:40:04,model=e1000 -net udp,vlan=5,sport=51304,dport=41304,daddr=127.0.0.1 \
I'm sure most people run dynagen and not native dynamips anymore, so I will provide a sample for a dynagen .net file:
# # Attaches R1 to NIC #1 (Ma0/0) of the sensor # note that the UDP ports are swapped # [[Router R1]] model = 3640 autostart = false slot0 = NM-4E E0/0 = NIO_udp:41300:127.0.0.1:51300 # # Attaches R2 to NIC #2 (Gi0/0) of the sensor # note that the UDP ports are swapped # [[Router R2]] model = 3640 autostart = false slot0 = NM-4E E0/0 = NIO_udp:41301:127.0.0.1:51301