You are here: Home > Publications > RIPE Labs > Chris Amin > RIS Live BGP Message Stream

RIS Live BGP Message Stream

Chris Amin — 15 Feb 2019
We are launching a prototype called RIS Live, a feed that offers BGP messages in real time. It collects information from the RIS Route Collectors (RRCs) and uses a WebSocket JSON API to monitor and detect routing events around the world.

Background

Since 2001, the RIPE NCC has collected and stored Internet routing data from multiple locations around the globe, using the Routing Information Service (RIS). Thanks to a complete redesign of the RIS infrastructure several years ago, we were able to build an experimental interface that allowed users to stream BGP data in nearly real time.

This experiment has already been used by some organisations for academic and research purposes. In 2017, INSPIRE group and CAIDA used it to develop ARTEMIS, a real-time BGP hijack detection tool, the software development stage of which received funding from the RIPE NCC Community Projects Fund 2017.

RIS Live 

We are now presenting RIS Live, an improved version of  the earlier experiment provided as a fully supported public prototype. RIS Live comes with a WebSocket JSON API to monitor and detect routing events around the world. For researchers, a non-interactive full stream ("firehose") is also available.

The new RIS Live demo

RIS Live takes messages coming from the RIS route collectors via the RIS collector architecture. Users can connect to RIS Live and request that the server filter the messages that they are interested in. There are various filters available, notably (more specific) CIDR prefix matching and AS path matching for BGP UPDATE messages (announcements and withdrawals). These messages are typically available on RIS Live less than one second after the original BGP message is seen.

RIS architecture including RIS Live

Users are encouraged to examine, test and use RIS Live and give feedback on what they find useful about it. If we receive positive feedback then the prototype will provide the basis for a fully supported production service. Feedback can be provided by filling in a short survey.

Get started

By going to the RIS Live homepage you can see an online demo of the stream. You can then take a look at the RIS Live Manual to get more in-depth technical and implementation details. This should help you get started with making the most of RIS Live in your own scripts, experiments, websites and other tools.

4 Comments

Stéphane Bortzmeyer says:
15 Feb, 2019 05:06 PM
Here is an asynchronous version of a Python client so you can do other things while waiting for updates. (In that case, we just display a timestamp.)

#!/usr/bin/env python3

PERIOD = 5
RFC3339 = '%Y-%m-%dT%H:%M:%SZ'

import sys
import json
import time
import asyncio

# https://websockets.readthedocs.io/
import websockets

class RISliveWebsocket():

    def __init__(self, router, asn):
        self.router = router
        self.asn = asn
        
    async def __aenter__(self):
        self._conn = await websockets.connect("wss://ris-live.ripe.net/v1/ws/?client=asynchronous-python-script-by-me")
        opening = json.dumps({"type": "ris_subscribe", "data": {"host": self.router, "path": self.asn}})
        await self._conn.send(opening)
        print("Connected, %s sent" % opening)
        return self

    async def __aexit__(self, *args, **kwargs):
        print("Goodbye")
        pass

    async def send(self, message):
        await self._conn.send(message)

    async def receive(self):
        print("Trying to receive")
        return await self._conn.recv()

async def tick():
    while True:
        await asyncio.sleep(PERIOD)
        print("Waking up, it is %s" % time.strftime(RFC3339, time.gmtime(time.time())))
        
async def main(router, asn):
    sock = RISliveWebsocket(router, asn)
    async with sock as feed:
        while True:
            print(await feed.receive())

if __name__ == '__main__':
    if len(sys.argv) != 3:
        print("Usage: %s RIS-router ASn" % sys.argv[0], file=sys.stderr)
        sys.exit(1)
    try:
        loop = asyncio.get_event_loop()
        loop.run_until_complete(asyncio.wait([main(sys.argv[1], sys.argv[2]), tick()]))
    except KeyboardInterrupt:
        pass # Does not call __aexit__?
Chris Amin says:
18 Feb, 2019 10:16 AM
Thanks, Stéphane! At some point I may add extra examples to the documentation. Is it okay if I include something based on your example?
Stéphane Bortzmeyer says:
19 Feb, 2019 09:58 AM
You're welcome to use this example as you see fit. A better version is available at https://www.bortzmeyer.org/files/ris-live.py
Mirjam Kühne says:
20 Feb, 2019 09:41 AM
Please also note the lightning talk by Jared Mauch at the recent NANOG 757 meeting: https://pc.nanog.org/[…]/20190219_Mauch_Lightning_Talk_Ris_v1.pdf
Add comment

You can add a comment by filling out the form below. Comments are moderated so they won't appear immediately. If you have a RIPE NCC Access account, we would like you to log in.