This post covers how to set up a BGP session with Vultr using BIRD 2. I found that the official Vultr documentation was somewhat lacking in this area, and mostly just covered BIRD 1 and didn’t cover the IPv6 side of things. Vultr is a great provider for BGP because they offer it for free with any VPS, and it’s where a lot of people get their start with BGP.
Vultr handles BGP a bit differently from most other providers. They give you a private ASN (64515
) to peer with and also expect you to set up a static route to 2001:19f0:ffff::1/128
, which isn’t mentioned in their documentation. If you’re new to BGP, this can get quite confusing, which is why I’m writing this post.
Before I share my BIRD configuration, I’ll explain what parts of the configuration are specific to me and what parts you’ll need to change to suit your setup.
- My ASN is
44354
. This is a public ASN that I operate, but Vultr can assign you a private ASN if you don’t have one and your prefixes will be announced with their public ASN. - My Public IPv4 address is
139.180.209.121
. Although we’re not using IPv4 for BGP, it’s best practice to use it as the router ID because it’s a globally unique identifier. This applies to if you ever end up doing BGP outside of Vultr as well. - My Public IPv6 address is
2401:c080:1400:616a:5400:5ff:fe10:3e85
. Ensure that this is the address that Vultr has assigned to your server and not another one that your server might have assigned itself. - The primary interface is
eth0
and my dummy interface isdummy1
. I will explain how to set up the dummy interface later in the post. You can view what interfaces you have withip a
. - The password I share with Vultr is
hunter2
. - I’m announcing two /44 blocks,
2a14:7c0:4b10::/44
and2a14:7c0:4b00::/44
.
BIRD Configuration Link to heading
log syslog all;
router id 139.180.209.121;
protocol device {
scan time 5;
}
protocol direct {
interface "dummy*";
ipv6;
}
protocol static {
ipv6;
route 2a14:7c0:4b10::/44 reject;
route 2a14:7c0:4b00::/44 reject;
}
protocol static STATIC6 {
ipv6;
route 2001:19f0:ffff::1/128 via fe80::5400:5ff:fe10:3e85%eth0;
}
protocol bgp vultr {
description "vultr";
local 2401:c080:1400:616a:5400:5ff:fe10:3e85 as 44354;
neighbor 2001:19f0:ffff::1 as 64515;
multihop 2;
password "hunter2";
ipv6 {
import all;
export filter {
if source ~ [ RTS_DEVICE ]
then accept;
else reject;
};
};
}
If you’re wondering how the link-local address is made, take the second half of the IPv6 address that Vultr has assigned to you (it will contain ff:fe in the middle) and append it to fe80::
.
i.e. fe80::5400:5ff:fe10:3e85
is the link-local address for 2401:c080:1400:616a:5400:5ff:fe10:3e85
.
You will also need to add the static route to 2001:19f0:ffff::1/128
as mentioned earlier. This is because Vultr expects you to have a static route to their BGP server because they use multihop.
Also make sure that you have set up the dummy interface in /etc/network/interfaces
:
auto dummy1
iface dummy1 inet6 static
pre-up /sbin/ip link add dummy1 type dummy || true
post-up /sbin/ip link set dummy1 up
post-up /sbin/ip -6 addr add 2a14:7c0:4b10::1/44 dev dummy1
post-up /sbin/ip -6 route add local 2a14:7c0:4b10::/44 dev lo
post-up /sbin/ip -6 addr add 2a14:7c0:4b00::1/44 dev dummy1
post-up /sbin/ip -6 route add local 2a14:7c0:4b00::/44 dev lo
post-up /sbin/ip -6 route add 2001:19f0:ffff::1/128 via fe80::5400:5ff:fe10:3e85 dev eth0 src 2401:c080:1400:616a:5400:5ff:fe10:3e85
Then restart your networking service.
If you don’t have a /etc/network/interfaces
file, like if your server is running Debian, you can make a systemd service file to do the same thing:
[Unit]
Description=Create dummy1 interface
After=network.target
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/sbin/ip link add dummy1 type dummy || true
ExecStart=/sbin/ip link set dummy1 up
ExecStart=/sbin/ip -6 addr add 2a14:7c0:4b10::1/44 dev dummy1
ExecStart=/sbin/ip -6 route add local 2a14:7c0:4b10::/44 dev lo
ExecStart=/sbin/ip -6 addr add 2a14:7c0:4b00::1/44 dev dummy1
ExecStart=/sbin/ip -6 route add local 2a14:7c0:4b00::/44 dev lo
ExecStart=/sbin/ip -6 route add 2001:19f0:ffff::1/128 via fe80::5400:5ff:fe10:3e85 dev eth0 src 2401:c080:1400:616a:5400:5ff:fe10:3e85
[Install]
WantedBy=multi-user.target
After creating the file, reload systemd with systemctl daemon-reload
and enable the service with systemctl enable dummy1.service
.
Now, you can start BIRD and check the logs to see if everything is working. If you’re having trouble, you can check the status of the BGP session with birdc s p all
. If it says Established
, then you’re all good.
You can also check that your prefixes are being announced on the internet using some websites that observe BGP data:
- Hurricane Electric’s BGP Toolkit (Sometimes is slow to update things like IRR data)
- BGP Tools (Currently my favorite)
And also for checking that you setup your IRR data correctly, the IRR Explorer gives some really good insights:
Some common issues that you might run into are:
- Port 179 blocked by firewall: Ensure that your firewall allows inbound and outbound traffic on TCP port 179 for BGP.
- Dummy interface setup issues: Verify the dummy interface is properly created and assigned the correct addresses.
- You’re not using the exact /128 address that Vultr has assigned to you. You have to use the exact address, not a different one that your server might have assigned itself from the same /64.
- Keep in mind, Vultr’s minimum acceptable prefix length is a /48, which aligns with the minimum prefix length allowed for internet routing as per RFC 7454 6.1.3.