Tag Archives: firewall

Cisco ASAv firewall REST API: Bulk Requests

Introduction

Continuing on the same track with ASA REST API we are going to explore how to be more efficient when firing up the json code toward our firewalls. In previous example we created a small number of service and network objects and groups, today we are going to experiment with larger number of objects created by smaller number of calls. Lets get the ball rolling.

Bulk service object creation

To create a bulk request we need to adjust some parameters such as API endpoint URL. As you recall, when we created a new service object we were pointing to this URL: https://<management-ip>/api/objects/networkservices.

Now we are going to redesign the call a little bit and will always point to same endpoint regardless of object type. We will simply use https://<management-ip>/api and the more specific resource URI will be part request body. This allows us for example create bulk of service and network objects in one call.

[
  {
    "resourceUri": "/api/objects/networkservices",
    "data": {     
  "kind": "object#TcpUdpServiceObj",
  "name": "TCP-21",
  "value": "tcp/21"
}, "method": "Post" }, { "resourceUri": "/api/objects/networkservices",    "data": {
  "kind": "object#TcpUdpServiceObj",
  "name": "TCP-22",
  "value": "tcp/22"
}, "method": "Post" }, { "resourceUri": "/api/objects/networkservices",    "data": {
  "kind": "object#TcpUdpServiceObj",
  "name": "TCP-23",
  "value": "tcp/23"
}, "method": "Post" }, { "resourceUri": "/api/objects/networkservices", "data": {
  "kind": "object#TcpUdpServiceObj",
  "name": "TCP-24",
  "value": "tcp/24"
}, "method": "Post" }
]

If everything is hunky dory you will receive a Status Code 200 OK and response body will contain additional details.

{
"entryMessages":
[
     {
     "resourceUri":"/api/objects/networkservices",
     "method":"POST",
     "selfLink":"http://10.201.230.5/api/objects/networkservices/TCP-21",
     "messages":
     [
         {
         "level":"Info",
         "code":"201",
         "details":"Created (201) - The request has been fulfilled and resulted in a new resource being created"
          }
     ]
     },
     {
     "resourceUri":"/api/objects/networkservices",
     "method":"POST",
     "selfLink":"http://10.201.230.5/api/objects/networkservices/TCP-22",
     "messages":
     [
         {
         "level":"Info",
         "code":"201",
         "details":"Created (201) - The request has been fulfilled and resulted in a new resource being created"
         }
     ]
     },
     {
     "resourceUri":"/api/objects/networkservices",
     "method":"POST",
     "selfLink":"http://10.201.230.5/api/objects/networkservices/TCP-23",
     "messages":
     [
         {
         "level":"Info",
         "code":"201",
         "details":"Created (201) - The request has been fulfilled and resulted in a new resource being created"
         }
     ]
     },
     {
     "resourceUri":"/api/objects/networkservices",
     "method":"POST",
     "selfLink":"http://10.201.230.5/api/objects/networkservices/TCP-24",
     "messages":
     [
         {
         "level":"Info",
         "code":"201",
         "details":"Created (201) - The request has been fulfilled and resulted in a new resource being created"
         }
     ]
     }
],
"commonMessages":[]
}

Ideally your deployment script would examine the response and capture the self links that can be used to un-deploy this call. Also the message details are important to verify if objects were successfully created.

Now we are going to look at error handling by creating another request that will have one already existing object and one new in it.

[
  {
    "resourceUri": "/api/objects/networkservices",
    "data": {     
  "kind": "object#TcpUdpServiceObj",
  "name": "TCP-24",
  "value": "tcp/24"
}, "method": "Post" }, { "resourceUri": "/api/objects/networkservices", "data": {
  "kind": "object#TcpUdpServiceObj",
  "name": "TCP-25",
  "value": "tcp/25"
}, "method": "Post" }
]

The response header will contain 400 Bad Request status code and body will reveal some clues.

{
"entryMessages":
[
     {
     "resourceUri":"/api/objects/networkservices",
     "method":"POST",
     "messages":
     [
         {
         "level":"Error",
         "code":"DUPLICATE",
         "context":"objectId",
         "details":"TCP-24"
         }
     ]
     },
     {
     "resourceUri":"/api/objects/networkservices",
     "method":"POST"
     }
],
"commonMessages":[]
}

The result result is that even the second object did not exists it was not created. When you reverse the object order in request, it will not help either. This means that the entire request need to create unique objects otherwise it will fail. So watch for return codes.

I have tried to create 103 unique objects in one request and I have found that the upper limit for single request is 100 entries.

{
"commonMessages":
[
     {
     "level":"Error",
     "code":"MAX-ENTRIES-LIMIT-EXCEEDED",
     "details":"The number of entries found are, 103. The bulk entries limit:100"
     }
]
}

Lets go back to our first four service objects and undeploy them using four unique DELETE Requests. The resource URIs are as follows:

Note: So far I have not found way of performing multiple object removal in single request. It seems that bulk operation only supports POST method toward service objects at the moment. The following below did not work.

[
  {
    "resourceUri": "/api/objects/networkservices/TCP-21",
    "method": "Delete"
  },
  {
    "resourceUri": "/api/objects/networkservices/TCP-21",
    "method": "Delete"
  }
]

Response had status code 400 Bad Request even if those URI are indeed valid and you can query them with GET request.

{
"entryMessages":
[
     {
     "resourceUri":"/api/objects/networkservices/TCP-21",
     "method":"DELETE",
     "messages":
     [
         {
         "level":"Error",
         "code":"INVALID-INPUT",
         "details":"Invalid resourceUri:/api/objects/networkservices/TCP-21"
         }
     ]
     },
     {
     "resourceUri":"/api/objects/networkservices/TCP-21",
     "method":"DELETE",
     "messages":
     [
         {
         "level":"Error",
         "code":"INVALID-INPUT",
         "details":"Invalid resourceUri:/api/objects/networkservices/TCP-21"
         }
     ]
     }
],
"commonMessages":[]
}

The 100 objects limitations also affect how are the responses constructed. When you query the following resource https://<management-ip>/api/objects/networkservices you will see that the body contains only 100 items even if 110 exists. You can see this by examining the offset, limit and total fields on body.

{
   "kind": "collection#NetworkServiceObjects",
   "selfLink": "https://10.201.230.5/api/objects/networkservices",
   "rangeInfo":
   {
       "offset": 0,
       "limit": 100,
       "total": 110
   },

Funny enough, the list will not start with the first configure service objects, but started from TCP-100 up till TCP-200. To see other items you need to manipulate the offset value. We can demonstrate this using API Console at documentation page.

rest-api-offset

Now the item list will start from TCP-110 and will include our older objects such as TCP-21, TCP-22 etc. You can also play with the limit parameter to constrain number of returned objects. If you look at Inspector, you will see the request parameters have been modified to include our query parameters.

rest-api-offset-body

Conclusion

Bulk object creation and retrieval handling should help you build more efficient communication patters between the firewall and automation tool or network controller.

Advertisements

Cisco ASAv firewall HA Pair

Introduction

In previous post I have introduced and demonstrated the ASA in virtual form factor. This post will built on top of previous that one and will show you how to setup redundant high available pair of these firewalls.

The HA setup is ideal in situations where you are building virtual infrastructure hosted on private or public cloud that needs to be available all the time, surviving failure of one of the firewalls that run as virtual machines. Standard vSphere VM placement best practices should be also considered, such as anti-affinity rules and resource allocation. Consult these with you VMware administrators.

The following diagram outlines the final setup. My home lab only has one ESXi hosts, so everything is running over there.

ASAv HA Setup

Active Firewall rollout

Start with the deployment of first firewall which will be the active one. After downloading the OVA package from Cisco go to vSphere\Virtual Machines\Right Click on Cluster\Deploy OVF Template.

asav-ha-step1

After browsing and selecting the OVA package, I am using asav931.ova, you will be ask to accept the extra configuration options and estimated disk size requirements.

asav-ha-step2

Next, accept the license agreement and and click next. You will have an option to select the name of the new primary ASA which will be ASAv03-Active and the location of the VM.

asav-ha-step3

You will now have a choice to select deployment size, from 1vCPU Standalone all the way up to 4vCPU. If you are deploying in production, you should consult the deployment guide for the right flavor. I am deploying in lab, therefore I have selected 1vCPU HA Primary.

asav-ha-step4

After selecting the deployment size, we need to specify the resource that ASAv will consume. If you select a cluster DRS can automatically place the VM to least utilized hypervisor. You can also specify certain ESXi hosts. I have just one ESXi host, so the choice will be obvious.

asav-ha-step5

To same some storage space, change the default virtual disk format from Thick Provisioned to Thin Provision.

On the next page, we need to configure network mapping. ASAv has by default 10 vNIC adapters which first of them is the Management and the last Gig0/8 is used by HA Heartbeat. Remaining interfaces can be used for production traffic. We leave unused interface in DMZ for now.

asav-ha-step6

Now you have an option to Customize the template by typing configuration parameters such as Management Interface Settings, Device Manager IP Settings and HA Connection Settings.

The Management address of Primary Unit will be 172.16.2.1/24 and Secondary will be 172.16.2.2/24. The default gateway will not be required at this moment, our management station sits on the same virtual switch. To allow remote access from day 1, specify that the allowed management subnet is 172.16.2.0/24

The Primary Unit HA address will be 172.16.3.1/24 and the Secondary will be 172.16.3.2/24.

asav-ha-step7

In Ready to Complete page, you get the summary of all configuration options, and you will have a choice to Power VM after deployment. Congratulations you just deployed your first HA Pair Firewall. After first power on, ASAv will perform initial configuration and reboot.

If everything worked as expected, you should be able to log in from management station via SSH.

asav-ha-step8

By default, however, not username was configured in template therefore it is still needed to jump to virtual console and create one and point the AAA authentication for SSH to local user database.

It is also worth to mention that although ASDM https access was enable, it would still need to have an account and aaa authentication configured properly to work.

ciscoasa(config)# username admin password cisco privilege 15
ciscoasa(config)# enable password cisco
ciscoasa(config)# aaa authentication ssh console LOCAL

Now you can actually connect to the ASA remotely. If you examine the configuration a little bit you find that it has setup the failover interface and peer and currently shows that its mate is down/unknown.

ciscoasa# sh failover
Failover On
Failover unit Primary
Failover LAN Interface: fover GigabitEthernet0/8 (up)
Unit Poll frequency 1 seconds, holdtime 15 seconds
Interface Poll frequency 5 seconds, holdtime 25 seconds
Interface Policy 1
Monitored Interfaces 1 of 61 maximum
MAC Address Move Notification Interval not set
Version: Ours 9.3(1), Mate Unknown
Last Failover at: 10:16:56 UTC Feb 20 2015
        This host: Primary – Active
                Active time: 873 (sec)
                slot 0: empty
                  Interface management (172.16.2.1): Unknown (Waiting)
        Other host: Secondary – Failed
                Active time: 0 (sec)
                  Interface management (172.16.2.2): Unknown (Waiting)
 

ciscoasa# show failover state

State          Last Failure Reason      Date/Time
This host  –   Primary
Active         None
Other host –   Secondary
Failed         Comm Failure             10:17:13 UTC Feb 20 2015

====Configuration State===
====Communication State===

Standby Firewall rollout

Before we are going to configure the other interfaces, lets set up the secondary unit. Again we are going to start by deploying a template from .OVA. To save some space, I will only show difference from deploying the primary unit.

The VM name will be set to ASAv03-Standby, and the deployment configuration will be set to 1vCPU HA Secondary. Selecting the right resource in production should be also considered to minimize that a single hypervisor failure will cause both firewalls go down. Therefore I recommended anti-affinity rules so those two VMs will never run on same machine.

The interface mapping will be exactly same as with primary unit. See the reference above. In the customization template page, enter the Management IP address and HA IP address settings for this unit.

asav-ha-step9

Deployment of this small flavor took no longer than 30 seconds, and after the initial reboot the Standby firewall is up an running.

While still setting remotely on primary unit we are going to check the failover pair state again.

Beginning configuration replication: Sending to mate.
ciscoasa# show failover
Failover On
Failover unit Primary
Failover LAN Interface: fover GigabitEthernet0/8 (up)
Unit Poll frequency 1 seconds, holdtime 15 seconds
Interface Poll frequency 5 seconds, holdtime 25 seconds
Interface Policy 1
Monitored Interfaces 1 of 61 maximum
MAC Address Move Notification Interval not set
Version: Ours 9.3(1), Mate 9.3(1)
Last Failover at: 10:16:56 UTC Feb 20 2015
        This host: Primary – Active
                Active time: 2111 (sec)
                slot 0: empty
                  Interface management (172.16.2.1): Normal (Monitored)
        Other host: Secondary – Standby Ready
                Active time: 0 (sec)
                  Interface management (172.16.2.2): Normal (Waiting)

ciscoasa# sh failover state

               State          Last Failure Reason      Date/Time
This host  –   Primary
               Active         None
Other host –   Secondary
               Standby Ready  Comm Failure             10:17:13 UTC Feb 20 2015

====Configuration State===
        Sync Done
====Communication State===
        Mac set

====VM Properties Compatibility===
vCPUs – This host:  1
        Other host: 1
Memory – This host:  2048 Mhz
         Other host: 2048 Mhz
Interfaces – This host:  9
             Other host: 9

Looking much better now. To see failover in action, lets first complete the configuration of other interfaces to get some traffic flowing through the firewall

prompt hostname priority state
!
interface GigabitEthernet0/0
 description OUTSIDE
 nameif outside
 security-level 0
 ip address 10.0.2.91 255.255.255.0 standby 10.0.2.92
!
interface GigabitEthernet0/1
 description INSIDE
 nameif inside
 security-level 100
 ip address 172.16.0.1 255.255.255.0 standby 172.16.0.2
!
interface GigabitEthernet0/2
 description DMZ
 nameif dmz
 security-level 50
 ip address 172.16.1.1 255.255.255.0 standby 172.16.1.2
!
monitor-interface outside
monitor-interface inside
monitor-interface dmz
!
route outside 0 0 10.0.2.1
!
policy-map global_policy
 class inspection_default
  inspect icmp

My outside router does not have static routes to these private network behind ASA so a object NAT will help to mitigate that.

object network inside_net
 subnet 172.16.0.0 255.255.255.0
nat (inside,outside) source dynamic inside_net interface

Now we should have connectivity from inside host to Internet. We get verify that by pulling google web page from client and also checking the NAT or connection table.

ciscoasa# sh nat detail
Manual NAT Policies (Section 1)
1 (inside) to (outside) source dynamic inside_net interface
    translate_hits = 12, untranslate_hits = 0
    Source – Origin: 172.16.0.0/24, Translated: 10.0.2.91/24

Now start continuous ping from inside machine and power off the primary firewall.

root@deb01:~# ping -c 100 8.8.8.8
100 packets transmitted, 85 received, 15% packet loss, time 99250ms
rtt min/avg/max/mdev = 10.771/11.988/21.956/2.426

From the output, I examined that from 100 packets, 15 was lost during switchover. With default pool and hold times it was not amazingly fast. We can do better.

failover polltime unit 1 holdtime 3
failover polltime interface 1 holdtime 5

Repeat the 100 ping test again and examine the results.

Now with adjusted timers, from 100 packets we lost 4 during switchover. Getting better :-). Lets see how this HA pair will cope with TCP sessions.

We are going to initiate a large file download from inside host and then shutdown the secondary (now active) ASA and examine the result on traffic flow.

The primary ASA took back the role of Active Firewall, but the TCP session has died. There is one another parameter that we need to tweak for HTTP sessions and to explicitly enable them.

ciscoasa/pri/act(config)# failover replication http
Now initiate the download again, and check that it will be re-established after failover.

Conclusion

After tweaking some default settings you have a highly available firewall cluster running in fully visualized environment.

s

Cisco ASAv firewall REST API – Resource Manipulation

Introduction

After the initial article about ASAv REST API we are going to explore how we can granularity manipulate various resources such as objects and object-groups. You will learn how to create modify, verify and delete each object type.

This can be useful when building an automation tool that needs to perform various configuration changes programmatically.

Service Object

Service objects are one of the most common objects types used in firewall. They can define OSI Layer 4 TCP and UDP ports as well as other protocols such as ARP, or GRE. We are going to demonstrate some basic operations that can be carried out with this type of object. CLI reference is also provided for comparison with REST API.

Create

CLI Reference

object service UDP-88
 service udp destination eq 80

Request Format

Header:
URL: https//<management-ip>/api/object/networkservices
Method: POST

Body:

{
  "kind": "object#TcpUdpServiceObj",
  "name": "UDP-88",
  "value": "udp/80"
}

Response Format

Header:
Status Code: 201 Created
Accept-Ranges: bytes
Content-Length: 0
Date: Wed, 18 Feb 2015 09:52:01 GMT
Server: CiscoASARestApiServer
Vary: Accept-Charset, Accept-Encoding, Accept-Language, Accept

As you can see, when we created new object we got its location URI. We will reference this address when doing changes or object removal. For service object the reference name is the object ID.

Modify

CLI Reference

object service UDP-88
 service udp destination eq 88

Request Format

Header:
URL: https//<management-ip>/api/objects/networkservices/UDP-88
Method: PATCH

Body:

{
  “kind”: “object#TcpUdpServiceObj“,
  “name”: “UDP-88“,
  “value”: “udp/88
}

Response Header Format

Header:
Status Code: 204 No Content
Accept-Ranges: bytes
Content-Length: 0
Date: Wed, 18 Feb 2015 09:52:48 GMT
Server: CiscoASARestApiServer
Vary: Accept-Charset, Accept-Encoding, Accept-Language, Accept
Patch request can be used to change resource attributes such as value or name.

Retrieve

CLI Reference

show run | be object service UDP-88
 Note: As ASA CLI does not include show object id command, this was the easiest way how to list object in running configuration.

Request Format

Header:

URL: https://<management-ip>>/api/objects/networkservices/UDP-88
Method: GET

Body: Empty

Response Format

Header:
Status Code: 200 OK
Accept-Ranges: bytes
Content-Length: 158
Content-Type: application/json; charset=UTF-8
Date: Wed, 18 Feb 2015 09:58:14 GMT
Server: CiscoASARestApiServer
Vary: Accept-Charset, Accept-Encoding, Accept-Language, Accept
Body:
{
   “kind”: “object#TcpUdpServiceObj“,
   “name”: “UDP-88“,
   “value”: “udp/88“,
   “objectId”: “UDP-80
}

GET request does not require anything in request body and when referencing certain object ID such as UDP-88 it will return just single resource. To get list of all resources under parent resource just remove the ID from the end of URL.

Delete

CLI Reference

no object service UDP-88

Request Format

Header
URL: https://<management-ip>/api/objects/networkservices/TCP-88
Method: DELETE

Body: Empty

Response Format

Header:
Status Code: 204 No Content
Accept-Ranges: bytes
Content-Length: 0
Date: Wed, 18 Feb 2015 10:02:05 GMT
Server: CiscoASARestApiServer

With REST API Delete request, rules still apply that you cannot remove an object that is being used or referenced elsewhere in configuration.

Service Object Group

As name implies service object groups glue together multiple objets. This eases the configuration and provides a little abstraction and simplification when constructing access rules.

Create

CLI Reference

object-group service krb5-udp
 description Default Kerberos UDP port
 service-object object UDP-88

Request Format

(Object within object group)

Header:
URL: https://<management-ip>/api/objects/networkservicegroups
Method: POST

Body:

{
"kind": "object#NetworkServiceGroup",
"name": "krb5-udp",
"members":
[
{
"kind": "objectRef#TcpUdpServiceObj",
"objectId": "UDP-88"
}
],
"description": "Default Kerberos UDP port"
}

Response Format

Header:
Status Code: 200 OK
Accept-Ranges: bytes
Content-Length: 124
Content-Type: application/json; charset=UTF-8
Date: Wed, 18 Feb 2015 10:35:10 GMT
Server: CiscoASARestApiServer
Vary: Accept-Charset, Accept-Encoding, Accept-Language, Accept

Request Format

(Object group within another object group)

CLI Reference

object-group service krb5-udp
 group-object krb5-udp

Header:

URL: https://<management-ip>/api/objects/networkservicegroups
Method: POST

Body:

{
"kind": "object#NetworkServiceGroup",
"name": "active-directory",
"members":
[
{
"kind": "objectRef#NetworkServiceGroup",
"objectId": "krb5-udp"
}
],
"description": "Default Active Directory ports"
}

Response Format

Header:
Status Code: 201 Created
Accept-Ranges: bytes
Content-Length: 0
Date: Wed, 18 Feb 2015 11:06:44 GMT
Server: CiscoASARestApiServer
Vary: Accept-Charset, Accept-Encoding, Accept-Language, Accept

Modify

CLI Reference

object-group service krb5-udp
 group-object krb5-udp
 group-object krb5-tcp

Request Format

(To change/add objects withing a group)

URL: https://<management-ip>/api/objects/networkservicegroups/active-directory
Method: PATCH

Body:

{
"kind": "object#NetworkServiceGroup",
"name": "active-directory",
"members":
[
{
"kind": "objectRef#NetworkServiceGroup",
"objectId": "krb5-udp"
},
{ "kind": "objectRef#NetworkServiceGroup", "objectId": "krb5-tcp" } ], "description": "Default Active Directory ports" }

Response Format

Header:
Status Code: 204 No Content
Content-Length: 0
Location: https://10.201.230.5/api/objects/networkservicegroups/active-directory
Server: CiscoASARestApiServer
Accept-Ranges: bytes
Vary: Accept-Charset, Accept-Encoding, Accept-Language, Accept
Date: Wed, 18 Feb 2015 11:57:32 GMT

Retrieve

CLI Reference

show object-group id active-directory

Request Format

 

URL: https://<management-ip>>/api/objects/networkservicegroups/active-directory
Method: GET

Body: Empty

Response Format

Header:

Status Code: 200 OK
Accept-Ranges: bytes
Content-Length: 512
Content-Type: application/json; charset=UTF-8
Date: Wed, 18 Feb 2015 12:01:52 GMT
Server: CiscoASARestApiServer
Vary: Accept-Charset, Accept-Encoding, Accept-Language, Accept
Body:
{
   “kind”: “object#NetworkServiceGroup“,
   “name”: “active-directory“,
   “members”:
   [
       {
           “kind”: “objectRef#NetworkServiceGroup“,
           “objectId”: “krb5-tcp
       },
       {
           “kind”: “objectRef#NetworkServiceGroup“,
           “objectId”: “krb5-udp
       }
   ],
   “description”: “Default Active Directory ports“,
   “objectId”: “active-directory
}

Delete

(Entire object group)

CLI Reference

no object-group service active-directory

Request Format

URL: https://<management-ip>/api/objects/networkservicegroups/active-directory

Method: DELETE

Body: Empty

Response Format

Header:
Status Code: 204 No Content
Accept-Ranges: bytes
Content-Length: 0
Date: Wed, 18 Feb 2015 12:11:13 GMT
Server: CiscoASARestApiServer
(Delete Object within a object group)

CLI Reference

object-group service active-directory
 no  group-object krb5-tcp

Request Format

Header:

URL: https://<management-ip>/api/objects/networkservicegroups/active-directory
Method: PATCH

Body:

{
     “kind”: “object#NetworkServiceGroup“,
     “name”: “active-directory“,
     “members”:
     [
         {
             “kind”: “objectRef#NetworkServiceGroup“,
             “objectId”: “krb5-udp
         }
      ],
      “description”: “Default Active Directory ports
}

Note: To delete an object within an object group, you can use Put operation with all existing objects except the ones you need to delete.In this particular example I am only leaving krb5-udp in the group.

Response Format

Header:
Status Code: 200 OK
Accept-Ranges: bytes
Content-Length: 374
Content-Type: application/json; charset=UTF-8
Date: Wed, 18 Feb 2015 12:07:46 GMT
Server: CiscoASARestApiServer
Vary: Accept-Charset, Accept-Encoding, Accept-Language, Accept

Object Network

Create

CLI Reference (host)

object network win-dc-01
 host 10.0.0.10

REST Request Format (host)

 

URL: https://<management-ip>/api/objects/networkobjects

Method: POST

Body:

{
  “host”: {
    “kind”: “IPv4Address“,
    “value”: “10.0.0.10
  },
  “kind”: “object#NetworkObj“,
  “name”: “win-dc-01
}

REST Response Header Format

Header:
Status Code: 201 Created
Accept-Ranges: bytes
Content-Length: 0
Date: Wed, 18 Feb 2015 14:40:47 GMT
Server: CiscoASARestApiServer
Vary: Accept-Charset, Accept-Encoding, Accept-Language, Accept

CLI Reference (network)

object network web-tier
 subnet 172.16.0.0 255.255.255.0

REST Request Format

Method: POST
Body:
{
  “host”: {
    “kind”: “IPv4Network“,
    “value”: “172.16.0.0/24
  },
  “kind”: “object#NetworkObj“,
  “name”: “web-tier
}

REST Response Header Format

Header:
Status Code: 201 Created
Accept-Ranges: bytes
Content-Length: 0
Date: Wed, 18 Feb 2015 14:48:08 GMT
Server: CiscoASARestApiServer
Vary: Accept-Charset, Accept-Encoding, Accept-Language, Accept

Modify

CLI Reference (host)

object network win-dc-01
 host 10.0.0.11

Request Format

(To change/add objects withing a group)

Header

URL: https://<management-ip>/api/objects/networkobjects/win-dc-01
Method: PATCH

Body:

{
  “host”: {
    “kind”: “IPv4Address“,
    “value”: “10.0.0.11
  },
  “kind”: “object#NetworkObj“,
  “name”: “win-dc-01
}

Response Format

Header:
Status Code: 204
Content-Length: 0
Location: https://10.201.230.5/api/objects/networkobjects/win-dc-01
Server: CiscoASARestApiServer
Accept-Ranges: bytes
Vary: Accept-Charset, Accept-Encoding, Accept-Language, Accept
Date: Wed, 18 Feb 2015 14:43:44 GMT

Retrieve

CLI Reference

show run | be object network win-dc-01

Request Format

Method: GET
Body: Empty

Response Format

Header:

Status Code: 200 OK
Accept-Ranges: bytes
Content-Length: 191
Content-Type: application/json; charset=UTF-8
Date: Wed, 18 Feb 2015 14:49:59 GMT
Server: CiscoASARestApiServer
Vary: Accept-Charset, Accept-Encoding, Accept-Language, Accept
Body:
{
   “kind”: “object#NetworkObj“,
   “name”: “win-dc-01“,
   “host”:
   {
       “kind”: “IPv4Address“,
       “value”: “10.0.0.11
   },
   “objectId”: “win-dc-01
}

Delete

CLI Reference

no object network win-dc-01
Request Format
Method: DELETE
Body: Empty

Response Format

Header:
Status Code: 204 No Content
Accept-Ranges: bytes
Content-Length: 0
Date: Wed, 18 Feb 2015 14:52:26 GMT
Server: CiscoASARestApiServer

Network Object Group

Create

CLI Reference

object-group network dc-win-servers
 network-object object dc-win-01

REST Request Format (host)

URL: https://<management-ip>/api/objects/networkobjectgroups
Method: POST

Body:

{
     “kind”: “object#NetworkObjGroup“,
     “name”: “dc-win-servers“,
     “members”:
     [
         {
             “kind”: “objectRef#NetworkObj“,
             “objectId”: “win-dc-01
         }
     ],
     “description”: “Corporate AD Servers
}

REST Response Header Format

Header:
Status Code: 201 Created
Accept-Ranges: bytes
Content-Length: 0
Date: Wed, 18 Feb 2015 15:02:28 GMT
Server: CiscoASARestApiServer
Vary: Accept-Charset, Accept-Encoding, Accept-Language, Accept

Modify

CLI Reference (host)

object-group network dc-win-servers
 network-object object dc-win-01
 network-object object dc-win-02

Request Format

(To change/add objects withing a group)
Header:
Method: PATCH

 

Body:

{
           “kind”: “object#NetworkObjGroup“,
           “name”: “dc-win-servers“,
           “members”:
           [
               {
                   “kind”: “objectRef#NetworkObj“,
                   “objectId”: “win-dc-01
               },
               {
                   “kind”: “objectRef#NetworkObj“,
                   “objectId”: win-dc-02
               }
           ],
           “description”: “Corporate AD Servers
}

Response Format

Header:
Status Code: 204
Content-Length: 0
Location: https://10.201.230.5/api/objects/networkobjectgroups/dc-win-servers
Server: CiscoASARestApiServer
Accept-Ranges: bytes
Vary: Accept-Charset, Accept-Encoding, Accept-Language, Accept
Date: Wed, 18 Feb 2015 15:09:07 GMT

Retrieve

 

CLI Reference

show object-group id dc-win-servers

Request Format

 
Method: GET
Body: Empty

Response Format

Header:

Status Code: 200 OK
Accept-Ranges: bytes
Content-Length: 465
Content-Type: application/json; charset=UTF-8
Date: Wed, 18 Feb 2015 15:12:39 GMT
Server: CiscoASARestApiServer
Vary: Accept-Charset, Accept-Encoding, Accept-Language, Accept
Body:
{
   “kind”: “object#NetworkObjGroup“,
   “name”: “dc-win-servers“,
   “members”:
   [
       {
           “kind”: “objectRef#NetworkObj“,
           “refLink”: “https://10.201.230.5/api/objects/networkobjects/win-dc-01“,
           “objectId”: “win-dc-01
       },
       {
           “kind”: “objectRef#NetworkObj“,
           “refLink”: “https://10.201.230.5/api/objects/networkobjects/win-dc-02“,
           “objectId”: “win-dc-02
       }
   ],
   “description”: “Corporate AD Servers“,
   “objectId”: “dc-win-servers
}

Delete

CLI Reference

no object-group network dc-win-servers

Request Format

Header:
Method: DELETE
Body: Empty

Response Format

Header:
Status Code: 204 No Content
Accept-Ranges: bytes
Content-Length: 0
Date: Wed, 18 Feb 2015 15:16:43 GMT
Server: CiscoASARestApiServer

To delete an object within an object group you can use the same approach with Patch operations and listing only objects that you want to keep in object group.

Access Control List

Create

CLI Reference

access-list global_access remark Allow web-tier to Domain Controllers
access-list global_access extended permit object-group active-directory object-group web-and-db-tier object-group dc-win-servers log
access-group global_access global

REST Request Format (host)

Header:
Method: POST
Body:
{
        “sourceAddress”: {
        “kind”: “objectRef#NetworkObjGroup“,
        “objectId”: “web-and-db-tier
      },
      “destinationAddress”: {
        “kind”: “objectRef#NetworkObjGroup“,
        “objectId”: “dc-win-servers
      },
      “sourceService”: {
        “kind”: “objectRef#NetworkServiceGroup“,
        “objectId”: “active-directory
      },
      “destinationService”: {
        “kind”: “objectRef#NetworkServiceGroup“,
        “objectId”: “active-directory
      },
      “permit”: true,
      “active”: true,
      “remarks”: [“Allow web-tier to Domain Controllers“],
      “ruleLogging”: {
        “logInterval”: 300,
        “logStatus”: “Informational
      }
}
To create another line in same global ACL just modify the Request body and a new line will be added in the end of ACL. A reference value will be returned.

REST Response Header Format

Header:
Status Code: 201 Created
Accept-Ranges: bytes
Content-Length: 0
Date: Wed, 18 Feb 2015 15:35:20 GMT
Server: CiscoASARestApiServer
Vary: Accept-Charset, Accept-Encoding, Accept-Language, Accept

Modify

CLI Reference

access-list global_access remark Allow Domain Controllers to Web-Tier
access-list global_access extended permit object-group active-directory object-group dc-win-servers object-group web-and-db-tier log
access-group global_access global

Request Format

(To change/add objects withing a group)
Header:
URL: https://<management-ip>/api/access/global/rules/3028343169
Method: PATCH

Body:

{
        “sourceAddress“: {
        “kind”: “objectRef#NetworkObjGroup“,
        “objectId”: “dc-win-servers
      },
      “destinationAddress“: {
        “kind”: “objectRef#NetworkObjGroup“,
        “objectId”: “web-and-db-tier
      },
      “sourceService”: {
        “kind”: “objectRef#NetworkServiceGroup“,
        “objectId”: “active-directory
      },
      “destinationService”: {
        “kind”: “objectRef#NetworkServiceGroup“,
        “objectId”: “active-directory
      },
      “permit”: true,
      “active”: true,
      “remarks”: [“Allow Domain Controllers to Web Tier“],
      “ruleLogging”: {
        “logInterval”: 300,
        “logStatus”: “Informational
      }
}

Response Format

Header:
Status Code: 204
Content-Length: 0
Location: https://10.201.230.5/api/access/global/rules/2372118638
Server: CiscoASARestApiServer
Accept-Ranges: bytes
Vary: Accept-Charset, Accept-Encoding, Accept-Language, Accept
Date: Wed, 18 Feb 2015 15:44:50 GMT

Retrieve

 

CLI Reference

show access-list global_access

Request Format

 
Method: GET
Body: Empty

Response Format

Header:

Status Code: 200 OK
Accept-Ranges: bytes
Content-Length: 2088
Content-Type: application/json; charset=UTF-8
Date: Wed, 18 Feb 2015 15:55:03 GMT
Server: CiscoASARestApiServer
Vary: Accept-Charset, Accept-Encoding, Accept-Language, Accept
Body:
{
   “kind”: “collection#ExtendedACE“,
   “rangeInfo”:
   {
       “offset”: 0,
       “limit”: 2,
       “total”: 2
   },
   “items”:
   [
       {
           “kind”: “object#ExtendedACE“,
           “selfLink”: “https://10.201.230.5/api/access/global/rules/3028343169“,
           “permit”: true,
           “sourceAddress”:
           {
               “kind”: “objectRef#NetworkObjGroup“,
               “objectId”: “web-and-db-tier
           },
           “destinationAddress”:
           {
               “kind”: “objectRef#NetworkObjGroup“,
               “refLink”: “https://10.201.230.5/api/objects/networkobjectgroups/dc-win-servers“,
               “objectId”: “dc-win-servers
           },
           “sourceService”:
           {
               “kind”: “objectRef#NetworkServiceGroup“,
               “objectId”: “active-directory
           },
           “destinationService”:
           {
               “kind”: “objectRef#NetworkServiceGroup“,
               “objectId”: “active-directory
           },
           “active”: true,
           “remarks”:
           [
               “Allow web-tier to Domain Controllers
           ],
           “ruleLogging”:
           {
               “logInterval”: 300,
               “logStatus”: “Informational
           },
           “isAccessRule”: true,
           “position”: 1,
           “objectId”: “3028343169
       },
       {
           “kind”: “object#ExtendedACE“,
           “selfLink”: “https://10.201.230.5/api/access/global/rules/2372118638“,
           “permit”: true,
           “sourceAddress”:
           {
               “kind”: “objectRef#NetworkObjGroup“,
               “refLink”: “https://10.201.230.5/api/objects/networkobjectgroups/dc-win-servers“,
               “objectId”: “dc-win-servers
           },
           “destinationAddress”:
           {
               “kind”: “objectRef#NetworkObjGroup“,
               “objectId”: “web-and-db-tier
           },
           “sourceService”:
           {
               “kind”: “objectRef#NetworkServiceGroup“,
               “objectId”: “active-directory
           },
           “destinationService”:
           {
               “kind”: “objectRef#NetworkServiceGroup“,
               “objectId”: “active-directory
           },
           “active”: true,
           “remarks”:
           [
               “Allow Domain Controllers to Web Tier
           ],
           “ruleLogging”:
           {
               “logInterval”: 300,
               “logStatus”: “Informational
           },
           “isAccessRule”: true,
           “position”: 2,
           “objectId”: “2372118638
       }
   ]
}

Delete

CLI Reference

no access-list global_access remark Allow Domain Controllers to Web Tier
no access-list global_access extended permit object-group active-directory object-group dc-win-servers object-group web-and-db-tier log

Request Format

Header:
Method: DELETE
Body: Empty

Response Format

Header:
Status Code: 204 No Content
Accept-Ranges: bytes
Content-Length: 0
Date: Wed, 18 Feb 2015 15:52:34 GMT
Server: CiscoASARestApiServer

Conclusion

ASA REST API is a very powerful interface, and as times goes I am sure that for customers that invested in this firewall product it will be the preferred way how to program their security policies automatically during application deployment.

Cisco ASAv firewall installation

Introduction

The data center networking trend is clear with every network service being slowly virtualized. Network devices that are virtual provide big advantage over their physical counterparts. First, VMs can be provisioned much more quicker and be part of a larger virtual infrastructure, you can easily scale them adding more virtual CPU or memory and you can snapshot them to save their actual state to a file and move them around.

Cisco has also introduced their virtual version of their popular firewall product ASA. It simple called ASAv and runs under popular hypervisors such as VMware vSphere or KVM. You can find the product home page here. This is different product and idea than Cisco ASA 1000V Cloud Firewall.

First you need to get hold of the ova package. You need to be entitled with Cisco to download the software from here or you can do a Google search and find it elsewhere. I had some problems with the latest release 9.3.2(200) where it would stuck at booting loop, the kernel complained about Illegal Instruction. Looks like it did not like my dual Opteron 4180 host. Therefore in this demo we are going to use release 9.3.1 which worked just fine.

Sharping the axe

Before we are going to deploy the actual virtual firewall, lets make some solid ground for it. Firewalls usually divide network into multiple security zones so first we are going to create some, and we use vSwitches for that. In my vSphere deployment I already have default vSwitch called vSwitch0, with a Portgroup called Native that has a connection to outside world.

We are going to create additional two vSwitches that will have following Portgroups: ASAv-inside and ASAv-DMZ respectively, and we are going to attach two linux instances to them. So in the end we end up with simple topology like this:

asav-network

To get started, log in to vSphere and go to Hosts\Configuration\Networking\Virtual Standard Switch, click add Add networking.

Select New Standard Switch, there is no need to assign physical adapter for breakout, we will attach this vSwitch to one of ASAv interfaces. The first port group will be called ASAv-inside with no VLAN tag. Follow the same steps for DMZ vSwitch and its ASAv-DMZ PortGroup.

asav1

Chopping the tree

Back to ASAv, after downloading, log into the vCenter and go to VMs and File\Deploy OVF Template.

Note: I tried to deploy the asav932-200.ova directly into ESXi, however I received and error that The OVF package requires support for OVF properties. Details: Line 264: Unsupported element ‘Property’

Answer the usual OVF deployment question such as name of VM, which Data Center and Cluster will be used. I only have one so it is no brainier. Deployment configuration specifies the number of vCPU that the VM will have and whether it will be part of HA pair. By default ASAv will come with 1 Management Interface Management0/0 and 9 regular interfaces GigabitEthernet0/0 – 0/8. You need to map each of them to correct port group created in previous step.

I am only really using 4 interfaces at this point, so I left the rest connected in ASAv-DMZ portgroup.

asav2

1 Mgmt Interface and 9 Regular Interfaces

Some basic configuration parameters such as IP configuration of management interface can also be entering during wizard. That makes me wonder if those parameters can be passed to template while deploying automatically via script.

asav3

Initial Configuration Options

After quick OVF deployment, you can look at default resource requirements which correspond to deployment size selected in wizard.

asav6

Resource utilization

And finally the ASAv console is available directly through vCenter.

asav3

ASAv Virtual Console

Before you can take full advantage of all ASAv features in your lab you need to license the box. If you are lucky you can ask a Cisco representative for a temporary license or *hint* do a smart Google search for a little piece of software.

Initial Configuration

To actually verify that the ASAs has indeed network connectivity, we will perform initial configuration and test reach ability to Google DNS servers.

#First virtual interface mapped to Native PortGroup
#
interface GigabitEthernet0/0
nameif outside
security-level 0
ip address dhcp
#
#Second virtual interface mapped to ASAv-inside PortGroup
#
interface GigabitEthernet0/1
nameif inside
security-level 100
ip address 192.168.1.1 255.255.255.0
#
#Management virtual interface mapped to Backend PortGroup
#
interface Management0/0
management-only
nameif management
security-level 0
ip address 10.0.1.41 255.255.255.0
#
# DNS, SSH and routing
#
dns server-group DefaultDNS
name-server 8.8.8.8
!
route outside 0.0.0.0 0.0.0.0 10.0.2.1 1
aaa authentication ssh console LOCAL
ssh 10.0.1.0 255.255.255.0 management
username cisco password

Verification

asav5

If you are currently aiming for CCIE Security this is an excellent way how to build your own virtual lab for practice. Coupled with virtual ACS server and IPS appliances it is very easy to test and learn new features, validate syntax for scripts and many more without harming your production environment.

I draw the line in the sand here and leave your imagination what you can do with multiple of these virtual firewalls bundled with couple of virtual routers and virtual machines to re-create complete data center infrastructure sandbox.

Resources

Introduction to ASAv

http://www.cisco.com/c/en/us/td/docs/security/asa/asa92/asav/quick-start/asav-quick/intro-asav.html

ASAv Product Overview

http://www.cisco.com/c/en/us/products/collateral/security/adaptive-security-virtual-appliance-asav/datasheet-c78-733399.pdf

Deploying ASAv

http://www.cisco.com/c/en/us/td/docs/security/asa/asa92/configuration/general/asa-general-cli/intro-asav.pdf