{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "## Analyzing BGP Route Policies" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Route policies for BGP are complex and error prone, which is why some of the biggest outages in the Internet involve misconfigured route policies that end up leaking routes or accepting routes they shouldn't (e.g., [BGP Leak Causing Internet Outages in Japan and Beyond](https://www.bgpmon.net/bgp-leak-causing-internet-outages-in-japan-and-beyond/), [How a Tiny Error Shut Off the Internet for Parts of the US](https://www.wired.com/story/how-a-tiny-error-shut-off-the-internet-for-parts-of-the-us/), [Telia engineer error to blame for massive net outage](https://www.theregister.com/2016/06/20/telia_engineer_blamed_massive_net_outage/)). While it is often clear to network engineers what the route policy should or should not do (e.g., see [MANRS guidelines](https://www.manrs.org/)), ensuring that the route policy implementation is correct is notoriously hard.\n", "\n", "In this notebook we show how you can use Batfish to validate your route policies. Batfish's `testRoutePolicies` question provides an easy way to test route-policy behavior---given a route, it shows how it is transformed (or denied) by the route policy. Batfish's `searchRoutePolicies` actively searches for routes that cause a policy to violate its intent.\n", "\n", "To illustrate these capabilities, we'll use an example network with two border routers, named `border1` and `border2`. Each router has a BGP session with a customer network and a BGP session with a provider network. Our goal in this notebook is to validate the in-bound route policy from the customer, called `from_customer`, and the out-bound route policy to the provider, called `to_provider`.\n", "\n", "The intent of the `from_customer` route policy is:\n", "\n", " * filter private addresses\n", " * only permit routes to known prefixes if they have the correct origin AS\n", " * tag permitted routes with an appropriate community, and update the local preference\n", "\n", "The intent of the `to_provider` route policy is:\n", "\n", " * advertise all prefixes that we own\n", " * advertise all customer routes\n", " * don't advertise anything else" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We'll start, as usual, by initializing the example network that we will use in this notebook." ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'example_snapshot'" ] }, "execution_count": 1, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Import packages\n", "%run startup.py\n", "from pybatfish.datamodel.route import BgpRouteConstraints\n", "bf = Session(host=\"localhost\")\n", "\n", "# Initialize a network and snapshot\n", "NETWORK_NAME = \"example_network\"\n", "SNAPSHOT_NAME = \"example_snapshot\"\n", "\n", "SNAPSHOT_PATH = \"networks/route-analysis\"\n", "\n", "bf.set_network(NETWORK_NAME)\n", "bf.init_snapshot(SNAPSHOT_PATH, name=SNAPSHOT_NAME, overwrite=True)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Example 1: Filter private addresses in-bound\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "When peering with external entities, an almost universally-desired policy is to filter out all announcements of the private IP address space. For our network, we'd like to ensure that the two `from_customer` route policies properly filter such announcements. \n", "\n", "Traditionally you might validate this policy through some form testing that involves the production or a lab device. With Batfish's `testRoutePolicies` question we can easily test a route policy's behavior without access to a device." ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "
| \n", " | Node | \n", "Policy_Name | \n", "Input_Route | \n", "Action | \n", "Output_Route | \n", "Difference | \n", "Trace | \n", "
|---|---|---|---|---|---|---|---|
| 0 | \n", "border1 | \n", "from_customer | \n", "Network: 10.0.0.0/24 AS Path: [] Communities: [] Local Preference: 0 Metric: 0 Next Hop IP: None Originator IP: 4.4.4.4 Origin Type: egp Protocol: bgp Source Protocol: None Tag: 0 Weight: 0 | \n",
" DENY | \n", "None | \n", "None | \n", "
| \n",
"
| 1 | \n", "border2 | \n", "from_customer | \n", "Network: 10.0.0.0/24 AS Path: [] Communities: [] Local Preference: 0 Metric: 0 Next Hop IP: None Originator IP: 4.4.4.4 Origin Type: egp Protocol: bgp Source Protocol: None Tag: 0 Weight: 0 | \n",
" DENY | \n", "None | \n", "None | \n", "
| \n",
"
| \n", " | Node | \n", "Policy_Name | \n", "Input_Route | \n", "Action | \n", "Output_Route | \n", "Difference | \n", "Trace | \n", "
|---|---|---|---|---|---|---|---|
| 0 | \n", "border2 | \n", "from_customer | \n", "Network: 192.168.0.0/32 AS Path: [] Communities: [] Local Preference: 100 Metric: 0 Next Hop IP: 0.0.0.1 Originator IP: 0.0.0.0 Origin Type: egp Protocol: bgp Source Protocol: None Tag: 0 Weight: 0 | \n",
" PERMIT | \n", "Network: 192.168.0.0/32 AS Path: [] Communities: [20:30] Local Preference: 300 Metric: 0 Next Hop IP: 0.0.0.1 Originator IP: 0.0.0.0 Origin Type: egp Protocol: bgp Source Protocol: None Tag: 0 Weight: 0 | \n",
" Communities: [] --> [20:30] Local Preference: 100 --> 300 | \n",
"
| \n",
"
| \n", " | Node | \n", "Policy_Name | \n", "Input_Route | \n", "Action | \n", "Output_Route | \n", "Difference | \n", "Trace | \n", "
|---|
| \n", " | Node | \n", "Policy_Name | \n", "Input_Route | \n", "Action | \n", "Output_Route | \n", "Difference | \n", "Trace | \n", "
|---|---|---|---|---|---|---|---|
| 0 | \n", "border1 | \n", "from_customer | \n", "Network: 2.0.0.0/8 AS Path: [] Communities: [] Local Preference: 0 Metric: 0 Next Hop IP: None Originator IP: 4.4.4.4 Origin Type: egp Protocol: bgp Source Protocol: None Tag: 0 Weight: 0 | \n",
" PERMIT | \n", "Network: 2.0.0.0/8 AS Path: [] Communities: [20:30] Local Preference: 0 Metric: 0 Next Hop IP: None Originator IP: 4.4.4.4 Origin Type: egp Protocol: bgp Source Protocol: None Tag: 0 Weight: 0 | \n",
" Communities: [] --> [20:30] | \n", "
| \n",
"
| 1 | \n", "border2 | \n", "from_customer | \n", "Network: 2.0.0.0/8 AS Path: [] Communities: [] Local Preference: 0 Metric: 0 Next Hop IP: None Originator IP: 4.4.4.4 Origin Type: egp Protocol: bgp Source Protocol: None Tag: 0 Weight: 0 | \n",
" PERMIT | \n", "Network: 2.0.0.0/8 AS Path: [] Communities: [20:30] Local Preference: 300 Metric: 0 Next Hop IP: None Originator IP: 4.4.4.4 Origin Type: egp Protocol: bgp Source Protocol: None Tag: 0 Weight: 0 | \n",
" Communities: [] --> [20:30] Local Preference: 0 --> 300 | \n",
"
| \n",
"
| \n", " | Node | \n", "Policy_Name | \n", "Input_Route | \n", "Action | \n", "Output_Route | \n", "Difference | \n", "Trace | \n", "
|---|
| \n", " | Node | \n", "Policy_Name | \n", "Input_Route | \n", "Action | \n", "Output_Route | \n", "Difference | \n", "Trace | \n", "
|---|
| \n", " | Node | \n", "Policy_Name | \n", "Input_Route | \n", "Action | \n", "Output_Route | \n", "Difference | \n", "Trace | \n", "
|---|
| \n", " | Node | \n", "Policy_Name | \n", "Input_Route | \n", "Action | \n", "Output_Route | \n", "Difference | \n", "Trace | \n", "
|---|---|---|---|---|---|---|---|
| 0 | \n", "border2 | \n", "to_provider | \n", "Network: 10.0.0.0/8 AS Path: [] Communities: [20:30] Local Preference: 100 Metric: 0 Next Hop IP: 0.0.0.1 Originator IP: 0.0.0.0 Origin Type: egp Protocol: bgp Source Protocol: None Tag: 0 Weight: 0 | \n",
" DENY | \n", "None | \n", "None | \n", "
| \n", " | Node | \n", "Policy_Name | \n", "Input_Route | \n", "Action | \n", "Output_Route | \n", "Difference | \n", "Trace | \n", "
|---|---|---|---|---|---|---|---|
| 0 | \n", "border2 | \n", "to_provider | \n", "Network: 10.0.0.0/8 AS Path: [] Communities: [2:30] Local Preference: 100 Metric: 0 Next Hop IP: 0.0.0.1 Originator IP: 0.0.0.0 Origin Type: egp Protocol: bgp Source Protocol: None Tag: 0 Weight: 0 | \n",
" PERMIT | \n", "Network: 10.0.0.0/8 AS Path: [] Communities: [2:30] Local Preference: 100 Metric: 0 Next Hop IP: 0.0.0.1 Originator IP: 0.0.0.0 Origin Type: egp Protocol: bgp Source Protocol: None Tag: 0 Weight: 0 | \n",
" \n", " |
| \n",
"