06 Feb

Alternate to IRINN IRR manual entry / ALTDB

IRINN (Indian Registry for Internet Names and Numbers) is a NIR (National Internet Registry) for India operating under the APNIC RIR (Regional Internet Registry). IRINN is run and managed by NIXI. It’s a decent NIR and was set up in 2012. Indian organisations have the option to either maintain relation with APNIC or with IRINN.

A large number of small networks prefer IRINN because it’s annual charges are 25000 INR / $351 USD against APNIC’s membership fee which is over 2x of that.

There are a couple of key disadvantages of using IRINN:

  1. The membership portal is rather limited and the entire process of creating, updating route objects as well as AS SETs via IRINN is rather a manual process. One raises a ticket and during working days IRINN processes those requests & updates the IRR entries. In backend entries just go in the APNIC’s IRR.
  2. Process of creating/updating/maintaining RPKI ROAs is also rather manual.

As of now there’s not much one can do about #2 other than just following manual process by opening a ticket with IRINN but for #1 if you have a challenge that it’s rather slow to update/change because it is a manual process.

Introduction to IRR’s

IRR or Internet Routing Registry is just the public register for BGP related activities. Logic is that one first publishes what one wants to do and then does it. So I can say I want to originate 2402:b580::/32 from AS58901, publish it one of the publicly visible registers (known as IRRs) and then I actually announce the pool.

So who can run an IRR?

Anyone can! IRRd software is open source and one can use it to set up an IRR server. The old and most widely used IRRd is available here and the new version of IRRd (IRRd version 4) is here which is quite advanced, offers many excellent features. What makes IRRs run by APNIC, ARIN, RIPE, RADB etc popular is the fact that RADB mirrors them all and a large number of tools default to RADB for generating the filtering config. As per data available here, RADB mirrors 23 other IRRs besides serving from its own database. So one can get entry to either of these available IRRs based on relation one has with them for creating the route objects or AS SETs and it just works.

ALTDB

Many people know of RADB which is run by merit. It’s a paid option and many networks use that for maintaining route objects. There’s also a free IRR called ATLDB. It’s free to create an account on it and approval of account is a manual process but once approved, creation/updation of route objects as well as AS SETs is all automated and works via email with a specific syntax. Unfortunately, there’s not much on the ALTDB website except a whois lookup tool, however, if you want to read in detail about IRR as well as using ALTDB, the Fremont Cabal Internet Exchange has an excellent guide on that (here).

The basic logic here is to do following: Create a maintainer object > Define routing policy of the ASN (peers, transit, downstream etc) > Create AS SET (if you have BGP downstream customers) > Create route objects for your IPv4 and IPv6 prefixes > Publish your ASSET on PeeringDB. Again one can follow the detailed steps given on the FCIX website.

Here’s an example of it in action for a test prefix of the pool I use:
2402:b580::/32

As of now, there’s no corresponding route object with it. Here’s a quick check on RADB:

anurag@devops01 ~> whois -h whois.radb.net 2402:b580::/32
%  No entries found for the selected source(s).
anurag@devops01 ~>

As of now, there’s no route object for it. Let’s say I want to start originating from AS58901, so I will put following in a plain text mail and send it to ALTDB email ID (auto-dbm@altdb.net) which processes these requests automatically.

route6:     2402:b580::/32
descr:      Anurag Bhatia R&D Network IPv6 Pool
origin:     AS58901
mnt-by:     MAINT-AS58901
changed:    me@anuragbhatia.com 20200205
source:     ALTDB

It’s important to send email in cleartext. One can check how to do that in a specific email client or web interface one uses. For Gmail the option is here:

I get following in reply from ALTDB:

And now query to RADB gives us:

anurag@devops01 ~> whois -h whois.radb.net 2402:b580::/32
route6:     2402:b580::/32
descr:      Anurag Bhatia R&D Pool
origin:     AS58901
mnt-by:     MAINT-AS58901
changed:    me@anuragbhatia.com 20200205
source:     ALTDB
anurag@devops01 ~>

And here goes the example of creating AS SET: AS-ANURAG. I sent following to the ATLDB:

as-set:     AS-ANURAG
descr:      Anurag Bhatia's AS SET
members:    AS58901
mnt-by:     MAINT-AS58901
changed:    me@anuragbhatia.com 20200205
source:     ALTDB

Upon confirmation, I get when I query RADB:

anurag@devops01 ~> whois -h whois.radb.net AS-ANURAG
as-set:     AS-ANURAG
descr:      Anurag Bhatia's AS SET
members:    AS58901
mnt-by:     MAINT-AS58901
changed:    me@anuragbhatia.com 20200205
source:     ALTDB
anurag@devops01 ~>

Remember if you happen to use ALTDB, make sure to ask IRINN to delete your route objects after you have successfully created them on ALTDB. Duplicate entries just add to the junk in IRR.

Further reading

  1. My detailed presentation on IRR last year at Singapore NOG: Let’s talk about the routing security
  2. Automated configuration of BGP on edge routers by University of Amsterdam
05 Apr

Tata – Airtel domestic peering IRR filtering and OpenDNS latency!

Last month I noticed quite high latency with Cisco’s OpenDNS from my home fibre connection. The provider at home is IAXN (AS134316) which is peering with content folks in Delhi besides transit from Airtel.

ping -c 5 208.67.222.222
PING 208.67.222.222 (208.67.222.222) 56(84) bytes of data.
64 bytes from 208.67.222.222: icmp_seq=1 ttl=51 time=103 ms
64 bytes from 208.67.222.222: icmp_seq=2 ttl=51 time=103 ms
64 bytes from 208.67.222.222: icmp_seq=3 ttl=51 time=103 ms
64 bytes from 208.67.222.222: icmp_seq=4 ttl=51 time=103 ms
64 bytes from 208.67.222.222: icmp_seq=5 ttl=51 time=103 ms


--- 208.67.222.222 ping statistics ---
5 packets transmitted, 5 received, 0% packet loss, time 4005ms
rtt min/avg/max/mdev = 103.377/103.593/103.992/0.418 ms

This is bit on the higher side as from Haryana to Mumbai (OpenDNS locations list here). My ISP is backhauling from Faridabad which is probably 6-8ms away from my city and 2-3ms further to Delhi and from there to Mumbai around 30ms. Thus latency should be around ~40-45ms.

Here’s how forward trace looked like

traceroute 208.67.222.222
traceroute to 208.67.222.222 (208.67.222.222), 30 hops max, 60 byte packets
 1  172.16.0.1 (172.16.0.1)  0.730 ms  0.692 ms  0.809 ms
 2  axntech-dynamic-218.140.201.103.axntechnologies.in (103.201.140.218)  4.904 ms  4.314 ms  4.731 ms
 3  10.10.26.1 (10.10.26.1)  6.000 ms  6.414 ms  6.326 ms
 4  10.10.26.9 (10.10.26.9)  6.836 ms  7.135 ms  7.047 ms
 5  nsg-static-77.249.75.182-airtel.com (182.75.249.77)  9.344 ms  9.416 ms  9.330 ms
 6  182.79.243.201 (182.79.243.201)  62.274 ms 182.79.177.69 (182.79.177.69)  66.874 ms 182.79.239.193 (182.79.239.193)  61.297 ms
 7  121.240.1.201 (121.240.1.201)  85.789 ms  82.250 ms  79.591 ms
 8  172.25.81.134 (172.25.81.134)  110.049 ms 172.31.29.245 (172.31.29.245)  114.350 ms  113.673 ms
 9  172.31.133.210 (172.31.133.210)  112.598 ms 172.19.138.86 (172.19.138.86)  114.889 ms 172.31.133.210 (172.31.133.210)  113.415 ms
10  115.110.234.50.static.mumbai.vsnl.net.in (115.110.234.50)  125.770 ms  125.056 ms  123.779 ms
11  resolver1.opendns.com (208.67.222.222)  113.648 ms  115.044 ms  106.066 ms

Forward trace looks fine except that latency jumps as soon as we hit Tata AS4755 backbone. OpenDNS connects with Tata AS4755 inside India and announces their anycast prefixes to them. If the forward trace is logically correct but has high latency, it often reflects the case of bad return path. Thus I requested friends at OpenDNS to share the return path towards me. As expected, it was via Tata AS6453 Singapore.

Here’s what Tata AS4755 Mumbai router had for IAXN prefix:

BGP routing table entry for 14.102.188.0/22 
Paths: (1 available, best #1, table Default-IP-Routing-Table) 
Not advertised to any peer 
6453 9498 134316 134316 134316 134316 134316 134316 134316 134316 134316 134316 
192.168.203.194 from 192.168.199.193 (192.168.203.194) 
Origin IGP, localpref 62, valid, internal, best 
Community: 4755:44 4755:97 4755:888 4755:2000 4755:3000 4755:47552 6453:50 6453:3000 6453:3400 6453:3402 
Originator: 192.168.203.194, Cluster list: 192.168.199.193 192.168.194.15 
Last update: Mon Mar 25 15:26:36 2019

Thus what was happening is this:

Forward path: IAXN (AS134316) > Airtel (AS9498) > Tata (AS4755) > OpenDNS (AS36692)

Return path: OpenDNS (AS36692) > Tata (AS4755) > Tata (AS6453) > Airtel (AS9498) > IAXN (AS134316)

While this may seem like a Tata – Airtel routing issue but it wasn’t. I could see some of the prefixes with a direct path as well. Here’s a trace from Tata AS4755 Mumbai PoP to an IP from a different pool of IAXN:

traceroute to 103.87.46.1 (103.87.46.1), 15 hops max, 60 byte packets
1 * * *
2 172.31.170.210 (172.31.170.210) 0.911 ms 0.968 ms 0.643 ms
3 172.23.78.233 (172.23.78.233) 1.233 ms 0.821 ms 0.810 ms
4 172.17.125.249 (172.17.125.249) 23.540 ms 23.454 ms 23.367 ms
5 115.110.232.174.static.Delhi.vsnl.net.in (115.110.232.174) 49.175 ms 48.832 ms 49.107 ms
6 182.79.153.87 (182.79.153.87) 48.777 ms 182.79.153.83 (182.79.153.83) 49.043 ms 182.79.177.127 (182.79.177.127) 54.879 ms
7 103.87.46.1 (103.87.46.1) 60.865 ms 60.540 ms 60.644 ms

This clearly was fine. So why Tata was treating 103.87.46.0/24 different from 14.102.188.0/22? The reason for that lies in following:

  • Airtel (AS9498) very likely peers with Tata (AS4755). They do interconnect for sure as we see in traceroutes and my understanding is that it’s based on settlement-free peering for Indian traffic.
  • Airtel (AS9498) buys IP transit from Tata (AS6453) (besides a few others). Tata AS6453 is carrying the routing announcements to other networks in the transit free zone and that confirms that Airtel (at least technically) has a downstream customer relationship here.
  • Tata (AS4755) has IRR based filters on peering but not the Tata (AS6453) for it’s downstream. Hence while Tata rejected the route in India, they did accept that in Singapore PoP.
  • My IP was from prefix 14.102.188.0/22 and there was no valid route object for it at any of key IRRs like ATLDB, APNIC or RADB. But other prefix 103.87.46.0/24 did had a valid route object on APNIC.

Now after almost 10 days of it, my ISP has changed the BGP announcement and announcing 14.102.189.0/24 (which does a valid route object on APNIC). This fixes the routing problem and give me pretty decent latency with OpenDNS:

ping -c 5 208.67.222.222
PING 208.67.222.222 (208.67.222.222): 56 data bytes
64 bytes from 208.67.222.222: icmp_seq=0 ttl=55 time=52.552 ms
64 bytes from 208.67.222.222: icmp_seq=1 ttl=55 time=53.835 ms
64 bytes from 208.67.222.222: icmp_seq=2 ttl=55 time=53.330 ms
64 bytes from 208.67.222.222: icmp_seq=3 ttl=55 time=52.700 ms
64 bytes from 208.67.222.222: icmp_seq=4 ttl=55 time=52.504 ms

--- 208.67.222.222 ping statistics ---
5 packets transmitted, 5 packets received, 0.0% packet loss
round-trip min/avg/max/stddev = 52.504/52.984/53.835/0.518 ms

So if you are a network operator and originating prefixes, please do document them in any of the IRRs. You can do that via IRR of your RIR (APNIC, ARIN etc) or a free IRR like ALTDB. If you have downstreams, make sure to create AS SET, add downstreams ASNs in your AS SET and also include that AS SET on peeringdb for the world to see!

Misc Notes

  • Posted strictly in my personal capacity and has nothing to do with my employrer.
  • Thanks for folks from Cisco/OpenDNS for quick replies with relevant data which helped in troubleshooting. 🙂
06 Apr

Route filter generation for Mikrotik RouterOS via IRR

A while back I posted about routing filter generation via bgpq3 for Cisco (ios and XR) and Juniper JunOS based routers. I have received a number of emails in last few months about automated filter generation for Mikrotik routeros. Since Mikrotik’s CCRs are getting quite popular across small to mid-sized ISPs.

So this blog post is about ways for generating filter config for a given ASN via IRR. One can use such logic with some kind of remote login mechanism like rancid (look for mtlogin here).

I tried building around bgpq3 but it seems more easy with another popular tool in the domain called IRR Power Tools. Once IRR Power Tools (IRRPT) is setup, it allows us to fetch prefixes based via Internet Routing Registries and also aggregates them.

 

So, for instance, let’s pick AS54456:

anurag@tools:~/irrpt$ bin/irrpt_fetch 54456
Processing AS54456 (Record 1)
   - Importing /home/anurag/irrpt/db/54456                   version 1.1
   - Importing /home/anurag/irrpt/db/54456.4                 version 1.1
   - Importing /home/anurag/irrpt/db/54456.6                 version 1.1
   - Importing /home/anurag/irrpt/db/54456.agg               version 1.1
   - Importing /home/anurag/irrpt/db/54456.4.agg             version 1.1
   - Importing /home/anurag/irrpt/db/54456.6.agg             version 1.1
Completed processing of 1 IRR object(s).
anurag@tools:~/irrpt$

 

So now we have got prefixes and this includes both basic route objects as well as aggregates.

anurag@tools:~/irrpt$ cat /home/anurag/irrpt/db/54456.4
199.116.76.0/24
199.116.77.0/24
199.116.78.0/24
199.116.79.0/24
anurag@tools:~/irrpt$
anurag@tools:~/irrpt$ cat /home/anurag/irrpt/db/54456.4.agg
199.116.76.0/22
anurag@tools:~/irrpt$

 

It offers a nice interface for generation of config for Cisco, Juniper, Extreme, Foundry and Force10. Example:

anurag@tools:~/irrpt/bin$ ./irrpt_pfxgen -f cisco 54456
conf t
no ip prefix-list CUSTOMER:54456
no ipv6 prefix-list CUSTOMERv6:54456
ip prefix-list CUSTOMER:54456 permit 199.116.76.0/22 le 24
end
write mem
anurag@tools:~/irrpt/bin$
anurag@tools:~/irrpt/bin$
anurag@tools:~/irrpt/bin$ ./irrpt_pfxgen -f juniper 54456
policy-options {
    replace: policy-statement CUSTOMER:54456 {
        term prefixes {
            from {
                route-filter 199.116.76.0/22 upto /24;
            }
            then next policy;
        }
        then reject;
    }
}
policy-options {
    replace: policy-statement CUSTOMERv6:54456 {
        term prefixes {
            from {
            }
            then next policy;
        }
        then reject;
    }
}
anurag@tools:~/irrpt/bin$

 

So I put a routeros instance in a VM to test and create config from their CLI. Config looks something like this:

[admin@MikroTik] > routing filter add chain=Cloudaccess prefix=199.116.76.0/22 prefix-length=22-24 action=accept
[admin@MikroTik] > routing filter add chain=Cloudaccess  action=reject
[admin@MikroTik] >

This seems logical and can be scripted. So one can have a script to read the aggregate file and if aggregate says /24 one can put it directly in the filter else allow filter up to /24 from whatever range the pool starts and similar logic in IPv6.

So here’s the script:

#!/bin/bash

# Script for generating BGP filter for Mikrotik RouterOS
# Input name of chain via $1 and ASN via $2

irrpt=/home/anurag/irrpt


# Grab latest filters via RADB / other IRRs using IRRPT
echo "Grabbing prefixes for AS$2"
php $irrpt/bin/irrpt_fetch $2


echo "***Start of Mikrotik routeros config below***"


# IPv4 config part
cat $irrpt/db/$2.4.agg | while read prefix

do
masklength=`echo $prefix|awk -F '/' '{print $2}'`
if [ "$masklength" -eq 24 ]
	then
	# Prefix is a /24 - generating config without defining prefix length
	echo "routing filter add chain=$1-IPv4 prefix=$prefix action=accept"


elif [ "$masklength" -lt 24 ]
	then
	# Prefix is greater than /24 - generating config with prefix length upto /24
	echo "routing filter add chain=$1-IPv4 prefix=$prefix prefix-length=$masklength-24 action=accept"

fi
done
# Last entry for denial of pools
echo "routing filter add chain=$1-IPv4 action=reject"




cat $irrpt/db/$2.6.agg | while read prefix6

do
masklength6=`echo $prefix6|awk -F '/' '{print $2}'`
if [ "$masklength6" -eq 48 ]
	then
	# Prefix is a /48 - generating config without defining prefix length
	echo "routing filter add chain=$1-IPv6 prefix=$prefix6 action=accept"


elif [ "$masklength6" -lt 48 ]
	then
	# Prefix is greater than /48 - generating config with prefix length upto /48
	echo "routing filter add chain=$1-IPv6 prefix=$prefix6 prefix-length=$masklength6-48 action=accept"

fi
done
# Last entry for denial of pools
echo "routing filter add chain=$1-IPv6 action=reject"




echo "***End of Mikrotik routeros config***"

 

So the script works except with a small bug in IPv6 aggregation which is the issue with IRRPT and I have reported same on their GitHub project page here.

 

An example of the script in progress for Cloudaccess AS54456:

anurag@tools:~/irrpt$ ./routeros.sh Cloudaccess 54456
Grabbing prefixes for AS54456
Processing AS54456 (Record 1)
Completed processing of 1 IRR object(s).
***Start of Mikrotik routeros config below***
routing filter add chain=Cloudaccess-IPv4 prefix=199.116.76.0/22 prefix-length=22-24 action=accept
routing filter add chain=Cloudaccess-IPv4 action=reject
routing filter add chain=Cloudaccess-IPv6 action=reject
***End of Mikrotik routeros config***
anurag@tools:~/irrpt$

 

Here’s another example of it in action with NPCI’s AS132351

anurag@tools:~/irrpt$ ./routeros.sh NPCI 132351
Grabbing prefixes for AS132351
Processing AS132351 (Record 1)
   - Importing /home/anurag/irrpt/db/132351                  version 1.1
   - Importing /home/anurag/irrpt/db/132351.4                version 1.1
   - Importing /home/anurag/irrpt/db/132351.6                version 1.1
   - Importing /home/anurag/irrpt/db/132351.agg              version 1.1
   - Importing /home/anurag/irrpt/db/132351.4.agg            version 1.1
   - Importing /home/anurag/irrpt/db/132351.6.agg            version 1.1
Completed processing of 1 IRR object(s).
***Start of Mikrotik routeros config below***
routing filter add chain=NPCI-IPv4 prefix=103.14.160.0/22 prefix-length=22-24 action=accept
routing filter add chain=NPCI-IPv4 action=reject
routing filter add chain=NPCI-IPv6 prefix=2001:df0:2f0::/46 prefix-length=46-48 action=accept
routing filter add chain=NPCI-IPv6 action=reject
***End of Mikrotik routeros config***
anurag@tools:~/irrpt$

 

 

 

 

Thinking to automate? 

The config between ***start*** and ***end*** can be pasted directly in CLI with Mikrotik. I would not recommend using it for manual filtering of any larger network. Automated filtering where filters are generated regularly makes sense but manual filtering without automation can be damaging. One can use a script like this for connecting to smaller networks. Also, IRRPR offers diff management via CVS (I hope they come up with git on that part) and it comes with an option to trigger email update so Network admins can know when to manually update. I would prefer that for non-commit based platforms since with Cisco ios or Mikrotik routeros it can be tricky to auto update prefix list. If one does no ip prefix list before triggering update it will cause a major noticeable impact. So ideal way to manage that on non-commit based devices would be to maintain a list of prefixes separately in the plain text file or a database and diff it against old one & only push for changes. Do-able and should be preferred that way instead of deleting and re-adding the whole list while automating.

 

Time to get back to work! 🙂