Firepyer – Automating Cisco FTD in FDM mode with Python

FTD FDM WTF?

In planning for some upcoming work for a client I started looking into options for automating the deployment and configuration of Cisco’s FTD (Firepower Threat Defense) devices. This is Cisco’s latest attempt at a NGFW, bringing together a unified platform containing the best bits from their long-standing ASA firewall and their Sourcefire IDP acquisition.

As of version 6.2.something, Cisco offers two methods of managing FTD devices. The first is using FMC (Firepower Management Center), a centralised management controller, which comes in either virtual or physical appliance format and can be used to manage a number of devices. The second option, which is the focus of this post is FDM (Firepower Device Manager) which is a local ‘on-box’ method of managing a standalone (or HA pair) appliance.

I won’t discuss the pros and cons of each, but currently there is no ability to migrate from one management option to the other, so choose wisely. If you find FDM fits your needs and you have a large number of devices to configure or just want some automation then read on…

Enter Firepyer

There’s plenty out there for automating devices configured to use FMC, but not much for standalone FDM devices. I found a few Ansible modules here and there and a bulk config tool, but these only cover a small portion of the FDM feature set, so I decided to create Firepyer.

Firepyer consumes the REST API that becomes available when you select FDM mode and provides some easy to use Python methods to interact with your NGFW and get/send structured data. Currently there’s only a hand full of operations that are implemented, but my aim is to get full CRUD (Create, Read, Update, Delete) support for the majority of popular features. The list of current features are shown in the Firepyer Docs.

Using Firepyer

If you’re familiar with Python then the docs should be enough to get you started using Firepyer, but if you’re pretty new then here’s how to get going (some commands may be different depending on your platform)…

1. It’s always good to use a virtual environment to separate dependencies between projects and system-level packages:

python -m venv venv

2. Then enter your new venv…

in Linux:

source ./venv/bin/activate

or in Windows:

.\venv\Scripts\activate

3. As Firepyer is available on PyPI (the Python Package Index) you can then easily install it into your venv:

pip install firepyer

4. Now start an interactive Python shell, import the Fdm class, create an object with your FTD details and start automating:

(venv) C:\Users\username> python
>>> from firepyer import Fdm
>>> fdm = Fdm(host='192.168.133.7', username='admin', password='Admin123')
>>> print(fdm.get_vrfs())

[{'description': "Customer A's VRF",
  'id': '67e4d858-503d-11eb-aab5-2921a41f8ca3',
  'interfaces': [{'hardwareName': 'GigabitEthernet0/2',
                  'id': 'aeb5b238-4d44-11eb-9e04-cd44159d2943',
                  'name': 'customer_a',
                  'type': 'physicalinterface',
                  'version': 'nh7piq3rw7pzs'}],
  'isSystemDefined': False,
  'links': {'self': 'https://192.168.133.7/api/fdm/latest/devices/default/routing/virtualrouters/67e4d858-503d-11eb-aab5-2921a41f8ca3'},
  'name': 'Customer-A',
  'type': 'virtualrouter',
  'version': 'crdwtc44cg5pu'},
 {'description': "Customer B's VRF",
  'id': '7360254c-503d-11eb-aab5-41ec0935f001',
  'interfaces': [{'hardwareName': 'GigabitEthernet0/3',
                  'id': 'afb288c9-4d44-11eb-9e04-41c0f86d8474',
                  'name': 'customer_b',
                  'type': 'physicalinterface',
                  'version': 'ocdhtp76zpfzz'}],
  'isSystemDefined': False,
  'links': {'self': 'https://192.168.133.7/api/fdm/latest/devices/default/routing/virtualrouters/7360254c-503d-11eb-aab5-41ec0935f001'},
  'name': 'Customer-B',
  'type': 'virtualrouter',
  'version': 'nl7onsmfqdujm'},
 {'description': 'This is a Global Virtual Router',
  'id': '42e95fbf-fd5a-42bf-a95f-bffd5a42bfd6',
  'interfaces': [{'hardwareName': 'Management0/0',
                  'id': 'b0b5a0ea-4d44-11eb-9e04-43089048338b',
                  'name': 'diagnostic',
                  'type': 'physicalinterface',
                  'version': 'inmqiea7woymm'},
                 {'hardwareName': 'GigabitEthernet0/1',
                  'id': 'ad6a9497-4d44-11eb-9e04-63d0b1958967',
                  'name': 'inside',
                  'type': 'physicalinterface',
                  'version': 'eqotynhtlcuyf'},
                 {'hardwareName': 'GigabitEthernet0/0',
                  'id': '8d6c41df-3e5f-465b-8e5a-d336b282f93f',
                  'name': 'outside',
                  'type': 'physicalinterface',
                  'version': 'h4kqp4iu2yvff'}],
  'isSystemDefined': True,
  'links': {'self': 'https://192.168.133.7/api/fdm/latest/devices/default/routing/virtualrouters/42e95fbf-fd5a-42bf-a95f-bffd5a42bfd6'},
  'name': 'Global',
  'type': 'virtualrouter',
  'version': 'cna3vbajed6et'}]

5. View the docs to see everything else you can do!

Disclaimer: Firepyer is still in early development so I take no responsibility if your network goes up in flames!