Showing posts with label RIPE. Show all posts
Showing posts with label RIPE. Show all posts

Monday, January 26, 2015

Validating BGP Announcements by Automating Filter Generation with Python: Part2


At first part of the post, i wrote that some tools use “whois”  client to query RIR databases. So it is possible to use a “whois cli tool” to gather the necessary data of your interest.

Whois

You can find whois flags for RIPE on http://www.ripe.net/data-tools/support/documentation/queries-ref-card  to elaborate the whois queries.  Lets pull routes of an AS34984 in Linux command Line:

root@test:~# whois -h whois.ripe.net -i or as34984 | grep route:
route:          151.250.0.0/16
…output omitted

In order to get route data as a variable, to play with, you still need to need to parse the related part of the data from  the output. A better approach, which i generally prefer , is to use a native library, so that your script won’t depend on  a tool,  as a result it would be executable both  on Windows, or or Linux/Mac.  For a native client library check  https://pypi.python.org/pypi/WhoisClient

Restful Web Services API


Even with a native library, you will still need to parse the output data. There is a better way, which is getting the data in a format like XML, YAML, JSON etc  so that it is easier to get related parts systematically.  Fortunately RIPE/ARIN has a RESTFul Web Services API  which is a REST interface to their WhoIS Database which are invoked via http requests. Here are the documentation links:

For ARIN documentation check: 


Querying RIPE  Web API and Processing  XML Input With Python


By looking at the documentation, it can be seen that for AS5400, which is BritishTelecom, url

http://rest.db.ripe.net/search.xml?query-string=as5400&inverse-attribute=origin  could be used to get all routes that has an origin of AS5400. The ony thing to get prefixes for another AS is to change the “as5400” value in the url itelf. If you open the url in your web browser you will see an xml output like below: 



So if we could open this url in python, and get the output, then parse it as xml, everything will be ok. To do so, lets examine the code i wrote, part by part:

Examining the code: 

At first part of the code we need to import libraries, which are: urllib, urllib2 and xml.etree.ElementTree   (you may also use lxml instead of xml.etree.ElementTree)


import urllib,urllib2
try:
    import xml.etree.cElementTree as ET
except ImportError:
    import xml.etree.ElementTree as ET

We determined how to create a URL to pull prefixes that is originated from an AS. Creating an AS variable is logical so that in further usages you can change the AS number or get the value as an input.

as_to_pull_prefixes = "AS5400"
url = "http://rest.db.ripe.net/search.xml?query-string=%s&inverse-attribute=origin" % as_to_pull_prefixes

As url is ready we need to open the url and assign the output to a string variable:

fp = urllib2.urlopen (url)
response = fp.read()

Then we need to parse XML from string into an element:

tree = ET.fromstring(response)
fp.close()

Last part is to get the prefix values from the xml output, which we turned into an element by using xml.etree.ElementTree. First we need to determine the hierarchy so that we can write a path argument. Having a look at the xml output, the hierarchy should be:

  • inside <objects> 
  • inside <object> that has a type value of  "route" (for ipv4 prefixes) 
  • inside <primary-key>
  • every <attribute> which has a name value of "route" 

To write such a path argument, you may wanted to have a look at https://docs.python.org/2/library/xml.etree.elementtree.html#elementtree-xpath. Here is the code:

interested =  tree.findall("./objects/object[@type='route']/primary-key/attribute[@name='route']")

Our job is still not done yet, cause inside the tree we created, which is "interested" variable, we need to take the values of "value": Here is the last piece of the code:

for child in interested:
    print child.get('value')

Trying It Out 

Here is the output when i executed the script:


To download the script, click here, or copy-paste the full code below:

import urllib,urllib2
try:
    import xml.etree.cElementTree as ET
except ImportError:
    import xml.etree.ElementTree as ET
###
###Variables which changes per request
as_to_pull_prefixes = "AS5400"
url = "http://rest.db.ripe.net/search.xml?query-string=%s&inverse-attribute=origin" % as_to_pull_prefixes
###
###Pull Info From IRR(RIPE)and assign it to a variable as string
fp = urllib2.urlopen (url)
response = fp.read()
###
###parse xml from  from string into an element 
tree = ET.fromstring(response)
fp.close()
###
###get interested data from element 
interested =  tree.findall("./objects/object[@type='route']/primary-key/attribute[@name='route']")
for child in interested:
    print child.get('value')
###############
##for more info on how to select interested data from xml
##https://docs.python.org/2/library/xml.etree.elementtree.html#elementtree-xpath
###############

Wednesday, January 21, 2015

Validating BGP Announcements by Automating Filter Generation with Python: Part1


Securing Internet Routing infrastructure has been a hot topic for a long time as hijack events occurs again and again either mistakenly or on purpose. Operators use different  techniques to validate BGP announcements. I will try to explain creating an ip/as prefix-list  by pulling information from a RIR database, in our case RIPE, using python. But first, lets take a look at other methods in Part1: 

RPKI

Probabily  the best  way to prevent BGP/IP hijacks is to use RPKI infrastructure, , which is a  PKI framework (trust anchor mechanism). Unfortunately the method needs legitamate AS/IP owners to register their sources. needless to say that no one is registering their sources, as a result the method is still not applicable. By 21.01.2015 the current validation states for all IPv4 prefixes is only %5.59, You can check validation states from http://rpki.surfnet.nl/ipcomp.html.


RPSL 

For RPKI is not applicable, we need another way to validate the BGP announcements, where IRR RPSL database entries comes into play. RPSL is a language commonly used by ISPs to describe their routing policies. ISP's could store their routing policies either on their own server or on open public whois databases including RIPE, RADB, APNIC etc.  RIPE (RIR for Europe) transformed its database to RPSL format in 2001.  Example entries in RIPE database are:

as-set:          AS-FUNET
descr:           Macro with all ASes exported by FUNET
members:         AS1741
members:         AS1739
members:         AS565
members:         AS15496
members:         AS30754
members:         AS39098
members:         AS39857
members:         AS39662
tech-c:          FH437-RIPE
admin-c:         FA1183-RIPE
mnt-by:          AS1741-MNT
source:          RIPE # Filtered
As-set object which was created by FUNET, and includes their members

aut-num:         AS5400
as-name:         BT
descr:           British Telecommunications plc
org:             ORG-CNS3-RIPE
import:          from AS1741 action pref=20; accept AS-FUNET
British Telecoms RPSL entry which accepts the informations in AS-FUNET  as-set entry.
Route−set: AS4763:RS−ROUTES:AS681
descr:     prefix filter for AS681
members:   130.216.0.0/16, 130.217.0.0/16,
132.181.0.0/16, 138.75.0.0/16, 139.80.0.0/16,
140.200.0.0/16, 156.62.0.0/16, 192.73.21.0/24
tech−c:    JA39
mnt−by:    MAINT−TELSTRA−NZ
changed:   jabley@patho.gen.nz 19991118
source:    RADB
Route-set sample

Using these databases it is possible to get infos for AS-SETs, AS entries, route objects etc. We know that RPKI validation states are really low, so what about the RPSL entries?  Unfortunately Inter Route Registries are not that accurate also. BGPmon analysis which is done at 2010, shows that only %46 of the global routing table entries has a  matching route-object. 


If  you wanted to update a BGP import policy automatically then you should force the facing AS owner to update their IRR entries (route-objects, as-sets…). Some providers area also very strict in the IRR usage , so  why shouldn’t you ? 

Getting  Info From RIR Databases

Tools

There are many great tools that are ready for use which does the whois queries behind, which some of are: 
  • IRR Toolset
  • IRR Power Tools
  • NETİ:IRR
  • Bgpq3
  • Md
  • P2BGPTool
Lets take a loot at one of these tools, namely  Bgpq3, before writing our own python script: 

Bgpq3 Installation and Usage

Download compressed bgpq3 file from http://snar.spb.ru/prog/bgpq3/ , extract and install it (below steps for Ubuntu):

admin@ubuntu:~# wget http://snar.spb.ru/prog/bgpq3/bgpq3-0.1.21.tgz 
admin@ubuntu:~#  tar -xvzf bgpq3-0.1.21.tgz 
admin@ubuntu:~#  cd bgpq3-0.1.21/
admin@ubuntu:~/bgpq3-0.1.21# ./configure
admin@ubuntu:~/bgpq3-0.1.21# sudo make && sudo make install


After installing we could create a prefix-list from command line using the tool. Below is a sample for creating Junos prefix list for as-set: AS-FUNET


You may check bgpq3 man page for  more parameters (cisco, juniper, as-path, ipv4, ipv6)

Definitely command line tools are useful  but if you wanted get data from command line output in  python script it means that you need to parse the data.  There are better ways which you may continue reading in Part 2. 


 

Internetworking Hints Copyright © 2011 -- Template created by O Pregador -- Powered by Blogger