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

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

process announce-routes {
run /usr/bin/python3.6m /home/htinoco/exampl.py;
encoder json;
}
process http-api {
run /usr/bin/python3.6m /home/htinoco/exabg-flask/http_api.py;
encoder json;
}

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 ponting to /home/htinoco/exampl.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.

postman

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

to annoucne 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.

32.PNG

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 environemnt (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.

DDoS Mitigation – RTBH – Blackhole Community

I’m working on a mini-series of videos to demonstrate a common practice with Service Provider networks in regards to DDoS Mitigation. A quick google search and you can find PDF documents from ISP’s all over the world with detailed BGP communities they accept and how they manipulate traffic through their particular AS.

A BGP community string is simply a way to control policy routing through your upstream provider network. The community string in which I’ve been concentrating on is the common “Blackhole” community. This community is advertised to upstream providers to instruct the ISP to discard all traffic to the destination prefix before it is routed to the customer. It is common practice to allow this community. Inquire with your provider for the BGP community document to better understand the way in which you can manipulate  upstream traffic to your advantage.

This lab was mostly rooted from personal projects I’m undergoing but also a great excuse to start pushing the limits of my new EVE-NG server.  I’m really enjoying the interface and the ease-of-use.

Here is the part 1 of the video series. More to come, stay tuned..!