Software Defined – BGP (ExaBGP, Postman, FLASK, Python3)

Hello,

I am currently studying for the BGP exam of the Nokia SRA certification path – while doing so, I have found an interesting way to manipulate my BGP routes – I gotta give credit to ThePacketGeek for all their information which made this possible for me.

I’m utilizing several different tools to quickly advertise routes into my EVE-NG Lab topology, which are the following:

  1. Exa-BGP : Exa-Networks GitHub
  2. PostMan : PostMan
  3. RSUB to quickly edit text from through ssh tunel on a remote server : Rsub
  4. Python3
  5. Ubuntu VM
  6. FLASK

I’ve installed UbuntuVM which is on the same network as my EVE-NG topology. Assuming you have a general understanding of the architecture, I’m going to dive right in. I’ve got a Nokia 7750 SR – VPRN with a dot1q sap facing a switch which allows a TCP connection to establish across the link to my VM hosting ExaBGP – All of this is hosted on the same physical server.

  • ExaBGP
    • Install ExaBGP with PIP3.
    • Create a configuration file for  ExaBGP to connect to your router.
      • sudo vi /etc/exabgp/conf.ini

——————————————————————————————————————————–

neighbor 10.0.0.200 { # Remote Peer router-id 10.0.0.25; # Local router-id local-address 10.0.0.25; # Local update-source local-as 65001; # local AS peer-as 65000; # Peer’s AS

api { processes [announce-routes, http-api]; #Running multiple processes, python3 script and HTTP API(FLASK)

}


 

Here is the python script I’m calling under the ‘announce-routes’ process, which is pointing to /home/htinoco/example.py;

#!/usr/bin/env python3 #Change this to the correct python version you’re using.

from __future__ import print_function

from sys import stdout from time import sleep

#Static routes I want to always announce when I start ExaBGP messages = [

‘announce route 250.10.0.0/24 next-hop self’, ‘announce route 120.20.0.0/24 next-hop self’, ‘announce route 110.20.0.0/24 next-hop self’, ‘announce route 150.20.0.1/24 next-hop self’, ‘announce route 100.10.1.0/24 next-hop self’, ]

sleep(5)

#Iterate through messages for message in messages: stdout.write(message + ‘\n’) stdout.flush() sleep(1)

#Loop endlessly to allow ExaBGP to continue running while True: sleep(1)

Now, there is also another process I’m calling, which is my FLASK app.

Here is my flask app:

from flask import Flask, request from sys import stdout

app = Flask(__name__)

# Setup a command route to listen for prefix advertisements @app.route(‘/’, methods=[‘POST’]) def command(): command = request.form[‘command’] stdout.write(‘%s\n’ % command) stdout.flush() return ‘%s\n’ % command

@app.route(‘/shutdown’, methods=[‘POST’]) def shutdown(): shutdown_server() return ‘Server shutting down…’

#The param localhost is applied so we can reach the api remotely –

if __name__ == ‘__main__’: app.run(host=”localhost”, port=7000, debug=True)

#Example POSTS using postman / (BODY/KEY:COMMAND/VALUE=) #announce route 100.10.0.0/16 next-hop 172.16.2.202 med 500 #announce route 100.20.0.0/16 next-hop 172.16.2.202 origin incomplete as-path [100 200 400] #announce route 100.30.0.0/16 next-hop 172.16.2.202 med 200 origin egp #announce route 100.40.0.0/16 next-hop 172.16.1.2/32 community [65000:666]

 

We are ready to roll! – navigate to /etc/exabgp and lets launch exabgp using the conf.ini file we created –

htinoco@ubuntu-server:/etc/exabgp$ exabgp conf.ini

 

Here is the output after starting exabgp:

: * Serving Flask app “http_api” ( lazy loading ) > * Running on http://0:7000/ (Press CTRL+C to quit) > * Restarting with stat > * Debugger is active! > * Debugger PIN: 157-288-415 04:35:45 | 2699 | api | route added to neighbor 10.0.0.200 local-ip 10.0.0.25 local-as 65001 peer-as 65000 router-id 10.0.0.25 family-allowed in-open : 100.10.0.0/24 next-hop self 04:35:46 | 2699 | api | route added to neighbor 10.0.0.200 local-ip 10.0.0.25 local-as 65001 peer-as 65000 router-id 10.0.0.25 family-allowed in-open : 200.20.0.0/24 next-hop self 04:35:47 | 2699 | api | route added to neighbor 10.0.0.200 local-ip 10.0.0.25 local-as 65001 peer-as 65000 router-id 10.0.0.25 family-allowed in-open : 210.20.0.0/24 next-hop self 04:35:48 | 2699 | api | route added to neighbor 10.0.0.200 local-ip 10.0.0.25 local-as 65001 peer-as 65000 router-id 10.0.0.25 family-allowed in-open : 220.20.0.1/24 next-hop self 04:35:49 | 2699 | api | route added to neighbor 10.0.0.200 local-ip 10.0.0.25 local-as 65001 peer-as 65000 router-id 10.0.0.25 family-allowed in-open : 240.20.1.1/24 next-hop self

We see the static routes advertisted to our BGP neighbor, from our python script.

We can now open up Postman and POST new routes as we please.

In this example, I’m using “POST” and KEY “command” (review the flask-app code)

to announce the route : announce route 44.44.24.4/32 next-hop self community [65000:666]

The out put from exabg tail process:

04:40:10 | 2699 | api | route added to neighbor 10.0.0.200 local-ip 10.0.0.25 local-as 65001 peer-as 65000 router-id 10.0.0.25 family-allowed in-open : 44.44.23.4/32 next-hop self community 65000:666

Now lets verify that I am seeing this route on my 7750 SR router that has the BGP session established with ExaBGP.

There they are! The static routes from our python script and the freshly announced /32 route utilizing the API POST method.

Now we have a SUPER EASY! way to pump routes into our lab environment (Or production) in order to test policies, verify proper traffic patterns, correct route installment, etc. The possibilities are endless! I am going to use this to for many other tests, such as applying MED, route manipulation with communities and just more general policy based routing.