Bird-lg-go

March 8, 2026 ยท View on GitHub

An alternative implementation for bird-lg written in Go. Both frontend and backend (proxy) are implemented, and can work with either the original Python implementation or the Go implementation.

The code on master branch no longer support BIRDv1. Branch "bird1" is the last version that supports BIRDv1.

Table of Contents

Build Instructions

You need to have Go 1.16 or newer installed on your machine.

Run make to build binaries for both the frontend and the proxy.

Optionally run make install to install them to /usr/local/bin (bird-lg-go and bird-lgproxy-go).

Build Docker Images

Use the Dockerfiles in frontend and proxy directory.

Ready-to-use images are available at:

Frontend

The frontend directory contains the code for the web frontend, where users see BGP states, do traceroutes and whois, etc. It's a replacement for "lg.py" in original bird-lg project.

Features implemented:

  • Show peering status (show protocol command)
  • Query route (show route for ..., show route where net ~ [ ... ])
  • Whois and traceroute
  • Work with both Python proxy (lgproxy.py) and Go proxy (proxy dir of this project)
  • Visualize AS paths as picture (bgpmap feature)

Configuration can be set in:

  • bird-lg.[json/yaml/etc] in current directory
  • /etc/bird-lg/bird-lg.[json/yaml/etc]
  • Commandline parameter
  • Environment variables

Configuration is handled by viper, any config format supported by it can be used.

Config KeyParameterEnvironment VariableDescription
servers--serversBIRDLG_SERVERSserver name prefixes, separated by comma
domain--domainBIRDLG_DOMAINserver name domain suffixes
listen--listenBIRDLG_LISTENaddress bird-lg is listening on (default "5000")
proxy_port--proxy-portBIRDLG_PROXY_PORTport bird-lgproxy is running on (default 8000)
whois--whoisBIRDLG_WHOISwhois server for queries (default "whois.verisign-grs.com"). Start with "/" to specify a local whois binary (e.g. "/usr/local/bin/whois").
dns_interface--dns-interfaceBIRDLG_DNS_INTERFACEdns zone to query ASN information (default "asn.cymru.com")
bgpmap_info--bgpmap-infoBIRDLG_BGPMAP_INFOthe infos displayed in bgpmap, separated by comma, start with : means allow multiline (default "asn,as-name,ASName,descr")
title_brand--title-brandBIRDLG_TITLE_BRANDprefix of page titles in browser tabs (default "Bird-lg Go")
navbar_brand--navbar-brandBIRDLG_NAVBAR_BRANDbrand to show in the navigation bar (default same as title_brand)
navbar_brand_url--navbar-brand-urlBIRDLG_NAVBAR_BRAND_URLthe url of the brand to show in the navigation bar (default "/")
navbar_all_servers--navbar-all-serversBIRDLG_NAVBAR_ALL_SERVERSthe text of "All servers" button in the navigation bar (default "All Servers")
navbar_all_url--navbar-all-urlBIRDLG_NAVBAR_ALL_URLthe URL of "All servers" button (default "all")
net_specific_mode--net-specific-modeBIRDLG_NET_SPECIFIC_MODEapply network-specific changes for some networks, use "dn42" for BIRD in dn42 network
protocol_filter--protocol-filterBIRDLG_PROTOCOL_FILTERprotocol types to show in summary tables (comma separated list); defaults to all if not set
name_filter--name-filterBIRDLG_NAME_FILTERprotocol name regex to hide in summary tables (RE2 syntax); defaults to none if not set
timeout--time-outBIRDLG_TIMEOUTtime before backend HTTP request times out, in seconds (default 120)
connection_timeout--connection-time-outBIRDLG_CONNECTION_TIMEOUTtime before backend TCP connection times out, in seconds (default 5)
trust_proxy_headers--trust-proxy-headersBIRDLG_TRUST_PROXY_HEADERStrust X-Forwarded-For, X-Real-IP, X-Forwarded-Proto and X-Forwarded-Host headers sent by a reverse proxy (default false)
vrf--vrfBIRDLG_VRFVRF device to bind TCP sockets to (Linux only)

Examples

Example: the following command starts the frontend with 2 BIRD nodes, with domain name "gigsgigscloud.dn42.lantian.pub" and "hostdare.dn42.lantian.pub", and proxies are running on port 8000 on both nodes.

./frontend --servers=gigsgigscloud,hostdare --domain=dn42.lantian.pub --proxy-port=8000

Example: the following docker-compose.yml entry does the same as above, but by starting a Docker container:

services:
  bird-lg:
    # Use xddxdd/bird-lg-go:develop for the latest build from master branch
    image: xddxdd/bird-lg-go:latest
    container_name: bird-lg
    restart: always
    environment:
      - BIRDLG_SERVERS=gigsgigscloud,hostdare
      - BIRDLG_DOMAIN=dn42.lantian.pub
    ports:
      - "5000:5000"

Demo: https://lg.lantian.pub

Proxy

The proxy directory contains the code for the "proxy" for bird commands and traceroutes. It's a replacement for "lgproxy.py" in original bird-lg project.

Features implemented:

  • Sending queries to BIRD
  • Sending "restrict" command to BIRD to prevent unauthorized changes
  • Executing traceroute command on Linux, FreeBSD and OpenBSD
  • Source IP restriction

Configuration can be set in:

  • bird-lgproxy.[json/yaml/etc] in current directory
  • /etc/bird-lg/bird-lgproxy.[json/yaml/etc]
  • Commandline parameter
  • Environment variables

Configuration is handled by viper, any config format supported by it can be used.

Config KeyParameterEnvironment VariableDescription
bird_socket--birdBIRD_SOCKETsocket file for bird (default "/var/run/bird/bird.ctl")
bird_restrict_cmds--bird-restrict-cmdsBIRDLG_BIRD_RESTRICT_CMDSrestrict bird commands to show protocols and show route only (default true)
listen--listenBIRDLG_LISTEN / BIRDLG_PROXY_PORTlisten address (default "8000")
allowed_ips--allowedALLOWED_IPSIPs or networks allowed to access this proxy, separated by commas; allow all if not set
traceroute_bin--traceroute-binBIRDLG_TRACEROUTE_BINtraceroute binary file
traceroute_flags--traceroute-flagsBIRDLG_TRACEROUTE_FLAGStraceroute flags, supports multiple flags separated with space
traceroute_raw--traceroute-rawBIRDLG_TRACEROUTE_RAWwhether to display traceroute outputs raw (default false)
traceroute_max_concurrent--traceroute-max-concurrentBIRDLG_TRACEROUTE_MAX_CONCURRENTmax concurrent traceroute requests allowed (default 10)
vrf--vrfBIRDLG_VRFVRF device to bind TCP sockets to (Linux only)

Traceroute Binary Autodetection

If traceroute_bin or traceroute_flags is not set, then on startup, the proxy will try to traceroute 127.0.0.1 with different traceroute binaries and arguments, in order to use the most optimized setting available, while maintaining compatibility with multiple variants of traceroute binaries.

Traceroute binaries will be autodetected in the following order:

  1. If traceroute_bin is set:
    1. [traceroute_bin] -q1 -N32 -w1 127.0.0.1 (Corresponds to Traceroute on Debian)
    2. [traceroute_bin] -q1 -w1 127.0.0.1 (Corresponds to Traceroute on FreeBSD)
    3. [traceroute_bin] 127.0.0.1 (Corresponds to Busybox Traceroute)
  2. mtr -w -c1 -Z1 -G1 -b 127.0.0.1 (MTR)
  3. traceroute -q1 -N32 -w1 127.0.0.1 (Corresponds to Traceroute on Debian)
  4. traceroute -q1 -w1 127.0.0.1 (Corresponds to Traceroute on FreeBSD)
  5. traceroute 127.0.0.1 (Corresponds to Busybox Traceroute)

Examples

Example: start proxy with default configuration, should work "out of the box" on Debian 9 with BIRDv1:

./proxy

Example: start proxy with custom bird socket location:

./proxy --bird /run/bird.ctl

Example: the following docker-compose.yml entry does the same as above, but by starting a Docker container:

services:
  bird-lgproxy:
    # Use xddxdd/bird-lgproxy-go:develop for the latest build from master branch
    # Use xddxdd/bird-lgproxy-go:latest-mtr to use MTR instead of Traceroute
    image: xddxdd/bird-lgproxy-go:latest
    container_name: bird-lgproxy
    restart: always
    volumes:
      - "/run/bird.ctl:/var/run/bird/bird.ctl"
    ports:
      - "192.168.0.1:8000:8000"

You can use source IP restriction to increase security. You should also bind the proxy to a specific interface and use an external firewall/iptables for added security.

Advanced Features

Display names

The server parameter is composed of server name prefixes, separated by comma. It also supports an extended syntax: It allows to define display names for the user interface that are different from the actual server names.

For instance, the two servers from the basic example can be displayed as "Gigs" and "Hostdare" using the following syntax (as known from email addresses):

./frontend --servers="Gigs<gigsgigscloud>,Hostdare<hostdare>" --domain=dn42.lantian.pub

IP addresses

You may also specify IP addresses as server names when no domain is specified. IPv6 link local addresses are supported, too.

For example:

./frontend --servers="Prod<prod.mydomain.local>,Test1<fd88:dead:beef::1>,Test2<fe80::c%wg0>" --domain=

These three servers are displayed as "Prod", "Test1" and "Test2" in the user interface.

API

The frontend provides an API for running BIRD/traceroute/whois queries.

See API docs for detailed information.

Telegram Bot Webhook

The frontend can act as a Telegram Bot webhook endpoint, to add BGP route/traceroute/whois lookup functionality to your tech group.

See Telegram docs for detailed information.

Credits

License

GPL 3.0