RIPE Scripting Pt2
By gregoire on Monday 3 March 2008, 11:31 - Permalink
The events
On 24th Feb, 2008, the whole world became unable to reach YouTube
(AS36561). What happened, is that Pakistan Telecom
(AS17557), who had decided to blacklist YouTube, started
announcing one of their prefixes, but in a more specific way (i.e. announcing a
/24 within a /20). This would have ended-up armlessly if PCCW
(AS3491), on of their upstreams, hadn't re-announced this
prefix to all of their peers (PCCW is a pretty big carrier, with quite a few
transit customers...). This /24 range contained YouTube's DNS, so that Pakistan
Telecom have been blackholing YouTube for about one hour.
The event chronology and analysis can be found here at RIPE
and on the excellent Renesys
What do we know ?
- Pakistan Telecom's announcement of YouTube's /24 seems a weird solution for blacklisting
- PCCW's Has taken AS17557's announce and spread it to all of its peers, why
would they do that ?...
And some of the assumptions and conclusions we might take about all
this
- Pakistan telecom certainly have Nailed the route to the /24 or had it point
to a web server stating "YouTube has been blocked
blablabla..."
This would have been done by adding a static route into one(several) of
their core routers, which I assume had a redistribute static
subnets configured in their IGP. Then, it becomes unclear how this
ended up as an announcement in the EGP towards PCCW. Was Pakistan Telekom
redistributing IGP into EGP ? I find it weird...
This shows that any network shall filter its announces to its exact
IRR
allocation.
- PCCW was obviously not filtering Pakistan Telekom's annoucements to their
IRR prefixes.
They should, as a transit upstream provider, operating a worldwide IP
Network, use IRR Records to automate IN prefix-filters on its
customer ports.
Avoiding that
Filtering your announcements (transit customer)
This is BGP 1-0-1, you will always want to manually control what your
announced prefixes are. It is just about maintaining an outbound prefix-filter,
that doesn't change that often, so please do it.
Filtering your customer's prefixes inbound
Your local IRR does contain all the info you need to do that. In order to
get an AS# and an allocated IPv4 PI, you need to be in contact with your RIR
(APNIC for Pakistan Telekom])
who first records your allocations before you can route them.
You can manually get all the routes of a given AS by doing an inverse
lookup of the origin attribute for a certain AS, here it
is below, for Pakistan Telekom:
whois -h whois.apnic.net -i origin as17557 | grep '^route:'
Which by the way shows that AS17557 sends-out deaggregated routes, which again,
is not very good in terms of Routing Table Growth...
Possibly, you want to automate that, so that your filters are updated every
night. If you have one single machine (or one per IRR) that does this for all
of your customers, there will very likely be a too many
connexions issue with the whois server from your robot, which means
that in a few minutes time, you'll temporarily be blacklisted as a potential
DoS source.
One other way to do it would consist in not using the whois binary, but a
persistent connexion on telnet whois.<your-IRR>.net 43 as
TCP/43 is the standard port for whois queries - a -k option for
keeping it persistent, netcat / nc for piping any command to a TCP
bound port. This would look something like this:
echo "-k -i origin as17557" | nc whois.apnic.net 43 | grep
'^route:' The above example is a bit dumb, as the only interrest of
Netcat is to maintain TCP/43 connectivity towards the host and therefore not
get blacklisted. This is when you start to understand that socket
programming is going to be necessary. d'Oh! I won't,
it never works the way I want, and I do suck a load at coding network
stuff.
If you're still into the socket programming thing, here are some links in PHP
and Python that might come in handy to you:
- an example of PHP / Socket / RIPE script here
- using the excellent Twisted event-driven-networking-framework in Python (probably one of
the smartest script languages to be born lately).
As a side note, another way of getting all the prefixes announced by an AS is
using the peval binary included in ISC's IRRToolSet or the RtConfig binary that builds router
filters accordingly to the IRR reccords. I won't detail this method as I've not
found it that optimal, but it still is worth a shot.
But...
We are (assuming I am) way too lazy to dive into socket programming
As a mentioned in one of my earlier posts, IRR 'flat database files' are
available on your favorite IRR's FTP. Why bother when you can handle the
computation yourself by using your favorite language (even LISP if you wanna)
to parse a text file ?
What we'll do first is setup a CRON entry in our robot to go
fetch those files we need every night. RIPE's ones are located here:
ftp://ftp.ripe.net/ripe/dbase/split/
Effectively, the 'plain ftp binary' can be used together with macros, defined
in the .netrc file in your homedir. The following example of my
own .netrc file displays 3 macros, to get 3 different ripe DB
files:
1 machine ftp.ripe.net2 login anonymous3 password greg@grrrrreg.net45 macdef getAutNumDB6 cd /ripe/dbase/split7 lcd ~/scripts8 get ripe.db.aut-num.gz9 quit1011 macdef getAsSetDB12 cd /ripe/dbase/split13 lcd ~/scripts14 get ripe.db.as-set.gz15 quit1617 macdef getInetNumDB18 cd /ripe/dbase/split19 lcd ~/scripts20 get ripe.db.inetnum.gz21 quit
Then, a tiny bashscript will go fetch those 3 files via FTP, and then gunzip
them, just modify the destination location on your machine (line 7,13,19 of the
.netrc file) if you wanna:
1 #!/bin/bash23 echo "## script gets ripe.db files##"4 echo "\$ getAsSetDB" | ftp -i ftp.ripe.net 1>/dev/null && echo `date "+[%Y-%m-%d | %H:%M:%S].....ripe.db.as-set transfer complete"`56 if [ ! -e "./ripe.db.as-set.gz" ]7 then echo `date "+[%Y-%m-%d | %H:%M:%S]..........ERROR:ripe.db.as-set.gz inexistant"`8 else9 gunzip -f ripe.db.as-set.gz && echo `date "+[%Y-%m-%d | %H:%M:%S]..........ripe.db.as-set.gz gunziped"`10 fi
And so on for other ripe.db files...
Next episode, we'll deal with those files with $SCRIPT-LANGUAGE :)