I’ve written the following scripts that will assist anyone in monitoring their (or anyone’s) IP space (IPv4, IPv6 and ASNs) against BGP hijacking.
The scripts rely on data provided by the Routing Information Service (RIS) which RIPE NCC have kindly opened up to the public to use. For years, RIPE have been running 25 Route Collectors around the world where they collect routing information and allow the public to download this data for analysis. In recent years, they started RIS to help users query this data via a REST API.
The script below (ris-live-prefix.py) will allow users to monitor an IPv4 or IPv6 prefix. The REST API will return JSON objects that match this request, as well as more specific BGP announcements.
ris-live-prefix.py
import json import websocket import ssl ws = websocket.WebSocket(sslopt={"cert_reqs": ssl.CERT_NONE}) ws.connect("wss://ris-live.ripe.net/v1/ws/?client=YOUR_ORG_NAME") params = { "moreSpecific": True, "host": "", "prefix": "45.146.72.0/22", "require": "", # can use "announcements" or "withdrawls" "socketOptions": { "includeRaw": True } } ws.send(json.dumps({ "type": "ris_subscribe", "data": params })) for data in ws: parsed = json.loads(data) print(parsed["type"], parsed["data"])
Optional step: change “YOUR_ORG_NAME” to anything unique to you. RIS Live maintainers will appreciate that.
This RIS Live stream has the tendency of breaking on a frequent basis; hence, use the below script to start it when it breaks. The script will also fix a problem with the python client not being able to verify the REST API SSL certificate authenticity
ris-live-prefix.sh
#!/bin/bash while true do WEBSOCKET_CLIENT_CA_BUNDLE=/etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem /usr/bin/python /path/to/your/ris-live-prefix.py | /usr/bin/sed s/u\'/\"/g | /usr/bin/sed s/\'/\"/g | /usr/bin/sed 's/^................//g' | /usr/bin/sed 's/)$//g' > /path/to/output/prefix-monitoring.json done
The additional sed commands are to there to filter the output and make it Logstash ready. You may have to alter that in accordance to whatever log analysis tool you’re using.
Moreover, if you want this script to run at boot time, you will have to create a cronjob for it, or run it as a service.
You can also monitor whether your ASN is being hijacked by modifying the above code slightly. The below script shows an example to monitor BGP updates for ASN 205986.
ris-live-asn.py
import json import websocket import ssl ws = websocket.WebSocket(sslopt={"cert_reqs": ssl.CERT_NONE}) ws.connect("wss://ris-live.ripe.net/v1/ws/?client=YOUR_ORG_NAME") params = { "moreSpecific": True, "host": "", "path": "205986", "require": "", # can use "announcements" or "withdrawls" "socketOptions": { "includeRaw": True } } ws.send(json.dumps({ "type": "ris_subscribe", "data": params })) for data in ws: parsed = json.loads(data) print(parsed["type"], parsed["data"])
and you’ll need to use the below script to keep it persistant
ris-live-asn.sh
#!/bin/bash while true do WEBSOCKET_CLIENT_CA_BUNDLE=/etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem /usr/bin/python /path/to/your/ris-live-asn.py | /usr/bin/sed s/u\'/\"/g | /usr/bin/sed s/\'/\"/g | /usr/bin/sed 's/^................//g' | /usr/bin/sed 's/)$//g' > /path/to/output/asn-monitoring.json done
Final notes
- If your organisation has multiple ASNs and multiple prefixes, you’ll need a script for each one of them
- RIS will show you all seen updates, including legitimate ones. So you need to use a filter in your favourite log analysis tool in order to highlight unexpected BGP updates.
- For prefix hijacking, your fliter needs to look for annoucements not originating from your as_path
- For ASN hijacking, your filter needs to look for annoucements where your next hop isn’t one of your transit ASNs.