Snapshots
Packaging your snapshot
Invariant will look for input files in specific directories relative to your snapshot directory.
A quick overview of the directory structure:
snapshot/ # Root directory of snapshot.
aws_configs/ # AWS JSON files.
batfish/ # Batfish configuration files.
configs/ # On-premise device configurations (Cisco, Juniper, Arista, Fortinet, etc).
def/ # Human-friendly name to IP mappings.
hosts/ # Host model files including iptables.
invariant/ #
locations/ # Human-friendly name to device and interface mappings.
policies/ # Policy files to be applied to this network.
probe_targets.yaml # Connectivity probe configuration file.
AWS configuration directory
Invariant is able to model your AWS VPC network and associated resources just like your on-premise network. You must supply the AWS JSON description files for each resource you wish to model. All AWS JSON files must be places in the aws_configs
directory to be recognized.
Retrieving AWS resources
The JSON files can be retrieved by through several methods:
- Using the AWS CLI.
- Using the boto3 client in Python.
To use the AWS CLI to fetch JSON files for VPCs:
aws ec2 describe-vpcs
To use the Python boto3 client to fetch JSON files for VPCs:
import boto3
ec2_client = boto3.client('ec2')
response = ec2_client.describe_vpcs()
The boto3-based Python script bf-aws-snapshot will quickly collect all required AWS JSON files.
AWS folder organization
In AWS your resources may be spread across multiple accounts and regions. If this is the case you must organize your resources in the aws_configs
by accounts and then regions. If you do not use multiple accounts or regions, you can omit the respective directory level.
Examples
Two accounts with two regions in each.
aws_configs/
account_1/
us-east-2/
us-west-2/
account_2/
us-east-2/
us-west-2/
The following two directory examples are equivalent for one account with one region
aws_configs/
account_1/
us-east-2/
aws_configs/
Batfish
ISP Schema
When creating your network you may wish to model the network outside of it such as the Internet. The ISP configuration file provides you this ability. You will need to create a file in the batfish directory named isp_config.json
.
Field | Type | Description |
---|---|---|
bgpPeers[].hostname | string | Hostname of the BGP peer. |
bgpPeers[].ispAttachment.hostname | string | Optional: Hostname of the attached ISP Peer. |
bgpPeers[].ispAttachment.interface | string | Interface of the attached ISP Peer. |
bgpPeers[].ispAttachment.vlanTag | integer | Optional: Dot1q encapsulation tag. |
bgpPeers[].ispAttachment | object | Optional: Attached ISP information. |
bgpPeers[].peerAddress | string | IP address of the BGP peer in xxx.xxx.xxx.xx format. |
bgpPeers[].vrf | string | Optional: VRF on the host. If left unspecified, default VRF is used. |
bgpPeers | list of objects | List of BGP peers connected. Use for more complex BGP connections. |
borderInterfaces[].borderInterface.hostname | string | Hostname of the border interface. |
borderInterfaces[].borderInterface.interface | string | Hostname of the border interface. |
borderInterfaces[].borderInterface | object | Object representing a single border interface. |
borderInterfaces | list of objects | List of layer 3 border interfaces connected directly to ISP. |
filter.onlyRemoteAsns | list of integers | List of ASNs that are not filtered out of the model. |
filter.onlyRemoteIps | list of strings | List of IPs that are not filtered out of the model. IPs are in the format xxx.xxx.xxx.xxx . |
ispNodeInfo[].asn | integer | Autonomous System Number (ASN) of the ISP. |
ispNodeInfo[].name | string | Name of the ISP node. |
ispNodeInfo[].role | enum(TRANSIT , PRIVATE_BACKBONE ) | Role of the ISP node. TRANSIT : Models Internet ISP providers. PRIVATE_BACKBONE : Models a private peering connection |
ispNodeInfo | object | List of ISP nodes providing access outside of the network. |
ispPeerings[].ispPeer.peer1.asn | integer | ASN of first peer. |
ispPeerings[].ispPeer.peer2.asn | integer | ASN of second peer. |
ispPeerings[].ispPeer | object | A pairing of ISP nodes |
ispPeerings | object | Allows for peering between ISP nodes. |
Example
The following is an example from our codelab It connects the codelab network to the Internet via two ISP nodes.
{
"borderInterfaces": [
{
"borderInterface": {
"hostname": "border-1",
"interface": "GigabitEthernet0/1"
}
},
{
"borderInterface": {
"hostname": "border-1",
"interface": "GigabitEthernet0/3"
}
}
],
"ispNodeInfo": [
{
"asn": 64501,
"name": "ISP1",
"role": "TRANSIT"
},
{
"asn": 64502,
"name": "ISP2",
"role": "TRANSIT"
}
]
}
On-premise configurations directory
On premise devices must be located under snapshot/configs/
. The directory is recursed and all files are attempted to be loaded. Organizing the configurations into folders is supported.
Supported on-premise devices
- A10
- Arista
- Cisco
- IOS
- IOS-XE
- IOS-XR
- NX-OS
- ASA
- Check Point
- Cumulus Linux
- F5 Big IP
- Fortinet
- Juniper
- EX
- MX
- PTX
- QFX
- SRX
- T-Series
- Palo Alto Networks
- SONiC
Definitions directory
The definitions directory contains one or more definition files. These files are YAML and are the same as Aerleon Definitions
Field | Type | Description |
---|---|---|
networks | list of objects | List of network groups and associated values (subnets and addresses) |
networks[].group_name | string | Name of the network group |
networks[].group_name.values | list | List of address and comment pairs, or network group references |
networks[].group_name.values[].address | string | IP address or subnet in CIDR notation |
networks[].group_name.values[].comment | string | Optional comment for the address |
networks[].group_name.values[].group_ref | string | Reference to another network group |
Field | Type | Description |
---|---|---|
services | list of objects | List of service definitions, including ports and protocols |
services[].service_name | string | Name of the service or service group |
services[].service_name.protocol | string | Protocol used by the service (e.g., tcp, udp) |
services[].service_name.port | string | Port number or range used by the service |
services[].service_name.service_ref | string | Reference to another service or service group |
We inject ports that are registered with the IANA. You can use any registered name in capital letters. For example, ssh is defined in IANA as port 22 on tcp, udp, and sctp. Use the service name SSH in this case.
Hosts directory
You are able to model hosts on the network by including JSON files in the snapshot/hosts
directory. Each host is a file in JSON format and can have multiple interfaces. You can include a reference to IPTables applied to the host.
Field | Type | Description |
---|---|---|
hostname | string | Name of the host. |
iptablesFile | string | Path to an IPTables file to be applied to the host. |
hostInterfaces | object | A set of key names to hostInterface objects. |
hostInterfaces.interface_name | object | interface_name is a user supplied key to the interface objects. |
hostInterfaces.interface_name.name | string | Name of the interface. |
hostInterfaces.interface_name.prefix | string | IP of interface in CIDR notation. |
hostInterfaces.interface_name.gateway | string | IP of the gateway. |
An example host file with IPtables and a single interface is below.
{
"hostname" : "host1",
"iptablesFile" : "iptables/host1.iptables",
"hostInterfaces" : {
"eth0" : {
"name": "eth0",
"prefix" : "10.0.0.20/24"
"gateway": "10.0.0.1
}
}
}
Locations directory
You can create locations by creating yaml files in the snapshot/invariant/locations
directory. Locations allow you to reference a specific interface and host for traffic flows. There is one location that is required and that is EXTERNAL.
EXTERNAL is used for Invariant to determine where the external boundary of your network is. Forgetting this file will result in an error.
locations:
EXTERNAL:
- devices: border-1
interfaces: GigabitEthernet0/1
- devices: border-1
interfaces: GigabitEthernet0/3
Policies directory
Policy files are YAML files that live in snapshot/invariant/policies
. The directory is recursed for all YAML files. You can use folders and file names to help organize your policies. Each file can have multiple access policies inside.
See Access Policy for schema and reference information.
Probe targets
Probe targets are located in a file snapshot/invariant/probe_targets.yaml
and allow you to create simple targets for conectivity tests. This is very useful when first onboarding your network snapshots.
Field | Type | Description |
---|---|---|
probe_targets | list of objects | List of probe target objects. |
probe_targets[].comment | string | Comment describing the probe. |
probe_targets[].target | string | Definition network to target for probing. |
probe_targets[].type | string | Type of probe, either tcp, udp, or icmp-echo. |
probe_targets[].ignore-filters | boolean | Should this probe ignore firewall filtering. |
Example probe targeting both Cloudflare and Google DNS servers.
probe_targets:
- comment: Custom probe - use both UDP and ICMP ECHO
target: CLOUDFLARE_DNS GOOGLE_DNS
type: icmp-echo udp
ignore-filters: False