SkillAgentSearch skills...

Birdseye

A Simple Secure Micro Service for Querying Bird (JSON API)

Install / Use

/learn @inex/Birdseye
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

Bird's Eye - A Simple Secure Micro Service for Querying BIRD

A simple secure PHP micro service to provide some BIRD protocol / routing information via a HTTP API as JSON, with an optional built-in looking-glass implementation.

This is the winning project from the RIPE IXP Tools Hackaton just prior to RIPE73 in Madrid, Spain. Since the hackathon, substantial improvements have been made.

The end of workshop presentation can be found here: [Keynote] [PDF]. A more detailed presentation to the Open Source Working Group at RIPE73, delivered by @nickhilliard, can be found here: [VIDEO]

Author: Barry O'Donovan, INEX, Dublin, Ireland

Live Examples

INEX runs a number of BIRD instances and many of them have a public looking glass powered by Bird's Eye as a standalone live example and also integrated with IXP Manager as a frontend consumer.

  • INEX Cork IPv4 Router Collector: https://www.inex.ie/rc1-cork-ipv4/
  • INEX Cork IPv6 Router Collector: https://www.inex.ie/rc1-cork-ipv6/

The landing pages for the above also document the API calls available.

You can see the IXP Manager integration for ~30 BIRD daemons at INEX at https://www.inex.ie/ixp/lg. GR-IX have also a public IXP Manager integration at: https://portal.gr-ix.gr/lg.

Complementary Projects

At the hackathon, the team also produced consumers of this API:

  • https://github.com/dfkbg/birdseye - Python CLI consumer by Daniel Karrenberg
  • https://github.com/ecix/birdseye - Python based web consumer by Annika Hannig

Rationale

Historically, IXPs made route collector and route server information available via looking-glasses. Over the past few years, many IXPs have selected BIRD as their route server / collector BGP daemon for a number of good reasons.

BIRD lacks an API to allow IXPs to provide these looking glass type tools. Moreover, this also affects an IXP's ability to monitor these routing daemons and peering participant sessions to them.

In a typical IXP, there will be six daemons per peering LAN:

  • two route servers and one route collector
  • separate daemon for ipv4 and ipv6

Having looked at existing BIRD LG implementations, INEX could not identify one that was designed with security in mind. Bird's Eye was written with security as a primary consideration.

Security

As this is intended to be deployed on an IXP's route server / route collector, security is vital. In that regard, the following considerations have been made:

  • Natural rate limiting via caching by default. All queries are cached for a (configurable) period of at least one minute. This means the most you can hit the BIRD daemon for a specific request is once per minute.
  • Built in rate limiter for queries that take variable parameters (e.g. route lookup).
  • Strict parameter parsing and checking.
  • Bundled birdc bash script for safe use via sudo - the web process will require this to access the BIRD socket.
  • birdc executed in restricted mode, to allow ''show'' commands only.

This API was not designed with the notion of making it publicly available. Ideally it would be run on an internal private network and fronted by one of the looking glass frontends above that consume this API, thereby providing multiple levels of API parameter validation.

Outlook

In an ideal world, this micro-service will be deprecated once the BIRD developers release a version with a built-in HTTP JSON API. This is a (hopefully) temporary solution to plug a gap.

Installation

This is a basic Lumen PHP application and the requirements are:

  • PHP >= 8.1
  • Mbstring PHP Extension

Download the release package (ensure you get the latest version rather than the example version listed below!) and install on your server. E.g.:

# E.g. Ubuntu 20.04 / 22.04 / 24.04 LTS
apt-get install php-cgi php-mbstring php-xml unzip
cd /srv
wget https://github.com/inex/birdseye/releases/download/vx.y.z/birdseye-vx.y.z.tar.bz2
tar jxf birdseye-vx.y.z.tar.bz2
cd birdseye-vx.y.z
chown -R www-data: storage  # or the appropriate web user on your system

You'll need a web server to front it. Apache or Lighttpd are good choices. As the requirements are small and you most likely don't have any other use for a web server on the route server / collector boxes, Lighttpd has a small footprint:

apt-get install lighttpd
lighty-enable-mod fastcgi
lighty-enable-mod fastcgi-php

And configure Lighttpd - see data/configs/lighttpd.conf for an example.

Install from Source with Composer

If you prefer to install from source with composer:

git clone https://github.com/inex/birdseye.git
cd birdseye
composer install --prefer-dist --no-dev
chown -R www-data: storage  # or the appropriate web user on your system

Configuration

We have tried to make configuration as easy as possible while allowing for the fact that there will typically be at least two BIRD processes to query on the same server. An explanation is easiest with an example:

Let's say there is a route server called rs1.inex.ie which provides both IPv4 and IPv6 services to two separate peering LANs.

To query the individual four daemons, we create DNS aliases as follows:

rs1-lan1-ipv4.inex.ie IN CNAME rs1.inex.ie
rs1-lan1-ipv6.inex.ie IN CNAME rs1.inex.ie
rs1-lan2-ipv4.inex.ie IN CNAME rs1.inex.ie
rs1-lan2-ipv6.inex.ie IN CNAME rs1.inex.ie

The micro-service will extract the first element of the hostname (e.g. rs1-lan1-ipv4, see beginning of bootstrap/app.php) and look for an environment file in the applications root directory (e.g. /srv/birdseye) named as follows for the above examples:

rs1-lan1-ipv4.inex.ie -> /srv/birdseye/birdseye-rs1-lan1-ipv4.env
rs1-lan1-ipv6.inex.ie -> /srv/birdseye/birdseye-rs1-lan1-ipv6.env
rs1-lan2-ipv4.inex.ie -> /srv/birdseye/birdseye-rs1-lan2-ipv4.env
rs1-lan2-ipv6.inex.ie -> /srv/birdseye/birdseye-rs1-lan2-ipv6.env

To create your env file, just (following the above naming convention):

cd /srv/birdseye
cp .env.example birdseye-rs1-lan1-ipv4.env

If you do not want to use hostnames and your Bird's Eye installation is behind a proxy, you can set the same element as above in the HTTP request header: X-BIRDSEYE. See the Varnish example below in the Serving Behind a Proxy section.

This example file has sane defaults but you need to edit it and fix the BIRDC parameter. In our naming case above (and for rs1-lan1-ipv4.inex.ie) and with Bird v1.x.y we'd set it to:

BIRDC="/usr/bin/sudo /srv/birdseye/bin/birdc -4 -s /var/run/bird/rs1-lan1-ipv4.ctl"

with the assumption that we've named and located the BIRD socket at that location. If you are using Bird v1.x.y with the IPv6 daemon, change the -4 switch to -6. From Bird's Eye v1.2.0 onwards, we now also support Bird v2; in this case use the -2 switch.

If you have a single BIRD daemon, you can skip DNS and just do:

cp .env.example .env

The last thing you need to do is give the www-data (or the appropriate web server user) user permission to run the birdc script. Edit /etc/sudoers and add (example):

www-data        ALL=(ALL)       NOPASSWD: /srv/birdseye/bin/birdc

Built in Looking Glass

This API has an optional built-in looking glass which utilises the API internally. This is mildly inefficient as it means a json_encode/json_decode of the same data but it proves the API, keeps us honest and the performance overhead is not excessive.

To enable it, set the following parameter to true in your configuration file:

LOOKING_GLASS_ENABLED=true

This will activate the looking glass routes, add a link to the header and make the looking glass available under the base URL /lg.

Disabling Caching on a Per-Request Basis

Caching was implemented to provide a natural rate-limiting mechanism for security and to reduce the load on BIRD.

In environments where you already have security in place (e.g. authenticated users on IXP Manager), you may want to disable caching for those requests. You can whitelist a set of IP addresses for this purpose by:

cp skipcache_ips.php.dist skipcache_ips.php

and then editing skipcache_ips.php to add your (for example) IXP Manager server's IP address.

If you then tag ?use_cache=0 to API requests, the cache will be avoided. Note that the results from BIRD will still be added to the cache so standard requests will still benefit with the freshest data.

Serving Behind a Proxy

The API requires prefixes (e.g. 192.0.2.0/24) to be submitted as GET requests and so they need to be URL encoded. Some web servers such as Apache squash these. A sample Apache configuration for proxying Bird's Eye requests is:

<VirtualHost 192.0.2.17:80 [2001:db8::17]:80>
    ServerName rc1-lan1-ipv4.example.com
    ServerAlias rc1-lan1-ipv6.example.com

    AllowEncodedSlashes NoDecode

    ProxyPass               /       http://10.8.5.126/     nocanon
    ProxyPassReverse        /       http://10.8.5.126/
</VirtualHost>

The code to work out what URL should be used in links can be seen here. In essence:

  • if the server is configured for HTTPS, then https:// is forced.
    • otherwise if $_SERVER['HTTP_X_FORWARDED_PROTO'] (X-Forwarded-Proto in the HTTP request header) is https, then https:// is forced.
    • otherwise it is http://
  • i
View on GitHub
GitHub Stars54
CategoryDevelopment
Updated2mo ago
Forks22

Languages

PHP

Security Score

95/100

Audited on Jan 19, 2026

No findings