Skip to main content

Configuring BGP with BIRD 1.6 on an Equinix Metal Server

Configuring BGP with BIRD 1.6 on an Equinix Metal Server

BIRD is an open source routing daemon for Unix-like systems. It can be used to establish BGP sessions between your servers and the Equinix Metal network. This is a guide for a minimum viable configuration to announce an IP address from your server via BGP.

Note: This guide is for BIRD 1.6 and its configuration is not forwards compatible with BIRD 2.0.

Previous versions of this Guide covered some Equinix Metal-created starter scripts in the packethost/network-helpers GitHub repository that can help you automate the process of pulling the BGP information you need from your server's BGP metadata and writing it into the BIRD configuration file.

Getting Started

If you are configuring BGP for the first time, the BGP on Equinix Metal doc contains a high-level overview of enabling and using BGP on the platform.

For the example here, we have set up Local BGP to advertise a public IPv4 address that is reserved to our Equinix Metal project: 10.99.200.138/32. Also note that in this example we configured BGP on Equinix Metal without a password.

Update the Network Interface

SSH into your server and update the server's network interfaces with a virtual loopback interface.

cat >>/etc/network/interfaces <<EOF
auto lo:0
iface lo:0 inet static
  address 10.99.200.138
  netmask 255.255.255.255
EOF

And then bring up the interface.

ifup lo:0

Installing BIRD

Next, install BIRD.

apt -y update && apt -y install bird

Gathering Your Neighbor Information

BIRD comes with a minimal configuration file that we are going to add a few things to in order to get the basic "announce an IP address" functionality going.

These things are found in your server's BGP metadata once you have enabled BGP on both your Project and your server.

To get your server's neighbor information, SSH into the server and cURL the metadata endpoint.

curl https://metadata.platformequinix.com/metadata | jq '.bgp_neighbors[0] | { customer_ip: .customer_ip, customer_as: .customer_as, multihop: .multihop, peer_ips: .peer_ips, peer_as: .peer_as }'

Which will return a blob of relevant BGP information.

{
  "customer_ip": "10.67.50.3",
  "customer_as": 65000,
  "multihop": true,
  "peer_ips": [
    "169.254.255.1",
    "169.254.255.2"
  ],
  "peer_as": 65530
}

You will also need to set up static routes in your config, so again cURL the metadata endpoint for the private IP address of the gateway to the upstream routers.

curl https://metadata.platformequinix.com/metadata | jq -r '.network.addresses[] | select(.public == false and .address_family == 4) | { gateway: .gateway }'

In response, you get your server's IPv4 gateway address.

{
    "gateway": "10.67.50.2"
}

Filling Out the BIRD Configuration File

Once BIRD is installed, its configuration file is found in /etc/bird/bird.conf. Use the following field mappings to fill it out.

router id should be set to the "customer_ip" returned from the metadata endpoint. In this example, it's "10.67.50.3". (As an aside, this also is your server's private IPv4 address.)

#Change this into your BIRD router ID. It's a world-wide unique identification
# of your router, usually one of router's IPv4 addresses.
router id 10.67.50.3;

Add protocol direct and set BIRD to interact with the loopback interface we set our IP address on above.

# Restrict network interfaces BIRD works with
protocol direct {
  interface "lo";
}

In protocol kernel set the configuration to persist, and change both import and export to all.

# The Kernel protocol is not a real routing protocol. Instead of communicating
# with other routers in the network, it performs synchronization of BIRD's
# routing tables with the OS kernel.
protocol kernel {
        persist;
        scan time 60;
        import all;
        export all;
}

Set the static routes between the routers and your server with protocol static. Use the "peer_ips" from the BGP information returned from the metadata endpoint, and the server's IPv4 gateway address.

protocol static {
  route 169.254.255.1/32 via 10.67.50.2;
  route 169.254.255.2/32 via 10.67.50.2;
}

Set up a basic filter.

filter metal_bgp {                                                                  
  # the IP range(s) to announce via BGP from this machine
  # these IP addresses need to be bound to the lo interface
  # to be reachable; the default behavior is to accept all
  # prefixes bound to interface lo
  # if net = A.B.C.D/32 then accept;
  accept;
}

And finally, define the BGP instances in protocol bgp, we've given ours friendly names, neighbor_v4_1 and neighbor_v4_2. The field mappings are as follows:

bird.conf metadata value
local as "customer_as" 65000
multihop multihop if the metadata shows multihop as true then you need to add multihop to BIRD
neighbor x as y "peer_ips" and "peer_as" Set one of the metadata's peer IPs (169.254.255.1, 169.254.255.2) as the neighbor per BGP instance. Set 65530 as the neighbors' AS.
protocol bgp neighbor_v4_1 {
  export filter metal_bgp;
  local as 65000;
  multihop;
  neighbor 169.254.255.1 as 65530;
}

protocol bgp neighbor_v4_2 {
  export filter metal_bgp;
  local as 65000;
  multihop;
  neighbor 169.254.255.2 as 65530;
}

Full Example Configuration File

Putting this all together, below is the example bird.conf file.

# This is a minimal configuration file.
#
# Please refer to the documentation in the bird-doc package or BIRD User's
# Guide on http://bird.network.cz/ for more information on configuring BIRD and
# adding routing protocols.

#Change this into your BIRD router ID. It's a unique identification
# of your router, usually one of router's IPv4 addresses.
router id 10.67.50.3;

# Restrict network interfaces BIRD works with
protocol direct {
  interface "lo";
}

# The Kernel protocol is not a real routing protocol. Instead of communicating
# with other routers in the network, it performs synchronization of BIRD's
# routing tables with the OS kernel.
protocol kernel {
        persist;
        scan time 60;
        import all;
        export all;
}

# The Device protocol is not a real routing protocol. It doesn't generate any
# routes and it only serves as a module for getting information about network
# interfaces from the kernel.
protocol device {
        scan time 60;
}

protocol static {
  route 169.254.255.1/32 via 10.67.50.2;
  route 169.254.255.2/32 via 10.67.50.2;
}

filter metal_bgp {
  # the IP range(s) to announce via BGP from this machine
  # these IP addresses need to be bound to the lo interface
  # to be reachable; the default behavior is to accept all
  # prefixes bound to interface lo
  # if net = A.B.C.D/32 then accept;
  accept;
}

protocol bgp neighbor_v4_1 {
  export filter metal_bgp;
  local as 65000;
  multihop;
  neighbor 169.254.255.1 as 65530;
}

protocol bgp neighbor_v4_2 {
  export filter metal_bgp;
  local as 65000;
  multihop;
  neighbor 169.254.255.2 as 65530;
}

Starting BIRD

Check that the config looks correct, then restart BIRD:

systemctl restart bird

Note: BIRD uses separate daemons for IPv4 and IPv6 routing. To configure BGP over IPv6 using BIRD, the process will be the same as above, except you will query the metadata endpoint for your server's IPv6 BGP information and you will modify the /etc/bird/bird6.conf file. And to restart BIRD:

systemctl restart bird6

Verifying the BIRD Configuration

You can check your BIRD configuration by starting up birdc.

birdc

and then using the show protocols all command for each neighbor.

bird> show protocols all neighbor_v4_1

The response should reflect the neighbor configuration you have provided in /etc/bird/bird.conf. Additionally, check the Export updates: line to see that your routes are being accepted by the upstream Equinix Metal routers. For example,

name     proto    table    state  since       info
neighbor_v4_1 BGP      master   up     17:01:12    Established
  Preference:     100
  Input filter:   ACCEPT
  Output filter:  metal_bgp
  Routes:         0 imported, 3 exported, 0 preferred
  Route change stats:     received   rejected   filtered    ignored   accepted
    Import updates:              0          0          0          0          0
    Import withdraws:            0          0        ---          0          0
    Export updates:              3          0          0        ---          3
    Export withdraws:            0        ---        ---        ---          0
  BGP state:          Established
    Neighbor address: 169.254.255.1
    Neighbor AS:      65530
    Neighbor ID:      86.109.10.78
    Neighbor caps:    refresh enhanced-refresh restart-aware AS4 add-path-rx
    Session:          external multihop AS4
    Source address:   10.67.50.3
    Hold timer:       115/180
    Keepalive timer:  35/60

To check and see if your server is now reachable at your advertised IP address, you can ping the IP address in a command line. If you are advertising a public IPv4 or IPv6 address, then you should be able to ping from any server. If you are announcing a private IPv4 address, however, you'll have to be connected to the private network so you can only ping from a server in the same project and metro (or just the same project if you have Backend Transfer enabled.)

Wrap-Up

Once you have configured BGP on the host, Equinix Metal provides monitoring for your BGP sessions. More information is on the Monitoring BGP page.

For a different example of the same process, but using FRR to manage the server's BGP session, we also have a Configuring BGP with FRR on an Equinix Metal Server guide.

For those interested, BIRD can also be automatically deployed via docker. See more about deploying BIRD with Docker.

Last updated

March 19, 2024

Category

Tagged

Technical
Subscribe to our newsletter

A monthly digest of the latest news, articles, and resources.