Monday, January 25, 2010

Simulation Cisco ASA with QEMU and GNS3

My howto is based on this HOWTO: http://blog.gns3.net/2009/12/how-to-emulate-cisco-asa/

Credit to Jeremy Grossmann.

List of tools/software use in this simulation
  • VMware Worksatation
  • GNS3 0.7 RC1
  • QEMU v 0.9.0 
  • Cisco ASA image: asa802-k8.bin


Referring to the above diagram, VMachine1_HOST will be the host of  ASA which we're going to simulate. I chose CentOS-5.4-x86_64 for the VMachine1_HOST. Any other linux OS should be ok. VMachine1_HOST and VMachine2 (optional) actually guest OS, installed in VMware Worksation. Any other virtual machine software, e.g. VirtualBox, should be ok too.

To inter-connect between VMware guest OS with GNS3 virtual network, we need to:
  • Configure VMachine1_HOST to use "Host-only" network interface (vmnet1-7 & vmnet9).
  • Both VMachine1_HOST VMware guest OS and "Cloud" need to configured to use same vmnet network interface. Same rule apply to VMachine2 VMware guest OS and it "Cloud".
 MaulanaSS "Cloud" is to enable ASA to communicate with physical network.

However, this simulation is not perfect because only "one" side is connected to ASA. It should be two side connected to ASA which are "inside" & "outside" network. But, until ASA ver 8 can be fully simulated using GNS3, this is the closest simulation we can get.

The next step is to get an initrd and a Linux kernel from your ASA image to use them with Qemu and also fix the initrd for our needs. The initrd is zipped and archived in the ASA image, asa802-k8.bin, we have to extract it.

These steps need to be done at VMachine1_HOST:
1) Create an hexadecimal dump of your image:
hexdump -C asa802-k8.bin > asa802-k8.hex

2) Search for the ZIP header:
grep "1f 8b 08 00 1d" asa802-k8.hex
001228b0  1f 8b 08 00 1d 3d 73 46  00 03 ec 3a 6d 54 14 57  |…..=sF…:mT.W|
We can see that the ZIP file starts at offset 1228b0.

3) Let’s find the image size:
ls -la asa802-k8.bin
-rwxr-xr-x  1 root  staff  14524416 26 Nov 20:14 asa802-k8.bin
14524416 bytes.

4) Now we need to find out where in the file we can start extracting the ZIP part.
echo "14524416 ; ibase=16 ; last - 1228B0" | bc | tail -n 1
13334352

5) Extract the zipped part of the ASA image:
tail -c 13334352 asa802-k8.bin > asa802-k8.gz

6) Decompress it with gzip:
gzip -d asa802-k8
gzip: asa802-k8.gz: decompression OK, trailing garbage ignored

7) Make a temp directory and go into it so we can extract the files contained in the uncompressed archive file (the initrd):
mkdir tmp ; cd tmp

8) Now extract the archive with cpio (you must have the administrator rights to successfully extract device files).
cpio -i --no-absolute-filenames --make-directories < ../asa802-k8

9) Copy the Linux kernel to your previous directory:
cp vmlinuz ../asa802-k8.kernel

10) Before compressing back the initrd, create the following script in asa/scripts/first_start.sh:
(Modified by me for better execution)
#!/bin/sh

FIRST_START=no
if test ! -e /mnt/disk0/lina_monitor
then
######################################
# fdisk /dev/hda << EOF
#n
#p
#1
#5
#979
#t
#4
#w
#EOF
# mkdosfs -F 16 /dev/hda1
######################################
DEV=/dev/hda
MNT=/mnt/disk0

#
# Create fdisk.in based on starting cylinder parameter, etc
#
echo "d" >  /asa/scripts/fdisk.in
echo "o" >> /asa/scripts/fdisk.in
echo "n" >> /asa/scripts/fdisk.in
echo "p" >> /asa/scripts/fdisk.in
echo "1" >> /asa/scripts/fdisk.in
echo $2  >> /asa/scripts/fdisk.in
echo " " >> /asa/scripts/fdisk.in
echo "t" >> /asa/scripts/fdisk.in
echo "4" >> /asa/scripts/fdisk.in
echo "w" >> /asa/scripts/fdisk.in

/bin/umount $MNT > /dev/null 2> /dev/null
echo -n "Initializing partition - "
/sbin/fdisk $DEV < /asa/scripts/fdisk.in > /dev/null 2> /dev/null
echo "done!"
/sbin/mkdosfs -F 16 /dev/hda1
echo ""
echo "System tables written to disk"
######################################
 mount -t vfat -o umask=0000,noatime,check=s,shortname=mixed /dev/hda1 /mnt/disk0
 cp /asa/bin/lina /mnt/disk0/lina
 cp /asa/bin/lina_monitor /mnt/disk0/lina_monitor
 FIRST_START=yes
fi
modprobe e100
modprobe e1000
ifconfig eth0 up
ifconfig eth1 up
ifconfig eth2 up
ifconfig eth3 up
ifconfig eth4 up
ifconfig eth5 up
if test $FIRST_START = yes
then
 echo ""
 echo ""
 echo "This is your first boot, please wait about 1 min and then type the following commands:"
 echo "cd /mnt/disk0"
 echo "/mnt/disk0/lina_monitor"
 echo ""
 echo "Please note to use the following command under ASA to save your configs:"
 echo "copy run disk0:/.private/startup-config"
 echo ""
# exit
fi
cd /mnt/disk0
/mnt/disk0/lina_monitor 

11) Set asa/scripts/first_start.sh file executable:
chmod +x asa/script/first_start.sh
 
12) In order for the script to be loaded at startup, edit etc/init.d/rcS and change /asa/bin/lina_monitor with /asa/scripts/first_start.sh

13) Now you can compress all the file and have the initrd ready to use in Qemu:
find . | cpio -o -H newc | gzip -9 > ../asa802-k8.initrd.gz


Starting ASA with QEMU
Make sure these command executed in the same directory that contain ASA initrd, asa802-k8.initrd.gz,
& kernel, asa802-k8.kernel.
1) Create FLASH file (QEMU virtual hard disk):
qemu-img create FLASH 256M

2) Create custom script, called qemu_ifup.sh, to automatically bring up "tap0" interface and enable TCP/IP forwarding at VMachine1_HOST:
#!/bin/sh
ifconfig tap0 192.168.222.222
echo 1 > /proc/sys/net/ipv4/ip_forward

3) Start ASA using QEMU command:
(add parameter to support communication with host computer)
qemu -m 256 -hda FLASH -kernel asa802-k8.kernel -initrd asa802-k8.initrd.gz -nographic -append "auto nousb console=ttyS0,9600 bigphysarea=16384 ide1=noprobe hda=980,16,32" -net "nic,vlan=0,macaddr=00:00:ab:cd:ef:00,model=pcnet" -net "nic,vlan=1,macaddr=00:00:ab:cd:ef:01,model=pcnet" -net "nic,vlan=2,macaddr=00:00:ab:cd:ef:02,model=pcnet" -net "nic,vlan=3,macaddr=00:00:ab:cd:ef:03,model=pcnet" -net "nic,vlan=4,macaddr=00:00:ab:cd:ef:04,model=pcnet" -net "nic,vlan=5,macaddr=00:00:ab:cd:ef:05,model=pcnet" -net "tap,vlan=0,ifname=tap0,script=qemu_ifup.sh" -serial "telnet::3000,server,nowait" -hdachs "980,16,32"
or you can create script file, e.g. called cisco_asa8.sh.

As you can see, the first ASA NIC port (interface Ethernet 0/0) and VMachine1_HOST tap0 interface is in the same VLAN (vlan=0). So, ASA interface Ethernet 0/0 IP address should be in the same subnet with VMachine1_HOST tap0 IP address. This way ASA can communicate with VMachine1_HOST computer and physical network.

If you decided to simulate ASA with another appliance, e.g. Cisco router 3640, you can use diagram at the beginning of the HOWTO as an example.


How to save configuration on ASA
For unknown reason, we cannot use write command to save configuration. However, there is workaround to overcome this issue. copy command will be use instead to save configuration:
copy run disk0:/.private/startup-config

Good luck!!!

2 comments:

  1. Hello, thanks is a fully help me, but I ask you:
    how connect the asa to the real Network, with qemu/kvm

    ReplyDelete
  2. Good question! If I remember correctly, you can bridge one of the ASA ethernet interface with physical ethernet interface. This way you can connect ASA with real network.

    Sorry, I already forgot how to do it exactly. ;)

    ReplyDelete