Introduction

In this post I will cover how to create a Cisco ASAv Vagrant box for use with the vagrant-libvirt provider as well as enabling the REST API.

This post assumes a working installation of Vagrant with the vagrant-libvirt plugin already installed. You can follow this post to get the vagrant-libvirt plugin installed.

For reference the following software will be used in this post.

  • ASAv - asav992.qcow2
  • Vagrant - Vagrant 2.1.0
  • vagrant-libvirt - 0.0.43

Download

Navigate to the Cisco software download page and download the asav992.qcow2 image. This image also contains the REST API plugin so there is no need to download that separately.

Note

A valid support contract may be required to download the ASAv image. It is possible to download an ASAv image as part of a VIRL subscription. At the time of writing asav971.qcow2 is the latest VIRL version.

Install

Create and change into directory for ASAv files. I like to keep my custom vagrant boxes under ~/vagrant/boxes/.


mkdir -p ~/vagrant/boxes/cisco/asav
cd ~/vagrant/boxes/cisco/asav
            

Copy the ASAv files downloaded earlier to the ~/vagrant/boxes/cisco/asav/ directory.


cp ~/Downloads/asav992.qcow2 .
          

The good folks who maintain the vagrant-libvirt plugin have a script can be used to convert qcow2 images to a vagrant box. Download the libvirt convertsion script.


curl -O https://raw.githubusercontent.com/vagrant-libvirt/vagrant-libvirt/master/tools/create_box.sh
          

Use a text editor to create a bootstrap config named day0-config with the below contents that will be applied to the ASAv on first boot.


# day0-config
!
console serial
!
interface Management0/0
 nameif management
 security-level 0
 ip address dhcp
 no shutdown
!
hostname asav
!
username enable_1 privilege 15
username vagrant password vagrant privilege 15
aaa authentication ssh console LOCAL
aaa authentication http console LOCAL
aaa authorization exec LOCAL auto-enable
ssh version 2
crypto key generate rsa modulus 2048
ssh 0.0.0.0 0.0.0.0 management
ssh key-exchange group dh-group14-sha1
http server enable
http 0.0.0.0 0.0.0.0 management
domain-name lab.local
!
username vagrant attributes
  service-type admin
  ssh authentication publickey AAAAB3NzaC1yc2EAAAABIwAAAQEA6NF8iallvQVp22WDkTkyrtvp9eWW6A8YVr+kz4TjGYe7gHzIw+niNltGEFHzD8+v1I2YJ6oXevct1YeS0o9HZyN1Q9qgCgzUFtdOKLv6IedplqoPkcmF0aYet2PkEDo3MlTBckFXPITAMzF8dJSIFo9D8HfdOV0IAdx4O7PtixWKn5y2hMNG0zQPyUecp4pzC6kivAIhyfHilFR61RGL+GPXQ2MWZWFYbAGjyiYJnAmCP3NOTd0jMZEnDkbUvxhMmBYSdETk1rRgm+R4LOzFUGaHqHDLKLX+FIPKcF96hrucXzcWyLbIbEgE98OHlnVYCzRdK8jlqm8tehUc9c9WhQ==
!
rest-api image boot:/asa-restapi-132300-lfbff-k8.SPA
rest-api agent
!
          

Create an ISO named day0.iso with the genisoimage command that contains the day0-config file created earlier. This ISO will be mounted on boot and the bootstrap configuration will be applied automagically.


genisoimage -r -o day0.iso day0-config

# output
I: -input-charset not specified, using utf-8 (detected in locale settings)
Total translation table size: 0
Total rockridge attributes bytes: 252
Total directory bytes: 0
Path table size(bytes): 10
Max brk space used 0
176 extents written (0 MB
          

Launch the Cisco ASAv VM.


virt-install \
    --connect=qemu:///system \
    --network network=vagrant-libvirt,model=virtio \
    --name=asav \
    --cpu host \
    --arch=x86_64 \
    --machine=pc-1.0 \
    --vcpus=1 \
    --ram=2048 \
    --os-type=linux \
    --noacpi \
    --virt-type=kvm \
    --watchdog i6300esb,action=reset \
    --disk path=asav992.qcow2,format=qcow2,device=disk,bus=virtio,cache=writethrough \
    --disk path=day0.iso,format=iso,device=cdrom \
    --graphics none \
    --import
            

You will be automatically connected to the console.


# output
WARNING  CDROM media does not print to the text console by default, so you likely will not see text install output. You might want to use --location. See the man page for examples of using --location with CDROM media

Starting install...
Creating domain...                                                                                                                                                           |    0 B  00:00:03
Connected to domain asav
Escape character is ^]
loader: Platform type set to default
Platform ASAv
.
.
<snip>
.
.
Trustpoint CA certificate accepted.
User enable_1 logged in to asa
Logins over the last 1 days: 1.
Failed logins since the last login: 0.
Type help or '?' for a list of available commands.
asav>
          

Check the IP address assigned via DHCP.


show int ip brie

# output
Interface                  IP-Address      OK? Method Status                Protocol
Management0/0              192.168.121.89  YES DHCP   up                    up
          

From your host terminal confirm you can SSH to the ASAv with the vagrant SSH key.


# host terminal
ssh vagrant@192.168.121.89 -i ~/.vagrant.d/insecure_private_key

# now in ASAv VM
User vagrant logged in to asav
Logins over the last 1 days: 1.
Failed logins since the last login: 0.
Type help or '?' for a list of available commands.
asav# exit
          

Now confirm you can access the ASAv via the REST API.


# host terminal
curl -k https://vagrant:vagrant@192.168.121.89/api/objects/networkobjects

# output
{"selfLink":"https://192.168.121.89/api/objects/networkobjects","rangeInfo":{"offset":0,"limit":0,"total":0},"items":[]}
          

If you successfully connected, exit and power off the VM.

To exit the console press and hold CTRL and SHIFT while pressing 6 then ]

Now power off the VM.


virsh destroy asav

# output
Domain asav destroyed
          

Create a file called metadata.json with the following contents.


{"provider":"libvirt","format":"qcow2","virtual_size":9}
            

Use the previously downloaded script create_box.sh to create a vagrant box.


bash create_box.sh asav992.qcow2

# output
{9}
==> Creating box, tarring and gzipping
./metadata.json
./Vagrantfile
./box.img
Total bytes written: 226959360 (217MiB, 21MiB/s)
==> asav992.box created
==> You can now add the box:
==>   'vagrant box add asav992.box --name asav992'
            

Create a metadata file called asav.json so that the box is added with the correct version number.


{
  "name": "cisco/asav",
  "description": "Cisco ASAv",
  "versions": [
    {
      "version": "9.9.2",
      "providers": [
        {
          "name": "libvirt",
          "url": "file:///home/bradmin/vagrant/boxes/cisco/asav/asav992.box"
        }
      ]
    }
  ]
}
          

Add the box to Vagrant.


vagrant box add asav.json

# output
==> box: Loading metadata for box 'asav.json'
    box: URL: file:///home/bradmin/vagrant/boxes/cisco/asav/asav.json
==> box: Adding box 'cisco/asav' (v9.9.2) for provider: libvirt
    box: Unpacking necessary files from: file:///home/bradmin/vagrant/boxes/cisco/asav/asav992.box
==> box: Successfully added box 'cisco/asav' (v9.9.2) for 'libvirt'!
            

Confirm the box was added successfully


vagrant box list

# output
CumulusCommunity/cumulus-vx          (libvirt, 3.4.2)
arista/veos                          (libvirt, 4.20.1F)
cisco/asav                           (libvirt, 9.9.2)
cisco/csr1000v                       (libvirt, 03.15.00.S-155-2-S)
cisco/iosv                           (libvirt, 15.6-1-T)
              

Testing

Now that we have the box installed lets create a Vagrantfile and confirm we can build VM's with Vagrant.

Create a test directory.


mkdir ~/asav-test
cd ~/asav-test
          

Add a Vagrantfile to the test directory with the following contents


# -*- mode: ruby -*-
# vi: set ft=ruby :

Vagrant.configure("2") do |config|
  config.vm.define "fw01" do |node|
    node.vm.box = "cisco/asav"

    # Turn off shared folders
    node.vm.synced_folder ".", "/vagrant", disabled: true

    # Do not try to insert new SSH key
    node.ssh.insert_key = false

    # Give VM time to boot
    node.vm.boot_timeout = 180

    # Set guest type to prevent guest type detection
    node.vm.guest = :freebsd

    # Provider-specific configuration
    node.vm.provider :libvirt do |domain|
      domain.nic_adapter_count = 8
      domain.memory = 2048
      domain.cpus = 1
      domain.driver = "kvm"
    end
  end
end
            

Now vagrant up and confirm you can login.


vagrant up

# output
Bringing machine 'fw01' up with 'libvirt' provider...
==> fw01: Checking if box 'cisco/asav' is up to date...
==> fw01: Creating image (snapshot of base box volume).
==> fw01: Creating domain with the following settings...
==> fw01:  -- Name:              asav_fw01
==> fw01:  -- Domain type:       kvm
==> fw01:  -- Cpus:              1
==> fw01:
==> fw01:  -- Feature:           acpi
==> fw01:  -- Feature:           apic
==> fw01:  -- Feature:           pae
==> fw01:  -- Memory:            2048M
==> fw01:  -- Management MAC:
==> fw01:  -- Loader:
==> fw01:  -- Base box:          cisco/asav
==> fw01:  -- Storage pool:      default
==> fw01:  -- Image:             /var/lib/libvirt/images/asav_fw01.img (9G)
==> fw01:  -- Volume Cache:      default
==> fw01:  -- Kernel:
==> fw01:  -- Initrd:
==> fw01:  -- Graphics Type:     vnc
==> fw01:  -- Graphics Port:     -1
==> fw01:  -- Graphics IP:       127.0.0.1
==> fw01:  -- Graphics Password: Not defined
==> fw01:  -- Video Type:        cirrus
==> fw01:  -- Video VRAM:        9216
==> fw01:  -- Sound Type:
==> fw01:  -- Keymap:            en-us
==> fw01:  -- TPM Path:
==> fw01:  -- INPUT:             type=mouse, bus=ps2
==> fw01: Creating shared folders metadata...
==> fw01: Starting domain.
==> fw01: Waiting for domain to get an IP address...
==> fw01: Waiting for SSH to become available...
==> fw01: Configuring and enabling network interfaces...
            

Confirm you can login to the box.


# Host terminal
vagrant ssh

# Now in vagrant box terminal
User vagrant logged in to asav
Logins over the last 1 days: 7.  Last login: 10:16:37 UTC May 7 2018 from 192.168.121.1
Failed logins since the last login: 0.
Type help or '?' for a list of available commands.
asav# show version

Cisco Adaptive Security Appliance Software Version 9.9(2)
Firepower Extensible Operating System Version 2.3(1.84)
Device Manager Version 7.9(2)

Compiled on Sun 25-Mar-18 17:32 PDT by builders
System image file is "boot:/asa992-smp-k8.bin"
Config file at boot was "startup-config"

asav up 1 min 37 secs

Hardware:   ASAv, 2048 MB RAM, CPU Xeon 5600 series 2393 MHz,
Model Id:   ASAv10
Internal ATA Compact Flash, 8192MB
Slot 1: ATA Compact Flash, 8192MB
BIOS Flash Firmware Hub @ 0x0, 0KB


 0: Ext: Management0/0       : address is 5254.0017.5463, irq 10

License mode: Smart Licensing
ASAv Platform License State: Unlicensed
No active entitlement: no feature tier and no throughput level configured
*Memory resource allocation is more than the permitted limit.

Licensed features for this platform:
Maximum VLANs                     : 50
Inside Hosts                      : Unlimited
Failover                          : Active/Standby
Encryption-DES                    : Enabled
Encryption-3DES-AES               : Enabled
Security Contexts                 : 0
Carrier                           : Disabled
AnyConnect Premium Peers          : 2
AnyConnect Essentials             : Disabled
Other VPN Peers                   : 250
Total VPN Peers                   : 250
AnyConnect for Mobile             : Disabled
AnyConnect for Cisco VPN Phone    : Disabled
Advanced Endpoint Assessment      : Disabled
Shared License                    : Disabled
Total TLS Proxy Sessions          : 2
Botnet Traffic Filter             : Enabled
Cluster                           : Disabled

Serial Number: 9A73HB13VFB

Image type          : Release
Key version         : A

Configuration has not been modified since last system restart.
asav#
            

We can build and login to the box with Vagrant. Lastly, let clean up a bit.


# back in host shell
vagrant destroy -f

# output
==> fw01: Removing domain...
          

Remove the original KVM image.


rm -f asav.qcow2
virsh undefine asav

# output
Domain asav has been undefined
          

Summary

The Cisco ASAv qemu image was successfully converted to a Vagrant libvirt box with the REST API enabled. Without a license what you can do is limited, but there is still enough functionality to get value from the platform. If you have a licensing contract, more power to you. Now go out there and automate the stuffing out of it.

Links

https://www.cisco.com/c/en/us/td/docs/security/asa/asa99/asav/quick-start/asav-quick/asav-kvm.html
https://www.cisco.com/c/en/us/td/docs/security/asa/api/qsg-asa-api.html






















Published: 2018-05-07