Route BGP with BIRD¶
There are many ways that you can announce your IP addresses with BGP, as it can differ by the use-case and operating system. 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.
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¶
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 bring up the interface.
ifup lo:0
Installing BIRD¶
First, install system dependencies.
On Ubuntu 18.04 this looks like:
apt -y update && apt -y install bird
Gathering Your Neighbor Information¶
BIRD comes with a minimal configuration file /etc/bird/bird.conf
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 public IP address of the gateway to the upstream routers.
curl https://metadata.platformequinix.com/metadata | jq -r '.network.addresses[] | select(.public == true and .address_family == 4) | { gateway: .gateway }'
In response, you get your server's IPv4 gateway address.
{
"gateway": "198.51.100.0"
}
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 198.51.100.0;
route 169.254.255.2/32 via 198.51.100.0;
}
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 198.51.100.0;
route 169.254.255.2/32 via 198.51.100.0;
}
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
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 those interested, BIRD can also be automatically deployed via docker. See more about deploying BIRD with Docker.