Bring up your first BGP session with BIRD 2
A safe, end-to-end walkthrough for verifying your ASN, configuring BIRD 2, announcing IPv4 and IPv6 space, and checking global propagation.

A BGP session has two separate jobs:
- establish a neighbour relationship with the upstream; and
- export only the prefixes you intend to originate.
Treat those as separate checkpoints. A session can be Established while exporting nothing, and a route can exist inside BIRD while being rejected by an export filter. This guide verifies each layer in order.
The addresses and customer ASN below are documentation examples. Replace every example value with the values issued by the GetVPS control panel. Do not paste the configuration unchanged.
Before you touch the VPS
You need the following:
| Item | Why it matters |
|---|---|
| A public ASN you control | The session and announcements originate from this ASN. |
| Your own IPv4 or IPv6 prefix | For broad public propagation, use an IPv4 /24 or shorter and an IPv6 /48 or shorter. |
A matching IRR route or route6 object | Networks commonly build prefix filters from IRR data. |
| A valid RPKI ROA | It authorises your ASN to originate the prefix and prevents an Invalid validation state. |
| A GetVPS VPS with BGP enabled | The portal generates the neighbour and source-address details used below. |
The ROA must cover the exact announcement and allow its prefix length. A ROA contains the prefix, authorised origin ASN, and maximum permitted length; setting maxLength incorrectly can make a legitimate announcement invalid. See the RPKI documentation if you are unsure.
Do not use a production prefix for your first attempt unless you have a maintenance window and a rollback plan. Once the route propagates, live traffic may move toward this VPS.
1. Provision the session
Open the BGP area in VPS Control and register your ASN. Verification goes to the contact address published for the ASN, so make sure that mailbox works before starting.
After verification, attach the session to the VPS and record all of the generated values:
| Portal value | Example used here |
|---|---|
| Customer ASN | AS64500 |
| GetVPS ASN | AS52025 |
| Local IPv4 source | 198.51.100.1 |
| IPv4 neighbour | 198.51.100.254 |
| Local IPv6 source | 2001:db8:ffff::1 |
| IPv6 neighbour | 2001:db8:ffff::254 |
| IPv4 announcement | 203.0.113.0/24 |
| IPv6 announcement | 2001:db8:100::/48 |
Keep the portal open while configuring BIRD. Most failed first sessions are a copied address or ASN that does not match the issued values.
2. Verify the local source addresses
BIRD must originate each TCP session from the exact local source address shown in the portal.
Find the primary interface and inspect its addresses:
ip -br link
ip -br addr
If both portal-issued source addresses are present, continue. If an address is missing, add it temporarily using the prefix length supplied by the portal:
sudo ip addr add 198.51.100.1/24 dev eth0
sudo ip addr add 2001:db8:ffff::1/64 dev eth0
Replace eth0 with the actual interface. These two commands do not survive a reboot.
To persist a missing source address, add it to the existing addresses: list for that interface under /etc/netplan/. Do not create a second competing definition without first checking the current merged configuration:
sudo netplan get
sudo netplan generate
sudo netplan try
netplan try provides an automatic rollback if you lose connectivity, but it evaluates the complete Netplan configuration. Keep the VPS console open while changing the primary interface.
3. Put an address from each announced prefix on loopback
The BGP announcement attracts traffic to the VPS; the kernel still needs a local address that can receive it. Use one address from each owned prefix on lo:
sudo ip addr add 203.0.113.1/32 dev lo
sudo ip addr add 2001:db8:100::1/128 dev lo
Persist the addresses with /etc/netplan/60-bgp-loopback.yaml:
network:
version: 2
renderer: networkd
ethernets:
lo:
addresses:
- 127.0.0.1/8
- ::1/128
- 203.0.113.1/32
- 2001:db8:100::1/128
Validate and test the complete Netplan configuration:
sudo chmod 600 /etc/netplan/60-bgp-loopback.yaml
sudo netplan generate
sudo netplan try
ip -br addr show dev lo
Netplan officially supports adding addresses to the standard loopback interface. Including 127.0.0.1/8 and ::1/128 keeps the normal host loopback addresses explicit.
4. Install BIRD 2
On Ubuntu or Debian:
sudo apt update
sudo apt install -y bird2
sudo cp -a /etc/bird/bird.conf /etc/bird/bird.conf.bak
The package uses /etc/bird/bird.conf. Confirm the path on a customised installation with systemctl cat bird.
5. Build an export-only configuration
This first configuration deliberately imports no routes. It creates one IPv4 and one IPv6 route inside BIRD, then uses exact-match export filters so no other prefix can leak to the upstream.
Replace /etc/bird/bird.conf with:
router id 198.51.100.1;
protocol device {}
protocol static originate_v4 {
ipv4;
route 203.0.113.0/24 unreachable;
}
protocol static originate_v6 {
ipv6;
route 2001:db8:100::/48 unreachable;
}
filter export_v4 {
if net = 203.0.113.0/24 then accept;
reject;
}
filter export_v6 {
if net = 2001:db8:100::/48 then accept;
reject;
}
protocol bgp getvps_v4 {
local as 64500;
source address 198.51.100.1;
neighbor 198.51.100.254 as 52025;
ipv4 {
import none;
export filter export_v4;
};
}
protocol bgp getvps_v6 {
local as 64500;
source address 2001:db8:ffff::1;
neighbor 2001:db8:ffff::254 as 52025;
ipv6 {
import none;
export filter export_v6;
};
}
The unreachable routes exist in BIRD's routing tables so they can be exported. This configuration does not include a kernel protocol, so BIRD does not install those unreachable routes into the Linux forwarding table. The loopback addresses configured earlier remain locally reachable.
Exact-match filters are intentional. Avoid broad rules such as if net ~ [203.0.113.0/24+] then accept; until you understand which more-specific routes they permit.
6. Validate before applying
Parse the file without changing the running daemon:
sudo bird -p -c /etc/bird/bird.conf
No output and exit status 0 means the syntax is valid. If parsing fails, restore the backup:
sudo cp -a /etc/bird/bird.conf.bak /etc/bird/bird.conf
If a host firewall is active, allow TCP/179 from the two issued neighbour addresses:
sudo ufw allow from 198.51.100.254 to any port 179 proto tcp
sudo ufw allow from 2001:db8:ffff::254 to any port 179 proto tcp
Then start BIRD and load the validated configuration:
sudo systemctl enable --now bird
sudo birdc configure
7. Check the session and exports
Start with protocol state:
sudo birdc show protocols
sudo birdc show protocols all getvps_v4
sudo birdc show protocols all getvps_v6
Both BGP protocols should reach Established. Next, verify the routes exist inside BIRD and pass the export filters:
sudo birdc show route protocol originate_v4
sudo birdc show route protocol originate_v6
sudo birdc show route export getvps_v4
sudo birdc show route export getvps_v6
The last two commands are the important boundary: they show what BIRD is offering to AS52025, not merely what exists in a local table.
8. Confirm external propagation
Allow a few minutes, then check the prefix from a public route collector or looking glass. The expected AS path begins with your ASN as the origin and includes AS52025 as the upstream.
Also verify the RPKI state is Valid, not merely that a route is visible. A visible route with an Invalid origin or prefix length will be rejected by networks performing route-origin validation.
Finally, test data-plane reachability from a machine outside the GetVPS network:
ping 203.0.113.1
ping -6 2001:db8:100::1
Pinging from the VPS itself only proves that the loopback address exists; it does not prove internet traffic is arriving over BGP.
Troubleshooting by state
| Symptom | Check first |
|---|---|
Idle | Confirm the protocol is enabled and the configuration loaded successfully. |
Active | Check source address, neighbour address, reachability, and TCP/179 filtering. |
OpenSent or OpenConfirm | Recheck both ASNs and look for authentication or capability errors in journalctl -u bird. |
Established, no exported route | Run show route export; check the static protocol and exact export filter. |
| Export visible, absent globally | Check prefix length, IRR object, portal prefix authorisation, and upstream filtering. |
Visible globally, RPKI Invalid | Correct the ROA origin ASN, covered prefix, or maxLength. |
| Route visible, service unreachable | Confirm the service address is on lo and the host firewall permits the traffic. |
Useful logs and diagnostics:
sudo journalctl -u bird --since '15 minutes ago'
sudo ss -tnp | grep ':179'
ip route get 198.51.100.254 from 198.51.100.1
ip -6 route get 2001:db8:ffff::254 from 2001:db8:ffff::1
Roll back cleanly
To withdraw the announcements without destroying the configuration:
sudo birdc disable getvps_v4
sudo birdc disable getvps_v6
Confirm the exports are gone and watch the public route collectors for withdrawal. Only then remove the loopback addresses if they are no longer required.
To return BIRD to its previous configuration:
sudo cp -a /etc/bird/bird.conf.bak /etc/bird/bird.conf
sudo bird -p -c /etc/bird/bird.conf
sudo birdc configure
Final checklist
- Both sessions are
Established. show route exportlists only prefixes you own.- IRR objects match the prefix and origin ASN.
- RPKI validation is
Valid. - Loopback service addresses persist after reboot.
- External IPv4 and IPv6 tests reach the VPS.
- You know how to disable both protocols and withdraw the routes.
That is the complete path: authorise, configure, validate, establish, export, and verify. BGP becomes much less mysterious when every layer has its own explicit check.
Continue reading